From d280ce0f4cb3f246279e920009fe72e1cba9fe03 Mon Sep 17 00:00:00 2001 From: prdas Date: Mon, 20 Apr 2026 17:54:01 +0200 Subject: [PATCH 1/3] Add caveman skill + AGENTS.md response-style block (treatment arm) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Treatment branch for the caveman token-cost A/B. Two mechanisms wired: 1. Custom instructions (always-on): appends a terse "Response Style" section to shared/instructions//AGENTS.md in both dataset trees. Harness already renames AGENTS.md to CLAUDE.md for Claude Code at run time (instruction_operations.py), so this block is unconditionally loaded into every session. 2. Skill (reinforcement): new shared/instructions//skills/caveman/ SKILL.md in both trees, copied into testbed .claude/skills/ by skills_operations.py when skills.enabled is true. Config toggles in shared/config.yaml: instructions.enabled and skills.enabled flipped from false to true. Only skills/caveman/SKILL.md is included. Upstream's companion skills (caveman-commit, caveman-help, caveman-review, compress) target commits / PR reviews / memory files — not exercised by BC-Bench runtime. Hooks, statusline, and /caveman mode switching are intentionally omitted — we want "full" intensity fixed for reproducibility, not interactive mode switching. Upstream: https://github.com/JuliusBrussee/caveman (MIT, LICENSE included). --- src/bcbench/agent/shared/config.yaml | 4 +- .../instructions/microsoft-BCApps/AGENTS.md | 18 +++++++ .../microsoft-BCApps/skills/caveman/LICENSE | 9 ++++ .../microsoft-BCApps/skills/caveman/SKILL.md | 48 +++++++++++++++++++ .../microsoftInternal-NAV/AGENTS.md | 18 +++++++ .../skills/caveman/LICENSE | 9 ++++ .../skills/caveman/SKILL.md | 48 +++++++++++++++++++ 7 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/LICENSE create mode 100644 src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/SKILL.md create mode 100644 src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/LICENSE create mode 100644 src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/SKILL.md diff --git a/src/bcbench/agent/shared/config.yaml b/src/bcbench/agent/shared/config.yaml index 2f271f326..274881dd6 100644 --- a/src/bcbench/agent/shared/config.yaml +++ b/src/bcbench/agent/shared/config.yaml @@ -63,14 +63,14 @@ prompt: # NOTE: the canonical source file is AGENTS.md; it is automatically renamed # to the agent-specific filename (AgentType.instruction_filename) during setup instructions: - enabled: false + enabled: true # controls: # 1. whether to copy skills from `src/bcbench/agent/shared/instructions//skills/` # - Copilot: copies to repo/.github/skills/ # - Claude: copies to repo/.claude/skills/ skills: - enabled: false + enabled: true # controls: # 1. whether to copy custom agents from `src/bcbench/agent/shared/instructions//agents/` diff --git a/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md b/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md index a54aa7011..4dbe247ef 100644 --- a/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md +++ b/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md @@ -7,3 +7,21 @@ Dynamics 365 Business Central is Microsoft's cloud-based ERP solution for small - Apps are compiled into `.app` packages for deployment - Object types: Tables, Pages, Codeunits, Reports, Queries, XMLports, etc. - Extensibility through events and object (table/page/enum) extensions + +## Response Style + +Respond terse like smart caveman. All technical substance stay. Only fluff die. + +- ACTIVE EVERY RESPONSE — no activation command, no mode toggle +- Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries, hedging +- Fragments OK. Short synonyms. Technical terms exact. +- Pattern: `[thing] [action] [reason]. [next step].` + +**Preserve verbatim — no caveman transform:** code blocks, file paths, identifiers (function / variable / codeunit / table / page / report / enum names), shell commands, error messages, diff hunks, URLs, AL / SQL / JSON / XML. + +**Code written into files** (production code, tests) stays normal per the file's conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales — NOT to file contents. + +Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..." +Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" + +Drop caveman style only for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread. Resume immediately after. diff --git a/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/LICENSE b/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/LICENSE new file mode 100644 index 000000000..fabc43146 --- /dev/null +++ b/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2026 Julius Brussee + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/SKILL.md b/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/SKILL.md new file mode 100644 index 000000000..45c9365a6 --- /dev/null +++ b/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/caveman/SKILL.md @@ -0,0 +1,48 @@ +--- +name: caveman +description: Reduce output tokens by responding in terse, fragment-based "caveman-speak" while preserving full technical accuracy. This style applies to EVERY response in the session without any activation command. Code blocks, file paths, identifiers, shell commands, and AL/SQL/JSON snippets MUST remain syntactically exact and unabbreviated. +--- + +Respond terse like smart caveman. All technical substance stay. Only fluff die. + +## Persistence + +ACTIVE EVERY RESPONSE. No revert after many turns. No filler drift. Still active if unsure. + +## Rules + +Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). Technical terms exact. + +Pattern: `[thing] [action] [reason]. [next step].` + +Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..." +Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" + +## Preserve verbatim — no caveman transform + +- Code blocks and inline code (AL, SQL, JSON, XML, PowerShell, shell) +- File paths — absolute and relative +- Identifiers — function names, variable names, type names, codeunit/table/page/report/enum names +- Shell commands and command-line arguments +- Error messages and diagnostic output (quoted exact) +- Diff hunks and patch content +- URLs and API endpoints + +## Examples + +"Why React component re-render?" → "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`." + +"Explain database connection pooling." → "Pool reuse open DB connections. No new connection per request. Skip handshake overhead." + +## Auto-clarity override + +Drop caveman ONLY for: +- Security warnings +- Irreversible action confirmations +- Multi-step sequences where fragment order risks misread + +Resume caveman immediately after clear part done. + +## Code written into files + +Code you write into files — production code, tests — stays normal per the file's conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales, NOT to file contents. diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md index 3ae3eeacf..1e04199a2 100644 --- a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md +++ b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md @@ -42,3 +42,21 @@ Business Central supports many countries and regions through a file-level inheri ## Development Focus **Important:** Unless explicitly specified otherwise, focus all development tasks on the **W1 (Worldwide)** layer. Country/region-specific changes should only be made when explicitly requested. + +## Response Style + +Respond terse like smart caveman. All technical substance stay. Only fluff die. + +- ACTIVE EVERY RESPONSE — no activation command, no mode toggle +- Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries, hedging +- Fragments OK. Short synonyms. Technical terms exact. +- Pattern: `[thing] [action] [reason]. [next step].` + +**Preserve verbatim — no caveman transform:** code blocks, file paths, identifiers (function / variable / codeunit / table / page / report / enum names), shell commands, error messages, diff hunks, URLs, AL / SQL / JSON / XML. + +**Code written into files** (production code, tests) stays normal per the file's conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales — NOT to file contents. + +Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..." +Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" + +Drop caveman style only for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread. Resume immediately after. diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/LICENSE b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/LICENSE new file mode 100644 index 000000000..fabc43146 --- /dev/null +++ b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2026 Julius Brussee + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/SKILL.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/SKILL.md new file mode 100644 index 000000000..45c9365a6 --- /dev/null +++ b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/caveman/SKILL.md @@ -0,0 +1,48 @@ +--- +name: caveman +description: Reduce output tokens by responding in terse, fragment-based "caveman-speak" while preserving full technical accuracy. This style applies to EVERY response in the session without any activation command. Code blocks, file paths, identifiers, shell commands, and AL/SQL/JSON snippets MUST remain syntactically exact and unabbreviated. +--- + +Respond terse like smart caveman. All technical substance stay. Only fluff die. + +## Persistence + +ACTIVE EVERY RESPONSE. No revert after many turns. No filler drift. Still active if unsure. + +## Rules + +Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). Technical terms exact. + +Pattern: `[thing] [action] [reason]. [next step].` + +Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..." +Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" + +## Preserve verbatim — no caveman transform + +- Code blocks and inline code (AL, SQL, JSON, XML, PowerShell, shell) +- File paths — absolute and relative +- Identifiers — function names, variable names, type names, codeunit/table/page/report/enum names +- Shell commands and command-line arguments +- Error messages and diagnostic output (quoted exact) +- Diff hunks and patch content +- URLs and API endpoints + +## Examples + +"Why React component re-render?" → "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`." + +"Explain database connection pooling." → "Pool reuse open DB connections. No new connection per request. Skip handshake overhead." + +## Auto-clarity override + +Drop caveman ONLY for: +- Security warnings +- Irreversible action confirmations +- Multi-step sequences where fragment order risks misread + +Resume caveman immediately after clear part done. + +## Code written into files + +Code you write into files — production code, tests — stays normal per the file's conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales, NOT to file contents. From 7026931de6db253d007d345ef0e27f29eafd47a7 Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Tue, 12 May 2026 17:58:54 +0200 Subject: [PATCH 2/3] Slim eval baseline: caveman-only instructions + first-party-app dataset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trim everything in the shared instruction tree to the bare minimum needed for the caveman experiment, and shrink the dataset to first-party apps so the local A/B loop runs in minutes rather than hours. Instruction tree (microsoft-BCApps + microsoftInternal-NAV): - AGENTS.md: drop the BC/AL overview prose; keep only the "Response Style" caveman block as the canonical instruction file. This is what the harness renames to copilot-instructions.md / CLAUDE.md and loads into the system prompt every turn (always-on enforcement). - skills/: drop al-test-generation; keep only skills/caveman/. - agents/: drop ALTest.agent.md (and the now-empty agents/ dir). - instructions/ (NAV only): drop codeunits/pages/tables.instructions.md. Local A/B (microsoft__BCApps-4699, claude-haiku-4.5, n=1) showed the extra instruction surface area was a net loss — input-side overhead from loading the skill files outweighed any output-side savings on a short patch task. caveman-compress was a particularly bad fit since it never fires during a bug-fix run; dropping it. Dataset: - Filter dataset/bcbench.jsonl to entries whose project_paths do NOT start with App\Layers\W1\BaseApp. 101 -> 16 entries, all under App\Apps\W1\ (Shopify, Sustainability, ExcelReports, SubscriptionBilling, etc.). BaseApp tasks pull in the entire base application and dominate eval wall time. Tests: - test_agent_skills.py: switch fixture from "al-test-generation" to "caveman" since that is now the only checked-in skill. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dataset/bcbench.jsonl | 85 ------ .../instructions/microsoft-BCApps/AGENTS.md | 16 +- .../microsoft-BCApps/agents/ALTest.agent.md | 267 ------------------ .../skills/al-test-generation/SKILL.md | 93 ------ .../microsoftInternal-NAV/AGENTS.md | 51 +--- .../agents/ALTest.agent.md | 267 ------------------ .../instructions/codeunits.instructions.md | 8 - .../instructions/pages.instructions.md | 8 - .../instructions/tables.instructions.md | 8 - .../skills/al-test-generation/SKILL.md | 93 ------ tests/test_agent_skills.py | 10 +- 11 files changed, 11 insertions(+), 895 deletions(-) delete mode 100644 src/bcbench/agent/shared/instructions/microsoft-BCApps/agents/ALTest.agent.md delete mode 100644 src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/al-test-generation/SKILL.md delete mode 100644 src/bcbench/agent/shared/instructions/microsoftInternal-NAV/agents/ALTest.agent.md delete mode 100644 src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/codeunits.instructions.md delete mode 100644 src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/pages.instructions.md delete mode 100644 src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/tables.instructions.md delete mode 100644 src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/al-test-generation/SKILL.md diff --git a/dataset/bcbench.jsonl b/dataset/bcbench.jsonl index 54796b9fb..c9fef5a01 100644 --- a/dataset/bcbench.jsonl +++ b/dataset/bcbench.jsonl @@ -1,101 +1,16 @@ {"metadata": {"area": "sustainability", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-210528", "base_commit": "1a672853b5e939932b2b9caff994bef826e928ff", "created_at": "2025-03-19", "environment_setup_version": "26.5", "project_paths": ["App\\Apps\\W1\\Sustainability\\app", "App\\Apps\\W1\\Sustainability\\test"], "FAIL_TO_PASS": [{"codeunitID": 148187, "functionName": ["VerifyEmissionFieldsMustBeEnabledWhenEnableValueChainTrackingIsEnabled"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al b/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al\nindex ff9b7640fa2..07bfdfa1233 100644\n--- a/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al\n+++ b/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al\n@@ -5123,6 +5123,47 @@ codeunit 148187 \"Sust. Certificate Test\"\n // [THEN] Confirmation Box should not pop up as there is no confirm Handler. \n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerYes')]\n+ procedure VerifyEmissionFieldsMustBeEnabledWhenEnableValueChainTrackingIsEnabled()\n+ var\n+ SustainabilitySetup: Record \"Sustainability Setup\";\n+ begin\n+ // [SCENARIO 569462] Verify \"Use Emissions In Purch. Doc.\", \"Item Emissions\", \"Resource Emissions\", \"Work/Machine Center Emissions\" must be enabled in Sustainability Setup.\n+ // When \"Enable Value Chain Tracking\" is enabled.\n+ LibrarySustainability.CleanUpBeforeTesting();\n+\n+ // [GIVEN] Update Sustainability Setup.\n+ SustainabilitySetup.Get();\n+ SustainabilitySetup.Validate(\"Use Emissions In Purch. Doc.\", false);\n+ SustainabilitySetup.Validate(\"Item Emissions\", false);\n+ SustainabilitySetup.Validate(\"Resource Emissions\", false);\n+ SustainabilitySetup.Validate(\"Work/Machine Center Emissions\", false);\n+ SustainabilitySetup.Validate(\"Enable Value Chain Tracking\", false);\n+ SustainabilitySetup.Modify();\n+\n+ // [WHEN] \"Enable Value Chain Tracking\" set to true in Sustainability Setup.\n+ SustainabilitySetup.Validate(\"Enable Value Chain Tracking\", true);\n+\n+ // [THEN] Verify \"Use Emissions In Purch. Doc.\", \"Item Emissions\", \"Resource Emissions\", \"Work/Machine Center Emissions\" must be enabled in Sustainability Setup.\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Use Emissions In Purch. Doc.\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Use Emissions In Purch. Doc.\"), SustainabilitySetup.TableCaption()));\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Item Emissions\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Item Emissions\"), SustainabilitySetup.TableCaption()));\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Resource Emissions\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Resource Emissions\"), SustainabilitySetup.TableCaption()));\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Work/Machine Center Emissions\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Work/Machine Center Emissions\"), SustainabilitySetup.TableCaption()));\n+ end;\n+\n local procedure CreateSustainabilityAccount(var AccountCode: Code[20]; var CategoryCode: Code[20]; var SubcategoryCode: Code[20]; i: Integer): Record \"Sustainability Account\"\n begin\n CreateSustainabilitySubcategory(CategoryCode, SubcategoryCode, i);\n", "patch": "diff --git a/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al b/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al\nindex 335c0099f4a..bf9281c17f7 100644\n--- a/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al\n+++ b/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al\n@@ -151,6 +151,8 @@ table 6217 \"Sustainability Setup\"\n if Rec.\"Enable Value Chain Tracking\" then\n if not ConfirmManagement.GetResponseOrDefault(ConfirmEnableValueChainTrackingQst, false) then\n Error('');\n+\n+ EnableEmissionsWhenValueChainTrackingIsEnabled();\n end;\n }\n }\n@@ -188,6 +190,17 @@ table 6217 \"Sustainability Setup\"\n exit(\"Enable Value Chain Tracking\");\n end;\n \n+ local procedure EnableEmissionsWhenValueChainTrackingIsEnabled()\n+ begin\n+ if not Rec.\"Enable Value Chain Tracking\" then\n+ exit;\n+\n+ Rec.Validate(\"Use Emissions In Purch. Doc.\", true);\n+ Rec.Validate(\"Item Emissions\", true);\n+ Rec.Validate(\"Resource Emissions\", true);\n+ Rec.Validate(\"Work/Machine Center Emissions\", true);\n+ end;\n+\n internal procedure GetFormat(FieldNo: Integer): Text\n begin\n GetSustainabilitySetup();\n"} -{"metadata": {"area": "inventory", "image_count": 0, "commnet": "Test might be insuffient"}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-224009", "base_commit": "719cf1cc85730da9c59cdcb0ac18ddaf11d113fd", "created_at": "2025-08-16", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137045, "functionName": ["CheckTrackingReservationEntriesUpdatedWheLotNoAllocated"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\nindex bfcb627e6e5..f8db5ec3cf2 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n@@ -1217,6 +1217,76 @@ codeunit 137045 \"SCM Bugfixes\"\n AssertReservationEntryCountForSales(SalesHeader, 3);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandlerOrderTracking,ItemTrackingLinesPageHandler')]\n+ procedure CheckTrackingReservationEntriesUpdatedWheLotNoAllocated()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ UnitofMeasure: Record \"Unit of Measure\";\n+ InventoryPostingSetup: Record \"Inventory Posting Setup\";\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ReservationEntry, ReservationEntry1 : Record \"Reservation Entry\";\n+ LotNo, LotNo1, LotNo2 : Code[50];\n+ begin\n+ // [SCENARIO 580079] Wrong Decimal Rounding with Quantity in Reservation Entries, using Order Tracking Policy where tracking lines are split into 3, each ending in x.xxxx7, which results with all 3 adding up to x.00001\n+ Initialize();\n+\n+ // [GIVEN] Created Lot Tracked Item.\n+ CreateTrackedItemWithOrderTrackingPolicy(Item);\n+\n+ // [GIVEN] Create new UOM for CASE (CA), Qty 24 Per Base UOM of PCS\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitofMeasure);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure, Item.\"No.\", UnitofMeasure.Code, 24);\n+\n+ // [GIVEN] Create Location\n+ LibraryWarehouse.CreateLocation(Location);\n+\n+ // [GIVEN] Create Inventory Posting Setup with Inventory Account\n+ LibraryInventory.CreateInventoryPostingSetup(InventoryPostingSetup, Location.Code, Item.\"Inventory Posting Group\");\n+ InventoryPostingSetup.Validate(\"Inventory Account\", LibraryERM.CreateGLAccountNo());\n+ InventoryPostingSetup.Modify();\n+\n+ // [GIVEN] Create Positive Adjustment for 288 Quantity with 1 Lot No\n+ LotNo := LibraryUtility.GenerateGUID();\n+ CreateItemJournalLineItemTrackingEnabled(ItemJournalLine, Item.\"No.\", Location.Code, 288);\n+ LibraryItemTracking.CreateItemJournalLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo, 288);\n+ LibraryInventory.PostItemJnlLineWithCheck(ItemJournalLine);\n+\n+ // [GIVEN] Create Positive Adjustment for 440 Quantity with 2 different Lot\n+ LotNo1 := LibraryUtility.GenerateGUID();\n+ LotNo2 := LibraryUtility.GenerateGUID();\n+ CreateItemJournalLineItemTrackingEnabled(ItemJournalLine, Item.\"No.\", Location.Code, 440);\n+ LibraryItemTracking.CreateItemJournalLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo1, 220);\n+ LibraryItemTracking.CreateItemJournalLineItemTracking(ReservationEntry1, ItemJournalLine, '', LotNo2, 220);\n+ LibraryInventory.PostItemJnlLineWithCheck(ItemJournalLine);\n+\n+ // [GIVEN] Created Sales Order with 1 Item and 3 quantity.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, '');\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", 12);\n+ SalesLine.Validate(\"Location Code\", Location.Code);\n+ SalesLine.Validate(\"Unit of Measure Code\", UnitofMeasure.Code);\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] From Item tracking lines (Sales Order), add a Lot No to the item.\n+ LibraryVariableStorage.Enqueue(ItemTrackingHandlerAction::AssignSpecificLot);\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(288);\n+ SalesLine.OpenItemTrackingLines(); // ItemTrackingLinesPageHandler required.\n+\n+ // [WHEN] Change the quantity from Item tracking lines (Sales Order), of a Lot No to 13.\n+ LibraryVariableStorage.Enqueue(ItemTrackingHandlerAction::AssignSpecificLot);\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(13);\n+ SalesLine.OpenItemTrackingLines(); // ItemTrackingLinesPageHandler required.\n+\n+ // [THEN] Reservation entry Quantity field should come with -12\n+ VerifyReservationEntryQuantity(Item.\"No.\", SalesHeader.\"No.\", -12);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1310,6 +1380,23 @@ codeunit 137045 \"SCM Bugfixes\"\n LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n end;\n \n+ local procedure CreateItemJournalLineItemTrackingEnabled(var ItemJournalLine: Record \"Item Journal Line\"; ItemNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal)\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, \"Item Journal Template Type\"::Item);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, \"Item Journal Template Type\"::Item, ItemJournalTemplate.Name);\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+ ItemJournalBatch.\"Item Tracking on Lines\" := true;\n+ ItemJournalBatch.Modify();\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", ItemNo, Quantity);\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n local procedure CreateCertifiedProductionBOMWithComponentStartingDate(var ProductionBOMHeader: Record \"Production BOM Header\"; UOMCode: Code[10]; ItemNo: Code[20]; QtyPer: Decimal; StartingDate: Date)\n var\n ProductionBOMLine: Record \"Production BOM Line\";\n@@ -1985,6 +2072,16 @@ codeunit 137045 \"SCM Bugfixes\"\n Assert.RecordCount(ReservationEntry, ExpectedCount);\n end;\n \n+ local procedure VerifyReservationEntryQuantity(ItemNo: Code[20]; SourceID: Code[20]; ExpectedQuantity: Decimal)\n+ var\n+ ReservEntry: Record \"Reservation Entry\";\n+ begin\n+ ReservEntry.SetRange(\"Item No.\", ItemNo);\n+ ReservEntry.SetRange(\"Source ID\", SourceID);\n+ ReservEntry.CalcSums(Quantity);\n+ ReservEntry.TestField(Quantity, ExpectedQuantity);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListModalPageHandler(var ContactLookup: Page \"Contact List\"; var Response: Action)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\nindex c1b41b1585b..a37726d678f 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n@@ -914,7 +914,7 @@ table 337 \"Reservation Entry\"\n ReservEntry.SetFilter(\"Entry No.\", '<>%1', \"Entry No.\");\n ReservEntry.SetSourceFilter(\"Source Type\", \"Source Subtype\", \"Source ID\", \"Source Ref. No.\", false);\n ReservEntry.SetSourceFilter(\"Source Batch Name\", \"Source Prod. Order Line\");\n- ReservEntry.SetRange(\"Reservation Status\", \"Reservation Status\"::Reservation);\n+ ReservEntry.SetFilter(\"Reservation Status\", '%1|%2', \"Reservation Status\"::Reservation, \"Reservation Status\"::Tracking);\n ReservEntry.CalcSums(\"Quantity (Base)\", Quantity);\n exit(\n Round((ReservEntry.\"Quantity (Base)\" + \"Quantity (Base)\") / \"Qty. per Unit of Measure\", UOMMgt.QtyRndPrecision()) -\n"} {"metadata": {"area": "shopify", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-211710", "base_commit": "f787c24e811a24e4bd5a2d987ea406b3d2fe6ad0", "created_at": "2025-03-31", "environment_setup_version": "26.5", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139648, "functionName": ["UnitTestSuggestShopifyPaymentsFailedTransaction"]}], "PASS_TO_PASS": [{"codeunitID": 139648, "functionName": ["UnitTestSuggestShopifyPaymentsMultipleTransactions", "UnitTestSuggestShopifyPaymentsOneTransaction"]}], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\nindex d4318405610..cf234743596 100644\n--- a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n+++ b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n@@ -32,7 +32,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n \n // [GIVEN] Shopify transaction is imported\n- CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale);\n+ CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n \n // [WHEN] Create Shopify transactions are run\n OrderTransaction.FindFirst();\n@@ -65,8 +65,8 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n \n // [GIVEN] Shopify transactions are imported\n- CreateOrderTransaction(OrderId, Amount * 0.75, 'manual', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale);\n+ CreateOrderTransaction(OrderId, Amount * 0.75, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n \n // [WHEN] Create Shopify transactions are run\n OrderTransaction.SetRange(\"Shopify Order Id\", OrderId);\n@@ -86,6 +86,45 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n until SuggestPayment.Next() = 0;\n end;\n \n+ [HandlerFunctions('SuggestShopifyPaymentsRequestPageHandler')]\n+ [Test]\n+ procedure UnitTestSuggestShopifyPaymentsFailedTransaction()\n+ var\n+ Item: Record Item;\n+ Customer: Record Customer;\n+ OrderTransaction: Record \"Shpfy Order Transaction\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ CashReceiptJournal: TestPage \"Cash Receipt Journal\";\n+ OrderId: BigInteger;\n+ SuccessTransactionId: BigInteger;\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO] Suggest Shopify payments does not create Cash Receipt Journal lines for failed transactions\n+ // [GIVEN] Invoice is posted\n+ Initialize();\n+ Amount := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(10000, 99999);\n+ CreateItem(Item, Amount);\n+ LibrarySales.CreateCustomer(Customer);\n+ CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n+\n+ // [GIVEN] One failed one success Shopify transaction is imported\n+ CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Failure);\n+ SuccessTransactionId := CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ Commit();\n+\n+ // [WHEN] Report is run\n+ CashReceiptJournal.OpenView();\n+ CashReceiptJournal.SuggestShopifyPayments.Invoke();\n+\n+ // [THEN] Only one Cash Receipt Journal line is created\n+ GenJournalLine.SetRange(\"Document Type\", GenJournalLine.\"Document Type\"::Payment);\n+ GenJournalLine.SetRange(\"Account No.\", Customer.\"No.\");\n+ LibraryAssert.RecordCount(GenJournalLine, 1);\n+ GenJournalLine.FindFirst();\n+ LibraryAssert.AreEqual(GenJournalLine.\"Shpfy Transaction Id\", SuccessTransactionId, 'Transaction Ids should match');\n+ end;\n+\n [HandlerFunctions('SuggestShopifyPaymentsRequestPageHandler')]\n [Test]\n procedure UnitTestSuggestShopifyPaymentsJournalLines()\n@@ -114,10 +153,10 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesInvoice(Item, Customer, 2, OrderId3);\n \n // [GIVEN] Shopify transactions are imported\n- CreateOrderTransaction(OrderId1, Amount, 'manual', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId2, Amount * 0.75, 'manual', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId2, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId3, Amount * 2, 'bogus', OrderTransaction.Type::Sale);\n+ CreateOrderTransaction(OrderId1, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId2, Amount * 0.75, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId2, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId3, Amount * 2, 'bogus', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n Commit();\n \n // [WHEN] Report is run\n@@ -154,7 +193,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesCreditMemo(Item, Customer, 1, RefundId);\n \n // [GIVEN] Shopify transaction is imported\n- CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Refund);\n+ CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Refund, OrderTransaction.Status::Success);\n \n // [WHEN] Create Shopify transactions are run\n OrderTransaction.FindFirst();\n@@ -210,7 +249,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n Item.Modify(true);\n end;\n \n- local procedure CreateOrderTransaction(OrderId: BigInteger; Amount: Decimal; Gateway: Code[20]; TransactionType: Enum \"Shpfy Transaction Type\")\n+ local procedure CreateOrderTransaction(OrderId: BigInteger; Amount: Decimal; Gateway: Code[20]; TransactionType: Enum \"Shpfy Transaction Type\"; Status: Enum \"Shpfy Transaction Status\"): BigInteger\n var\n OrderTransaction: Record \"Shpfy Order Transaction\";\n begin\n@@ -219,7 +258,9 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n OrderTransaction.Amount := Amount;\n OrderTransaction.Gateway := Gateway;\n OrderTransaction.Type := TransactionType;\n+ OrderTransaction.Status := Status;\n OrderTransaction.Insert();\n+ exit(OrderTransaction.\"Shopify Transaction Id\");\n end;\n \n local procedure CreateRefund(OrderId: BigInteger; RefundId: BigInteger; Amount: Decimal)\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\nindex 773ba116023..274900e6ee5 100644\n--- a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n+++ b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n@@ -17,7 +17,7 @@ report 30118 \"Shpfy Suggest Payments\"\n dataitem(OrderTransaction; \"Shpfy Order Transaction\")\n {\n RequestFilterFields = \"Created At\";\n- DataItemTableView = sorting(Type) where(Type = filter(Capture | Sale | Refund));\n+ DataItemTableView = sorting(Type) where(Type = filter(Capture | Sale | Refund), Status = filter(Success));\n \n trigger OnAfterGetRecord()\n begin\n"} -{"metadata": {"area": "manufacturing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220984", "base_commit": "da8aacf769f29847b57739a6db797e65057ea268", "created_at": "2025-07-15", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Manufacturing"], "FAIL_TO_PASS": [{"codeunitID": 137404, "functionName": ["ExchangeProductionBOMItemShouldSetEndingDate"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al b/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al\nindex f6545527796..b7f7674ae29 100644\n--- a/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al\n@@ -4829,6 +4829,54 @@ codeunit 137404 \"SCM Manufacturing\"\n Assert.AreEqual(StandardTask.Code, ProdOrderLine.\"Standard Task Code\", StandardTaskFieldErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('RunExchangeProdBOMItemReportWithStartDateParameter')]\n+ procedure ExchangeProductionBOMItemShouldSetEndingDate()\n+ var\n+ Item: array[5] of Record Item;\n+ MainItem: Record Item;\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ i: Integer;\n+ begin\n+ // [SCENARIO 592157] Replacing a component in a Production BOM should set the Ending Date of the replaced component.\n+ Initialize();\n+\n+ LibraryInventory.CreateItem(MainItem);\n+ MainItem.Validate(\"Replenishment System\", MainItem.\"Replenishment System\"::\"Prod. Order\");\n+ MainItem.Modify(true);\n+\n+ // [GIVEN] Create a Production BOM Header\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, MainItem.\"Base Unit of Measure\");\n+\n+ // [GIVEN] Create Items\n+ for i := 1 to 5 do\n+ LibraryInventory.CreateItem(Item[i]);\n+\n+ // [GIVEN] Add only Items[1..4] to the BOM\n+ for i := 1 to 4 do\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, Item[i].\"No.\", LibraryRandom.RandIntInRange(10, 20));\n+\n+ // [GIVEN] Certify BOM and assign to Main Item\n+ ModifyStatusInProductionBOM(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+ MainItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ MainItem.Modify(true);\n+\n+ // [GIVEN] Enqueue parameter values for report\n+ EnqueueExchProdBOMItemReportParameter(Item[1].\"No.\", Item[5].\"No.\", Today);\n+\n+ // [WHEN] Run the Exchange Production BOM Item report\n+ RunExchangeProductionBOMItemReport();\n+\n+ // [THEN] Validate that the replaced item has an Ending Date of (StartDate - 1)\n+ ValidateEndingDateSet(ProductionBOMHeader.\"No.\", Item[1].\"No.\", Today);\n+\n+ // [AND] Ensure no test artifacts are left behind\n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -7704,6 +7752,23 @@ codeunit 137404 \"SCM Manufacturing\"\n standardTask.Modify(true);\n end;\n \n+ local procedure EnqueueExchProdBOMItemReportParameter(ExchangeItemNo: Code[20]; ReplaceItemNo: Code[20]; StartDate: Date)\n+ begin\n+ LibraryVariableStorage.Enqueue(ExchangeItemNo);\n+ LibraryVariableStorage.Enqueue(ReplaceItemNo);\n+ LibraryVariableStorage.Enqueue(StartDate);\n+ end;\n+\n+ local procedure ValidateEndingDateSet(ProdBOMHeaderNo: Code[20]; ItemNo: Code[20]; StartingDate: Date)\n+ var\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ begin\n+ ProductionBOMLine.SetRange(\"Production BOM No.\", ProdBOMHeaderNo);\n+ ProductionBOMLine.SetRange(\"No.\", ItemNo);\n+ ProductionBOMLine.FindFirst();\n+ Assert.AreEqual(StartingDate - 1, ProductionBOMLine.\"Ending Date\", 'Ending Date is not correctly set on the Production BOM line.')\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ProdBOMVersionComparisonHandlerForActionSet(var ProdBOMVersionComparison: TestPage \"Prod. BOM Version Comparison\")\n@@ -7793,5 +7858,28 @@ codeunit 137404 \"SCM Manufacturing\"\n ExchangeProductionBOMItem.WithType.AssertEquals(ProductionBOMLineType::Item);// [THEN] Verify WithType Default Type is ITEM\n ExchangeProductionBOMItem.OK().Invoke();\n end;\n+\n+ [RequestPageHandler]\n+ procedure RunExchangeProdBOMItemReportWithStartDateParameter(var ExchangeProductionBOMItem: TestRequestPage \"Exchange Production BOM Item\")\n+ var\n+ FromProductionBOMLineType: Enum \"Production BOM Line Type\";\n+ ExchangeItemNo: Variant;\n+ ReplaceItemNo: Variant;\n+ StartDate: Variant;\n+ begin\n+ ExchangeItemNo := LibraryVariableStorage.DequeueText();\n+ ReplaceItemNo := LibraryVariableStorage.DequeueText();\n+ StartDate := LibraryVariableStorage.DequeueDate();\n+ ExchangeProductionBOMItem.ExchangeType.SetValue(FromProductionBOMLineType::Item);\n+ ExchangeProductionBOMItem.ExchangeNo.SetValue(ExchangeItemNo);\n+ ExchangeProductionBOMItem.WithType.SetValue(FromProductionBOMLineType::Item);\n+ ExchangeProductionBOMItem.WithNo.SetValue(ReplaceItemNo);\n+ ExchangeProductionBOMItem.\"Create New Version\".SetValue(false);\n+ ExchangeProductionBOMItem.\"Delete Exchanged Component\".SetValue(false);\n+ ExchangeProductionBOMItem.Recertify.SetValue(true);\n+ ExchangeProductionBOMItem.CopyRoutingLink.SetValue(true);\n+ ExchangeProductionBOMItem.StartingDate.SetValue(StartDate);\n+ ExchangeProductionBOMItem.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al b/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al\nindex 83bf3f09247..fc62ac19292 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al\n@@ -157,7 +157,7 @@ report 99001043 \"Exchange Production BOM Item\"\n CopyPositionFields(ProductionBOMLine2, ProductionBOMLine3);\n ShouldModifyProductionBOMLine := true;\n OnIntegerOnPostDataItemOnBeforeModifyProductionBOMLine(ProductionBOMLine, ShouldModifyProductionBOMLine);\n- if not ShouldModifyProductionBOMLine then begin\n+ if ShouldModifyProductionBOMLine then begin\n ProductionBOMLine.\"Ending Date\" := StartingDate - 1;\n ProductionBOMLine.Modify();\n end;\n"} {"metadata": {"area": "visualization", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-224668", "base_commit": "e99adb71b2355dc29eb398ab9ae0d59003a84d5d", "created_at": "2025-08-25", "environment_setup_version": "27.0", "project_paths": ["App\\Apps\\W1\\EssentialBusinessHeadlines\\app", "App\\Apps\\W1\\EssentialBusinessHeadlines\\test"], "FAIL_TO_PASS": [{"codeunitID": 139600, "functionName": ["TestHeadlineCanBeHidden"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al b/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al\nindex db731e8675d..fb82838356c 100644\n--- a/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al\n+++ b/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al\n@@ -700,6 +700,33 @@ codeunit 139600 \"Test Essential Bus. Headlines\"\n TestRecentlyOverdueInvoiceWithOverdueInvoices(5);\n end;\n \n+ [Test]\n+ procedure TestHeadlineCanBeHidden()\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ begin\n+ // [GIVEN] Initial state when no data is present\n+ Initialize();\n+\n+ // [GIVEN] One invoice that was due yesterday\n+ CreateInvoicesWithDueDateYesterday(1);\n+\n+ // [WHEN] Run the headline computation\n+ EssentialBusHeadlineMgt.HandleRecentlyOverdueInvoices();\n+\n+ // [THEN] Recently overdue invoices headline is visible\n+ Assert.IsTrue(GetVisibility(EssentialBusinessHeadline.\"Headline Name\"::RecentlyOverdueInvoices), 'Expected recently overdue invoices headline to be visible');\n+\n+ // [WHEN] Simulate no more overdue invoices by deleting all customer ledger entries\n+ CustLedgerEntry.DeleteAll();\n+\n+ // [WHEN] Recompute the headline computation\n+ EssentialBusHeadlineMgt.HandleRecentlyOverdueInvoices();\n+\n+ // [THEN] The headline is hidden\n+ Assert.IsFalse(GetVisibility(EssentialBusinessHeadline.\"Headline Name\"::RecentlyOverdueInvoices), 'Expected recently overdue invoices headline to be not visible after recompute');\n+ end;\n+\n local procedure TestRecentlyOverdueInvoiceWithOverdueInvoices(NumberOfNewlyOverdueInvoices: Integer)\n var\n OverdueInvoicesTxt: Text;\n", "patch": "diff --git a/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al b/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al\nindex 831aa80efcd..10436a095d8 100644\n--- a/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al\n+++ b/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al\n@@ -677,7 +677,7 @@ codeunit 1437 \"Essential Bus. Headline Mgt.\"\n var\n EssentialBusinessHeadline: Record \"Ess. Business Headline Per Usr\";\n begin\n- if EssentialBusinessHeadline.Get(HeadlineName) then begin\n+ if EssentialBusinessHeadline.Get(HeadlineName, UserSecurityId()) then begin\n EssentialBusinessHeadline.Validate(\"Headline Visible\", false);\n EssentialBusinessHeadline.Modify();\n end;\n"} -{"metadata": {"area": "finance", "image_count": 0, "commnet": "Test might be insuffient"}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218323", "base_commit": "cf24533288281b2df45cbb33654a17f430a0619f", "created_at": "2025-06-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134992, "functionName": ["PostVATSettlementWhenJournalTemplateNameMandatoryIsEnabled"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al\nindex 5c994880ad2..b8c9d7f62bd 100644\n--- a/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al\n@@ -765,6 +765,53 @@ codeunit 134992 \"ERM Financial Reports IV\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('RHCalcAndPostVATSettlementSetCountryFilter')]\n+ procedure PostVATSettlementWhenJournalTemplateNameMandatoryIsEnabled()\n+ var\n+ Customer: Record Customer;\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ VATEntry: Record \"VAT Entry\";\n+ GLEntry: Record \"G/L Entry\";\n+ MyNotifications: Record \"My Notifications\";\n+ GeneralLedgerSetup: Record \"General Ledger Setup\";\n+ InstructionMgt: Codeunit \"Instruction Mgt.\";\n+ PostingDate: Date;\n+ begin\n+ // [SCENARIO 571198] No error should appears when user try to Calculate and Post VAT Settlement when Journal Template Name Mandatory is enabled\n+ Initialize();\n+\n+ // [GIVEN] Set Journal Templ. Name Mandatory to false on General ledger Setup.\n+ GeneralLedgerSetup.Get();\n+ GeneralLedgerSetup.\"Journal Templ. Name Mandatory\" := true;\n+ GeneralLedgerSetup.Modify();\n+\n+ MyNotifications.Disable(InstructionMgt.GetPostingAfterWorkingDateNotificationId());\n+ GLEntry.SetCurrentKey(\"Posting Date\", \"G/L Account No.\", \"Dimension Set ID\");\n+ GLEntry.FindLast();\n+ PostingDate := GLEntry.\"Posting Date\" + 1;\n+\n+ // [GIVEN] Create customer and post a sales invoice\n+ LibrarySales.CreateCustomerWithCountryCodeAndVATRegNo(Customer);\n+ CreateAndPostGeneralJournalLine(\n+ VATPostingSetup, PostingDate, GenJournalLine.\"Account Type\"::Customer, Customer.\"No.\",\n+ GenJournalLine.\"Gen. Posting Type\"::Sale, 1, true);\n+\n+ LibraryVariableStorage.Enqueue(Customer.\"Country/Region Code\"); // set country/region filter for RHCalcAndPostVATSettlementSetCountryFilter\n+ Clear(LibraryReportDataset);\n+\n+ // [WHEN] Run Calculate and Post VAT Settlement report\n+ SaveCalcAndPostVATSettlementReport(VATPostingSetup, PostingDate, PostingDate, PostingDate, Format(LibraryRandom.RandInt(100)), true);\n+\n+ // [THEN] VAT Entry for the second invoice is closed\n+ // [THEN] Closing entry created with type 'Settlement'\n+ VATEntry.SetRange(\"Bill-to/Pay-to No.\", Customer.\"No.\");\n+ VATEntry.FindFirst();\n+ VATEntry.Get(VATEntry.\"Closed by Entry No.\");\n+ VATEntry.TestField(Type, VATEntry.Type::Settlement);\n+ end;\n+\n local procedure Initialize()\n var\n ObjectOptions: Record \"Object Options\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al\nindex c7ffd42ba4c..d596be8a7fd 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al\n@@ -57,6 +57,7 @@ codeunit 11 \"Gen. Jnl.-Check Line\"\n OverrideDimErr: Boolean;\n LogErrorMode: Boolean;\n IsBatchMode: Boolean;\n+ IgnoreJournalTemplNameMandatoryCheck: Boolean;\n \n #pragma warning disable AA0074\n Text000: Label 'can only be a closing date for G/L entries';\n@@ -380,6 +381,11 @@ codeunit 11 \"Gen. Jnl.-Check Line\"\n OverrideDimErr := true;\n end;\n \n+ procedure SetIgnoreJournalTemplNameMandatoryCheck()\n+ begin\n+ IgnoreJournalTemplNameMandatoryCheck := true;\n+ end;\n+\n local procedure CheckDates(GenJnlLine: Record \"Gen. Journal Line\")\n var\n AccountingPeriodMgt: Codeunit \"Accounting Period Mgt.\";\n@@ -400,8 +406,9 @@ codeunit 11 \"Gen. Jnl.-Check Line\"\n end;\n end;\n \n- if GLSetup.\"Journal Templ. Name Mandatory\" then\n- GenJnlLine.TestField(\"Journal Template Name\", ErrorInfo.Create());\n+ if not IgnoreJournalTemplNameMandatoryCheck then\n+ if GLSetup.\"Journal Templ. Name Mandatory\" then\n+ GenJnlLine.TestField(\"Journal Template Name\", ErrorInfo.Create());\n OnBeforeDateNotAllowed(GenJnlLine, DateCheckDone);\n if not DateCheckDone then\n if DateNotAllowed(GenJnlLine.\"Posting Date\", GenJnlLine.\"Journal Template Name\") then\ndiff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al\nindex da61c5f2c5d..35021399a12 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al\n@@ -138,6 +138,7 @@ codeunit 12 \"Gen. Jnl.-Post Line\"\n MultiplePostingGroups: Boolean;\n SourceCodeSetupRead: Boolean;\n IsGLRegInserted: Boolean;\n+ IgnoreJournalTemplNameMandatoryCheck: Boolean;\n \n NeedsRoundingErr: Label '%1 needs to be rounded', Comment = '%1 - amount';\n PurchaseAlreadyExistsErr: Label 'Purchase %1 %2 already exists for this vendor.', Comment = '%1 = Document Type; %2 = Document No.';\n@@ -332,6 +333,8 @@ codeunit 12 \"Gen. Jnl.-Post Line\"\n if CheckLine then begin\n if OverrideDimErr then\n GenJnlCheckLine.SetOverDimErr();\n+ if IgnoreJournalTemplNameMandatoryCheck then\n+ GenJnlCheckLine.SetIgnoreJournalTemplNameMandatoryCheck();\n OnCheckGenJnlLineOnBeforeRunCheck(GenJournalLine);\n GenJnlCheckLine.RunCheck(GenJournalLine);\n end;\n@@ -7113,6 +7116,15 @@ codeunit 12 \"Gen. Jnl.-Post Line\"\n Error(DimMgt.GetDimValuePostingErr());\n end;\n \n+ /// \n+ /// Sets the global variable IgnoreJournalTemplNameMandatoryCheck for the current instance of the codeunit.\n+ /// If IgnoreJournalTemplNameMandatoryCheck is not set \"Journal Templ. Name Mandatory\" check is performed before gen. journal line \n+ /// \n+ procedure SetIgnoreJournalTemplNameMandatoryCheck()\n+ begin\n+ IgnoreJournalTemplNameMandatoryCheck := true;\n+ end;\n+\n local procedure IsGainLossAccount(CurrencyCode: Code[10]; GLAccNo: Code[20]): Boolean\n var\n Currency: Record Currency;\ndiff --git a/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al b/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al\nindex 88068be074e..f09dab3691a 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al\n@@ -849,6 +849,7 @@ report 20 \"Calc. and Post VAT Settlement\"\n GenJnlLine, 0, DefaultDimSource, GenJnlLine.\"Source Code\",\n GenJnlLine.\"Shortcut Dimension 1 Code\", GenJnlLine.\"Shortcut Dimension 2 Code\", 0, 0);\n OnPostGenJnlLineOnBeforeGenJnlPostLineRun(GenJnlLine);\n+ GenJnlPostLine.SetIgnoreJournalTemplNameMandatoryCheck();\n GenJnlPostLine.Run(GenJnlLine);\n end;\n \n"} {"metadata": {"area": "eservice", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-193853", "base_commit": "a4732079d0c963a7104d5b5c534ee87f3cd105e7", "created_at": "2024-09-09", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\EnforcedDigitalVouchers\\app", "App\\Apps\\W1\\EnforcedDigitalVouchers\\test library", "App\\Apps\\W1\\EnforcedDigitalVouchers\\test"], "FAIL_TO_PASS": [{"codeunitID": 139515, "functionName": ["PostMultipleGeneralJournalLinesSamePostingDateDocNoOnlyFirstHasIncDoc"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al b/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al\nindex 304e94e908f6..d917601e5a98 100644\n--- a/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al\n+++ b/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al\n@@ -912,6 +912,59 @@ codeunit 139515 \"Digital Vouchers Tests\"\n UnbindSubscription(DigVouchersDisableEnforce);\n end;\n \n+ [Test]\n+ procedure PostMultipleGeneralJournalLinesSamePostingDateDocNoOnlyFirstHasIncDoc()\n+ var\n+ GenJournalLine: array[2] of Record \"Gen. Journal Line\";\n+ GenJournalLineToPost: Record \"Gen. Journal Line\";\n+ GenJournalTemplate: Record \"Gen. Journal Template\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ IncomingDocument: Record \"Incoming Document\";\n+ DigVouchersDisableEnforce: Codeunit \"Dig. Vouchers Disable Enforce\";\n+ DocNo: Code[20];\n+ i: Integer;\n+ begin\n+ // [SCENARIO 540097] Stan can post multiple general journals lines with same posting date and document number, only the first line has incoming document\n+\n+ Initialize();\n+ BindSubscription(DigVouchersDisableEnforce);\n+ // [GIVEN] Digital voucher feature is enabled\n+ EnableDigitalVoucherFeature();\n+ // [GIVEN] Digital voucher entry setup for general journal is \"Attachment\"\n+ InitSetupCheckOnly(\"Digital Voucher Entry Type\"::\"General Journal\", \"Digital Voucher Check Type\"::Attachment);\n+ // [GIVEN] General journal lines with the same template and batch are created\n+ // [GIVEN] General journal line \"X\" with \"Posting Date\" = 01.01.2024 and \"Document No.\" = \"X\"\n+ // [GIVEN] General journal line \"Y\" with \"Posting Date\" = 01.01.2024 and \"Document No.\" = \"X\"\n+ DocNo := LibraryUtility.GenerateGUID();\n+ LibraryERM.CreateGenJournalTemplate(GenJournalTemplate);\n+ LibraryERM.CreateGenJournalBatch(GenJournalBatch, GenJournalTemplate.Name);\n+ for i := 1 to ArrayLen(GenJournalLine) do begin\n+ LibraryJournals.CreateGenJournalLine(\n+ GenJournalLine[i], GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name,\n+ GenJournalLine[i].\"Document Type\"::Invoice, GenJournalLine[i].\"Account Type\"::\"G/L Account\",\n+ LibraryERM.CreateGLAccountNo(), GenJournalLine[i].\"Bal. Account Type\"::\"G/L Account\",\n+ LibraryERM.CreateGLAccountNo(), LibraryRandom.RandDec(100, 2));\n+ GenJournalLine[i].Validate(\"Document No.\", DocNo);\n+ GenJournalLine[i].Modify(true);\n+ end;\n+ // [GIVEN] Only journal line \"X\" has incoming document attached\n+ GenJournalLine[1].\"Incoming Document Entry No.\" := MockIncomingDocument();\n+ GenJournalLine[1].Modify(true);\n+\n+ GenJournalLineToPost.SetRange(\"Journal Template Name\", GenJournalBatch.\"Journal Template Name\");\n+ GenJournalLineToPost.SetRange(\"Journal Batch Name\", GenJournalBatch.Name);\n+ GenJournalLineToPost.FindSet();\n+ // [WHEN] Post both general journal lines\n+ Codeunit.Run(Codeunit::\"Gen. Jnl.-Post Batch\", GenJournalLineToPost);\n+\n+ // [THEN] Posting is successfull and we have an incoming document with \"Posting Date\" = 01.01.2024 and \"Document No.\" = \"X\"\n+ IncomingDocument.SetRange(\"Posting Date\", GenJournalLine[1].\"Posting Date\");\n+ IncomingDocument.SetRange(\"Document No.\", GenJournalLine[1].\"Document No.\");\n+ Assert.RecordIsNotEmpty(IncomingDocument);\n+\n+ UnbindSubscription(DigVouchersDisableEnforce);\n+ end;\n+\n local procedure Initialize()\n var\n CompanyInformation: Record \"Company Information\";\n@@ -1076,6 +1129,19 @@ codeunit 139515 \"Digital Vouchers Tests\"\n exit(IncomingDocument.\"Entry No.\");\n end;\n \n+ local procedure MockIncomingDocument(): Integer\n+ var\n+ IncomingDocument: Record \"Incoming Document\";\n+ IncomingDocumentAttachment: Record \"Incoming Document Attachment\";\n+ begin\n+ IncomingDocument.\"Entry No.\" :=\n+ LibraryUtility.GetNewRecNo(IncomingDocument, IncomingDocument.FieldNo(\"Entry No.\"));\n+ IncomingDocument.Insert();\n+ IncomingDocumentAttachment.\"Incoming Document Entry No.\" := IncomingDocument.\"Entry No.\";\n+ IncomingDocumentAttachment.Insert();\n+ exit(IncomingDocument.\"Entry No.\");\n+ end;\n+\n local procedure ReceiveAndInvoicePurchaseInvoice(): Code[20]\n var\n PurchaseHeader: Record \"Purchase Header\";\n", "patch": "diff --git a/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al b/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al\nindex 72dc980e3347..5775bd7fc2b0 100644\n--- a/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al\n+++ b/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al\n@@ -224,6 +224,8 @@ codeunit 5579 \"Digital Voucher Impl.\"\n SourceCodeSetup.Get();\n if IsPaymentReconciliationJournal(DigitalVoucherEntrySetup.\"Entry Type\", RecRef) then\n exit(true);\n+ if IsGenJnlLineWithIncDocAttachedToAdjLine(DigitalVoucherEntrySetup.\"Entry Type\", RecRef) then\n+ exit(true);\n exit(false);\n end;\n \n@@ -345,6 +347,27 @@ codeunit 5579 \"Digital Voucher Impl.\"\n exit(SourceCodeValue = SourceCodeSetup.\"Payment Reconciliation Journal\");\n end;\n \n+ local procedure IsGenJnlLineWithIncDocAttachedToAdjLine(DigitalVoucherEntryType: Enum \"Digital Voucher Entry Type\"; RecRef: RecordRef): Boolean\n+ var\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ AdjacentGenJournalLine: Record \"Gen. Journal Line\";\n+ IncomingDocument: Record \"Incoming Document\";\n+ begin\n+ if DigitalVoucherEntryType <> DigitalVoucherEntryType::\"General Journal\" then\n+ exit(false);\n+ RecRef.SetTable(GenJournalLine);\n+ AdjacentGenJournalLine.ReadIsolation(IsolationLevel::ReadCommitted);\n+ AdjacentGenJournalLine.SetRange(\"Journal Template Name\", GenJournalLine.\"Journal Template Name\");\n+ AdjacentGenJournalLine.SetRange(\"Journal Batch Name\", GenJournalLine.\"Journal Batch Name\");\n+ AdjacentGenJournalLine.SetRange(\"Posting Date\", GenJournalLine.\"Posting Date\");\n+ AdjacentGenJournalLine.SetRange(\"Document No.\", GenJournalLine.\"Document No.\");\n+ AdjacentGenJournalLine.SetFilter(\"Line No.\", '<>%1', GenJournalLine.\"Line No.\");\n+ AdjacentGenJournalLine.SetFilter(\"Incoming Document Entry No.\", '<>0');\n+ if not AdjacentGenJournalLine.FindFirst() then\n+ exit(false);\n+ exit(IncomingDocument.Get(AdjacentGenJournalLine.\"Incoming Document Entry No.\"));\n+ end;\n+\n local procedure AttachDigitalVoucherFromReportPDF(ReportUsage: Enum \"Report Selection Usage\"; RecRef: RecordRef; IsInvoice: Boolean; PostingDate: Date; DocNo: Code[20]; AccountTableNo: Integer; AccountNo: Code[20]; StandardReportID: Integer)\n var\n TempAttachReportSelections: Record \"Report Selections\" temporary;\n"} -{"metadata": {"area": "sales", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223493", "base_commit": "faff33469cd77044de7a55542cfd61531ec098ee", "created_at": "2025-08-11", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134658, "functionName": ["VerifyYourReferenceUpdatedInCustLedgerEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al b/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al\nindex b2cb6ea36fb..0e345a6a6f8 100644\n--- a/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al\n@@ -27,6 +27,8 @@ codeunit 134658 \"Edit Posted Documents\"\n UnexpectedVolumeErr: Label 'Unexpected Volume shown.';\n CashFlowWorkSheetLineMustNotBeFoundErr: Label 'Cash Flow Worksheet Line must not be found.';\n YourReferenceErr: Label 'Your reference must be editable';\n+ SalesInvoiceYourReferenceErr: Label 'Sales Invoice Your Reference not updated';\n+ CustLedgerEntryYourReferenceErr: Label 'Customer Ledger Entry Your Reference not updated';\n \n [Test]\n [HandlerFunctions('PostedSalesShipmentUpdateGetEditablelModalPageHandler')]\n@@ -996,6 +998,46 @@ codeunit 134658 \"Edit Posted Documents\"\n LibraryLowerPermissions.SetOutsideO365Scope();\n end;\n \n+ [Test]\n+ [HandlerFunctions('PostedSalesInvoiceYourReferenceModalPageHandler')]\n+ procedure VerifyYourReferenceUpdatedInCustLedgerEntry()\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ SalesInvoiceHeader: Record \"Sales Invoice Header\";\n+ YourReference: Text[35];\n+ PostedSalesInvoice: TestPage \"Posted Sales Invoice\";\n+ begin\n+ // [SCENARIO 595854] Verify Your Reference Field updated in Customer Ledger Entries,\n+ // when changed with Update document on Posted Sales Invoice.\n+ Initialize();\n+\n+ LibraryLowerPermissions.SetO365Setup();\n+ LibraryLowerPermissions.AddSalesDocsPost();\n+\n+ // [GIVEN] Create and post a Sales Order.\n+ SalesInvoiceHeader.Get(CreateAndPostSalesOrderGetInvoiceNo());\n+ YourReference := LibraryRandom.RandText(35);\n+ LibraryVariableStorage.Enqueue(YourReference);\n+\n+ // [GIVEN] Opened \"Posted Sales Invoice - Update\" page.\n+ PostedSalesInvoice.OpenView();\n+ PostedSalesInvoice.GoToRecord(SalesInvoiceHeader);\n+ PostedSalesInvoice.\"Update Document\".Invoke();\n+\n+ // [WHEN] Press OK on the page via PostedSalesInvoiceYourReferenceModalPageHandler.\n+\n+ // [THEN] Verify Your Reference field updated on Sales Invoice Header and Customer Ledger Entry.\n+ SalesInvoiceHeader.Get(SalesInvoiceHeader.\"No.\");\n+ Assert.AreEqual(YourReference, SalesInvoiceHeader.\"Your Reference\", SalesInvoiceYourReferenceErr);\n+\n+ CustLedgerEntry.SetRange(\"Document No.\", SalesInvoiceHeader.\"No.\");\n+ CustLedgerEntry.FindFirst();\n+ Assert.AreEqual(YourReference, CustLedgerEntry.\"Your Reference\", CustLedgerEntryYourReferenceErr);\n+\n+ LibraryVariableStorage.AssertEmpty();\n+ LibraryLowerPermissions.SetOutsideO365Scope();\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Edit Posted Documents\");\n@@ -1535,6 +1577,14 @@ codeunit 134658 \"Edit Posted Documents\"\n PostedSalesInvUpdate.Cancel().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedSalesInvoiceYourReferenceModalPageHandler(var PostedSalesInvUpdate: TestPage \"Posted Sales Inv. - Update\")\n+ begin\n+ PostedSalesInvUpdate.\"Your Reference\".SetValue(LibraryVariableStorage.DequeueText());\n+ PostedSalesInvUpdate.OK().Invoke();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerTrue(QuestionText: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al b/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al\nindex 6a5f0a883a3..626b74297f4 100644\n--- a/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al\n@@ -56,6 +56,7 @@ codeunit 1409 \"Sales Inv. Header - Edit\"\n CustLedgerEntry.Description := SalesInvoiceHeader.\"Posting Description\";\n CustLedgerEntry.\"Promised Pay Date\" := SalesInvoiceHeader.\"Promised Pay Date\";\n CustLedgerEntry.\"Due Date\" := SalesInvoiceHeader.\"Due Date\";\n+ CustLedgerEntry.\"Your Reference\" := SalesInvoiceHeader.\"Your Reference\";\n if CustLedgerEntry.\"Dispute Status\" <> '' then begin\n if DisputeStatus.get(CustLedgerEntry.\"Dispute Status\") then\n if (DisputeStatus.\"Overwrite on hold\") and ClearOnHold(SalesInvoiceHeader) then\ndiff --git a/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al\nindex c64fa944c7e..546c3b5513a 100644\n--- a/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al\n@@ -44,6 +44,7 @@ codeunit 103 \"Cust. Entry-Edit\"\n CustLedgEntry.\"Applies-to ID\" := Rec.\"Applies-to ID\";\n CustLedgEntry.Validate(\"Payment Method Code\", Rec.\"Payment Method Code\");\n CustLedgEntry.Validate(\"Payment Reference\", Rec.\"Payment Reference\");\n+ CustLedgEntry.Validate(\"Your Reference\", Rec.\"Your Reference\");\n CustLedgEntry.Validate(\"Remaining Pmt. Disc. Possible\", Rec.\"Remaining Pmt. Disc. Possible\");\n CustLedgEntry.\"Pmt. Disc. Tolerance Date\" := Rec.\"Pmt. Disc. Tolerance Date\";\n CustLedgEntry.Validate(\"Max. Payment Tolerance\", Rec.\"Max. Payment Tolerance\");\n@@ -122,7 +123,8 @@ codeunit 103 \"Cust. Entry-Edit\"\n (CurrCustLedgerEntry.\"Payment Reference\" <> NewCustLedgerEntry.\"Payment Reference\") or\n (CurrCustLedgerEntry.\"Message to Recipient\" <> NewCustLedgerEntry.\"Message to Recipient\") or\n (CurrCustLedgerEntry.\"Recipient Bank Account\" <> NewCustLedgerEntry.\"Recipient Bank Account\") or\n- (CurrCustLedgerEntry.\"On Hold\" <> NewCustLedgerEntry.\"On Hold\");\n+ (CurrCustLedgerEntry.\"On Hold\" <> NewCustLedgerEntry.\"On Hold\") or\n+ (CurrCustLedgerEntry.\"Your Reference\" <> NewCustLedgerEntry.\"Your Reference\");\n OnAfterLogFieldChanged(CurrCustLedgerEntry, NewCustLedgerEntry, Changed);\n exit(Changed);\n end;\n"} {"metadata": {"area": "shopify", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-193649", "base_commit": "3a5cb3aed7e735e557547556f727cce66b15affe", "created_at": "2024-09-06", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139695, "functionName": ["UnitTestCopyInvoice"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al b/App/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al\nnew file mode 100644\nindex 000000000000..288b4d8039f0\n--- /dev/null\n+++ b/App/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al\n@@ -0,0 +1,67 @@\n+codeunit 139695 \"Shpfy Invoices Test\"\n+{\n+ Subtype = Test;\n+ TestPermissions = Disabled;\n+\n+ var\n+ LibraryAssert: Codeunit \"Library Assert\";\n+ Any: Codeunit Any;\n+ LibrarySales: Codeunit \"Library - Sales\";\n+ LibraryInventory: Codeunit \"Library - Inventory\";\n+ LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n+ IsInitialized: Boolean;\n+\n+ [Test]\n+ procedure UnitTestCopyInvoice()\n+ var\n+ Item: Record Item;\n+ Customer: Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ InvoiceNo: Code[20];\n+ OrderId: BigInteger;\n+ begin\n+ // [SCENARIO] Shopify related fields are not copied to the new invoice\n+ // [GIVEN] Posted sales invoice with Shopify related fields and empty invoice\n+ Initialize();\n+ OrderId := Any.IntegerInRange(10000, 99999);\n+ LibraryInventory.CreateItem(Item);\n+ LibrarySales.CreateCustomer(Customer);\n+ InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer.\"No.\");\n+\n+ // [WHEN] Copy the invoice\n+ CopySalesDocument(SalesHeader, InvoiceNo);\n+\n+ // [THEN] Shopify related fields are not copied\n+ LibraryAssert.IsTrue(SalesHeader.\"Shpfy Order Id\" = 0, 'Shpfy Order Id is not copied');\n+ end;\n+\n+ local procedure Initialize()\n+ begin\n+ if IsInitialized then\n+ exit;\n+ IsInitialized := true;\n+ LibraryERMCountryData.CreateVATData();\n+ LibraryERMCountryData.UpdateGeneralPostingSetup();\n+ end;\n+\n+ local procedure CreateAndPostSalesInvoice(Item: Record Item; Customer: Record Customer; NumberOfLines: Integer; OrderId: BigInteger): Code[20]\n+ var\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer.\"No.\");\n+ SalesHeader.\"Shpfy Order Id\" := OrderId;\n+ SalesHeader.Modify();\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", NumberOfLines);\n+ exit(LibrarySales.PostSalesDocument(SalesHeader, true, true));\n+ end;\n+\n+ local procedure CopySalesDocument(var ToSalesHeader: Record \"Sales Header\"; DocNo: Code[20])\n+ var\n+ CopyDocumentMgt: Codeunit \"Copy Document Mgt.\";\n+ begin\n+ CopyDocumentMgt.SetProperties(true, false, false, false, false, false, false);\n+ CopyDocumentMgt.CopySalesDoc(\"Sales Document Type From\"::\"Posted Invoice\", DocNo, ToSalesHeader);\n+ end;\n+}\ndiff --git a/App/Apps/W1/Shopify/test/app.json b/App/Apps/W1/Shopify/test/app.json\nindex fad22c7daf0e..ba1deea22a10 100644\n--- a/App/Apps/W1/Shopify/test/app.json\n+++ b/App/Apps/W1/Shopify/test/app.json\n@@ -71,6 +71,10 @@\n {\n \"from\": 139645,\n \"to\": 139649\n+ },\n+ {\n+ \"from\": 139695,\n+ \"to\": 139699\n }\n ],\n \"target\": \"OnPrem\",\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al b/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al\nindex cf03c116eaef..a6a20c46d2da 100644\n--- a/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al\n+++ b/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al\n@@ -1,6 +1,8 @@\n namespace Microsoft.Integration.Shopify;\n \n using Microsoft.Sales.History;\n+using Microsoft.Utilities;\n+using Microsoft.Sales.Document;\n \n codeunit 30364 \"Shpfy Update Sales Invoice\"\n {\n@@ -19,4 +21,12 @@ codeunit 30364 \"Shpfy Update Sales Invoice\"\n begin\n SalesInvoiceHeader.\"Shpfy Order Id\" := SalesInvoiceHeaderRec.\"Shpfy Order Id\";\n end;\n+\n+ [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Copy Document Mgt.\", 'OnCopySalesDocOnAfterTransferPostedInvoiceFields', '', false, false)]\n+ local procedure OnCopySalesDocOnAfterCopySalesDocUpdateHeader(var ToSalesHeader: Record \"Sales Header\")\n+ begin\n+ Clear(ToSalesHeader.\"Shpfy Order Id\");\n+ Clear(ToSalesHeader.\"Shpfy Order No.\");\n+ Clear(ToSalesHeader.\"Shpfy Refund Id\");\n+ end;\n }\n\\ No newline at end of file\n"} -{"metadata": {"area": "sales", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220036", "base_commit": "e21460ab75c1fb80ba3033e3755672cbd4ed8d9f", "created_at": "2025-07-04", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM", "App\\Layers\\W1\\Tests\\Misc"], "FAIL_TO_PASS": [{"codeunitID": 134905, "functionName": ["VerifyEmailOnReminderPageWhenCustomerHasNoContacts"]}, {"codeunitID": 134825, "functionName": ["GetPrimaryConactCustomerWithoutContact"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\nindex f8b1cf9e56e..71c12b1ce1a 100644\n--- a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n@@ -587,6 +587,55 @@ codeunit 134905 \"ERM Issued Reminder Addnl Fee\"\n Assert.AreEqual(ReminderFinChargeEntry.\"Due Date\", CustLedgerEntry.\"Due Date\", ReminderDueDateErr);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure VerifyEmailOnReminderPageWhenCustomerHasNoContacts()\n+ var\n+ Customer: Record Customer;\n+ ReminderLevel: Record \"Reminder Level\";\n+ ReminderText: Record \"Reminder Text\";\n+ ReminderHeader: Record \"Reminder Header\";\n+ ReminderPage: TestPage Reminder;\n+ CustomerCard: TestPage \"Customer Card\";\n+ EMail: Text[80];\n+ DueDate: Date;\n+ DocumentDate: Date;\n+ begin\n+ // [SCENARIO 581797] [ALL-E] Field Email on Reminder is empty when customer does not have any contacts\n+ Initialize();\n+\n+ // [GIVEN] Create Customer with E-Mail and Reminder Terms Code.\n+ CreateCustomer(Customer, '');\n+ Customer.Validate(\"Reminder Terms Code\", CreateReminderTerms());\n+ EMail := 'test1@test.com';\n+ Customer.Modify(true);\n+\n+ CustomerCard.OpenEdit();\n+ CustomerCard.GoToRecord(Customer);\n+ CustomerCard.\"E-Mail\".SetValue(EMail);\n+ CustomerCard.Close();\n+\n+ // [GIVEN] Create Reminder Level with Random Grace Period and Random Additional Fee.\n+ ReminderLevel.SetRange(\"Reminder Terms Code\", Customer.\"Reminder Terms Code\");\n+ ReminderLevel.FindFirst();\n+ LibraryERM.CreateReminderText(\n+ ReminderText, Customer.\"Reminder Terms Code\",\n+ ReminderLevel.\"No.\", ReminderText.Position::Ending, ReminderEndingText);\n+\n+ // [WHEN] Post Sales Invoice and Create Reminder.\n+ DueDate := CreateAndPostSalesInvoice(Customer.\"No.\", '');\n+ DocumentDate := CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', CalcDate(ReminderLevel.\"Grace Period\", DueDate));\n+ CreateReminder(Customer.\"No.\", DocumentDate, false);\n+\n+ // [THEN] Find Reminder Header for Customer and open Reminder Page.\n+ FindReminderHeader(ReminderHeader, Customer.\"No.\");\n+ ReminderPage.OpenEdit();\n+ ReminderPage.GoToRecord(ReminderHeader);\n+\n+ // [THEN] Verify E-Mail on Reminder Page.\n+ ReminderPage.ContactEmail.AssertEquals(EMail);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\ndiff --git a/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al b/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al\nindex 70b34d374fa..33cc3001fc3 100644\n--- a/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al\n+++ b/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al\n@@ -25,6 +25,7 @@ codeunit 134825 \"UT Customer Table\"\n DeleteCustomerSalesDocExistsErr: Label 'You cannot delete %1 %2 because there is at least one outstanding Sales %3 for this customer.';\n DialogErr: Label 'Dialog';\n PhoneNoCannotContainLettersErr: Label '%1 must not contain letters in %2 %3=''%4''.';\n+ ContactNoShouldNotBeEmpty: Label 'Contact No. should not be empty';\n \n [Test]\n [Scope('OnPrem')]\n@@ -740,8 +741,8 @@ codeunit 134825 \"UT Customer Table\"\n // [WHEN] Function GetPrimaryConact is being run with parameter \"CONT\"\n Customer.GetPrimaryContact(Customer.\"No.\", Contact);\n \n- // [THEN] Variable Contact is empty\n- Contact.TestField(\"No.\", '');\n+ // [THEN] Variable Contact exists without customer contact\n+ Assert.IsTrue(Contact.\"No.\" <> '', ContactNoShouldNotBeEmpty);\n end;\n \n [Test]\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\nindex 9fdc21c529d..de6b7a0cc2e 100644\n--- a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n@@ -2302,7 +2302,22 @@ table 18 Customer\n begin\n Clear(PrimaryContact);\n if Customer.Get(CustomerNo) then\n- if PrimaryContact.Get(Customer.\"Primary Contact No.\") then;\n+ if not PrimaryContact.Get(Customer.\"Primary Contact No.\") then\n+ GetContact(CustomerNo, PrimaryContact);\n+ end;\n+\n+ local procedure GetContact(CustomerNo: Code[20]; var PrimaryContact: Record Contact)\n+ var\n+ ContactBusinessRelation: Record \"Contact Business Relation\";\n+ begin\n+ ContactBusinessRelation.SetCurrentKey(\"Link to Table\", \"No.\");\n+ ContactBusinessRelation.SetRange(\"Link to Table\", ContactBusinessRelation.\"Link to Table\"::Customer);\n+ ContactBusinessRelation.SetRange(\"No.\", CustomerNo);\n+ if ContactBusinessRelation.FindSet() then\n+ repeat\n+ if PrimaryContact.Get(ContactBusinessRelation.\"Contact No.\") then\n+ exit;\n+ until ContactBusinessRelation.Next() = 0;\n end;\n \n local procedure GetCustomerPriceGroupPriceCalcMethod(): Enum \"Price Calculation Method\";\n"} {"metadata": {"area": "sustainability", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-188438", "base_commit": "b3cff264abfbab722f8657c126f23aa07ad00056", "created_at": "2024-07-03", "environment_setup_version": "24.3", "project_paths": ["App\\Apps\\W1\\Sustainability\\app", "App\\Apps\\W1\\Sustainability\\test"], "FAIL_TO_PASS": [{"codeunitID": 148181, "functionName": ["TestCustomAmountIsPositiveForNegativeTotalOfGL"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al b/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al\nindex 54ca91b65b2f..bfae0fd4c73a 100644\n--- a/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al\n+++ b/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al\n@@ -5,9 +5,13 @@ codeunit 148181 \"Sustainability Journal Test\"\n \n var\n Assert: Codeunit Assert;\n+ LibraryERM: Codeunit \"Library - ERM\";\n+ LibraryRandom: Codeunit \"Library - Random\";\n LibrarySustainability: Codeunit \"Library - Sustainability\";\n+ LibraryUtility: Codeunit \"Library - Utility\";\n OneDefaultTemplateShouldBeCreatedLbl: Label 'One default template should be created after page is opened', Locked = true;\n OneDefaultBatchShouldBeCreatedLbl: Label 'One default batch should be created after page is opened', Locked = true;\n+ CustomAmountMustBePositiveLbl: Label 'The custom amount must be positive', Locked = true;\n \n [Test]\n procedure TestDefaultTemplateAndBatchSuccessfullyInserted()\n@@ -100,4 +104,46 @@ codeunit 148181 \"Sustainability Journal Test\"\n // [THEN] The Check should fail\n asserterror SustainabilityJournalMgt.CheckScopeMatchWithBatch(SustainabilityJournalLine);\n end;\n+\n+ [Test]\n+ procedure TestCustomAmountIsPositiveForNegativeTotalOfGL()\n+ var\n+ SustainAccountCategory: Record \"Sustain. Account Category\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJouralLine: Record \"Gen. Journal Line\";\n+ SustainabilityCalcMgt: Codeunit \"Sustainability Calc. Mgt.\";\n+ GenJournalTemplateCode: Code[10];\n+ GLAccountNo: Code[20];\n+ GLAmount, CustomAmount : Decimal;\n+ begin\n+ // [SCENARIO 540221] Test that the custom amount is positive when the total of the GL is negative\n+\n+ // [GIVEN] G/L Account exists\n+ GLAccountNo := LibraryERM.CreateGLAccountNoWithDirectPosting();\n+\n+ // [GIVEN] G/L Batch and Template exist\n+ GenJournalTemplateCode := LibraryERM.SelectGenJnlTemplate();\n+ LibraryERM.CreateGenJournalBatch(GenJournalBatch, GenJournalTemplateCode);\n+\n+ // [GIVEN] G/L Entry with Amount = -1000 for the G/L Account\n+ GLAmount := -LibraryRandom.RandDec(1000, 2);\n+ LibraryERM.CreateGeneralJnlLine2WithBalAcc(GenJouralLine, GenJournalTemplateCode, GenJournalBatch.Name, GenJouralLine.\"Document Type\"::Payment, GenJouralLine.\"Account Type\"::\"G/L Account\", GLAccountNo, GenJouralLine.\"Account Type\"::\"G/L Account\", LibraryERM.CreateGLAccountNoWithDirectPosting(), GLAmount);\n+ LibraryERM.PostGeneralJnlLine(GenJouralLine);\n+\n+ // [GIVEN] Sustain Account Category with the G/L Account calculation foundation\n+ SustainAccountCategory := CreateSustAccountCategoryWithGLAccountNo(GLAccountNo);\n+\n+ // [WHEN] Getting the collectable amount for sustanability account category\n+ CustomAmount := SustainabilityCalcMgt.GetCollectableGLAmount(SustainAccountCategory, 0D, 0D);\n+\n+ // [THEN] The custom amount = 1000\n+ Assert.AreEqual(Abs(GLAmount), CustomAmount, CustomAmountMustBePositiveLbl);\n+ end;\n+\n+ local procedure CreateSustAccountCategoryWithGLAccountNo(GLAccountNo: Code[20]) SustainAccountCategory: Record \"Sustain. Account Category\"\n+ begin\n+ SustainAccountCategory := LibrarySustainability.InsertAccountCategory(LibraryUtility.GenerateGUID(), LibraryUtility.GenerateGUID(), Enum::\"Emission Scope\"::\"Scope 2\", Enum::\"Calculation Foundation\"::Custom, true, true, true, 'GL', true);\n+ SustainAccountCategory.\"G/L Account Filter\" := GLAccountNo;\n+ SustainAccountCategory.Modify(true);\n+ end;\n }\n\\ No newline at end of file\n", "patch": "diff --git a/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al b/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al\nindex 4644c8733d76..35add37418cc 100644\n--- a/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al\n+++ b/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al\n@@ -70,7 +70,7 @@ codeunit 6218 \"Sustainability Calc. Mgt.\"\n begin\n FilterGLEntry(SustainAccountCategory, FromDate, ToDate, GLEntry);\n GLEntry.CalcSums(Amount);\n- exit(GLEntry.Amount);\n+ exit(Abs(GLEntry.Amount));\n end;\n \n internal procedure CollectGeneralLedgerAmount(var SustainabilityJnlLine: Record \"Sustainability Jnl. Line\")\n"} -{"metadata": {"area": "reporting", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-224447", "base_commit": "cc0427613cdcf235d834b83a7e69b98288686d0d", "created_at": "2025-08-21", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134979, "functionName": ["SendIssuedReminderByEmailAndEntryCreatedInEmailRelatedRecords"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\nindex 1667c4a29d8..01f9284203b 100644\n--- a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n@@ -844,6 +844,53 @@ codeunit 134979 \"Reminder Automation Tests\"\n ReminderTermSetupPage.ReminderLevelSetup.CustomerCommunications.Invoke();\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('ModalEmailEditorHandler,CancelMailSendingStrMenuHandler')]\n+ procedure SendIssuedReminderByEmailAndEntryCreatedInEmailRelatedRecords()\n+ var\n+ Customer: Record Customer;\n+ IssuedReminderHeader: Record \"Issued Reminder Header\";\n+ ReminderTerms: Record \"Reminder Terms\";\n+ ReminderHeader: Record \"Reminder Header\";\n+ LanguageCode: Code[10];\n+ FileName: Text;\n+ begin\n+ // [SCENARIO 591799] Issued reminder emails are not logged in sent e-mail history of a customer\n+ Initialize();\n+\n+ // [WHEN] A connector is installed and an account is added\n+ InstallConnectorAndAddAccount();\n+\n+ // [GIVEN] Create reminder term with levels\n+ CreateReminderTermsWithLevels(ReminderTerms, GetDefaultDueDatePeriodForReminderLevel(), Any.IntegerInRange(2, 5));\n+\n+ // [GIVEN] Create reminder attachment text, file name = XXX, language code = Y\n+ LanguageCode := LibraryERM.GetAnyLanguageDifferentFromCurrent();\n+ CreateReminderAttachmentText(ReminderTerms, LanguageCode);\n+\n+ // [GIVEN] Create a customer X with overdue entries\n+ CreateCustomerWithOverdueEntries(Customer, ReminderTerms, Any.IntegerInRange(2, 5));\n+\n+ // [GIVEN] Set language code Y for customer X\n+ Customer.\"Language Code\" := LanguageCode;\n+ Customer.Modify();\n+ FileName := LibraryVariableStorage.DequeueText();\n+ LibraryVariableStorage.Enqueue(Customer.\"No.\");\n+ LibraryVariableStorage.Enqueue(FileName);\n+\n+ // [GIVEN] Create and issue reminder for customer X \n+ CreateAndIssueReminder(ReminderHeader, Customer.\"No.\");\n+\n+ // [WHEN] Run action \"Send by mail\" on issued reminder\n+ IssuedReminderHeader.SetRange(\"Pre-Assigned No.\", ReminderHeader.\"No.\");\n+ IssuedReminderHeader.FindFirst();\n+ CustomReportSelectionPrint(IssuedReminderHeader, Enum::\"Report Selection Usage\"::Reminder, 1);\n+\n+ // [THEN] Verified in ModalEmailEditorHandler page\n+ LibraryVariableStorage.Clear();\n+ end;\n+\n local procedure CreateReminderAttachmentText(ReminderTerms: Record \"Reminder Terms\"; LanguageCode: Code[10])\n var\n ReminderLevel: Record \"Reminder Level\";\n@@ -1179,6 +1226,57 @@ codeunit 134979 \"Reminder Automation Tests\"\n end;\n end;\n \n+ local procedure InstallConnectorAndAddAccount()\n+ var\n+ TempAccount: Record \"Email Account\" temporary;\n+ ConnectorMock: Codeunit \"Connector Mock\";\n+ EmailScenarioMock: Codeunit \"Email Scenario Mock\";\n+ begin\n+ ConnectorMock.Initialize();\n+ ConnectorMock.AddAccount(TempAccount);\n+ EmailScenarioMock.DeleteAllMappings();\n+ EmailScenarioMock.AddMapping(Enum::\"Email Scenario\"::Default, TempAccount.\"Account Id\", TempAccount.Connector);\n+ end;\n+\n+ local procedure CustomReportSelectionPrint(Document: Variant; ReportUsage: Enum \"Report Selection Usage\"; CustomerNoFieldNo: Integer)\n+ var\n+ ReportSelections: Record \"Report Selections\";\n+ TempReportSelections: Record \"Report Selections\" temporary;\n+ RecRef: RecordRef;\n+ FieldRef: FieldRef;\n+ CustomerNo: Code[20];\n+ begin\n+ RecRef.GetTable(Document);\n+ FieldRef := RecRef.Field(CustomerNoFieldNo);\n+ CustomerNo := CopyStr(Format(FieldRef.Value), 1, MaxStrLen(CustomerNo));\n+\n+ RecRef.SetRecFilter();\n+ RecRef.SetTable(Document);\n+\n+ ReportSelections.FindEmailAttachmentUsageForCust(ReportUsage, CustomerNo, TempReportSelections);\n+ ReportSelections.SendEmailToCust(ReportUsage.AsInteger(), Document, '', '', true, CustomerNo);\n+ end;\n+\n+ [StrMenuHandler]\n+ [Scope('OnPrem')]\n+ procedure CancelMailSendingStrMenuHandler(Options: Text; var Choice: Integer; Instruction: Text)\n+ begin\n+ Choice := 1; //Save as Draft //Discard email\t\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ModalEmailEditorHandler(var EmailEditor: TestPage \"Email Editor\")\n+ var\n+ Customer: Record Customer;\n+ EmailRelatedRecord: Record \"Email Related Record\";\n+ begin\n+ Customer.Get(LibraryVariableStorage.DequeueText());\n+ EmailRelatedRecord.SetRange(\"Table Id\", Database::Customer);\n+ EmailRelatedRecord.SetRange(\"System Id\", Customer.SystemId);\n+ Assert.IsTrue(EmailRelatedRecord.FindFirst(), EmailRelatedRecordNotFoundErr);\n+ end;\n+\n [ModalPageHandler()]\n procedure CreateRemindersSetupModalPageHandler(var CreateRemindersSetup: TestPage \"Create Reminders Setup\")\n begin\n@@ -1271,4 +1369,5 @@ codeunit 134979 \"Reminder Automation Tests\"\n Any: Codeunit Any;\n IsInitialized: Boolean;\n FiltersAreNotSavedErr: Label 'Filters are not saved';\n+ EmailRelatedRecordNotFoundErr: Label 'Email related record not found';\n }\n\\ No newline at end of file\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\nindex 7a71bebba78..5e7b5d9c79b 100644\n--- a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n+++ b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n@@ -1269,7 +1269,8 @@ table 77 \"Report Selections\"\n Database::\"Sales Invoice Header\",\n Database::\"Sales Cr.Memo Header\",\n Database::\"Sales Shipment Header\",\n- Database::\"Return Receipt Header\"];\n+ Database::\"Return Receipt Header\",\n+ Database::\"Issued Reminder Header\"];\n \n OnAfterIsCustomerAccount(DocumentTableId, IsCustomer);\n end;\n@@ -1521,7 +1522,10 @@ table 77 \"Report Selections\"\n // Related Source - Customer or vendor receiving the document\n TableId := GetAccountTableId(DocumentRecord.Number());\n if TableId = Database::Customer then begin\n- FieldName := 'Sell-to Customer No.';\n+ if DocumentRecord.Number() = Database::\"Issued Reminder Header\" then\n+ FieldName := 'Customer No.'\n+ else\n+ FieldName := 'Sell-to Customer No.';\n OnSendEmailDirectlyOnAfterSetFieldName(DocumentRecord.Number(), FieldName);\n if DataTypeManagement.FindfieldByName(DocumentRecord, FieldRef, FieldName) and Customer.Get(Format(FieldRef.Value())) then begin\n SourceTableIDs.Add(Database::Customer);\n"} -{"metadata": {"area": "finance", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226875", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-15", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\General Journal"], "FAIL_TO_PASS": [{"codeunitID": 134920, "functionName": ["VendorNameFieldPopulatesOnlyForVendorAccountType"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al\nindex 9e6664f2979..0e9383fc12c 100644\n--- a/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al\n@@ -6000,6 +6000,53 @@ codeunit 134920 \"ERM General Journal UT\"\n GenJournalLine[4].TestField(\"Document No.\", NewDocNo);\n end;\n \n+ [Test]\n+ procedure VendorNameFieldPopulatesOnlyForVendorAccountType()\n+ var\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalTemplate: Record \"Gen. Journal Template\";\n+ GLAccount: Record \"G/L Account\";\n+ Vendor: Record Vendor;\n+ PurchaseJournal: TestPage \"Purchase Journal\";\n+ begin\n+ // [SCENARIO 599505] Purchase Journal page validates vendor name field based on account type\n+ Initialize();\n+\n+ // [GIVEN] Create a vendor with random name\n+ LibraryPurchase.CreateVendor(Vendor);\n+ Vendor.Name := LibraryRandom.RandText(20);\n+ Vendor.Modify(true);\n+\n+ // [GIVEN] Create Purchase Journal Template and Batch\n+ LibraryERM.CreateGenJournalBatch(GenJournalBatch, LibraryJournals.SelectGenJournalTemplate(GenJournalTemplate.Type::Purchases, Page::\"Purchase Journal\"));\n+\n+ // [WHEN] Open Purchase Journal page and perform actions as per YAML recording\n+ PurchaseJournal.OpenEdit();\n+ PurchaseJournal.CurrentJnlBatchName.SetValue(GenJournalBatch.Name);\n+\n+ // [GIVEN] Set Document Type to Invoice and Document No. to random value\n+ PurchaseJournal.\"Document Type\".SetValue(\"Gen. Journal Document Type\"::Invoice);\n+ PurchaseJournal.\"Document No.\".SetValue(LibraryRandom.RandText(10));\n+\n+ // [GIVEN] Set Account Type to Vendor and Account No. to Vendor.\"No.\"\n+ PurchaseJournal.\"Account Type\".SetValue(\"Gen. Journal Account Type\"::Vendor);\n+ PurchaseJournal.\"Account No.\".SetValue(Vendor.\"No.\");\n+\n+ // [THEN] Verify Vendor Name page field is populated with Vendor.Name\n+ PurchaseJournal.\"\".AssertEquals(Vendor.Name);\n+\n+ // [WHEN] Set Account Type to G/L Account and Account No. to a new G/L Account.\"No.\"\n+ PurchaseJournal.\"Account Type\".SetValue(\"Gen. Journal Account Type\"::\"G/L Account\");\n+ LibraryERM.CreateGLAccount(GLAccount);\n+ PurchaseJournal.\"Account No.\".SetValue(GLAccount.\"No.\");\n+\n+ // [THEN] Verify Vendor Name field should be empty for G/L Account\n+ PurchaseJournal.\"\".AssertEquals('');\n+\n+ // [CLEANUP] Close Purchase Journal page\n+ PurchaseJournal.Close();\n+ end;\n+\n local procedure Initialize()\n begin\n LibrarySetupStorage.Restore();\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\nindex fa043e01294..4d5abfe80aa 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n@@ -170,7 +170,7 @@ page 254 \"Purchase Journal\"\n CurrPage.SaveRecord();\n end;\n }\n- field(\"\"; AccName)\n+ field(\"\"; GetVendorName())\n {\n ApplicationArea = Basic, Suite;\n Caption = 'Vendor Name';\n@@ -1661,6 +1661,14 @@ page 254 \"Purchase Journal\"\n NumberOfRecords := Rec.Count();\n end;\n \n+ local procedure GetVendorName(): Text[100]\n+ begin\n+ if (Rec.\"Account Type\" = Rec.\"Account Type\"::Vendor) and (AccName <> '') then\n+ exit(AccName);\n+\n+ exit('');\n+ end;\n+\n local procedure EnableApplyEntriesAction()\n begin\n ApplyEntriesActionEnabled :=\n"} -{"metadata": {"area": "finance", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226223", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-09", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134043, "functionName": ["NoVATEntryAddCurrExchRateAdjust"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al\nindex ee712bb9f9b..26f12019b95 100644\n--- a/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al\n@@ -1192,6 +1192,38 @@ codeunit 134043 \"ERM Additional Currency\"\n StrSubstNo(AmountLCYError, GenJournalLine.\"Amount (LCY)\"));\n end;\n \n+ [Test]\n+ [HandlerFunctions('StatisticsMessageHandler')]\n+ procedure NoVATEntryAddCurrExchRateAdjust()\n+ var\n+ Currency: Record Currency;\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ GeneralLedgerSetup: Record \"General Ledger Setup\";\n+ VATEntry: Record \"VAT Entry\";\n+ PostingDate: Date;\n+ begin\n+ // [SCENARIO 598998] \"Attempted to divide by zero\" error during Exchange Rates Adjustment if the company has no Tax/VAT Entries.\n+ Initialize();\n+ VATEntry.DeleteAll();\n+\n+ // [GIVEN] Currency FCY with exchange rates.\n+ PostingDate := WorkDate();\n+ CreateCurrencyWithExchangeRates(Currency, 1, PostingDate);\n+\n+ // [GIVEN] General Ledger Setup \"Additional Reporting Currency\" = \"FCY\"\n+ LibraryERM.SetAddReportingCurrency(Currency.Code);\n+\n+ // [GIVEN] General Ledger Setup \"VAT Exchange Rate Adjustment\" := Adjust Additional-Currency Amount\n+ UpdateGenLedgerVATExchRateAdjustment(\n+ GeneralLedgerSetup.\"VAT Exchange Rate Adjustment\"::\"Adjust Additional-Currency Amount\");\n+\n+ // [THEN] Run Adjust Exchange Rate with Adjust G/L Account and without other Adjustments\n+ CurrencyExchangeRate.Get(Currency.code, LibraryERM.FindEarliestDateForExhRate());\n+\n+ // [THEN] Report should executed without any error\n+ RunAdjustExchangeRates(CurrencyExchangeRate, Currency.Code);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al b/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al\nindex 467c235ce97..bdb56817ec5 100644\n--- a/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al\n@@ -308,6 +308,8 @@ codeunit 699 \"Exch. Rate Adjmt. Process\"\n Window.Open(AdjustingVATEntriesTxt + VATEntryProgressBarTxt);\n \n VATEntryNoTotal := VATEntry.Count();\n+ if VATEntryNoTotal = 0 then\n+ exit;\n SetVATEntryFilters(VATEntry, ExchRateAdjmtParameters.\"Start Date\", ExchRateAdjmtParameters.\"End Date\");\n if VATPostingSetup.FindSet() then\n repeat\n"} -{"metadata": {"area": "service", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-221877", "base_commit": "0b60a161ce9c6976c82d811815aa974cf29181f8", "created_at": "2025-07-24", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136101, "functionName": ["AutoUpdateServiceHeaderStatusOnServiceItemLineAdd"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\nindex 5a74dfc12b9..204066e8ac0 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n@@ -122,6 +122,7 @@ codeunit 136101 \"Service Orders\"\n AvailableExpectedQuantityErr: Label 'Available expected quantity must be %1.', Comment = '%1=Value';\n VATCountryRegionLbl: Label 'VAT Country/Region Code must be %1', Comment = '%1 = Country/Region Code';\n ServiceOrderErr: Label 'Service Order does not exist.';\n+ ServiceOrderStatusShouldChangedErr: Label 'Service Header Status should have changed when adding Service Item';\n \n [Test]\n [Scope('OnPrem')]\n@@ -5688,6 +5689,54 @@ codeunit 136101 \"Service Orders\"\n ServiceStatistics.SubForm.\"Amount Including VAT\".AssertEquals(0);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure AutoUpdateServiceHeaderStatusOnServiceItemLineAdd()\n+ var\n+ ServiceHeader: Record \"Service Header\";\n+ ServiceItem: Record \"Service Item\";\n+ Customer: Record Customer;\n+ ServiceOrderPage: TestPage \"Service Order\";\n+ InitialStatus: Enum \"Service Document Status\";\n+ FinalStatus: Enum \"Service Document Status\";\n+ begin\n+ // [SCENARIO 582114] Test that Service Header Status changes automatically when adding Service Item to Finished Service Order\n+\n+ // [GIVEN] Initialize and create test data\n+ Initialize();\n+ LibrarySales.CreateCustomer(Customer);\n+ LibraryService.CreateServiceItem(ServiceItem, Customer.\"No.\");\n+\n+ // [GIVEN] Create a Service Order and set status to Finished\n+ LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ ServiceHeader.Validate(Status, ServiceHeader.Status::Finished);\n+ ServiceHeader.Modify(true);\n+ InitialStatus := ServiceHeader.Status;\n+\n+ // [WHEN] Open Service Order page and add Service Item Line (simulating user action)\n+ ServiceOrderPage.OpenEdit();\n+ ServiceOrderPage.Filter.SetFilter(\"No.\", ServiceHeader.\"No.\");\n+\n+ // [THEN] Verify initial status is Finished\n+ ServiceOrderPage.Status.AssertEquals(ServiceHeader.Status::Finished);\n+\n+ // [GIVEN] Add Service Item to the Service Item Lines subform\n+ ServiceOrderPage.ServItemLines.New();\n+ ServiceOrderPage.ServItemLines.ServiceItemNo.SetValue(ServiceItem.\"No.\");\n+ ServiceOrderPage.ServItemLines.Next(); // Move focus to trigger validation\n+\n+ // [THEN] Verify that Service Header Status has changed automatically\n+ ServiceOrderPage.Status.AssertEquals(ServiceHeader.Status::Pending); // Expected new status based on repair status priority\n+\n+ // [THEN] Verify the change was logged in Service Document Log\n+ ServiceHeader.Get(ServiceHeader.\"Document Type\", ServiceHeader.\"No.\");\n+ FinalStatus := ServiceHeader.Status;\n+\n+ // [THEN] Verify status actually changed\n+ Assert.AreNotEqual(InitialStatus, FinalStatus, ServiceOrderStatusShouldChangedErr);\n+ ServiceOrderPage.Close();\n+ end;\n+\n local procedure CreateServiceDocumentWithResourceWith100PctDisc(\n var ServiceHeader: Record \"Service Header\"; ServiceLine: Record \"Service Line\"; DocumentType: Enum \"Service Document Type\";\n CustomerNo: Code[20]; ResourceNo: Code[20]; Quantity: Decimal; UnitPrice: Decimal)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al b/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al\nindex 1c8fcc9eb8a..60fc813bbe7 100644\n--- a/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al\n@@ -201,6 +201,10 @@ table 5901 \"Service Item Line\"\n UseServItemLineAsxRec := true;\n Modify(true);\n end;\n+\n+ if Rec.\"Repair Status Code\" <> '' then\n+ Validate(\"Repair Status Code\", Rec.\"Repair Status Code\");\n+\n OnAfterValidateServiceItemNoOnBeforeUpdateResponseTimeHours(Rec, xRec);\n UpdateResponseTimeHours();\n CreateDimFromDefaultDim(0);\n"} -{"metadata": {"area": "reporting", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-219082", "base_commit": "908f59111599c95d0ba5af721b5ef34d8f4aac1f", "created_at": "2025-06-25", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136101, "functionName": ["PrintServiceOrderWithWorkDescription"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\nindex b74fec47106..55070a77a9a 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n@@ -17,6 +17,7 @@ using Microsoft.Finance.VAT.Setup;\n using Microsoft.Foundation.Address;\n using Microsoft.Foundation.ExtendedText;\n using Microsoft.Foundation.NoSeries;\n+using Microsoft.Foundation.Reporting;\n using Microsoft.Foundation.Shipping;\n using Microsoft.Foundation.UOM;\n using Microsoft.Inventory.Item;\n@@ -5620,6 +5621,39 @@ codeunit 136101 \"Service Orders\"\n Assert.AreEqual(Customer[2].\"Country/Region Code\", ServiceHeader.\"VAT Country/Region Code\", VATCountryRegionLbl);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ServiceOrderReportRequestPageHandler')]\n+ procedure PrintServiceOrderWithWorkDescription()\n+ var\n+ Item: Record Item;\n+ ServiceHeader: Record \"Service Header\";\n+ ServiceItem: Record \"Service Item\";\n+ ServiceItemLine: Record \"Service Item Line\";\n+ ServiceLine: Record \"Service Line\";\n+ ServiceOrder: TestPage \"Service Order\";\n+ begin\n+ // [SCENARIO 575369] Verify Printing Service Order with Work Description does not throw error.\n+ Initialize();\n+\n+ // [GIVEN] Create Item\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create Service Order with Work Description\n+ LibraryService.CreateServiceItem(ServiceItem, LibrarySales.CreateCustomerNo());\n+ LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader.\"Document Type\"::Order, ServiceItem.\"Customer No.\");\n+ LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, ServiceItem.\"No.\");\n+ LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Item, Item.\"No.\");\n+\n+ // [WHEN] Open Service Order Card and click Print\n+ CreateCustomReportSelectionForCustomer(ServiceHeader.\"Customer No.\", \"Report Selection Usage\"::\"SM.Order\", 5900);\n+ ServiceOrder.OpenEdit();\n+ ServiceOrder.GotoRecord(ServiceHeader);\n+ ServiceOrder.WorkDescription.SetValue(LibraryRandom.RandText(20));\n+ ServiceOrder.\"&Print\".Invoke();\n+\n+ // [THEN] Verify no transaction error should occur.\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerTRUE(Question: Text[1024]; var Reply: Boolean)\n@@ -7923,6 +7957,23 @@ codeunit 136101 \"Service Orders\"\n exit(ServiceInvoiceHeader.\"No.\");\n end;\n \n+ local procedure CreateCustomReportSelectionForCustomer(CustomerNo: Code[20]; ReportSelectionUsage: Enum \"Report Selection Usage\"; ReportID: Integer)\n+ var\n+ CustomReportSelection: Record \"Custom Report Selection\";\n+ CustomReportLayout: Record \"Custom Report Layout\";\n+ begin\n+ CustomReportSelection.Init();\n+ CustomReportSelection.Validate(\"Source Type\", Database::Customer);\n+ CustomReportSelection.Validate(\"Source No.\", CustomerNo);\n+ CustomReportSelection.Validate(Usage, ReportSelectionUsage);\n+ CustomReportSelection.Validate(Sequence, 1);\n+ CustomReportSelection.Validate(\"Report ID\", ReportID);\n+ CustomReportSelection.Validate(\"Use for Email Body\", true);\n+ CustomReportSelection.Validate(\n+ \"Email Body Layout Code\", CustomReportLayout.InitBuiltInLayout(CustomReportSelection.\"Report ID\", CustomReportLayout.Type::Word.AsInteger()));\n+ CustomReportSelection.Insert(true);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmMessageHandler(Question: Text[1024]; var Reply: Boolean)\n@@ -8256,5 +8307,11 @@ codeunit 136101 \"Service Orders\"\n LibraryVariableStorage.Enqueue(CreditLimitNotification.CreditLimitDetails.OutstandingAmtLCY.Value);\n LibraryVariableStorage.Enqueue(CreditLimitNotification.CreditLimitDetails.TotalAmountLCY.Value);\n end;\n+\n+ [RequestPageHandler]\n+ procedure ServiceOrderReportRequestPageHandler(var ServiceOrder: TestRequestPage \"Service Order\")\n+ begin\n+ ServiceOrder.Cancel().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\nindex b1515adac7d..09f7b8b3998 100644\n--- a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n+++ b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n@@ -582,8 +582,11 @@ table 77 \"Report Selections\"\n \n IsHandled := false;\n OnBeforePrintDocument(TempReportSelections, IsGUI, RecVarToPrint, IsHandled);\n- if not IsHandled then\n+ if not IsHandled then begin\n+ if IsGUI then\n+ Commit();\n REPORT.RunModal(TempReportSelections.\"Report ID\", IsGUI, false, RecVarToPrint);\n+ end;\n \n OnAfterPrintDocument(TempReportSelections, IsGUI, RecVarToPrint, IsHandled);\n \n"} -{"metadata": {"area": "finance", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-216918", "base_commit": "1ea776a43bea699ee3b63beb68162372fcb1226f", "created_at": "2025-05-29", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134284, "functionName": ["JobJnlLineWithNonDeductNormalVATInFCYFromGenJnlLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al\nindex be592f1e578..e6b29da63e9 100644\n--- a/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al\n@@ -1135,6 +1135,52 @@ codeunit 134284 \"Non Ded. VAT Misc.\"\n Assert.RecordIsNotEmpty(GLEntry);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure JobJnlLineWithNonDeductNormalVATInFCYFromGenJnlLine()\n+ var\n+ Customer: Record Customer;\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ GenJnlLine: Record \"Gen. Journal Line\";\n+ JobJnlLine: Record \"Job Journal Line\";\n+ JobTransferLine: Codeunit \"Job Transfer Line\";\n+ DeductiblePercent: Decimal;\n+ begin\n+ // [FEATURE] [Normal VAT] [UT]\n+ // [SCENARIO 575793] Job journal line with FCY built from the general journal line includes non deductible VAT in \"Unit Cost\"\n+ Initialize();\n+ LibraryNonDeductibleVAT.SetUseForJobCost();\n+ // [GIVEN] VAT Posting Setup, where \"Tax Calculation Type\"::\"Normal VAT\", 'Deductible %' is '60'\n+ DeductiblePercent := LibraryRandom.RandInt(90);\n+ CreateNonDeductibleVATPostingSetup(VATPostingSetup, \"Tax Calculation Type\"::\"Normal VAT\", '', DeductiblePercent);\n+ // [GIVEN] Job \"X\" with currency which factor is 0.5\n+ LibrarySales.CreateCustomer(Customer);\n+ LibraryJob.CreateJob(Job, Customer.\"No.\");\n+ Job.Validate(\"Currency Code\", LibraryERM.CreateCurrencyWithRandomExchRates());\n+ Job.Modify(true);\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+ // [GIVEN] General journal line where line contains \"Non-Deductible VAT Amount\" = 100, \"Job No.\" = \"X\" \"Job Line Type\" = 'Billable'\n+ // [GIVEN] \"Job Quantity\" = 2, \"Job Unit Cost\" = 50\n+ CreateJobGLJournalLine(GenJnlLine, JobTask, VATPostingSetup);\n+\n+ // [WHEN] Run FromGenJnlLineToJnlLine\n+ JobTransferLine.FromGenJnlLineToJnlLine(GenJnlLine, JobJnlLine);\n+\n+ // [THEN] JobJnlLine contains \"Unit Cost LCY\" = (\"Job Unit Cost\" + \"Non-Deductible VAT Amount\") * \"Currency Factor\" / \"Job Quantity\" = (50 + 100) * 0.5 / 2 = 37.5\n+ Assert.AreEqual(\n+ Round(JobJnlLine.\"Unit Cost (LCY)\"),\n+ Round(GenJnlLine.\"Job Total Cost (LCY)\" / GenJnlLine.\"Job Quantity\") +\n+ Round(Round(GenJnlLine.\"Non-Deductible VAT Amount\" * GenJnlLine.\"Job Currency Factor\") / GenJnlLine.\"Job Quantity\"),\n+ 'Unit Cost (LCY) with Non-Deductible VAT amount is not correct in Job Journal Line');\n+ // [THEN] JobJnlLine contains \"Total Unit Cost\" = (\"Job Unit Cost\" + \"Non-Deductible VAT Amount\") * \"Currency Factor\" = (50 + 100) * 0.5 = 75\n+ Assert.AreEqual(\n+ Round(JobJnlLine.\"Total Cost (LCY)\"),\n+ Round(GenJnlLine.\"Job Total Cost (LCY)\" + Round(GenJnlLine.\"Non-Deductible VAT Amount\" * GenJnlLine.\"Job Currency Factor\")),\n+ 'Total Cost (LCY) with Non-Deductible VAT amount is not correct in Job Journal Line');\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1368,6 +1414,15 @@ codeunit 134284 \"Non Ded. VAT Misc.\"\n GenJournalLine.Modify(true);\n end;\n \n+ local procedure CreateJobGLJournalLine(var GenJournalLine: Record \"Gen. Journal Line\"; JobTask: Record \"Job Task\"; VATPostingSetup: Record \"VAT Posting Setup\")\n+ begin\n+ LibraryJob.CreateJobGLJournalLine(GenJournalLine.\"Job Line Type\"::Billable, JobTask, GenJournalLine);\n+ GenJournalLine.Validate(\"Gen. Posting Type\", GenJournalLine.\"Gen. Posting Type\"::Purchase);\n+ GenJournalLine.Validate(\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ GenJournalLine.Validate(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n+ GenJournalLine.Modify(true);\n+ end;\n+\n local procedure FindFAPostingGroup(GenProdPostingGroup: Code[20]; VATProductPostingGroup: Code[20]): Code[20]\n var\n FAPostingGroup: Record \"FA Posting Group\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\nindex 26f99dcabd6..f35c5e941b5 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n@@ -4937,16 +4937,7 @@ table 81 \"Gen. Journal Line\"\n TempJobJnlLine.Validate(\"No.\", \"Account No.\");\n TempJobJnlLine.Validate(Quantity, \"Job Quantity\");\n \n- if \"Currency Factor\" = 0 then begin\n- if \"Job Currency Factor\" = 0 then\n- TmpJobJnlOverallCurrencyFactor := 1\n- else\n- TmpJobJnlOverallCurrencyFactor := \"Job Currency Factor\";\n- end else\n- if \"Job Currency Factor\" = 0 then\n- TmpJobJnlOverallCurrencyFactor := 1 / \"Currency Factor\"\n- else\n- TmpJobJnlOverallCurrencyFactor := \"Job Currency Factor\" / \"Currency Factor\";\n+ TmpJobJnlOverallCurrencyFactor := GetGenJnlLineToJobCurrencyFactor();\n \n UpdateAmountsOnTempJobJnlLine(TmpJobJnlOverallCurrencyFactor);\n \n@@ -7628,6 +7619,22 @@ table 81 \"Gen. Journal Line\"\n RecordRestrictionMgt.RestrictRecordUsage(GenJournalLine, RestrictBatchUsageDetailsTxt);\n end;\n \n+ /// \n+ /// Calculates the currency factor for the general journal line based on the job currency factor and the journal line currency factor.\n+ /// \n+ /// Resulted currency factor\n+ procedure GetGenJnlLineToJobCurrencyFactor(): Decimal\n+ begin\n+ if \"Currency Factor\" = 0 then begin\n+ if \"Job Currency Factor\" = 0 then\n+ exit(1);\n+ exit(\"Job Currency Factor\");\n+ end;\n+ if \"Job Currency Factor\" = 0 then\n+ exit(1 / \"Currency Factor\");\n+ exit(\"Job Currency Factor\" / \"Currency Factor\");\n+ end;\n+\n /// \n /// Event triggered before creating dimensions from the Default Dimensions during the validation of the \"Account No.\" field.\n /// By subscribing to this event, developers can override the default dimension creation process for the \"Account No.\" field.\ndiff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex 2b5a6a4ca7e..c9d976f7272 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -17,6 +17,8 @@ using Microsoft.Foundation.Enums;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.History;\n using Microsoft.Foundation.Company;\n+using Microsoft.Projects.Project.Journal;\n+using Microsoft.Projects.Project.Job;\n \n /// \n /// Defines the implementation of Non-Deductible VAT\n@@ -436,6 +438,36 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n FALedgEntry.\"Non-Ded. VAT FA Cost\" := GenJnlLine.\"Non-Ded. VAT FA Cost\";\n end;\n \n+ procedure CopyNonDedVATFromGenJnlLineToJobJnlLine(var JobJnlLine: Record \"Job Journal Line\"; GenJnlLine: Record \"Gen. Journal Line\")\n+ var\n+ Job: Record Job;\n+ CurrencyFactor, NonDedVATAmountLCY, UnitCost, UnitCostLCY, TotalCost, TotalCostLCY : Decimal;\n+ begin\n+ if not UseNonDeductibleVATAmountForJobCost() then\n+ exit;\n+ if not Job.Get(JobJnlLine.\"Job No.\") then\n+ exit;\n+ NonDedVATAmountLCY := GenJnlLine.\"Non-Deductible VAT Amount LCY\";\n+ if GenJnlLine.\"Currency Code\" <> Job.\"Currency Code\" then begin\n+ CurrencyFactor := GenJnlLine.GetGenJnlLineToJobCurrencyFactor();\n+ NonDedVATAmountLCY := Round(GenJnlLine.\"Non-Deductible VAT Amount\" * CurrencyFactor);\n+ end;\n+ UnitCostLCY := Round(NonDedVATAmountLCY / JobJnlLine.Quantity);\n+ UnitCost := Round(GenJnlLine.\"Non-Deductible VAT Amount\" / JobJnlLine.Quantity);\n+ TotalCostLCY := NonDedVATAmountLCY;\n+ TotalCost := GenJnlLine.\"Non-Deductible VAT Amount\";\n+ if JobJnlLine.\"Unit Cost\" > 0 then begin\n+ UnitCostLCY := Abs(UnitCostLCY);\n+ UnitCost := Abs(UnitCost);\n+ TotalCostLCY := Abs(TotalCostLCY);\n+ TotalCost := Abs(TotalCost);\n+ end;\n+ JobJnlLine.\"Unit Cost (LCY)\" += UnitCostLCY;\n+ JobJnlLine.\"Unit Cost\" += UnitCost;\n+ JobJnlLine.\"Total Cost (LCY)\" += TotalCostLCY;\n+ JobJnlLine.\"Total Cost\" += TotalCost;\n+ end;\n+\n procedure CheckPrepmtWithNonDeductubleVATInPurchaseLine(PurchaseLine: Record \"Purchase Line\")\n begin\n if (PurchaseLine.\"Prepayment %\" <> 0) and (PurchaseLine.\"Non-Deductible VAT %\" <> 0) then\ndiff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al\nindex 216076f8cf0..4114e9a6815 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al\n@@ -15,6 +15,7 @@ using Microsoft.FixedAssets.Ledger;\n using Microsoft.Foundation.Enums;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.History;\n+using Microsoft.Projects.Project.Journal;\n \n /// \n /// Provides an interface of the Non-Deductible VAT functionality.\n@@ -430,6 +431,11 @@ codeunit 6200 \"Non-Deductible VAT\"\n NonDedVATImpl.CopyNonDedVATFromGenJnlLineToFALedgEntry(FALedgEntry, GenJnlLine);\n end;\n \n+ procedure CopyNonDedVATFromGenJnlLineToJobJnlLine(var JobJnlLine: Record \"Job Journal Line\"; GenJnlLine: Record \"Gen. Journal Line\")\n+ begin\n+ NonDedVATImpl.CopyNonDedVATFromGenJnlLineToJobJnlLine(JobJnlLine, GenJnlLine);\n+ end;\n+\n /// \n /// Throws an error if purchase line contains prepayment and Non-Deductible VAT\n /// \ndiff --git a/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al\nindex d541dd087c6..50866220a3f 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al\n@@ -498,18 +498,7 @@ codeunit 1004 \"Job Transfer Line\"\n JobJnlLine.\"Total Cost (LCY)\" := GenJnlLine.\"Job Total Cost (LCY)\";\n JobJnlLine.\"Total Cost\" := GenJnlLine.\"Job Total Cost\";\n \n- if NonDeductibleVAT.UseNonDeductibleVATAmountForJobCost() then\n- if JobJnlLine.\"Unit Cost\" > 0 then begin\n- JobJnlLine.\"Unit Cost (LCY)\" += Abs(Round(GenJnlLine.\"Non-Deductible VAT Amount LCY\" / JobJnlLine.Quantity));\n- JobJnlLine.\"Unit Cost\" += Abs(Round(GenJnlLine.\"Non-Deductible VAT Amount\" / JobJnlLine.Quantity));\n- JobJnlLine.\"Total Cost (LCY)\" += Abs(GenJnlLine.\"Non-Deductible VAT Amount LCY\");\n- JobJnlLine.\"Total Cost\" += Abs(GenJnlLine.\"Non-Deductible VAT Amount\");\n- end else begin\n- JobJnlLine.\"Unit Cost (LCY)\" += Round(GenJnlLine.\"Non-Deductible VAT Amount LCY\" / JobJnlLine.Quantity);\n- JobJnlLine.\"Unit Cost\" += Round(GenJnlLine.\"Non-Deductible VAT Amount\" / JobJnlLine.Quantity);\n- JobJnlLine.\"Total Cost (LCY)\" += GenJnlLine.\"Non-Deductible VAT Amount LCY\";\n- JobJnlLine.\"Total Cost\" += GenJnlLine.\"Non-Deductible VAT Amount\";\n- end;\n+ NonDeductibleVAT.CopyNonDedVATFromGenJnlLineToJobJnlLine(JobJnlLine, GenJnlLine);\n \n JobJnlLine.\"Unit Price (LCY)\" := GenJnlLine.\"Job Unit Price (LCY)\";\n JobJnlLine.\"Unit Price\" := GenJnlLine.\"Job Unit Price\";\n"} -{"metadata": {"area": "service", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218856", "base_commit": "7bfa7e70c56ba44878906b722f59a492dc75f376", "created_at": "2025-06-23", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136102, "functionName": ["ChangeCustomerOfTypePeronInServiceContract"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al\nindex ad01a498eef..1b594959106 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al\n@@ -10,6 +10,8 @@ using Microsoft.Finance.Dimension;\n using Microsoft.Finance.GeneralLedger.Account;\n using Microsoft.Finance.GeneralLedger.Ledger;\n using Microsoft.Finance.VAT.Setup;\n+using Microsoft.CRM.BusinessRelation;\n+using Microsoft.CRM.Contact;\n using Microsoft.Inventory.Item;\n using Microsoft.Projects.Resources.Resource;\n using Microsoft.Sales.Customer;\n@@ -42,6 +44,7 @@ codeunit 136102 \"Service Contracts\"\n var\n ServiceContractHeader2: Record \"Service Contract Header\";\n Assert: Codeunit Assert;\n+ LibraryMarketing: Codeunit \"Library - Marketing\";\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n LibraryService: Codeunit \"Library - Service\";\n LibraryUtility: Codeunit \"Library - Utility\";\n@@ -3563,6 +3566,49 @@ codeunit 136102 \"Service Contracts\"\n Assert.Equal('', Format(ServiceContractHeader.\"Last Invoice Period End\"));\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler,SignContractConfirmHandler,ServContrctTemplateListHandler')]\n+ [Scope('OnPrem')]\n+ procedure ChangeCustomerOfTypePeronInServiceContract()\n+ var\n+ ContactBusinessRelation: Record \"Contact Business Relation\";\n+ Contact: Record Contact;\n+ ServiceContractHeader: Record \"Service Contract Header\";\n+ ServiceContractLine: Record \"Service Contract Line\";\n+ ShiptoAddress: Record \"Ship-to Address\";\n+ ServContractManagement: Codeunit ServContractManagement;\n+ ContactCard: TestPage \"Contact Card\";\n+ begin\n+ // [SCENARIO 578655] Change Customer No. on Service Contract of Customer type Person.\n+ Initialize();\n+\n+ // [GIVEN] Create Contact of type Person.\n+ LibraryMarketing.CreatePersonContact(Contact);\n+\n+ // [GIVEN] Open Contact Card and invoke Create Customer.\n+ ContactCard.OpenEdit();\n+ ContactCard.Filter.SetFilter(\"No.\", Contact.\"No.\");\n+ ContactCard.CreateCustomer.Invoke();\n+\n+ // [GIVEN] Create Service Contract Header and Service Contract Line.\n+ CreateServiceContract(ServiceContractHeader, ServiceContractLine, ServiceContractHeader.\"Contract Type\"::Contract);\n+ ModifyServiceContractHeader(ServiceContractHeader, ServiceContractHeader.\"Service Period\");\n+\n+ // [GIVEN] Find Contact Business Relation of the Contact.\n+ ContactBusinessRelation.SetRange(\"Contact No.\", Contact.\"No.\");\n+ ContactBusinessRelation.SetRange(\"Link to Table\", ContactBusinessRelation.\"Link to Table\"::Customer);\n+ ContactBusinessRelation.FindFirst();\n+\n+ // [GIVEN] Create Ship to Address.\n+ LibrarySales.CreateShipToAddress(ShiptoAddress, ContactBusinessRelation.\"No.\");\n+\n+ // [WHEN] Change Customer No. in Service Contract.\n+ ServContractManagement.ChangeCustNoOnServContract(ShiptoAddress.\"Customer No.\", ShiptoAddress.Code, ServiceContractHeader);\n+\n+ // [THEN] Check Customer No. is updated.\n+ CheckChangeCustomerNo(ServiceContractHeader, ContactBusinessRelation.\"No.\");\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5358,6 +5404,11 @@ codeunit 136102 \"Service Contracts\"\n Error(MessageText);\n end;\n \n+ [MessageHandler]\n+ procedure MessageHandler(Message: Text[1024])\n+ begin\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure InvoiceConfirmHandler(ConfirmMessage: Text[1024]; var Result: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al b/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al\nindex 4f315c8f604..572b132d573 100644\n--- a/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al\n@@ -1389,7 +1389,7 @@ table 5965 \"Service Contract Header\"\n if (\"Bill-to Customer No.\" <> '') and (\"Bill-to Contact No.\" <> '') then begin\n Cont.Get(\"Bill-to Contact No.\");\n if ContBusinessRelation.FindByRelation(ContBusinessRelation.\"Link to Table\"::Customer, \"Bill-to Customer No.\") then\n- if ContBusinessRelation.\"Contact No.\" <> Cont.\"Company No.\" then\n+ if (ContBusinessRelation.\"Contact No.\" <> Cont.\"Company No.\") and (Cont.Type = Cont.Type::Company) then\n Error(Text045, Cont.\"No.\", Cont.Name, \"Bill-to Customer No.\");\n end;\n \n@@ -2240,6 +2240,7 @@ table 5965 \"Service Contract Header\"\n ContBusinessRelation: Record \"Contact Business Relation\";\n Cust: Record Customer;\n Cont: Record Contact;\n+ ContactBusinessRelationFound: Boolean;\n IsHandled: Boolean;\n begin\n IsHandled := false;\n@@ -2251,13 +2252,18 @@ table 5965 \"Service Contract Header\"\n \"Contact No.\" := Cont.\"No.\";\n \"Phone No.\" := Cont.\"Phone No.\";\n \"E-Mail\" := Cont.\"E-Mail\";\n- if Cont.Type = Cont.Type::Person then\n- \"Contact Name\" := Cont.Name\n- else\n+ if Cont.Type = Cont.Type::Person then begin\n+ \"Contact Name\" := Cont.Name;\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"No.\");\n+ end else begin\n+ if not ContactBusinessRelationFound then\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\");\n+\n if Cust.Get(\"Customer No.\") then\n \"Contact Name\" := Cust.Contact\n else\n \"Contact Name\" := ''\n+ end;\n end else begin\n \"Contact Name\" := '';\n \"Phone No.\" := '';\n@@ -2265,7 +2271,7 @@ table 5965 \"Service Contract Header\"\n exit;\n end;\n \n- if ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\") then begin\n+ if ContactBusinessRelationFound then begin\n if (\"Customer No.\" <> '') and\n (\"Customer No.\" <> ContBusinessRelation.\"No.\")\n then\n@@ -2289,23 +2295,29 @@ table 5965 \"Service Contract Header\"\n ContBusinessRelation: Record \"Contact Business Relation\";\n Cust: Record Customer;\n Cont: Record Contact;\n+ ContactBusinessRelationFound: Boolean;\n begin\n if Cont.Get(ContactNo) then begin\n \"Bill-to Contact No.\" := Cont.\"No.\";\n- if Cont.Type = Cont.Type::Person then\n- \"Bill-to Contact\" := Cont.Name\n- else\n+ if Cont.Type = Cont.Type::Person then begin\n+ \"Bill-to Contact\" := Cont.Name;\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"No.\");\n+ end else begin\n+ if not ContactBusinessRelationFound then\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\");\n+\n if Cust.Get(\"Bill-to Customer No.\") then\n \"Bill-to Contact\" := Cust.Contact\n else\n \"Bill-to Contact\" := '';\n+ end;\n end else begin\n \"Bill-to Contact\" := '';\n exit;\n end;\n \n OnUpdateBillToCustOnBeforeContBusinessRelationFindByContact(Rec, Cust, Cont);\n- if ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\") then begin\n+ if ContactBusinessRelationFound then begin\n if \"Bill-to Customer No.\" = '' then begin\n SkipBillToContact := true;\n Validate(\"Bill-to Customer No.\", ContBusinessRelation.\"No.\");\n"} -{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-215225", "base_commit": "cc7b76c98d2c241ae675ae9b79fe1b634617ec36", "created_at": "2025-05-12", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136305, "functionName": ["CheckUnitCostAndPriceNotZeroInRecurringJobJnlAfterPosting"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\nindex e427075ebd9..1a379eb28aa 100644\n--- a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n@@ -2938,6 +2938,35 @@ codeunit 136305 \"Job Journal\"\n Assert.AreNotEqual(GenJournalLine.\"Job Total Cost (LCY)\", PreviousProjectTotalCostLCY, ProjectTotalCostErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerTrue,MessageHandler')]\n+ procedure CheckUnitCostAndPriceNotZeroInRecurringJobJnlAfterPosting()\n+ var\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ Resource: Record Resource;\n+ RecurringJobJnl: TestPage \"Recurring Job Jnl.\";\n+ begin\n+ // [SCENARIO 575092] Verify that the Unit Price and Unit Cost are not 0 in the recurring job journal after posting.\n+ Initialize();\n+\n+ // [GIVEN] Create a Resource.\n+ FindResource(Resource);\n+\n+ // [GIVEN] Create Job, job task & multiple Job planning line.\n+ CreateFullJob(Job, JobTask, Resource);\n+\n+ // [GIVEN] Create Recurring Job Journal.\n+ OpenRecurringJobJnl(RecurringJobJnl, JobTask, Resource.\"No.\");\n+\n+ // [WHEN] Post Recurring Job Journal.\n+ PostRecurringJobJnl(RecurringJobJnl);\n+\n+ // [THEN] Verify that the Unit Price and Unit Cost are not zero in the recurring job journal after posting.\n+ RecurringJobJnl.\"Unit Price\".AssertEquals(Resource.\"Unit Price\");\n+ RecurringJobJnl.\"Unit Cost\".AssertEquals(Resource.\"Unit Cost\");\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3917,6 +3946,51 @@ codeunit 136305 \"Job Journal\"\n JobJnlLine.TestField(\"Reserved Qty. (Base)\", 0);\n end;\n \n+ local procedure FindResource(var Resource: Record Resource)\n+ begin\n+ Resource.Get(LibraryJob.CreateConsumable(\"Job Planning Line Type\"::Resource));\n+ Resource.Validate(Type, Resource.Type::Person);\n+ Resource.Validate(\"Unit Cost\", LibraryRandom.RandIntInRange(100, 200));\n+ Resource.Validate(\"Unit Price\", LibraryRandom.RandIntInRange(300, 500));\n+ Resource.Modify(true);\n+ end;\n+\n+ local procedure CreateFullJob(var Job: Record Job; var JobTask: Record \"Job Task\"; Resource: Record Resource)\n+ var\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ begin\n+ LibraryJob.CreateJob(Job);\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+\n+ LibraryJob.CreateJobPlanningLine(\n+ JobTask, JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\",\n+ JobPlanningLine.Type::Resource, Resource.\"No.\", LibraryRandom.RandInt(10), JobPlanningLine);\n+ end;\n+\n+ local procedure OpenRecurringJobJnl(var RecurringJobJnl: TestPage \"Recurring Job Jnl.\"; JobTask: Record \"Job Task\"; ResourceNo: Code[20])\n+ var\n+ JobJournalLineType: Enum \"Job Journal Line Type\";\n+ RecurringMethod: Option ,Fixed,Variable;\n+ begin\n+ RecurringJobJnl.OpenEdit();\n+ RecurringJobJnl.\"Recurring Method\".SetValue(Format(RecurringMethod::Variable));\n+ RecurringJobJnl.\"Recurring Frequency\".SetValue('10D');\n+ RecurringJobJnl.\"Document No.\".SetValue(JobTask.\"Job No.\");\n+ RecurringJobJnl.\"Job No.\".SetValue(JobTask.\"Job No.\");\n+ RecurringJobJnl.\"Job Task No.\".SetValue(JobTask.\"Job Task No.\");\n+ RecurringJobJnl.Type.SetValue(Format(JobJournalLineType::Resource));\n+ RecurringJobJnl.\"No.\".SetValue(ResourceNo);\n+ RecurringJobJnl.Quantity.SetValue(Format(LibraryRandom.RandInt(5)));\n+ RecurringJobJnl.Close();\n+ end;\n+\n+ local procedure PostRecurringJobJnl(var RecurringJobJnl: TestPage \"Recurring Job Jnl.\")\n+ begin\n+ RecurringJobJnl.OpenEdit();\n+ RecurringJobJnl.\"P&ost\".Invoke();\n+ Commit();\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListPageHandler(var ContactList: TestPage \"Contact List\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al\nindex 9f7bd75b991..57af0bb5690 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al\n@@ -275,6 +275,7 @@ codeunit 1013 \"Job Jnl.-Post Batch\"\n \n local procedure UpdateAndDeleteLines()\n var\n+ UnitCost, UnitPrice : Decimal;\n IsHandled: Boolean;\n begin\n OnBeforeUpdateAndDeleteLines(JobJnlLine);\n@@ -295,8 +296,12 @@ codeunit 1013 \"Job Jnl.-Post Batch\"\n JobJnlLine2.Validate(\"Posting Date\", CalcDate(JobJnlLine2.\"Recurring Frequency\", JobJnlLine2.\"Posting Date\"));\n if (JobJnlLine2.\"Recurring Method\" = JobJnlLine2.\"Recurring Method\"::Variable) and\n (JobJnlLine2.\"No.\" <> '')\n- then\n+ then begin\n+ UnitCost := JobJnlLine2.\"Unit Cost\";\n+ UnitPrice := JobJnlLine2.\"Unit Price\";\n JobJnlLine2.DeleteAmounts();\n+ UpdateUnitCostAndPrice(JobJnlLine2, UnitCost, UnitPrice);\n+ end;\n JobJnlLine2.Modify();\n until JobJnlLine2.Next() = 0;\n end else begin\n@@ -339,6 +344,15 @@ codeunit 1013 \"Job Jnl.-Post Batch\"\n NoSeriesBatch.SaveState();\n end;\n \n+ local procedure UpdateUnitCostAndPrice(var JobJournalLine: Record \"Job Journal Line\"; UnitCost: Decimal; UnitPrice: Decimal)\n+ begin\n+ if (UnitCost = 0) and (UnitPrice = 0) then\n+ exit;\n+\n+ JobJournalLine.\"Unit Cost\" := UnitCost;\n+ JobJournalLine.\"Unit Price\" := UnitPrice;\n+ end;\n+\n procedure SetSuppressCommit(NewSuppressCommit: Boolean)\n begin\n SuppressCommit := NewSuppressCommit;\n"} -{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213629", "base_commit": "e0211616ed03e968b987e2becd1069b217690c34", "created_at": "2025-04-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136306, "functionName": ["CopyJobAndCreateProjectJournalLineWithoutError"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\nindex 36cc3d9db4a..369594bf631 100644\n--- a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n@@ -58,6 +58,7 @@ codeunit 136306 \"Job Invoicing\"\n DetailLevel: Option All,\"Per Job\",\"Per Job Task\",\"Per Job Planning Line\";\n LineDiscountPctErr: Label '%1 should be %2', Comment = '%1 = Field Caption, %2 = Field Value';\n WrongNoOfLinesLbl: Label 'Wrong number of lines created.';\n+ ValueFalseErr: Label 'Value must be equal to false';\n \n [Test]\n [HandlerFunctions('TransferToInvoiceHandler,MessageHandler')]\n@@ -4043,6 +4044,44 @@ codeunit 136306 \"Job Invoicing\"\n Assert.AreEqual(1, InvoicesList.Count, WrongNoOfLinesLbl);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler,ConfirmHandler')]\n+ [Scope('OnPrem')]\n+ procedure CopyJobAndCreateProjectJournalLineWithoutError()\n+ var\n+ Job: Record Job;\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ JobTask: Record \"Job Task\";\n+ JobJournalLine: Record \"Job Journal Line\";\n+ CopyJob: Codeunit \"Copy Job\";\n+ JobLineType: Enum \"Job Line Type\";\n+ TargetJobNo: Code[20];\n+ begin\n+ // [SCENARIO 573397] Copy project of System-Created Entry must be equal to 'No' in Project Planning Line\n+ Initialize();\n+\n+ // [GIVEN] Create Job with Customer\n+ CreateJobWithCustomer(Job);\n+\n+ // [GIVEN] Create Job Task\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+\n+ // [GIVEN] Create Job Journal Line of type \"Both Budget and Billable\" and post it.\n+ CreateAndPostJobJournalLineWithIteAndType(JobJournalLine, JobTask, JobLineType::\"Both Budget and Billable\");\n+\n+ // [GIVEN] Create target Job Id\n+ TargetJobNo := LibraryUtility.GenerateGUID();\n+\n+ // [WHEN] Copy Job by setting Copy Quantity as true.\n+ CopyJob.SetCopyOptions(false, true, false, 0, 0, 0);\n+ CopyJob.CopyJob(Job, TargetJobNo, TargetJobNo, Job.\"Bill-to Customer No.\", '');\n+\n+ // [THEN] Find the created Job Planning Line and \"System-Created Entry\" should be set false\n+ JobPlanningLine.SetRange(\"Job No.\", TargetJobNo);\n+ JobPlanningLine.FindFirst();\n+ Assert.IsFalse(JobPlanningLine.\"System-Created Entry\", ValueFalseErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5676,6 +5715,20 @@ codeunit 136306 \"Job Invoicing\"\n until JobPlanningLine.Next() = 0;\n end;\n \n+ local procedure CreateAndPostJobJournalLineWithIteAndType(var JobJournalLine: Record \"Job Journal Line\"; JobTask: Record \"Job Task\"; JobLineType: Enum \"Job Line Type\")\n+ var\n+ Item: Record Item;\n+ begin\n+ LibraryInventory.CreateItem(Item);\n+ LibraryJob.CreateJobJournalLine(JobLineType, JobTask, JobJournalLine);\n+ JobJournalLine.Validate(Type, JobJournalLine.Type::Item);\n+ JobJournalLine.Validate(\"No.\", Item.\"No.\");\n+ JobJournalLine.Validate(Quantity, LibraryRandom.RandInt(100));\n+ JobJournalLine.Modify(true);\n+\n+ LibraryJob.PostJobJournal(JobJournalLine);\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure TransferSalesCreditMemoReportWithDatesHandler(var JobTransferToCreditMemo: TestRequestPage \"Job Transfer to Credit Memo\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al\nindex 162d6cc55e7..544c740a441 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al\n@@ -192,6 +192,7 @@ codeunit 1006 \"Copy Job\"\n TargetJobPlanningLine.\"Completely Picked\" := false;\n TargetJobPlanningLine.\"Ledger Entry No.\" := 0;\n TargetJobPlanningLine.\"Ledger Entry Type\" := TargetJobPlanningLine.\"Ledger Entry Type\"::\" \";\n+ TargetJobPlanningLine.\"System-Created Entry\" := false;\n OnCopyJobPlanningLinesOnBeforeTargetJobPlanningLineInsert(TargetJobPlanningLine, SourceJobPlanningLine);\n TargetJobPlanningLine.Insert(true);\n OnCopyJobPlanningLinesOnAfterTargetJobPlanningLineInsert(TargetJobPlanningLine, SourceJobPlanningLine);\n"} -{"metadata": {"area": "intercompany", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213524", "base_commit": "594d5dfcee2efe390ab75b6b0e30bc5a9f13f7f0", "created_at": "2025-04-16", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134154, "functionName": ["ICNavigateFromSalesCreditMemoLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al\nindex 0480aea9fa6..3ca288e85d2 100644\n--- a/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al\n@@ -3408,6 +3408,40 @@ codeunit 134154 \"ERM Intercompany III\"\n Assert.AreEqual(300, SalesLine.\"Line Amount\", 'When a sales order with a discount amount and prices including VAT is received from intercompany, the line amount should be preserved');\n end;\n \n+ [Test]\n+ procedure ICNavigateFromSalesCreditMemoLine()\n+ var\n+ Customer: Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ ICOutboxTransactions: TestPage \"IC Outbox Transactions\";\n+ PostedSalesCreditMemo: TestPage \"Posted Sales Credit Memo\";\n+ begin\n+ // [SCENARIO 574577] \"Unable to navigate to the related document\" error message if you use Go to Document from the Intercompany Outbox Transactions for a Credit Memo.\n+ Initialize();\n+ LibraryApplicationArea.EnableEssentialSetup();\n+ CleanupIC(false, true, true, false);\n+ CreateCustomerWithICPartner(Customer);\n+\n+ // [GIVEN] A posted sales credit memo to an IC customer\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::\"Credit Memo\", Customer.\"No.\");\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, LibraryInventory.CreateItemNo(), 1);\n+ LibrarySales.PostSalesDocument(SalesHeader, true, true);\n+\n+ // [GIVEN] The posted sales credit memo IC transaction should be on the Outbox\n+ ICOutboxTransactions.OpenEdit();\n+\n+ // [WHEN] Navigating from Outbox for this transaction\n+ PostedSalesCreditMemo.Trap();\n+ ICOutboxTransactions.GoToDocument.Invoke();\n+\n+ // [THEN] It should open the Posted Sales Credit Memo\n+ PostedSalesCreditMemo.\"Pre-Assigned No.\".AssertEquals(SalesHeader.\"No.\");\n+\n+ // Cleanup\n+ CleanupIC(false, true, true, false);\n+ end;\n+\n local procedure Initialize()\n var\n ICSetup: Record \"IC Setup\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al b/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al\nindex 92bf43b1d84..944f49028e6 100644\n--- a/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al\n@@ -56,6 +56,20 @@ codeunit 437 \"IC Navigation\"\n exit(true);\n end;\n \n+ local procedure NavigateToSalesCreditMemo(DocumentNo: Code[20]): Boolean\n+ var\n+ SalesCrMemoHeader: Record \"Sales Cr.Memo Header\";\n+ PostedSalesCreditMemo: Page \"Posted Sales Credit Memo\";\n+ begin\n+ // An IC Transaction of type Sales Credit Memo can only be sent when posted.\n+ if not SalesCrMemoHeader.Get(DocumentNo) then\n+ exit(false);\n+ // The related document is a Posted Sales Credit Memo.\n+ PostedSalesCreditMemo.SetRecord(SalesCrMemoHeader);\n+ PostedSalesCreditMemo.Run();\n+ exit(true);\n+ end;\n+\n local procedure NavigateToSalesInvoice(DocumentNo: Code[20]; ICPartnerCode: Code[20]): Boolean\n var\n Customer: Record Customer;\n@@ -120,6 +134,8 @@ codeunit 437 \"IC Navigation\"\n exit(NavigateToSalesOrderDocument(DocumentNo, ICDirectionType, ICPartnerCode));\n DocumentType::Invoice:\n exit(NavigateToSalesInvoice(DocumentNo));\n+ DocumentType::\"Credit Memo\":\n+ exit(NavigateToSalesCreditMemo(DocumentNo));\n else begin\n ShouldNavigateToDoc := false;\n OnNavigateToSalesDocumentOnAfterCheckDocumentType(DocumentNo, ICDirectionType, ICPartnerCode, DocumentType, ShouldNavigateToDoc);\n"} -{"metadata": {"area": "inventory", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213741", "base_commit": "aba5cc540cc2ff7bfc88064b9c6728b32f120fce", "created_at": "2025-04-22", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Assembly"], "FAIL_TO_PASS": [{"codeunitID": 137911, "functionName": ["VerifyAdjustCostItemEntriesMustBeExecutedForAssemblyItem"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al b/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al\nindex 46d1c5d5be0..55f596ef397 100644\n--- a/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al\n@@ -40,6 +40,7 @@ codeunit 137911 \"SCM Calculate Assembly Cost\"\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n+ LibraryManufacturing: Codeunit \"Library - Manufacturing\";\n WorkDate2: Date;\n TEXT_PARENT: Label 'Parent';\n TEXT_CHILD: Label 'Child';\n@@ -452,6 +453,54 @@ codeunit 137911 \"SCM Calculate Assembly Cost\"\n ComponentItem.\"Standard Cost\", ComponentItem.\"Standard Cost\" * CurrExchRate);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ procedure VerifyAdjustCostItemEntriesMustBeExecutedForAssemblyItem()\n+ var\n+ AssemblyItem, ComponentItem, NonInvItem : Record Item;\n+ ValueEntry: Record \"Value Entry\";\n+ begin\n+ // [SCENARIO 574360] Verify \"Adjust Cost - Item Entries\" must be executed for Assembly item which include non-Inventory item in Assembly BOM.\n+ // When \"Automatic Cost Posting\" is false in Inventory Setup and \"Inc. Non. Inv. Cost To Prod\" is true in Mfg Setup.\n+ Initialize();\n+\n+ // [GIVEN] Set Automatic Cost Posting to false.\n+ LibraryInventory.SetAutomaticCostPosting(false);\n+\n+ // [GIVEN] Update \"Inc. Non. Inv. Cost To Prod\" in Manufacturing Setup.\n+ LibraryManufacturing.UpdateNonInventoryCostToProductionInManufacturingSetup(true);\n+\n+ // [GIVEN] Create an Assembled item with \"Costing Method\"::Standard.\n+ CreateItem(AssemblyItem, AssemblyItem.\"Costing Method\"::Standard, AssemblyItem.\"Replenishment System\"::Assembly, 0);\n+\n+ // [GIVEN] Create an Component item with \"Costing Method\"::FIFO.\n+ CreateItem(ComponentItem, ComponentItem.\"Costing Method\"::FIFO, ComponentItem.\"Replenishment System\"::Purchase, LibraryRandom.RandIntInRange(100, 200));\n+\n+ // [GIVEN] Create Non-Inventory item with Unit Cost.\n+ LibraryInventory.CreateNonInventoryTypeItem(NonInvItem);\n+ NonInvItem.Validate(\"Unit Cost\", LibraryRandom.RandIntInRange(200, 500));\n+ NonInvItem.Modify();\n+\n+ // [GIVEN] Post Positive Adjustment for Component item.\n+ PostPositiveAdjustment(ComponentItem.\"No.\", LibraryRandom.RandIntInRange(200, 500));\n+\n+ // [GIVEN] Create Assembly List for Component and Non-Inventory item.\n+ CreateAssemblyListComponent(AssemblyItem.\"No.\", ComponentItem.\"No.\", 1);\n+ CreateAssemblyListComponent(AssemblyItem.\"No.\", NonInvItem.\"No.\", 1);\n+\n+ // [GIVEN] Create and post Assembly Order.\n+ CreateAndPostAssemblyHeader(AssemblyItem.\"No.\", 1, WorkDate());\n+\n+ // [WHEN] Run \"Adjust Cost - Item Entries\"\n+ LibraryCosting.AdjustCostItemEntries(AssemblyItem.\"No.\", '');\n+\n+ // [THEN] Verify \"Adjust Cost - Item Entries\" must be executed for Assembly item.\n+ ValueEntry.SetRange(\"Item Ledger Entry Type\", ValueEntry.\"Item Ledger Entry Type\"::\"Assembly Output\");\n+ ValueEntry.SetRange(\"Entry Type\", ValueEntry.\"Entry Type\"::\"Direct Cost - Non Inventory\");\n+ ValueEntry.SetRange(\"Item No.\", AssemblyItem.\"No.\");\n+ Assert.RecordCount(ValueEntry, 0);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"SCM Calculate Assembly Cost\");\n@@ -585,5 +634,10 @@ codeunit 137911 \"SCM Calculate Assembly Cost\"\n ItemLedgerEntry.TestField(\"Cost Amount (Actual)\", ExpectedCostLCY);\n ItemLedgerEntry.TestField(\"Cost Amount (Actual) (ACY)\", Round(ExpectedCostACY, Currency.\"Amount Rounding Precision\"));\n end;\n+\n+ [MessageHandler]\n+ procedure MessageHandler(Message: Text[1024])\n+ begin\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al\nindex 9bc596d4312..92b2588e89d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al\n@@ -158,10 +158,12 @@ codeunit 5896 \"Calc. Inventory Adjmt. - Order\"\n if HasNewCost(InventoryAdjmtEntryOrder.\"Indirect Cost\", InventoryAdjmtEntryOrder.\"Indirect Cost (ACY)\") then\n InventoryAdjustmentBuffer.AddCost(\n ItemLedgerEntry.\"Entry No.\", InventoryAdjustmentBuffer.\"Entry Type\"::\"Indirect Cost\", \"Cost Variance Type\"::\" \", InventoryAdjmtEntryOrder.\"Indirect Cost\", InventoryAdjmtEntryOrder.\"Indirect Cost (ACY)\");\n- if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n- if HasNewCost(InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\") then\n- InventoryAdjustmentBuffer.AddCost(\n- ItemLedgerEntry.\"Entry No.\", InventoryAdjustmentBuffer.\"Entry Type\"::\"Direct Cost - Non Inventory\", \"Cost Variance Type\"::\" \", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\");\n+\n+ if ItemLedgerEntry.\"Order Type\" = ItemLedgerEntry.\"Order Type\"::Production then\n+ if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n+ if HasNewCost(InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\") then\n+ InventoryAdjustmentBuffer.AddCost(\n+ ItemLedgerEntry.\"Entry No.\", InventoryAdjustmentBuffer.\"Entry Type\"::\"Direct Cost - Non Inventory\", \"Cost Variance Type\"::\" \", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\");\n \n if Item.\"Costing Method\" <> Item.\"Costing Method\"::Standard then\n exit;\n@@ -171,11 +173,12 @@ codeunit 5896 \"Calc. Inventory Adjmt. - Order\"\n InventoryAdjustmentBuffer.\"Entry Type\"::Variance, InventoryAdjustmentBuffer.\"Variance Type\"::Material,\n InventoryAdjmtEntryOrder.\"Single-Level Material Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Material Cost (ACY)\");\n \n- if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n- if HasNewCost(InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\") then\n- InventoryAdjustmentBuffer.AddCost(ItemLedgerEntry.\"Entry No.\",\n- InventoryAdjustmentBuffer.\"Entry Type\"::Variance, InventoryAdjustmentBuffer.\"Variance Type\"::\"Material - Non Inventory\",\n- InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\");\n+ if ItemLedgerEntry.\"Order Type\" = ItemLedgerEntry.\"Order Type\"::Production then\n+ if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n+ if HasNewCost(InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\") then\n+ InventoryAdjustmentBuffer.AddCost(ItemLedgerEntry.\"Entry No.\",\n+ InventoryAdjustmentBuffer.\"Entry Type\"::Variance, InventoryAdjustmentBuffer.\"Variance Type\"::\"Material - Non Inventory\",\n+ InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\");\n \n if HasNewCost(InventoryAdjmtEntryOrder.\"Single-Level Capacity Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Capacity Cost (ACY)\") then\n InventoryAdjustmentBuffer.AddCost(ItemLedgerEntry.\"Entry No.\",\n"} -{"metadata": {"area": "manufacturing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-206527", "base_commit": "d8e867062d4137cf5df2d9d2b8a71bb53210f685", "created_at": "2025-02-07", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137088, "functionName": ["ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\nindex 7415eaa53cc..2573227dbca 100644\n--- a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n@@ -45,6 +45,8 @@ codeunit 137088 \"SCM Order Planning - III\"\n LineExistErr: Label 'Requistion line in %1 worksheet should exist for item %2';\n PurchaseLineQuantityBaseErr: Label '%1.%2 must be nearly equal to %3.', Comment = '%1 : Purchase Line, %2 : Quantity (Base), %3 : Value.';\n BOMFixedQtyCalcFormulaErr: Label 'BOM Fixed Quantity Calculation Formula should be used to calculate the values.';\n+ RelesedProdOrderComponentQtyPerRoundingErr: Label 'Relesed Production Order Item Component Quantity per %1 Not Match With Expected Result %2';\n+ RelesedProdOrderComponentExpQtyRoundingErr: Label 'Relesed Production Order Item Component Expected Quantity %1 Not Match With Expected Result %2';\n \n [Test]\n [HandlerFunctions('MakeSupplyOrdersPageHandler')]\n@@ -2988,6 +2990,73 @@ codeunit 137088 \"SCM Order Planning - III\"\n VerifyStartingTimeOnFirmPlannedProductionOrder(StartingTime, ChildItem.\"No.\", ProductionOrderNo);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalPageHandler,ErrorMessageHandler')]\n+ procedure ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking()\n+ var\n+ BaseItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ComponentItem: Record Item;\n+ ProdOrderComp: Record \"Prod. Order Component\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ ProductItem: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ ExpectedQty: Decimal;\n+ RelesedProdOrderNo: Code[20];\n+ Status: Enum \"Production Order Status\";\n+ begin\n+ // [SCENARIO 562766] If a component's Item UOM has a 'Quantity Rounding Precision' of 1, & a Finished Good consumes partial quantity, \n+ // the Prod. Order created from the Planning of a Sales Order pulls in the Component with a 'Qty. Per' and 'Exp. Qty.' of 0.\n+ Initialize();\n+\n+ // [GIVEN] Created Component Item\n+ LibraryInventory.CreateItem(ComponentItem);\n+ ComponentItem.Validate(\"Replenishment System\", ComponentItem.\"Replenishment System\"::Purchase);\n+ ComponentItem.Validate(\"Rounding Precision\", LibraryRandom.RandPrecision());\n+ ComponentItem.Validate(\"Reordering Policy\", ComponentItem.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ ComponentItem.Validate(\"Include Inventory\", true);\n+ ComponentItem.Modify(true);\n+\n+ // [GIVEN] Set Qty. Rounding Precision = 1 for Component Item\n+ BaseItemUnitOfMeasure.Get(ComponentItem.\"No.\", ComponentItem.\"Base Unit of Measure\");\n+ BaseItemUnitOfMeasure.Validate(\"Qty. Rounding Precision\", 1);\n+ BaseItemUnitOfMeasure.Modify();\n+\n+ // [GIVEN] Created Production Bom using Component Item\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ComponentItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, ComponentItem.\"No.\", LibraryRandom.RandDecInDecimalRange(0.01, 0.99, 2));\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify();\n+\n+ // [GIVEN] Created Master Item and Production Bom Assigned to Master Item\n+ LibraryInventory.CreateItem(ProductItem);\n+ ProductItem.Validate(\"Replenishment System\", ProductItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProductItem.Validate(\"Rounding Precision\", 1);\n+ ProductItem.Validate(\"Reordering Policy\", ProductItem.\"Reordering Policy\"::Order);\n+ ProductItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProductItem.Modify(true);\n+\n+ // [GIVEN] Created Sales Order Using Master Item Quantity - 1\n+ CreateSalesOrder(SalesHeader, ProductItem.\"No.\", '', 1, 1);\n+\n+ // [WHEN] Created Released Prod. Order From Sales Order Using Planning\n+ LibraryPlanning.CreateProdOrderUsingPlanning(ProductionOrder, Status::\"Firm Planned\", SalesHeader.\"No.\", ProductItem.\"No.\");\n+ RelesedProdOrderNo := LibraryManufacturing.ChangeStatusFirmPlanToReleased(ProductionOrder.\"No.\");\n+\n+ // [WHEN] Find Released Production Order Component\n+ FindProdOrderLine(ProdOrderLine, RelesedProdOrderNo);\n+ FindProdOrderComponent(ProdOrderComp, ProdOrderLine.\"Prod. Order No.\", ComponentItem.\"No.\");\n+\n+ // [WHEN] Getting Expected result using Component Rounding Precision\n+ ExpectedQty := Round(ProductionBOMLine.\"Quantity per\" * BaseItemUnitOfMeasure.\"Qty. Rounding Precision\" / BaseItemUnitOfMeasure.\"Qty. Rounding Precision\", ComponentItem.\"Rounding Precision\");\n+\n+ // [THEN] Expected Quantity must be Equal to Production Order Component \"Quantity per\" And \"Expected Quantity\"\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Quantity per\", StrSubstNo(RelesedProdOrderComponentQtyPerRoundingErr, ProdOrderComp.\"Quantity per\", ExpectedQty));\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Expected Quantity\", StrSubstNo(RelesedProdOrderComponentExpQtyRoundingErr, ProdOrderComp.\"Expected Quantity\", ExpectedQty));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3805,6 +3874,14 @@ codeunit 137088 \"SCM Order Planning - III\"\n Assert.IsTrue(ProductionOrder.\"Starting Time\" = StartingTime, '');\n end;\n \n+ local procedure FindProdOrderLine(var ProdOrderLine: Record \"Prod. Order Line\"; ProductionOrderNo: Code[20])\n+ begin\n+ ProdOrderLine.Reset();\n+ ProdOrderLine.SetRange(Status, ProdOrderLine.Status::Released);\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProductionOrderNo);\n+ ProdOrderLine.FindFirst();\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure MakeSupplyOrdersPageHandler(var MakeSupplyOrders: Page \"Make Supply Orders\"; var Response: Action)\n@@ -3911,5 +3988,16 @@ codeunit 137088 \"SCM Order Planning - III\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ procedure ModalPageHandler(var CreateOrderFromSales: Page \"Create Order From Sales\"; var Response: Action)\n+ begin\n+ Response := Action::Yes;\n+ end;\n+\n+ [MessageHandler]\n+ procedure ErrorMessageHandler(Message: Text[1024])\n+ begin\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\nindex 36930a9e2aaa..5d44df0a5969 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n@@ -43,6 +43,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp: Record \"Prod. Order Component\";\n ProdOrderRoutingLine2: Record \"Prod. Order Routing Line\";\n ProdBOMLine: array[99] of Record \"Production BOM Line\";\n+ ProdLineItem: Record Item;\n UOMMgt: Codeunit \"Unit of Measure Management\";\n MfgCostCalcMgt: Codeunit \"Mfg. Cost Calculation Mgt.\";\n VersionMgt: Codeunit VersionManagement;\n@@ -260,8 +261,8 @@ codeunit 99000773 \"Calculate Prod. Order\"\n \n local procedure TransferBOMProcessItem(Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var ErrorOccured: Boolean)\n var\n- Item2: Record Item;\n ComponentSKU: Record \"Stockkeeping Unit\";\n+ Item2: Record Item;\n IsHandled: Boolean;\n QtyRoundPrecision: Decimal;\n begin\n@@ -297,6 +298,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp.Validate(\"Unit of Measure Code\", ProdBOMLine[Level].\"Unit of Measure Code\");\n if (ProdOrderComp.\"Item No.\" <> '') and Item2.Get(ProdOrderComp.\"Item No.\") then\n QtyRoundPrecision := UOMMgt.GetQtyRoundingPrecision(Item2, ProdBOMLine[Level].\"Unit of Measure Code\");\n+ CheckingRoundingPrecision(Item2, ProdLineItem, QtyRoundPrecision, Level);\n if QtyRoundPrecision <> 0 then\n ProdOrderComp.\"Quantity per\" := Round(ProdBOMLine[Level].\"Quantity per\" * LineQtyPerUOM / ItemQtyPerUOM, QtyRoundPrecision)\n else\n@@ -975,6 +977,21 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderLineToCheck.TestField(Quantity);\n end;\n \n+ local procedure CheckingRoundingPrecision(ChildItem: Record Item; ProdLineItem: Record Item; var QtyRoundPrecision: Decimal; Level: Integer)\n+ begin\n+ if (ChildItem.\"Rounding Precision\" = 0) or (QtyRoundPrecision = 0) then\n+ exit;\n+\n+ if (not ProdLineItem.Get(ProdOrderLine.\"Item No.\")) or (ProdLineItem.\"Replenishment System\" <> ProdLineItem.\"Replenishment System\"::\"Prod. Order\") then\n+ exit;\n+\n+ if (ChildItem.\"Base Unit of Measure\" <> ProdBOMLine[Level].\"Unit of Measure Code\") then\n+ exit;\n+ QtyRoundPrecision := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision\" := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision (Base)\" := ChildItem.\"Rounding Precision\";\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterInsertProdRoutingLine(var ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; ProdOrderLine: Record \"Prod. Order Line\")\n begin\n"} -{"metadata": {"area": "pricing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208851", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-04", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134117, "functionName": ["AmountTypeFieldDoesNotChangeOnClosePageSalesPriceList"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al b/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al\nindex 5f586214ecb..c18252ac131 100644\n--- a/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al\n@@ -4366,6 +4366,39 @@ codeunit 134117 \"Price Lists UI\"\n PurchasePriceList.Caption()));\n end;\n \n+ [Test]\n+ procedure AmountTypeFieldDoesNotChangeOnClosePageSalesPriceList()\n+ var\n+ PriceListHeader: Record \"Price List Header\";\n+ CustomerDiscountGroup: Record \"Customer Discount Group\";\n+ SalesPriceList: TestPage \"Sales Price List\";\n+ PriceListHeaderCode: Code[20];\n+ begin\n+ // [SCENARIO 566994] Bug fix to ensure the field \"Amount Type\" does not change after closing the page \"Sales Price List\" \n+ Initialize(true);\n+\n+ // [GIVEN] Sales Price List for discount\n+ PriceListHeaderCode := LibraryUtility.GenerateGUID();\n+ SalesPriceList.OpenEdit();\n+ SalesPriceList.New();\n+ SalesPriceList.Code.SetValue(PriceListHeaderCode);\n+ SalesPriceList.Description.SetValue(LibraryUtility.GenerateGUID());\n+ SalesPriceList.SourceType.SetValue(\"Price Source Type\"::\"Customer Disc. Group\");\n+ SalesPriceList.AmountType.SetValue(\"Price Amount Type\"::Discount);\n+ CustomerDiscountGroup.Init();\n+ CustomerDiscountGroup.Code := LibraryUtility.GenerateGUID();\n+ CustomerDiscountGroup.Insert();\n+ SalesPriceList.AssignToNo.SetValue(CustomerDiscountGroup.Code);\n+ SalesPriceList.Status.SetValue(\"Price Status\"::Active);\n+\n+ // [WHEN] Close the page \"Sales Price List\"\n+ SalesPriceList.Close();\n+\n+ // [THEN] Check the field \"Amount Type\" has not reverted to Price & Discount\n+ PriceListHeader.Get(PriceListHeaderCode);\n+ Assert.IsTrue((PriceListHeader.\"Amount Type\" = PriceListHeader.\"Amount Type\"::Discount), 'The field \"Amount Type\" has changed after closing the page \"Sales Price List\"');\n+ end;\n+\n local procedure Initialize(Enable: Boolean)\n var\n PriceListHeader: Record \"Price List Header\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al\nindex fb6adbb607d..9e6fd459241 100644\n--- a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al\n@@ -562,6 +562,7 @@ table 7000 \"Price List Header\"\n var\n xAmountType: Enum \"Price Amount Type\";\n begin\n+ CopyTo(PriceSource);\n xAmountType := \"Amount Type\";\n if \"Source Type\" in [\"Source Type\"::\"Customer Disc. Group\", \"Source Type\"::\"Customer Price Group\"] then\n \"Amount Type\" := PriceSource.GetDefaultAmountType()\n"} -{"metadata": {"area": "sales", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208320", "base_commit": "d080f087349d4713e1782f2f2630819714cb6738", "created_at": "2025-02-27", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134386, "functionName": ["UpdateEmailAndPhoneNoWhenChangeBillToOfSalesInvoice"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al\nindex bc3ad2bbe5c..30e993b56af 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al\n@@ -4462,6 +4462,51 @@ codeunit 134386 \"ERM Sales Documents II\"\n SalesOrder.SalesLines.\"Invoice Discount Amount\".AssertEquals(SalesHeader.\"Invoice Discount Value\");\n end;\n \n+ [HandlerFunctions('CustomerLookupHandler,ConfirmHandlerYes')]\n+ [Test]\n+ procedure UpdateEmailAndPhoneNoWhenChangeBillToOfSalesInvoice()\n+ var\n+ Contact: array[2] of Record Contact;\n+ Customer: array[2] of Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesInvoice: TestPage \"Sales Invoice\";\n+ begin\n+ // [SCENARIO 564632] The Email and Phone No. should update when selecting Another Customer in the \"Bill-to\" field of a Sales Invoice\n+ Initialize();\n+\n+ // [GIVEN] Create First Customer with First Contact with Phone = \"111111111\", Mobile Phone = \"222222222\" and Email = \"contact1@mail.com\"\n+ LibraryMarketing.CreateContactWithCustomer(Contact[1], Customer[1]);\n+ UpdateContactInfo(Contact[1], '111111111', '222222222', 'contact1@mail.com');\n+ Contact[1].Modify(true);\n+\n+ // [GIVEN] Create Second Customer with Second Contact with Phone = \"333333333\", Mobile Phone = \"444444444\" and Email = \"contact2@mail.com\"\n+ LibraryMarketing.CreateContactWithCustomer(Contact[2], Customer[2]);\n+ UpdateContactInfo(Contact[2], '333333333', '444444444', 'contact2@mail.com');\n+ Contact[2].Modify(true);\n+\n+ // [GIVEN] Create Sales Invoice with First Customer\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer[1].\"No.\");\n+\n+ // [GIVEN] Sales Invoice Card is opened\n+ LibraryVariableStorage.Enqueue(Customer[2].\"No.\");\n+ LibraryVariableStorage.Enqueue('');\n+ LibraryVariableStorage.Enqueue(true); // yes to change \"Bill-to Customer No.\"\n+ SalesInvoice.OpenEdit();\n+ SalesInvoice.FILTER.SetFilter(\"No.\", SalesHeader.\"No.\");\n+\n+ // [WHEN] Select Second Customer when lookup \"Bill-to Customer Name\"\n+ SalesInvoice.\"Bill-to Name\".Lookup();\n+\n+ // [THEN] Verify Sales Invoice \"Phone No.\" = \"333333333\"\n+ SalesInvoice.BillToContactPhoneNo.AssertEquals(Contact[2].\"Phone No.\");\n+\n+ // [THEN] Verify Sales Invoice \"Mobile Phone No.\" = \"444444444\"\n+ SalesInvoice.BillToContactMobilePhoneNo.AssertEquals(Contact[2].\"Mobile Phone No.\");\n+\n+ // [THEN] Verify Sales Invoice \"Email\" = \"contact2@mail.com\"\n+ SalesInvoice.BillToContactEmail.AssertEquals(Contact[2].\"E-Mail\");\n+ end;\n+\n [Test]\n [Scope('OnPrem')]\n procedure UpdateExtendedTextTypeNotAllowed()\n@@ -6595,5 +6640,14 @@ codeunit 134386 \"ERM Sales Documents II\"\n CustomerLookup.Filter.SetFilter(Name, LibraryVariableStorage.DequeueText());\n CustomerLookup.OK().Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ procedure CustomerLookupHandler(var CustomerLookup: TestPage \"Customer Lookup\")\n+ begin\n+ CustomerLookup.GotoKey(LibraryVariableStorage.DequeueText());\n+ Assert.AreEqual(LibraryVariableStorage.DequeueText(),\n+ CustomerLookup.Filter.GetFilter(\"Date Filter\"), 'Wrong Date Filter.');\n+ CustomerLookup.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al\nindex 1dee700e044..a3b2013773f 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al\n@@ -648,6 +648,23 @@ page 507 \"Blanket Sales Order\"\n Rec.SetRange(\"Bill-to Customer No.\");\n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al\nindex 84ba27e1b17..3f876b15fd0 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al\n@@ -552,6 +552,23 @@ page 44 \"Sales Credit Memo\"\n \n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al\nindex ee0d93e0f64..930047f5653 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al\n@@ -803,6 +803,25 @@ page 43 \"Sales Invoice\"\n CurrPage.Update();\n end;\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if not ((BillToOptions = BillToOptions::\"Custom Address\") and not ShouldSearchForCustByName) then begin\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al\nindex 77cf2b1863e..2a751833971 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al\n@@ -812,6 +812,25 @@ page 42 \"Sales Order\"\n CurrPage.Update();\n end;\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if not ((BillToOptions = BillToOptions::\"Custom Address\") and not ShouldSearchForCustByName) then begin\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al\nindex 7827a9ece78..5851f14e04b 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al\n@@ -763,6 +763,23 @@ page 41 \"Sales Quote\"\n \n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al\nindex e9c58725477..a0e9bb787e7 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al\n@@ -613,6 +613,23 @@ page 6630 \"Sales Return Order\"\n \n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\n"} -{"metadata": {"area": "inventory", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227219", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137038, "functionName": ["ReleaseTransferOrderWhenVariantMandatory"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\nindex f3c55b5f7a0..c7d556a7bc7 100644\n--- a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n@@ -49,6 +49,7 @@\n DerivedTransLineErr: Label 'Expected no Derived Transfer Line i.e. line with \"Derived From Line No.\" equal to original transfer line.';\n IncorrectSNUndoneErr: Label 'The Serial No. of the item on the transfer shipment line that was undone was different from the SN on the corresponding transfer line.';\n ApplToItemEntryErr: Label '%1 must be %2 in %3.', Comment = '%1 is Appl-to Item Entry, %2 is Item Ledger Entry No. and %3 is Transfer Line';\n+ VariantCodeMandatoryErr: Label '%1 must have a value in %2: Document No.=%3, Line No.=%4. It cannot be zero or empty.', Comment = '%1:Field Caption, %2: TableCaption, %3:Document No, %4: Line No.';\n \n [Test]\n [HandlerFunctions('MessageHandler')]\n@@ -4096,6 +4097,48 @@\n 'The cost amount of the undo transfer shipment entry should match the original transfer shipment entry (with opposite sign)');\n end;\n \n+ [Test]\n+ procedure ReleaseTransferOrderWhenVariantMandatory()\n+ var\n+ InTransitLocation: Record Location;\n+ Item: Record Item;\n+ ItemVariant: array[2] of Record \"Item Variant\";\n+ FromLocation: Record Location;\n+ ToLocation: Record Location;\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ begin\n+ // [SCENARIO 601487] Release Transfer Order when Variant Mandatory in Inventory Setup.\n+ Initialize();\n+\n+ // [GIVEN] Create From/To Locations and InTransit Location\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(FromLocation);\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(ToLocation);\n+ LibraryWarehouse.CreateInTransitLocation(InTransitLocation);\n+\n+ // [GIVEN] Create Item and two Variants\n+ LibraryInventory.CreateItem(Item);\n+ LibraryInventory.CreateItemVariant(ItemVariant[1], Item.\"No.\");\n+ LibraryInventory.CreateItemVariant(ItemVariant[2], Item.\"No.\");\n+\n+ // [GIVEN] Set Inventory Setup to require variant if exists\n+ SetVariantMandatoryInInventorySetup();\n+\n+ // [GIVEN] Create Transfer Order and Line.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, FromLocation.Code, ToLocation.Code, InTransitLocation.Code);\n+ LibraryInventory.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", LibraryRandom.RandIntInRange(10, 100));\n+\n+ // [WHEN] Try to release the transfer order\n+ asserterror LibraryWarehouse.ReleaseTransferOrder(TransferHeader);\n+\n+ // [THEN] Assert error matches expected label\n+ Assert.ExpectedError(\n+ StrSubstNo(\n+ VariantCodeMandatoryErr,\n+ TransferLine.FieldCaption(\"Variant Code\"), TransferLine.TableCaption(),\n+ TransferLine.\"Document No.\", TransferLine.\"Line No.\"));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5670,6 +5713,15 @@\n until WarehouseActivityLine.Next() = 0;\n end;\n \n+ local procedure SetVariantMandatoryInInventorySetup()\n+ var\n+ InventorySetup: Record \"Inventory Setup\";\n+ begin\n+ InventorySetup.Get();\n+ InventorySetup.Validate(\"Variant Mandatory if Exists\", true);\n+ InventorySetup.Modify(true);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al\nindex 979cdb45246..1254b0d5d0d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al\n@@ -119,7 +119,7 @@ codeunit 5708 \"Release Transfer Document\"\n if IsHandled then\n exit;\n \n- TransLine.SetLoadFields(\"Document No.\", Quantity, \"Item No.\");\n+ TransLine.SetLoadFields(\"Document No.\", Quantity, \"Item No.\", \"Variant Code\");\n TransLine.SetRange(\"Document No.\", TransHeader.\"No.\");\n TransLine.SetFilter(Quantity, '<>0');\n if TransLine.IsEmpty() then\n@@ -131,6 +131,8 @@ codeunit 5708 \"Release Transfer Document\"\n Item.Get(TransLine.\"Item No.\");\n if Item.IsInventoriableType() then\n TransLine.TestField(\"Unit of Measure Code\");\n+ if Item.IsVariantMandatory() then\n+ TransLine.TestField(\"Variant Code\");\n until TransLine.Next() = 0;\n TransLine.SetFilter(\"Item No.\", '');\n end;\n"} -{"metadata": {"area": "finance", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227358", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-18", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134227, "functionName": ["RecurringJournalSuccessfullyPostedWhenUnlinkIncomingDocumentOnPostingOptionIsActivated"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\nindex 82601475bc6..adef8e520c9 100644\n--- a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n@@ -1410,6 +1410,22 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n GenJournalLine[1].\"Line No.\"));\n end;\n \n+ [Test]\n+ procedure RecurringJournalSuccessfullyPostedWhenUnlinkIncomingDocumentOnPostingOptionIsActivated()\n+ var\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ RecurringFrequency: array[6] of DateFormula;\n+ begin\n+ // [SCENARIO 602441] The changes to the Gen. Journal Line record cannot be saved because some information is not up-to-date\" error when posting Recurring General Journal and the Unlink Incoming Document on Posting option is activated.\n+ Initialize();\n+\n+ // [GIVEN] Create Recurring Journal Lines.\n+ CreateRecurringJournalLineWithVariable(GenJournalLine, RecurringFrequency);\n+\n+ // [THEN] Post Recurring Journal Lines Successfully\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"ERM PostRecurringJournal\");\n@@ -1954,6 +1970,73 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n Assert.AreEqual(GenJnlAllocation.\"Dimension Set ID\", DimensionSetID, AllocationDimensionErr);\n end;\n \n+ local procedure CreateRecurringJournalLineWithVariable(var GenJournalLine: Record \"Gen. Journal Line\"; var RecurringFrequency: array[6] of DateFormula)\n+ var\n+ GLAccount: Record \"G/L Account\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ Vendor: Record Vendor;\n+ Counter: Integer;\n+ NoOfLines: Integer;\n+ begin\n+ // Use Random Number Generator to generate the No. of lines.\n+ NoOfLines := 2 * LibraryRandom.RandInt(3);\n+\n+ //[GIVEN] Find G/L Account\n+ FindGLAccount(GLAccount);\n+\n+ //[GIVEN] Create Vendor\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ //[WHEN] Create Recurring Journal Lines with Allocation and with random values.\n+ CreateRecurringGenJournalTemplateAndBatch(GenJournalBatch);\n+ for Counter := 1 to NoOfLines do begin\n+ if Counter = 1 then begin\n+ CreateGeneralJournalLineWithAccountType(\n+ GenJournalLine, GenJournalBatch, GenJournalLine.\"Recurring Method\"::\"V Variable\", -1000,\n+ Vendor.\"No.\");\n+ RecurringFrequency[Counter] := GenJournalLine.\"Recurring Frequency\";\n+ GenJournalLine.\"Document No.\" := '123';\n+ GenJournalLine.Modify();\n+ end else\n+ CreateGeneralJournalLineDocType(\n+ GenJournalLine, GenJournalBatch, GenJournalLine.\"Recurring Method\"::\"V Variable\", 1000,\n+ GLAccount.\"No.\");\n+ GenJournalLine.\"Document No.\" := '123';\n+ GenJournalLine.Modify();\n+ GLAccount.Next();\n+ RecurringFrequency[Counter] := GenJournalLine.\"Recurring Frequency\";\n+ end;\n+ end;\n+\n+ local procedure CreateGeneralJournalLineWithAccountType(var GenJournalLine: Record \"Gen. Journal Line\"; GenJournalBatch: Record \"Gen. Journal Batch\"; RecurringMethod: Enum \"Gen. Journal Recurring Method\"; Amount: Decimal; AccountNo: Code[20])\n+ begin\n+ CreateGeneralJournalLineWithType(\n+ GenJournalLine, GenJournalBatch, RecurringMethod, GenJournalLine.\"Document Type\"::Invoice,\n+ GenJournalLine.\"Account Type\"::Vendor, AccountNo, Amount);\n+ end;\n+\n+ local procedure CreateGeneralJournalLineDocType(var GenJournalLine: Record \"Gen. Journal Line\"; GenJournalBatch: Record \"Gen. Journal Batch\"; RecurringMethod: Enum \"Gen. Journal Recurring Method\"; Amount: Decimal; AccountNo: Code[20])\n+ begin\n+ CreateGeneralJournalLineWithType(\n+ GenJournalLine, GenJournalBatch, RecurringMethod, GenJournalLine.\"Document Type\"::Invoice,\n+ GenJournalLine.\"Account Type\"::\"G/L Account\", AccountNo, Amount);\n+ end;\n+\n+ local procedure CreateRecurringGenJournalTemplateAndBatch(var GenJournalBatch: Record \"Gen. Journal Batch\")\n+ var\n+ GenJnlTemplate: Record \"Gen. Journal Template\";\n+ begin\n+ LibraryERM.FindRecurringTemplateName(GenJnlTemplate);\n+ GenJnlTemplate.Validate(Type, GenJnlTemplate.Type::General);\n+ GenJnlTemplate.Validate(Recurring, true);\n+ GenJnlTemplate.Validate(\"Bal. Account Type\", GenJnlTemplate.\"Bal. Account Type\"::\"G/L Account\");\n+ GenJnlTemplate.Validate(\"Force Doc. Balance\", true);\n+ GenJnlTemplate.Validate(\"Copy VAT Setup to Jnl. Lines\", true);\n+ GenJnlTemplate.Validate(\"Unlink Inc. Doc On Posting\", true);\n+ GenJnlTemplate.Modify(true);\n+ LibraryERM.CreateRecurringBatchName(GenJournalBatch, GenJnlTemplate.Name);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al\nindex 61aff663d95..72ec7e79918 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al\n@@ -1006,6 +1006,7 @@ codeunit 13 \"Gen. Jnl.-Post Batch\"\n exit;\n if not CurrGenJnlTemplate.\"Unlink Inc. Doc On Posting\" then\n exit;\n+ GenJnlLine.GET(GenJnlLine.\"Journal Template Name\", GenJnlLine.\"Journal Batch Name\", GenJnlLine.\"Line No.\");\n GenJnlLine.\"Incoming Document Entry No.\" := 0;\n GenJnlLine.Modify();\n end;\n"} -{"metadata": {"area": "warehouse", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226004", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-07", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137055, "functionName": ["InventoryPickRoundingCausesResidualQuantity"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al\nindex 6e2c6a34131..8eaf3b44088 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al\n@@ -41,6 +41,8 @@ codeunit 137055 \"SCM Warehouse Pick\"\n LocationCodeMustNotOccurErr: Label 'Location code %1 must not occur. Expected value - %2', Comment = '%1 : occured location code, %2 : expected location code.';\n ReturnQtyMismatchErr: Label 'The value in the %1 field in the %2 does not match.', Comment = '%1 :FieldCaption, %2:Table Caption';\n ReservationAction: Option AutoReserve,GetQuantities;\n+ PickQuantityErr: Label 'Expected picked quantity %1 %2, but got %3 %2', Comment = '%1, %3 - Quantity; %2 - Unit of Measure Code';\n+ ShipQtyErr: Label 'Sales line should be fully shipped with no residual quantity';\n \n [Test]\n [HandlerFunctions('ReservationPageHandler')]\n@@ -1776,6 +1778,98 @@ codeunit 137055 \"SCM Warehouse Pick\"\n StrSubstNo(ReturnQtyMismatchErr, PurchaseLine.\"Return Qty. Shipped\", PurchaseLine.TableCaption));\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('CreateInvtPutAwayPickRequestPageHandler,MessageHandler')]\n+ procedure InventoryPickRoundingCausesResidualQuantity()\n+ var\n+ Item: Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ Location: Record Location;\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ Customer: Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ UnitOfMeasure: Record \"Unit of Measure\";\n+ Bin: Record Bin;\n+ TotalPickedQty: Decimal;\n+ QtyPerUOM: Decimal;\n+ QtyRoundingPrecision: Decimal;\n+ OrderQuantity: Decimal;\n+ BinCode: Code[20];\n+ begin\n+ // [SCENARIO 579500] Inventory pick rounding causes residual quantity When picking items with non-integer UOM conversion and very small \n+ // Quantity Rounding Precision, the pick process may result in rounding residuals\n+ Initialize();\n+\n+ // [GIVEN] Setup variables for rounding test with random values within problematic ranges\n+ SetStaticValues579500(QtyPerUOM, QtyRoundingPrecision, OrderQuantity);\n+\n+ // [GIVEN] Generate random bin code\n+ BinCode := LibraryUtility.GenerateRandomCode(SalesLine.FieldNo(\"Bin Code\"), Database::\"Sales Line\"); // Random bin code\n+\n+ // [GIVEN] Create item with specific UOM configuration for rounding test and LOT tracking with expiration dates\n+ LibraryInventory.CreateItem(Item);\n+ SetupItemTrackingWithExpirationDates(Item);\n+\n+ // [GIVEN] Add secondary UOM with problematic conversion factor and very small rounding precision\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure, Item.\"No.\", UnitOfMeasure.Code, QtyPerUOM);\n+ ItemUnitOfMeasure.Validate(\"Qty. Rounding Precision\", QtyRoundingPrecision);\n+ ItemUnitOfMeasure.Modify(true);\n+\n+ // [GIVEN] Set Sales Unit of Measure to the secondary UOM\n+ Item.Validate(\"Sales Unit of Measure\", UnitOfMeasure.Code);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Setup Location with Require Pick = YES and Pick According to FEFO = Yes\n+ LibraryWarehouse.CreateLocationWMS(Location, false, false, true, false, false);\n+ Location.Validate(\"Bin Mandatory\", true);\n+ Location.Validate(\"Pick According to FEFO\", true);\n+ Location.Modify(true);\n+\n+ // [GIVEN] Add Warehouse Employee for location\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create bin for the location\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, BinCode, '', '');\n+\n+ // [GIVEN] Add inventory for the item (sufficient for order quantity)\n+ CreateInventoryForLotAndExpiry579500(Item.\"No.\", Location.Code, Bin.Code);\n+\n+ // [GIVEN] Create Customer\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Sales Order with random quantity \n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", OrderQuantity);\n+ SalesLine.Validate(\"Location Code\", Location.Code);\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Release Sales Order\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+\n+ // [GiVEN] Create Inventory Pick from Sales Order\n+ Commit();\n+ SalesHeader.CreateInvtPutAwayPick();\n+\n+ // [WHEN] autofill Qty. to Handle, post the pick\n+ PostInventoryActivity(WarehouseActivityHeader.\"Source Document\"::\"Sales Order\", SalesHeader.\"No.\", WarehouseActivityLine.\"Activity Type\"::\"Invt. Pick\");\n+\n+ // [GIVEN] Get total picked quantity from Item Ledger Entries\n+ GetTotalPickedQuantity(Item.\"No.\", Location.Code, QtyPerUOM, TotalPickedQty);\n+\n+ // [THEN] Assert that picked quantity equals expected with tolerance for rounding\n+ Assert.AreNearlyEqual(OrderQuantity, TotalPickedQty, QtyRoundingPrecision * 10,\n+ StrSubstNo(PickQuantityErr, OrderQuantity, UnitOfMeasure.Code, TotalPickedQty));\n+\n+ // [THEN] Validate that no residual quantity remains (no second pick is required) Check that sales line is fully shipped\n+ SalesLine.Get(SalesLine.\"Document Type\", SalesLine.\"Document No.\", SalesLine.\"Line No.\");\n+ Assert.AreEqual(SalesLine.Quantity, SalesLine.\"Quantity Shipped\", ShipQtyErr);\n+ end;\n+\n local procedure Initialize()\n var\n WarehouseActivityLine: Record \"Warehouse Activity Line\";\n@@ -2604,6 +2698,128 @@ codeunit 137055 \"SCM Warehouse Pick\"\n exit(-PurchaseLine.\"Return Qty. to Ship\");\n end;\n \n+ local procedure SetupItemTrackingWithExpirationDates(var Item: Record Item)\n+ var\n+ ItemTrackingCode: Record \"Item Tracking Code\";\n+ begin\n+ LibraryInventory.CreateItemTrackingCode(ItemTrackingCode);\n+ ItemTrackingCode.Validate(\"Lot Specific Tracking\", true);\n+ ItemTrackingCode.Validate(\"Use Expiration Dates\", true);\n+ ItemTrackingCode.Validate(\"Man. Expir. Date Entry Reqd.\", true);\n+ ItemTrackingCode.Modify(true);\n+\n+ Item.Validate(\"Item Tracking Code\", ItemTrackingCode.Code);\n+ Item.Modify(true);\n+ end;\n+\n+ local procedure SetStaticValues579500(var QtyPerUOM: Decimal; var QtyRoundingPrecision: Decimal; var OrderQuantity: Decimal)\n+ begin\n+ QtyPerUOM := 2.888;\n+ QtyRoundingPrecision := 0.00001;\n+ OrderQuantity := 248;\n+ end;\n+\n+ local procedure GetTotalPickedQuantity(ItemNo: Code[20]; LocationCode: Code[10]; QtyPerUOM: Decimal; var TotalPickedQty: Decimal)\n+ var\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ begin\n+ TotalPickedQty := 0;\n+ ItemLedgerEntry.SetRange(\"Item No.\", ItemNo);\n+ ItemLedgerEntry.SetRange(\"Location Code\", LocationCode);\n+ ItemLedgerEntry.SetRange(\"Entry Type\", ItemLedgerEntry.\"Entry Type\"::Sale);\n+ if ItemLedgerEntry.FindSet() then\n+ repeat\n+ TotalPickedQty += Abs(ItemLedgerEntry.Quantity) / QtyPerUOM;\n+ until ItemLedgerEntry.Next() = 0;\n+ end;\n+\n+ local procedure PostInventoryActivity(SourceDocument: Enum \"Warehouse Activity Source Document\"; SourceNo: Code[20]; ActivityType: Enum \"Warehouse Activity Type\")\n+ var\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ begin\n+ WarehouseActivityHeader.SetRange(\"Source Document\", SourceDocument);\n+ WarehouseActivityHeader.SetRange(\"Source No.\", SourceNo);\n+ WarehouseActivityHeader.SetRange(Type, WarehouseActivityHeader.Type::\"Invt. Pick\");\n+ WarehouseActivityHeader.FindFirst();\n+\n+ // Autofill Qty. to Handle\n+ WarehouseActivityLine.SetRange(\"Activity Type\", ActivityType);\n+ WarehouseActivityLine.SetRange(\"No.\", WarehouseActivityHeader.\"No.\");\n+ WarehouseActivityLine.SetRange(\"Action Type\", WarehouseActivityLine.\"Action Type\"::Take);\n+ if WarehouseActivityLine.FindSet() then\n+ repeat\n+ WarehouseActivityLine.Validate(\"Qty. to Handle\", WarehouseActivityLine.Quantity);\n+ WarehouseActivityLine.Modify(true);\n+ until WarehouseActivityLine.Next() = 0;\n+\n+ // Post the pick (Ship)\n+ LibraryWarehouse.PostInventoryActivity(WarehouseActivityHeader, false);\n+ end;\n+\n+ local procedure CreateInventoryForLotAndExpiry579500(ItemNo: Code[20]; LocationCode: Code[10]; BinCode: Code[20])\n+ var\n+ LotNo: array[10] of Code[50];\n+ ExpiryDate: array[10] of Date;\n+ Quantity: array[10] of Decimal;\n+ i: Integer;\n+ begin\n+ LotNo[1] := 'LOT01';\n+ LotNo[2] := 'LOT03';\n+ LotNo[3] := 'LOT06';\n+ LotNo[4] := 'LOT01';\n+ LotNo[5] := 'LOT02';\n+ LotNo[6] := 'LOT03';\n+ LotNo[7] := 'LOT04';\n+ LotNo[8] := 'LOT02';\n+ LotNo[9] := 'LOT03';\n+ LotNo[10] := 'LOT05';\n+\n+ ExpiryDate[1] := 20251130D;\n+ ExpiryDate[2] := 20250925D;\n+ ExpiryDate[3] := 20250925D;\n+ ExpiryDate[4] := 20250925D;\n+ ExpiryDate[5] := 20251130D;\n+ ExpiryDate[6] := 20250925D;\n+ ExpiryDate[7] := 20250606D;\n+ ExpiryDate[8] := 20250616D;\n+ ExpiryDate[9] := 20250925D;\n+ ExpiryDate[10] := 20250713D;\n+\n+ Quantity[1] := 434.97616;\n+ Quantity[2] := 17.3126;\n+ Quantity[3] := 17.0373;\n+ Quantity[4] := 4.13394;\n+ Quantity[5] := 4.34355;\n+ Quantity[6] := 151.33333;\n+ Quantity[7] := 40.01221;\n+ Quantity[8] := 1.78787;\n+ Quantity[9] := 42.73313;\n+ Quantity[10] := 4.013;\n+\n+ for i := 1 to ArrayLen(LotNo) do\n+ UpdateItemInventoryWithLot(ItemNo, LocationCode, BinCode, Quantity[i], LotNo[i], ExpiryDate[i]);\n+ end;\n+\n+ local procedure UpdateItemInventoryWithLot(ItemNo: Code[20]; LocationCode: Code[10]; BinCode: Code[20]; Quantity: Decimal; LotNo: Code[50]; ExpiryDate: Date)\n+ var\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+ ItemJournalBatch.Validate(\"Item Tracking on Lines\", true);\n+ ItemJournalBatch.Modify(true);\n+\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", ItemNo, Quantity);\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.\"Lot No.\" := LotNo;\n+ ItemJournalLine.\"Expiration Date\" := ExpiryDate;\n+ ItemJournalLine.Modify(true);\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ReservationPageHandler(var Reservation: TestPage Reservation)\n@@ -2716,5 +2932,12 @@ codeunit 137055 \"SCM Warehouse Pick\"\n ProdOrderRouting.\"No.\".SetValue(MachineCenter.\"No.\");\n ProdOrderRouting.\"Setup Time\".SetValue(100);\n end;\n+\n+ [RequestPageHandler]\n+ procedure CreateInvtPutAwayPickRequestPageHandler(var CreateInvtPutAwayPickMvmt: TestRequestPage \"Create Invt Put-away/Pick/Mvmt\")\n+ begin\n+ CreateInvtPutAwayPickMvmt.CInvtPick.SetValue(true);\n+ CreateInvtPutAwayPickMvmt.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\nindex ee0c77f69da..dea4f3bdce6 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n@@ -420,7 +420,7 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n CreatePickOrMoveLine(\n NewWarehouseActivityLine, RemQtyToPickBase, SalesLine.\"Outstanding Qty. (Base)\", SalesLine.\"Reserved Quantity\" <> 0);\n OnCreatePickOrMoveFromSalesOnAfterCreatePickOrMoveLine(NewWarehouseActivityLine, SalesLine, CurrWarehouseActivityHeader, ShowError, AutoCreation, LineCreated);\n-\n+ CorrectQtyRounding(SalesLine, CurrWarehouseActivityHeader);\n if SalesHeader.\"Shipping Advice\" = SalesHeader.\"Shipping Advice\"::Complete then begin\n if RemQtyToPickBase < 0 then begin\n if AutoCreation then begin\n@@ -2313,6 +2313,36 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n exit(true);\n end;\n \n+ local procedure CorrectQtyRounding(SalesLine: Record \"Sales Line\"; WarehouseActivityHeader: Record \"Warehouse Activity Header\")\n+ var\n+ WareHouseActivityLine: Record \"Warehouse Activity Line\";\n+ TotalQtyPicked: Decimal;\n+ TotalQtyOutstanding: Decimal;\n+ TotalPickedQuantityCalculated: Decimal;\n+ TotalQtyOutStandingCalculated: Decimal;\n+ begin\n+ if WarehouseActivityHeader.Type <> WarehouseActivityHeader.Type::\"Invt. Pick\" then\n+ exit;\n+\n+ WareHouseActivityLine.SetSource(Database::\"Sales Line\", SalesLine.\"Document Type\".AsInteger(), SalesLine.\"Document No.\", SalesLine.\"Line No.\", 0);\n+ WareHouseActivityLine.SetRange(\"No.\", WarehouseActivityHeader.\"No.\");\n+ WareHouseActivityLine.CalcSums(Quantity, \"Qty. (Base)\", \"Qty. Outstanding\", \"Qty. Outstanding (Base)\");\n+ TotalQtyPicked := WareHouseActivityLine.Quantity;\n+ TotalQtyOutstanding := WareHouseActivityLine.\"Qty. Outstanding\";\n+ TotalPickedQuantityCalculated := Round(WareHouseActivityLine.\"Qty. (Base)\" / SalesLine.\"Qty. per Unit of Measure\", 0.00001);\n+ TotalQtyOutStandingCalculated := Round(WareHouseActivityLine.\"Qty. Outstanding (Base)\" / SalesLine.\"Qty. per Unit of Measure\", 0.00001);\n+ if TotalQtyPicked = TotalPickedQuantityCalculated then\n+ exit;\n+\n+ if Abs(TotalPickedQuantityCalculated - TotalQtyPicked) > SalesLine.\"Qty. Rounding Precision\" then\n+ exit;\n+\n+ WareHouseActivityLine.FindLast();\n+ WareHouseActivityLine.Quantity += (TotalPickedQuantityCalculated - TotalQtyPicked);\n+ WareHouseActivityLine.\"Qty. Outstanding\" += (TotalQtyOutStandingCalculated - TotalQtyOutstanding);\n+ WareHouseActivityLine.Modify();\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterAutoCreatePickOrMove(var WarehouseRequest: Record \"Warehouse Request\"; LineCreated: Boolean; var WarehouseActivityHeader: Record \"Warehouse Activity Header\"; Location: Record Location; HideDialog: Boolean)\n begin\n"} -{"metadata": {"area": "inventory", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223202", "base_commit": "071306f0d5dbae52846a3a732e27560b476295c9", "created_at": "2025-08-07", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Manufacturing"], "FAIL_TO_PASS": [{"codeunitID": 137210, "functionName": ["FirmedProdOrderStatisticsCheckOverhead"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al b/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al\nindex 57db2703546..edc1079c082 100644\n--- a/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al\n@@ -41,6 +41,7 @@ codeunit 137210 \"SCM Copy Production BOM\"\n ProdBOMNo: Code[20];\n CountError: Label 'Version Count Must Match.';\n OverHeadCostErr: Label 'Overhead Cost must be %1 in %2.', Comment = '%1= Field Value, %2= FieldCaption.';\n+ ManufacturingOverhead: Label 'Expected Overhead = %1, but Statistics shows = %2', Comment = '%1=Expected Overhead, %2=Overhead from Statistics page.';\n \n [Normal]\n local procedure Initialize()\n@@ -609,6 +610,86 @@ codeunit 137210 \"SCM Copy Production BOM\"\n ProductionOrderStatistics.MfgOverhead_ExpectedCost.Caption()));\n end;\n \n+ [Test]\n+ procedure FirmedProdOrderStatisticsCheckOverhead()\n+ var\n+ ParentItem: Record Item;\n+ RawItem: Record Item;\n+ ProductionOrder: Record \"Production Order\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ FirmedProductionOrder: TestPage \"Firm Planned Prod. Order\";\n+ ProductionOrderStatistics: TestPage \"Production Order Statistics\";\n+ MfgOverheadExpectedCost: Decimal;\n+ MfgOverheadExpectedCost1: Decimal;\n+ Quantity: Decimal;\n+ begin\n+ // [SCENARIO 593018] Manufacturing overhead is wrong in the production order statistics page (99000816) and report (99000791).\n+ Initialize();\n+\n+ // [GIVEN] Create Raw Item with specified Unit Cost\n+ CreateItem(RawItem, 0, 0);\n+ RawItem.Validate(Type, RawItem.Type::Inventory);\n+ RawItem.Validate(\"Unit Cost\", LibraryRandom.RandIntInRange(100, 100));\n+ RawItem.Modify(true);\n+\n+ // [GIVEN] Create Production BOM and add Raw Item with Qty = 1\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, RawItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, RawItem.\"No.\", 1);\n+ ProductionBOMHeader.Validate(\"Unit of Measure Code\", RawItem.\"Base Unit of Measure\");\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify(true);\n+\n+ // [GIVEN] Create Parent Item with Indirect Cost % and link to BOM\n+ CreateItem(ParentItem, 0, 0); // No direct cost or overhead\n+ ParentItem.Validate(\"Indirect Cost %\", LibraryRandom.RandIntInRange(10, 10));\n+ ParentItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ParentItem.Modify(true);\n+\n+ // [GIVEN] Create Firm Planned Production Order for Parent Item\n+ LibraryManufacturing.CreateProductionOrder(ProductionOrder, ProductionOrder.Status::\"Firm Planned\", ProductionOrder.\"Source Type\"::Item, '', 0);\n+\n+ // [GIVEN] Store Quantity in Variable.\n+ Quantity := LibraryRandom.RandIntInRange(20, 20);\n+\n+ // [GIVEN] Create line only (do NOT populate header)\n+ LibraryManufacturing.CreateProdOrderLine(ProdOrderLine, ProductionOrder.Status, ProductionOrder.\"No.\", ParentItem.\"No.\", '', '', Quantity);\n+\n+ // [WHEN] Refresh Prod Order with Lines = false (header only)\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, false, true, true, false);\n+\n+ MfgOverheadExpectedCost := (RawItem.\"Unit Cost\" * ParentItem.\"Indirect Cost %\" / 100 * Quantity);\n+\n+ // [GIVEN] Create Firm Planned Production Order for Parent Item\n+ LibraryManufacturing.CreateProductionOrder(ProductionOrder, ProductionOrder.Status::\"Firm Planned\", ProductionOrder.\"Source Type\"::Item, '', 0);\n+\n+ // [GIVEN] Create multiple lines (do NOT populate header)\n+ LibraryManufacturing.CreateProdOrderLine(ProdOrderLine, ProductionOrder.Status, ProductionOrder.\"No.\", ParentItem.\"No.\", '', '', LibraryRandom.RandIntInRange(10, 10));\n+ LibraryManufacturing.CreateProdOrderLine(ProdOrderLine, ProductionOrder.Status, ProductionOrder.\"No.\", ParentItem.\"No.\", '', '', LibraryRandom.RandIntInRange(10, 10));\n+\n+ // [WHEN] Refresh Prod Order with Lines = false (header only)\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, false, true, true, false);\n+\n+ // [WHEN] Open Firmed Prod Order Statistics page\n+ FirmedProductionOrder.OpenEdit();\n+ FirmedProductionOrder.GoToRecord(ProductionOrder);\n+ ProductionOrderStatistics.Trap();\n+ FirmedProductionOrder.Statistics.Invoke();\n+\n+ // [THEN] Get Mfg Overhead Expected Cost\n+ Evaluate(MfgOverheadExpectedCost1, ProductionOrderStatistics.MfgOverhead_ExpectedCost.Value());\n+\n+ // [ASSERT] Overhead in statistics equals expected overhead\n+ Assert.AreEqual(\n+ MfgOverheadExpectedCost,\n+ MfgOverheadExpectedCost1,\n+ StrSubstNo(ManufacturingOverhead,\n+ Format(MfgOverheadExpectedCost),\n+ Format(MfgOverheadExpectedCost1)));\n+ \n+ end;\n+\n [Normal]\n local procedure CreateProductionBOM(var ProductionBOMHeader: Record \"Production BOM Header\")\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al\nindex 84769ae059d..aad60ef36b9 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al\n@@ -305,9 +305,12 @@ codeunit 99000758 \"Mfg. Cost Calculation Mgt.\"\n ExpSubDirCost := ExpSubDirCost + Round(ExpSubDirCostRtng * ShareOfTotalCapCost);\n ExpCapOvhdCost := ExpCapOvhdCost + Round(ExpCapOvhdCostRtng * ShareOfTotalCapCost);\n ExpMfgDirCost := ExpMatCost + ExpCapDirCost + ExpSubDirCost + ExpCapOvhdCost;\n- ExpOvhdCost := ExpMfgOvhdCost + ProdOrderLine.\"Overhead Rate\" * ProdOrderLine.\"Quantity (Base)\";\n- ExpMfgOvhdCost := ExpOvhdCost +\n- Round(CostCalculationMgt.CalcOvhdCost(ExpMfgDirCost, ProdOrderLine.\"Indirect Cost %\", 0, 0));\n+ ExpOvhdCost := ExpMfgOvhdCost;\n+ if ExpMfgDirCost = 0 then\n+ ExpMfgOvhdCost := ExpOvhdCost +\n+ Round(CostCalculationMgt.CalcOvhdCost(ExpMfgDirCost, ProdOrderLine.\"Indirect Cost %\", ProdOrderLine.\"Overhead Rate\", ProdOrderLine.\"Quantity (Base)\"))\n+ else\n+ ExpMfgOvhdCost := Round(CostCalculationMgt.CalcOvhdCost(ExpMfgDirCost, ProdOrderLine.\"Indirect Cost %\", ProdOrderLine.\"Overhead Rate\", ProdOrderLine.\"Quantity (Base)\"));\n \n OnAfterCalcProdOrderLineExpCost(ProdOrderLine, ShareOfTotalCapCost, ExpMatCost, ExpCapDirCost, ExpSubDirCost, ExpCapOvhdCost, ExpMfgOvhdCost);\n #if not CLEAN26\n"} -{"metadata": {"area": "finance", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226448", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-10", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134282, "functionName": ["CheckVATEntryNonDeductibleVATPurchaseInvoicePosting"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\nindex 6d22cda27cb..2ddbcc070b0 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n@@ -285,6 +285,62 @@ codeunit 134282 \"Non-Deductible UT\"\n PurchaseLine.TestField(\"Non-Deductible VAT Amount\", 0);\n end;\n \n+ [Test]\n+ procedure CheckVATEntryNonDeductibleVATPurchaseInvoicePosting()\n+ var\n+ GenPostingSetup: Record \"General Posting Setup\";\n+ GLAccount: Record \"G/L Account\";\n+ PurchHeader: Record \"Purchase Header\";\n+ PurchLine: Record \"Purchase Line\";\n+ VATEntry: Record \"VAT Entry\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ Vendor: Record Vendor;\n+ GLAccountNo: Code[20];\n+ PostedDocumentNo: Code[20];\n+ VATRate: Decimal;\n+ begin\n+ // [SCENARIO 595966] Check VAT Entry Non-Deductible VAT on Purchase Invoice Posting with G/L Account Line.\n+ Initialize();\n+\n+ // [GIVEN] Create Vendor and set Prices Including VAT\n+ LibraryPurchase.CreateVendor(Vendor);\n+ Vendor.Validate(\"Prices Including VAT\", true);\n+ Vendor.Modify(true);\n+\n+ // [GIVEN] Enable Non-Deductible VAT in VAT Setup (with confirm handler)\n+ LibraryNonDeductibleVAT.EnableNonDeductibleVAT();\n+\n+ // [GIVEN] Create G/L Account and set posting groups/categories\n+ VATRate := 20.0;\n+ GLAccountNo := CreateGLAccountWithVATPostingSetup(VATRate);\n+ GLAccount.Get(GLAccountNo);\n+\n+ // [GIVEN] Create/Modify VAT Product Posting Group and VAT Posting Setup.\n+ LibraryERM.CreateVATPostingSetup(VATPostingSetup, Vendor.\"VAT Bus. Posting Group\", GLAccount.\"VAT Prod. Posting Group\");\n+ VATPostingSetup.Validate(\"VAT Calculation Type\", VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\");\n+ VATPostingSetup.Validate(\"Allow Non-Deductible VAT\", VATPostingSetup.\"Allow Non-Deductible VAT\"::Allow);\n+ VATPostingSetup.Validate(\"VAT %\", 20);\n+ VATPostingSetup.Validate(\"Non-Deductible VAT %\", 100);\n+ VATPostingSetup.Modify(true);\n+\n+ // [WHEN] Create and post Purchase Invoice for the vendor with G/L Account line\n+ LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader.\"Document Type\"::Invoice, Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(PurchLine, PurchHeader, PurchLine.Type::\"G/L Account\", GLAccountNo, 1);\n+ PurchLine.Validate(\"Direct Unit Cost\", 14.19);\n+ PurchLine.Modify(true);\n+ PurchHeader.Validate(\"Vendor Invoice No.\", 'Test-1001');\n+ PurchHeader.Modify(true);\n+ LibraryERM.CreateGeneralPostingSetup(GenPostingSetup, PurchLine.\"Gen. Bus. Posting Group\", PurchLine.\"Gen. Prod. Posting Group\");\n+ PostedDocumentNo := LibraryPurchase.PostPurchaseDocument(PurchHeader, false, true);\n+\n+ // [THEN] verify that Purchase Invoice is posted with 0 VAT Amount and 0 Non-Deductible VAT Amount\n+ VATEntry.SetRange(\"Document No.\", PostedDocumentNo);\n+ VATEntry.SetRange(\"Document Type\", VATEntry.\"Document Type\"::Invoice);\n+ VATEntry.FindFirst();\n+ Assert.AreEqual(0, VATEntry.Base, 'Vat Base should be 0.');\n+ Assert.AreEqual(0, VATEntry.Amount, 'Vat Amount should be 0.');\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Non-Deductible UT\");\n@@ -383,4 +439,33 @@ codeunit 134282 \"Non-Deductible UT\"\n Assert.AreEqual(ExpectedAmount, VATEntry.\"Non-Deductible VAT Base\", StrSubstNo(AmountErrorLbl, VATEntry.FieldCaption(\"Non-Deductible VAT Base\"), ExpectedAmount));\n Assert.AreEqual(ExpectedAmount, VATEntry.\"Non-Deductible VAT Amount\", StrSubstNo(AmountErrorLbl, VATEntry.FieldCaption(\"Non-Deductible VAT Amount\"), ExpectedAmount));\n end;\n+\n+ local procedure CreateGLAccountWithVATPostingSetup(var VATRate: Decimal) GLAccountNo: Code[20]\n+ var\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ begin\n+ VATRate := LibraryRandom.RandIntInRange(2, 5);\n+ LibraryERM.CreateVATPostingSetupWithAccounts(VATPostingSetup,\n+ VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\", VATRate);\n+ GLAccountNo := VATPostingSetup.\"Purchase VAT Account\";\n+ UpdateGLAccountPostingGroups(GLAccountNo,\n+ VATPostingSetup.\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ end;\n+\n+ local procedure UpdateGLAccountPostingGroups(GLAccountNo: Code[20]; VATProdPostingGroup: Code[20]; VATBusPostingGroup: Code[20])\n+ var\n+ GLAccount: Record \"G/L Account\";\n+ GenProductPostingGroup: Record \"Gen. Product Posting Group\";\n+ begin\n+ GLAccount.Get(GLAccountNo);\n+ LibraryERM.CreateGenProdPostingGroup(GenProductPostingGroup);\n+ GLAccount.\"Gen. Posting Type\" := GLAccount.\"Gen. Posting Type\"::Purchase;\n+ GLAccount.Validate(\"Account Category\", GLAccount.\"Account Category\"::Expense);\n+ GLAccount.Validate(\"Account Type\", GLAccount.\"Account Type\"::Posting);\n+ GLAccount.Validate(\"Direct Posting\", true);\n+ GLAccount.\"Gen. Prod. Posting Group\" := GenProductPostingGroup.Code;\n+ GLAccount.\"VAT Prod. Posting Group\" := VATProdPostingGroup;\n+ GLAccount.\"VAT Bus. Posting Group\" := VATBusPostingGroup;\n+ GLAccount.Modify(true);\n+ end;\n }\n\\ No newline at end of file\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex c9d976f7272..a9f725ac966 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -16,6 +16,7 @@ using Microsoft.FixedAssets.Ledger;\n using Microsoft.Foundation.Enums;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.History;\n+using Microsoft.Purchases.Vendor;\n using Microsoft.Foundation.Company;\n using Microsoft.Projects.Project.Journal;\n using Microsoft.Projects.Project.Job;\n@@ -951,6 +952,8 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n GeneralLedgerSetup.GetRecordOnce();\n UpdateNonDeductibleAmounts(GenJournalLine.\"Non-Deductible VAT Base ACY\", GenJournalLine.\"Non-Deductible VAT Amount ACY\", BaseAmountACY, VATAmountACY, GetNonDedVATPctFromGenJournalLine(GenJournalLine), GeneralLedgerSetup.\"Amount Rounding Precision\");\n AdjustVATAmounts(VATAmountACY, BaseAmountACY, GenJournalLine.\"Non-Deductible VAT Amount ACY\", GenJournalLine.\"Non-Deductible VAT Base ACY\");\n+ if IsNormalVATInvoiceForVendor(GenJournalLine) then\n+ UpdateNonDeductibleAmounts(GenJournalLine.\"Non-Deductible VAT Base LCY\", GenJournalLine.\"Non-Deductible VAT Amount LCY\", BaseAmount, VATAmount, GetNonDedVATPctFromGenJournalLine(GenJournalLine), GeneralLedgerSetup.\"Amount Rounding Precision\");\n AdjustVATAmounts(VATAmount, BaseAmount, GenJournalLine.\"Non-Deductible VAT Amount LCY\", GenJournalLine.\"Non-Deductible VAT Base LCY\");\n end;\n \n@@ -1152,6 +1155,17 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n exit(DocAmountRoundingPrecision);\n end;\n \n+ local procedure IsNormalVATInvoiceForVendor(GenJournalLine: Record \"Gen. Journal Line\"): Boolean\n+ var\n+ Vendor: Record Vendor;\n+ begin\n+ if (GenJournalLine.\"Document Type\" = GenJournalLine.\"Document Type\"::Invoice) and\n+ (GenJournalLine.\"VAT Calculation Type\" = GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\") and\n+ (Vendor.Get(GenJournalLine.\"Bill-to/Pay-to No.\") and (Vendor.\"Prices Including VAT\")) then\n+ exit(true);\n+ exit(false);\n+ end;\n+\n [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Company-Initialize\", 'OnCompanyInitialize', '', false, false)]\n local procedure CreateVATSetupOnCompanyInitialize()\n var\n"} -{"metadata": {"area": "finance", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227153", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-16", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Report"], "FAIL_TO_PASS": [{"codeunitID": 134982, "functionName": ["ReconcileCustVendAccounts_MultiplePostingGroups"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al b/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al\nindex 073ba04a94f..03f6e89bb23 100644\n--- a/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al\n+++ b/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al\n@@ -1498,6 +1498,93 @@ codeunit 134982 \"ERM Financial Reports\"\n Assert.AreNotEqual(0, GLEntry.\"Source Currency Amount\", SourceCurrencyCodeErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('RHReconcileCustandVendAccs')]\n+ procedure ReconcileCustVendAccounts_MultiplePostingGroups()\n+ var\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ CustomerPostingGroup: array[2] of Record \"Customer Posting Group\";\n+ Customer: Record Customer;\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ GLAccount: array[3] of Record \"G/L Account\";\n+ ReconcileCustAndVendAccs: Report \"Reconcile Cust. and Vend. Accs\";\n+ Amount1, Amount2 : Decimal;\n+ WorkdateTxt: Text[30];\n+ begin\n+ // [SCENARIO 601857] Report Reconcile Customer and Vendor Accounts shows wrong amounts when multiple posting groups are used\n+ Initialize();\n+\n+ // [GIVEN] Enable Allow Multiple Posting Groups\n+ SalesReceivablesSetup.Get();\n+ SalesReceivablesSetup.Validate(\"Allow Multiple Posting Groups\", true);\n+ SalesReceivablesSetup.Modify(true);\n+\n+ // [GIVEN] Create two Customer Posting Groups with different Receivables Accounts\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup[1]);\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup[2]);\n+ LibrarySales.CreateAltCustomerPostingGroup(CustomerPostingGroup[1].Code, CustomerPostingGroup[2].Code);\n+\n+ // [GIVEN] Create a customer with one of the posting groups and enable multiple posting groups\n+ LibrarySales.CreateCustomer(Customer);\n+ Customer.Validate(\"Customer Posting Group\", CustomerPostingGroup[1].Code);\n+ Customer.Validate(\"Allow Multiple Posting Groups\", true);\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Create General Journal Batch\n+ LibraryJournals.CreateGenJournalBatch(GenJournalBatch);\n+\n+ // [GIVEN] Post payment 1 with first posting group\n+ Amount1 := -1 * LibraryRandom.RandDec(1000, 2);\n+ LibraryERM.CreateGLAccount(GLAccount[1]);\n+ LibraryJournals.CreateGenJournalLine(\n+ GenJournalLine,\n+ GenJournalBatch.\"Journal Template Name\",\n+ GenJournalBatch.Name,\n+ GenJournalLine.\"Document Type\"::Payment,\n+ GenJournalLine.\"Account Type\"::Customer,\n+ Customer.\"No.\",\n+ GenJournalLine.\"Bal. Account Type\"::\"G/L Account\",\n+ GLAccount[1].\"No.\",\n+ Amount1);\n+ GenJournalLine.Validate(\"Posting Group\", CustomerPostingGroup[1].Code);\n+ GenJournalLine.Modify(true);\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+\n+ // [GIVEN] Post payment 2 with second posting group\n+ Amount2 := -1 * LibraryRandom.RandDec(2000, 2);\n+ LibraryERM.CreateGLAccount(GLAccount[2]);\n+ LibraryJournals.CreateGenJournalLine(\n+ GenJournalLine,\n+ GenJournalBatch.\"Journal Template Name\",\n+ GenJournalBatch.Name,\n+ GenJournalLine.\"Document Type\"::Payment,\n+ GenJournalLine.\"Account Type\"::Customer,\n+ Customer.\"No.\",\n+ GenJournalLine.\"Bal. Account Type\"::\"G/L Account\",\n+ GLAccount[2].\"No.\",\n+ Amount2);\n+ GenJournalLine.Validate(\"Posting Group\", CustomerPostingGroup[2].Code);\n+ GenJournalLine.Modify(true);\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+\n+ // [WHEN] Run the Reconcile Cust. And Vend. Accounts report with DateFilter as Workdate\n+ WorkdateTxt := Format(WorkDate());\n+ Clear(ReconcileCustAndVendAccs);\n+ GLAccount[3].SetRange(\"Date Filter\", WorkDate());\n+ GLAccount[3].FindFirst();\n+ ReconcileCustAndVendAccs.SetTableView(GLAccount[3]);\n+ Commit();\n+ ReconcileCustAndVendAccs.Run();\n+\n+ // [THEN] Verify: Amounts are distributed to correct G/L accounts\n+ LibraryReportDataset.LoadDataSetFile();\n+ LibraryReportDataset.AssertElementWithValueExists('No_GLAccount', CustomerPostingGroup[1].\"Receivables Account\");\n+ LibraryReportDataset.AssertElementWithValueExists('No_GLAccount', CustomerPostingGroup[2].\"Receivables Account\");\n+ LibraryReportDataset.AssertElementWithValueExists('Amount', Amount1);\n+ LibraryReportDataset.AssertElementWithValueExists('Amount', Amount2);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al\nindex e033f91eb0b..2153bcde821 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al\n@@ -472,130 +472,88 @@ report 33 \"Reconcile Cust. and Vend. Accs\"\n \n local procedure CalcCustAccAmount(PostingGr: Code[20]): Decimal\n var\n- Cust: Record Customer;\n DtldCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n CustAccAmount: Decimal;\n begin\n- Cust.SetCurrentKey(\"Customer Posting Group\");\n- Cust.SetRange(\"Customer Posting Group\", PostingGr);\n-\n- if Cust.Find('-') then\n- repeat\n- DtldCustLedgEntry.SetCurrentKey(\"Customer No.\", \"Posting Date\");\n- DtldCustLedgEntry.SetRange(\"Customer No.\", Cust.\"No.\");\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n- DtldCustLedgEntry.CalcSums(\"Amount (LCY)\");\n- CustAccAmount := CustAccAmount + DtldCustLedgEntry.\"Amount (LCY)\";\n- until Cust.Next() = 0;\n+ DtldCustLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\");\n+ DtldCustLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n+ DtldCustLedgEntry.CalcSums(\"Amount (LCY)\");\n+ CustAccAmount := CustAccAmount + DtldCustLedgEntry.\"Amount (LCY)\";\n \n exit(CustAccAmount);\n end;\n \n local procedure CalcCustCreditAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Cust: Record Customer;\n DtldCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n CustCreditAmount: Decimal;\n begin\n- Cust.SetCurrentKey(\"Customer Posting Group\");\n- Cust.SetRange(\"Customer Posting Group\", PostingGr);\n-\n- if Cust.Find('-') then\n- repeat\n- DtldCustLedgEntry.SetCurrentKey(\"Customer No.\", \"Posting Date\", \"Entry Type\");\n- DtldCustLedgEntry.SetRange(\"Customer No.\", Cust.\"No.\");\n- DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n- DtldCustLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n- CustCreditAmount := CustCreditAmount + DtldCustLedgEntry.\"Credit Amount (LCY)\";\n- until Cust.Next() = 0;\n+ DtldCustLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldCustLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n+ DtldCustLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n+ CustCreditAmount := CustCreditAmount + DtldCustLedgEntry.\"Credit Amount (LCY)\";\n \n exit(CustCreditAmount);\n end;\n \n local procedure CalcCustDebitAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Cust: Record Customer;\n DtldCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n CustDebitAmount: Decimal;\n begin\n- Cust.SetCurrentKey(\"Customer Posting Group\");\n- Cust.SetRange(\"Customer Posting Group\", PostingGr);\n-\n- if Cust.Find('-') then\n- repeat\n- DtldCustLedgEntry.SetCurrentKey(\"Customer No.\", \"Posting Date\", \"Entry Type\");\n- DtldCustLedgEntry.SetRange(\"Customer No.\", Cust.\"No.\");\n- DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n- DtldCustLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n- CustDebitAmount := CustDebitAmount + DtldCustLedgEntry.\"Debit Amount (LCY)\";\n- until Cust.Next() = 0;\n+ DtldCustLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldCustLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n+ DtldCustLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n+ CustDebitAmount := CustDebitAmount + DtldCustLedgEntry.\"Debit Amount (LCY)\";\n \n exit(-CustDebitAmount);\n end;\n \n local procedure CalcVendAccAmount(PostingGr: Code[20]): Decimal\n var\n- Vend: Record Vendor;\n DtldVendLedgEntry: Record \"Detailed Vendor Ledg. Entry\";\n VendAccAmount: Decimal;\n begin\n- Vend.SetCurrentKey(\"Vendor Posting Group\");\n- Vend.SetRange(\"Vendor Posting Group\", PostingGr);\n-\n- if Vend.Find('-') then\n- repeat\n- DtldVendLedgEntry.SetCurrentKey(\"Vendor No.\", \"Posting Date\");\n- DtldVendLedgEntry.SetRange(\"Vendor No.\", Vend.\"No.\");\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n- DtldVendLedgEntry.CalcSums(\"Amount (LCY)\");\n- VendAccAmount := VendAccAmount + DtldVendLedgEntry.\"Amount (LCY)\";\n- until Vend.Next() = 0;\n+ DtldVendLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\");\n+ DtldVendLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n+ DtldVendLedgEntry.CalcSums(\"Amount (LCY)\");\n+ VendAccAmount := VendAccAmount + DtldVendLedgEntry.\"Amount (LCY)\";\n \n exit(VendAccAmount);\n end;\n \n local procedure CalcVendCreditAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Vend: Record Vendor;\n DtldVendLedgEntry: Record \"Detailed Vendor Ledg. Entry\";\n VendCreditAmount: Decimal;\n begin\n- Vend.SetCurrentKey(\"Vendor Posting Group\");\n- Vend.SetRange(\"Vendor Posting Group\", PostingGr);\n-\n- if Vend.Find('-') then\n- repeat\n- DtldVendLedgEntry.SetCurrentKey(\"Vendor No.\", \"Posting Date\", \"Entry Type\");\n- DtldVendLedgEntry.SetRange(\"Vendor No.\", Vend.\"No.\");\n- DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n- DtldVendLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n- VendCreditAmount := VendCreditAmount + DtldVendLedgEntry.\"Credit Amount (LCY)\";\n- until Vend.Next() = 0;\n+ DtldVendLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldVendLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n+ DtldVendLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n+ VendCreditAmount := VendCreditAmount + DtldVendLedgEntry.\"Credit Amount (LCY)\";\n \n exit(VendCreditAmount);\n end;\n \n local procedure CalcVendDebitAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Vend: Record Vendor;\n DtldVendLedgEntry: Record \"Detailed Vendor Ledg. Entry\";\n VendDebitAmount: Decimal;\n begin\n- Vend.SetCurrentKey(\"Vendor Posting Group\");\n- Vend.SetRange(\"Vendor Posting Group\", PostingGr);\n-\n- if Vend.Find('-') then\n- repeat\n- DtldVendLedgEntry.SetCurrentKey(\"Vendor No.\", \"Posting Date\", \"Entry Type\");\n- DtldVendLedgEntry.SetRange(\"Vendor No.\", Vend.\"No.\");\n- DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n- DtldVendLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n- VendDebitAmount := VendDebitAmount + DtldVendLedgEntry.\"Debit Amount (LCY)\";\n- until Vend.Next() = 0;\n+ DtldVendLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldVendLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n+ DtldVendLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n+ VendDebitAmount := VendDebitAmount + DtldVendLedgEntry.\"Debit Amount (LCY)\";\n \n exit(-VendDebitAmount);\n end;\n"} -{"metadata": {"area": "sales", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227240", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134905, "functionName": ["VerifyDueDateAfterUpdateDueDateInCustLedgerEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\nindex 71c12b1ce1a..6d8f4aaca9e 100644\n--- a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n@@ -636,6 +636,68 @@ codeunit 134905 \"ERM Issued Reminder Addnl Fee\"\n ReminderPage.ContactEmail.AssertEquals(EMail);\n end;\n \n+ [Test]\n+ procedure VerifyDueDateAfterUpdateDueDateInCustLedgerEntry()\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ Customer: Record Customer;\n+ CustomerPostingGroup: Record \"Customer Posting Group\";\n+ GLAccount: Record \"G/L Account\";\n+ ReminderFinChargeEntry: Record \"Reminder/Fin. Charge Entry\";\n+ ReminderLevel: Record \"Reminder Level\";\n+ VATProductPostingGroup: Record \"VAT Product Posting Group\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ DueDate: Date;\n+ DocumentDate: Date;\n+ IssuedReminderNo: Code[20];\n+ begin\n+ // [SCENARIO 598460] The Due date in created Reminder is updated incorrectly when changing the Due date in the Customer Ledger Entry.\n+ Initialize();\n+\n+ // [GIVEN] Create Customer and VAT Posting Setup. \n+ CreateCustomer(Customer, '');\n+ CustomerPostingGroup.Get(Customer.\"Customer Posting Group\");\n+ GLAccount.Get(CustomerPostingGroup.\"Additional Fee Account\");\n+ LibraryERM.CreateVATProductPostingGroup(VATProductPostingGroup);\n+ GLAccount.Validate(\"VAT Prod. Posting Group\", VATProductPostingGroup.Code);\n+ GLAccount.Modify(true);\n+\n+ LibraryERM.CreateVATPostingSetup(VATPostingSetup, Customer.\"VAT Bus. Posting Group\", VATProductPostingGroup.Code);\n+\n+ //[GIVEN] Create and post Sales Invoice.\n+ DueDate := CreateAndPostSalesInvoice(Customer.\"No.\", '');\n+ GetReminderLevel(ReminderLevel, Customer.\"Reminder Terms Code\");\n+ DocumentDate := CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', CalcDate(ReminderLevel.\"Grace Period\", DueDate));\n+\n+ // [GIVEN] Create and Issue Reminder.\n+ CreateReminder(Customer.\"No.\", DocumentDate, false);\n+ IssuedReminderNo := IssueReminder(DocumentDate);\n+\n+ // [WHEN] Update Due Date in forward direction for Customer Ledger Entry.\n+ DueDate := DocumentDate + LibraryRandom.RandIntInRange(16, 17);\n+ CustLedgerEntry.SetRange(\"Customer No.\", Customer.\"No.\");\n+ CustLedgerEntry.FindLast();\n+ CustLedgerEntry.Validate(\"Due Date\", DueDate);\n+ CustLedgerEntry.Modify(true);\n+\n+ // [VERIFY] Verify Due Date in Reminder/Fin. Charge Entry should be equal to Cust. Ledger Entry - Due Date.\n+ ReminderFinChargeEntry.SetRange(Type, ReminderFinChargeEntry.Type::Reminder);\n+ ReminderFinChargeEntry.SetRange(\"No.\", IssuedReminderNo);\n+ ReminderFinChargeEntry.FindFirst();\n+ Assert.AreEqual(ReminderFinChargeEntry.\"Due Date\", CustLedgerEntry.\"Due Date\", ReminderDueDateErr);\n+\n+ // [WHEN] Update Due Date in backward direction for Customer Ledger Entry.\n+ DueDate := DocumentDate - LibraryRandom.RandIntInRange(16, 17);\n+ CustLedgerEntry.Validate(\"Due Date\", DueDate);\n+ CustLedgerEntry.Modify(true);\n+\n+ // [VERIFY] Verify Due Date in Reminder/Fin. Charge Entry should be equal to Cust. Ledger Entry - Due Date.\n+ ReminderFinChargeEntry.SetRange(Type, ReminderFinChargeEntry.Type::Reminder);\n+ ReminderFinChargeEntry.SetRange(\"No.\", IssuedReminderNo);\n+ ReminderFinChargeEntry.FindFirst();\n+ Assert.AreEqual(ReminderFinChargeEntry.\"Due Date\", CustLedgerEntry.\"Due Date\", ReminderDueDateErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\nindex 9ff59101df2..ff238e73dcf 100644\n--- a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n@@ -409,9 +409,6 @@ codeunit 393 \"Reminder-Issue\"\n if IsHandled then\n exit;\n \n- if NewDueDate < ReminderEntry2.\"Due Date\" then\n- exit;\n-\n ReminderEntry2.Validate(\"Due Date\", NewDueDate);\n ReminderEntry2.Modify();\n end;\n"} {"metadata": {"area": "shopify", "image_count": 8}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-5633", "base_commit": "260795201c277427aa3bb70bc24672bb8d60c87b", "created_at": "2025-11-26T21:22:42Z", "environment_setup_version": "27.2", "project_paths": ["src\\Apps\\W1\\Shopify\\App", "src\\Apps\\W1\\Shopify\\Test"], "FAIL_TO_PASS": [{"codeunitID": 139606, "functionName": ["UnitTestExportShipmentThirdParty"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al\nindex 87c4a69e3a..2aa63a294f 100644\n--- a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al\n+++ b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al\n@@ -154,6 +154,36 @@ codeunit 139606 \"Shpfy Shipping Test\"\n LibraryAssert.IsTrue(FulfillmentRequest.Contains(StrSubstNo(QuantityLbl, SalesShipmentLine.Quantity)), 'quantity check');\n end;\n \n+ [Test]\n+ procedure UnitTestExportShipmentThirdParty()\n+ var\n+ SalesShipmentHeader: Record \"Sales Shipment Header\";\n+ FulfillmentOrderHeader: Record \"Shpfy FulFillment Order Header\";\n+ ExportShipments: Codeunit \"Shpfy Export Shipments\";\n+ ShippingHelper: Codeunit \"Shpfy Shipping Helper\";\n+ DeliveryMethodType: Enum \"Shpfy Delivery Method Type\";\n+ FulfillmentRequests: List of [Text];\n+ AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]];\n+ ShopifyOrderId: BigInteger;\n+ LocationId: BigInteger;\n+ begin\n+ // [SCENARIO] Export a Sales Shipment record into a Json token that contains the shipping info for a third-party fulfillment service\n+ // [GIVEN] A random Sales Shipment, a random LocationId for a third-party fulfillment location, a random Shop\n+ Initialize();\n+ LocationId := Any.IntegerInRange(10000, 99999);\n+ CreateThirdPartyFulfillmentLocation(Shop, LocationId);\n+ DeliveryMethodType := DeliveryMethodType::Shipping;\n+ ShopifyOrderId := ShippingHelper.CreateRandomShopifyOrder(LocationId, DeliveryMethodType);\n+ FulfillmentOrderHeader := ShippingHelper.CreateShopifyFulfillmentOrder(ShopifyOrderId, DeliveryMethodType);\n+ ShippingHelper.CreateRandomSalesShipment(SalesShipmentHeader, ShopifyOrderId);\n+\n+ // [WHEN] Invoke the function CreateFulfillmentOrderRequest()\n+ FulfillmentRequests := ExportShipments.CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType, AssignedFulfillmentOrderIds);\n+\n+ // [THEN] We must find no fulfilment data in the json token as the location is for a third-party fulfillment service\n+ LibraryAssert.AreEqual(0, FulfillmentRequests.Count, 'FulfillmentRequest count check');\n+ end;\n+\n local procedure Initialize()\n var\n CommunicationMgt: Codeunit \"Shpfy Communication Mgt.\";\n@@ -188,6 +218,17 @@ codeunit 139606 \"Shpfy Shipping Test\"\n LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::\"Shpfy Shipping Test\");\n end;\n \n+ local procedure CreateThirdPartyFulfillmentLocation(ShopifyShop: Record \"Shpfy Shop\"; LocationId: BigInteger)\n+ var\n+ ShopLocation: Record \"Shpfy Shop Location\";\n+ begin\n+ ShopLocation.\"Shop Code\" := ShopifyShop.Code;\n+ ShopLocation.Id := LocationId;\n+ ShopLocation.Name := 'Third-Party Fulfillment Service';\n+ ShopLocation.\"Is Fulfillment Service\" := true;\n+ ShopLocation.Insert();\n+ end;\n+\n [HttpClientHandler]\n internal procedure HttpSubmitHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean\n begin\n", "patch": "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\nindex 1f790f98d1..6160dcd402 100644\n--- a/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al\n+++ b/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al\n@@ -90,11 +90,13 @@ codeunit 30190 \"Shpfy Export Shipments\"\n TrackingCompany: Enum \"Shpfy Tracking Companies\";\n PrevFulfillmentOrderId: BigInteger;\n IsHandled: Boolean;\n+ EmptyFulfillment: Boolean;\n TrackingUrl: Text;\n GraphQueryStart: Text;\n GraphQuery: TextBuilder;\n LineCount: Integer;\n GraphQueries: List of [Text];\n+ UnfulfillableOrders: List of [BigInteger];\n begin\n Clear(PrevFulfillmentOrderId);\n \n@@ -165,11 +167,17 @@ codeunit 30190 \"Shpfy Export Shipments\"\n end;\n GraphQuery.Append('lineItemsByFulfillmentOrder: [');\n GraphQueryStart := GraphQuery.ToText();\n+ EmptyFulfillment := true;\n repeat\n // Skip fulfillment orders that are assigned and not accepted\n if AssignedFulfillmentOrderIds.ContainsKey(TempFulfillmentOrderLine.\"Shopify Fulfillment Order Id\") then\n continue;\n \n+ if not CanFulfillOrder(TempFulfillmentOrderLine, Shop, UnfulfillableOrders) then\n+ continue;\n+\n+ EmptyFulfillment := false;\n+\n if PrevFulfillmentOrderId <> TempFulfillmentOrderLine.\"Shopify Fulfillment Order Id\" then begin\n if PrevFulfillmentOrderId <> 0 then\n GraphQuery.Append(']},');\n@@ -202,7 +210,8 @@ codeunit 30190 \"Shpfy Export Shipments\"\n until TempFulfillmentOrderLine.Next() = 0;\n GraphQuery.Append(']}]})');\n GraphQuery.Append('{fulfillment { legacyResourceId name createdAt updatedAt deliveredAt displayStatus estimatedDeliveryAt status totalQuantity location { legacyResourceId } trackingInfo { number url company } service { serviceName type } fulfillmentLineItems(first: 10) { pageInfo { endCursor hasNextPage } nodes { id quantity originalTotalSet { presentmentMoney { amount } shopMoney { amount }} lineItem { id isGiftCard }}}}, userErrors {field,message}}}\"}');\n- GraphQueries.Add(GraphQuery.ToText());\n+ if not EmptyFulfillment then\n+ GraphQueries.Add(GraphQuery.ToText());\n end;\n exit(GraphQueries);\n end;\n@@ -225,6 +234,27 @@ codeunit 30190 \"Shpfy Export Shipments\"\n end;\n end;\n \n+ local procedure CanFulfillOrder(FulfillmentOrderLine: Record \"Shpfy FulFillment Order Line\"; Shop: Record \"Shpfy Shop\"; var UnfulfillableOrders: List of [BigInteger]): Boolean\n+ var\n+ ShopLocation: Record \"Shpfy Shop Location\";\n+ SyncLocations: Codeunit \"Shpfy Sync Shop Locations\";\n+ begin\n+ if UnfulfillableOrders.Contains(FulfillmentOrderLine.\"Shopify Fulfillment Order Id\") then\n+ exit(false);\n+\n+ if not ShopLocation.Get(Shop.Code, FulfillmentOrderLine.\"Shopify Location Id\") then\n+ exit(true);\n+\n+ if not ShopLocation.\"Is Fulfillment Service\" then\n+ exit(true);\n+\n+ if ShopLocation.Name = SyncLocations.GetFulfillmentServiceName() then\n+ exit(true);\n+\n+ UnfulfillableOrders.Add(FulfillmentOrderLine.\"Shopify Fulfillment Order Id\");\n+ exit(false);\n+ end;\n+\n local procedure GetNotifyCustomer(Shop: Record \"Shpfy Shop\"; SalesShipmmentHeader: Record \"Sales Shipment Header\"; LocationId: BigInteger): Boolean\n var\n IsHandled: Boolean;\n"} {"metadata": {"area": "shopify", "image_count": 3}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-4822", "base_commit": "f0b7291eb64a17df19a536e44be37380b2e4203d", "created_at": "2025-09-19T13:01:33Z", "environment_setup_version": "27.0", "project_paths": ["src\\Apps\\W1\\Shopify\\App", "src\\Apps\\W1\\Shopify\\Test"], "FAIL_TO_PASS": [{"codeunitID": 139539, "functionName": ["TestCreateCompanyLocationSellToBillTo"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al\nindex be8c01cb17..d27dba8d65 100644\n--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al\n+++ b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al\n@@ -23,6 +23,7 @@ codeunit 139539 \"Shpfy Company Locations Test\"\n Customer: Record Customer;\n InitializeTest: Codeunit \"Shpfy Initialize Test\";\n OutboundHttpRequests: Codeunit \"Library - Variable Storage\";\n+ Assert: Codeunit \"Library Assert\";\n IsInitialized: Boolean;\n ResponseResourceUrl: Text;\n UnexpectedAPICallsErr: Label 'More than expected API calls to Shopify detected.';\n@@ -57,6 +58,37 @@ codeunit 139539 \"Shpfy Company Locations Test\"\n ShopifyCompanies.OpenEdit();\n ShopifyCompanies.GoToRecord(ShopifyCompany);\n ShopifyCompanies.Locations.GoToRecord(CompanyLocation);\n+\n+ // Cleanup\n+ CompanyLocation.Delete();\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('HttpSubmitHandler')]\n+ procedure TestCreateCompanyLocationSellToBillTo()\n+ var\n+ ShopifyCustomer: Record \"Shpfy Customer\";\n+ CompanyAPI: Codeunit \"Shpfy Company API\";\n+ begin\n+ // [GIVEN] A valid customer and company location setup\n+ RegExpectedOutboundHttpRequests();\n+ Initialize();\n+ ShopifyCompany.GetBySystemId(CompanyLocation.\"Company SystemId\");\n+ Customer.\"Bill-to Customer No.\" := 'BILLTO';\n+ Customer.Modify(true);\n+\n+ // [WHEN] CreateCompanyLocation is called\n+ CompanyAPI.SetCompany(ShopifyCompany);\n+ CompanyAPI.SetShop(Shop);\n+ CompanyAPI.CreateCustomerAsCompanyLocation(Customer, ShopifyCompany, ShopifyCustomer);\n+\n+ // [THEN] Company location should be created successfully\n+#pragma warning disable AA0210\n+ CompanyLocation.SetRange(\"Customer Id\", Customer.SystemId);\n+#pragma warning restore AA0210\n+ CompanyLocation.FindFirst();\n+ Assert.AreEqual(Customer.\"No.\", CompanyLocation.\"Sell-to Customer No.\", 'Sell-to Customer No. mismatch');\n+ Assert.AreEqual(Customer.\"Bill-to Customer No.\", CompanyLocation.\"Bill-to Customer No.\", 'Bill-to Customer No. mismatch');\n end;\n \n [Test]\n", "patch": "diff --git a/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al b/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al\nindex 2d2014446c..d09ff272d8 100644\n--- a/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al\n+++ b/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al\n@@ -523,7 +523,7 @@ codeunit 30286 \"Shpfy Company API\"\n JResponse := CommunicationMgt.ExecuteGraphQL(GraphQuery.ToText());\n if JResponse.SelectToken('$.data.companyLocationCreate.companyLocation', JCompanyLocation) then\n if not JsonHelper.IsTokenNull(JCompanyLocation) then begin\n- LocationId := CreateCustomerLocation(JCompanyLocation.AsObject(), ShopifyCompany, Customer.SystemId);\n+ LocationId := CreateCustomerLocation(JCompanyLocation.AsObject(), ShopifyCompany, Customer);\n if JsonHelper.GetJsonArray(JCompanyLocation, JContactRoles, 'company.contactRoles.edges') then begin\n foreach JItem in JContactRoles do\n CompanyContactRoles.Add(JsonHelper.GetValueAsText(JItem, 'node.name'), CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JItem, 'node.id')));\n@@ -540,7 +540,7 @@ codeunit 30286 \"Shpfy Company API\"\n /// \n /// JSON object containing the company location data from Shopify API response.\n /// The parent Shopify company record.\n- /// The GUID of the Business Central customer that was exported.\n+ /// The Business Central customer record used to populate additional fields.\n /// \n /// This procedure:\n /// - Extracts the Shopify-generated ID and creates the initial record\n@@ -552,7 +552,7 @@ codeunit 30286 \"Shpfy Company API\"\n /// The procedure assumes the JSON structure matches Shopify's companyLocationCreate response format.\n /// All text fields are properly truncated to match the field lengths in the table definition.\n /// \n- local procedure CreateCustomerLocation(JCompanyLocation: JsonObject; ShopifyCompany: Record \"Shpfy Company\"; CustomerId: Guid): BigInteger\n+ local procedure CreateCustomerLocation(JCompanyLocation: JsonObject; ShopifyCompany: Record \"Shpfy Company\"; Customer: Record Customer): BigInteger\n var\n CompanyLocation: Record \"Shpfy Company Location\";\n CompanyLocationId: BigInteger;\n@@ -580,7 +580,10 @@ codeunit 30286 \"Shpfy Company API\"\n #pragma warning restore AA0139\n CompanyLocation.Recipient := CopyStr(JsonHelper.GetValueAsText(JCompanyLocation, 'billingAddress.recipient', MaxStrLen(CompanyLocation.Recipient)), 1, MaxStrLen(CompanyLocation.Recipient));\n CompanyLocation.\"Shpfy Payment Terms Id\" := CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JCompanyLocation, 'buyerExperienceConfiguration.paymentTermsTemplate.id'));\n- CompanyLocation.\"Customer Id\" := CustomerId;\n+ CompanyLocation.\"Customer Id\" := Customer.SystemId;\n+ CompanyLocation.\"Sell-to Customer No.\" := Customer.\"No.\";\n+ if Customer.\"Bill-to Customer No.\" <> '' then\n+ CompanyLocation.\"Bill-to Customer No.\" := Customer.\"Bill-to Customer No.\";\n CompanyLocation.Modify(true);\n exit(CompanyLocationId);\n end;\n"} {"metadata": {"area": "shopify", "image_count": 5}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-4699", "base_commit": "effc43e8f96bc2b06545bcf81b9579bd08542747", "created_at": "2025-09-05T11:48:36Z", "environment_setup_version": "27.0", "project_paths": ["src\\Apps\\W1\\Shopify\\App", "src\\Apps\\W1\\Shopify\\Test"], "FAIL_TO_PASS": [{"codeunitID": 139567, "functionName": ["UnitTestCreateItemFCYToLCYConversion"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al\nindex a352529aba..f626c18258 100644\n--- a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al\n+++ b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al\n@@ -22,6 +22,7 @@ codeunit 139567 \"Shpfy Create Item Test\"\n \n var\n LibraryAssert: Codeunit \"Library Assert\";\n+ LibraryERM: Codeunit \"Library - ERM\";\n LibraryRandom: Codeunit \"Library - Random\";\n \n [Test]\n@@ -487,4 +488,42 @@ codeunit 139567 \"Shpfy Create Item Test\"\n LibraryAssert.RecordIsNotEmpty(ItemReference);\n until ShopifyVariant.Next() = 0;\n end;\n+\n+ [Test]\n+ procedure UnitTestCreateItemFCYToLCYConversion()\n+ var\n+ Item: Record Item;\n+ Shop: Record \"Shpfy Shop\";\n+ ShopifyVariant: Record \"Shpfy Variant\";\n+ ProductInitTest: Codeunit \"Shpfy Product Init Test\";\n+ InitializeTest: Codeunit \"Shpfy Initialize Test\";\n+ begin\n+ // [SCENARIO] Create a Item from a Shopify Product with the SKU value containing the Item No.\n+\n+ // [GIVEN] The Shop with the setting \"SKU Mapping\" = \"Item No.\";\n+ Shop := InitializeTest.CreateShop();\n+ Shop.\"SKU Mapping\" := \"Shpfy SKU Mapping\"::\"Item No.\";\n+ Shop.\"Currency Code\" := CreateCurrencyAndExchangeRate(2, 2);\n+ Shop.Modify();\n+\n+ // [GIVEN] A Shopify variant record of a standard shopify product. (The variant record always exists, even if the products don't have any variants.)\n+ ShopifyVariant := ProductInitTest.CreateStandardProduct(Shop);\n+ ShopifyVariant.Price := 10;\n+ ShopifyVariant.\"Unit Cost\" := 6;\n+ ShopifyVariant.Modify();\n+ ShopifyVariant.SetRecFilter();\n+\n+ // [WHEN] Executing the report \"Shpfy Create Item\" with the \"Shpfy Variant\" Record.\n+ Codeunit.Run(Codeunit::\"Shpfy Create Item\", ShopifyVariant);\n+\n+ // [THEN] Check Item fields\n+ LibraryAssert.IsTrue(Item.GetBySystemId(ShopifyVariant.\"Item SystemId\"), 'Get Item');\n+ LibraryAssert.AreNearlyEqual(ShopifyVariant.\"Unit Cost\" / 2, Item.\"Unit Cost\", 0.1, 'Unit Cost');\n+ LibraryAssert.AreNearlyEqual(ShopifyVariant.Price / 2, Item.\"Unit Price\", 0.1, 'Unit Price');\n+ end;\n+\n+ local procedure CreateCurrencyAndExchangeRate(ExchangeRateAmount: Decimal; AdjustmentExchangeRateAmount: Decimal): Code[10]\n+ begin\n+ exit(LibraryERM.CreateCurrencyWithExchangeRate(WorkDate() - 1, ExchangeRateAmount, AdjustmentExchangeRateAmount));\n+ end;\n }\n", "patch": "diff --git a/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al b/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al\nindex 4e6ffd2866..717c4f204b 100644\n--- a/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al\n+++ b/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al\n@@ -8,6 +8,7 @@ namespace Microsoft.Integration.Shopify;\n using Microsoft.Inventory.Item;\n using Microsoft.Foundation.UOM;\n using Microsoft.Purchases.Vendor;\n+using Microsoft.Finance.Currency;\n using Microsoft.Inventory.Item.Catalog;\n \n /// \n@@ -230,6 +231,7 @@ codeunit 30171 \"Shpfy Create Item\"\n ItemCategory: Record \"Item Category\";\n ItemVariant: Record \"Item Variant\";\n Vendor: Record Vendor;\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n CurrentTemplateCode: Code[20];\n ItemNo: Code[20];\n Code: Text;\n@@ -258,10 +260,16 @@ codeunit 30171 \"Shpfy Create Item\"\n CreateItemUnitOfMeasure(ShopifyVariant, Item);\n \n if ShopifyVariant.\"Unit Cost\" <> 0 then\n- Item.Validate(\"Unit Cost\", ShopifyVariant.\"Unit Cost\");\n+ if Shop.\"Currency Code\" = '' then\n+ Item.Validate(\"Unit Cost\", ShopifyVariant.\"Unit Cost\")\n+ else\n+ Item.Validate(\"Unit Cost\", Round(CurrencyExchangeRate.ExchangeAmtFCYToLCY(WorkDate(), Shop.\"Currency Code\", ShopifyVariant.\"Unit Cost\", CurrencyExchangeRate.ExchangeRate(WorkDate(), Shop.\"Currency Code\"))));\n \n if ShopifyVariant.Price <> 0 then\n- Item.Validate(\"Unit Price\", ShopifyVariant.Price);\n+ if Shop.\"Currency Code\" = '' then\n+ Item.Validate(\"Unit Price\", ShopifyVariant.Price)\n+ else\n+ Item.Validate(\"Unit Price\", Round(CurrencyExchangeRate.ExchangeAmtFCYToLCY(WorkDate(), Shop.\"Currency Code\", ShopifyVariant.Price, CurrencyExchangeRate.ExchangeRate(WorkDate(), Shop.\"Currency Code\"))));\n \n if ShopifyProduct.\"Product Type\" <> '' then begin\n ItemCategory.SetFilter(Description, FilterMgt.CleanFilterValue(ShopifyProduct.\"Product Type\", MaxStrLen(ItemCategory.Description)));\n"} -{"metadata": {"area": "inventory", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223790", "base_commit": "e33326f4a8f7341c0857ef5a7013a3fe593d8146", "created_at": "2025-08-13", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137035, "functionName": ["CheckPlanningWorksheetPlanComponentwhenStockkeepingUnitsSetup"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al\nindex cd0d28c59b88..9867c364a8cb 100644\n--- a/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al\n@@ -45,6 +45,8 @@ codeunit 137035 \"SCM PS Bugs-I\"\n QuantityErr: Label 'Quantity update should be possible in %1.', Comment = '%1= Table Name.';\n DueDateErr: Label 'Planned production order due date not match with planning worksheet due date';\n SKUInventoryErr: Label 'Expected inventory to be blank for non-inventory item';\n+ MainItemErr: Label 'New planning worksheet line not created for main item';\n+ CompoItemErr: Label 'New planning worksheet line not created for component item';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1320,6 +1322,97 @@ codeunit 137035 \"SCM PS Bugs-I\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('SKURequestPageHandler')]\n+ procedure CheckPlanningWorksheetPlanComponentwhenStockkeepingUnitsSetup()\n+ var\n+ CompItem: Record Item;\n+ InventorySetup: Record \"Inventory Setup\";\n+ Location: Record Location;\n+ MainItem: Record Item;\n+ ManufacturingSetup: Record \"Manufacturing Setup\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ Requisitionline: Record \"Requisition Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Itemcard: TestPage \"Item Card\";\n+ SKUCardPage: TestPage \"Stockkeeping Unit Card\";\n+ ActualCount: Integer;\n+ begin\n+ // [SCENARIO 579977] Check Planning Worksheet Plan Component when Stockkeeping Units Setup for Items.\n+ Initialize();\n+\n+ // [GIVEN] Set Manufacturing Setup for Dynamic Low-Level Code and Inventory Setup for ombined MPS/MRP Calculation.\n+ ManufacturingSetup.Get();\n+ ManufacturingSetup.Validate(\"Dynamic Low-Level Code\", true);\n+ ManufacturingSetup.Modify(true);\n+ InventorySetup.Get();\n+ InventorySetup.Validate(\"Combined MPS/MRP Calculation\", true);\n+ InventorySetup.Modify(true);\n+\n+ // [GIVEN] Create Item with Replenishment System as Production Order.\n+ LibraryInventory.CreateItem(CompItem);\n+\n+ // [GIVEN] Create Location.\n+ LibraryWarehouse.CreateLocation(Location);\n+\n+ // [GIVEN] Create Stockkeeping Unit for Item and Location.\n+ Commit();\n+ LibraryVariableStorage.Enqueue(Location.Code);\n+ ItemCard.OpenView();\n+ ItemCard.GotoRecord(CompItem);\n+ ItemCard.\"&Create Stockkeeping Unit\".Invoke();\n+ ItemCard.OK().Invoke();\n+\n+ // [GIVEN] Modify Stockkeeping Unit for Item.\n+ SKUCardPage.OpenView();\n+ SKUCardPage.Filter.SetFilter(\"Item No.\", CompItem.\"No.\");\n+ SKUCardPage.Filter.SetFilter(\"Location Code\", Location.\"Code\");\n+ SKUCardPage.\"Replenishment System\".SetValue(\"Replenishment System\"::Purchase);\n+ SKUCardPage.\"Reordering Policy\".SetValue(\"Reordering Policy\"::\"Order\");\n+ SKUCardPage.Close();\n+\n+ // [GIVEN] Create BOM for the item.\n+ LibraryManufacturing.CreateCertifiedProductionBOM(ProductionBOMHeader, CompItem.\"No.\", 1);\n+\n+ // [GIVEN] Create Main Item with Replenishment System as Production Order.\n+ LibraryInventory.CreateItem(MainItem);\n+\n+ // [GIVEN] Create Stockkeeping Unit for Main Item and Location.\n+ Commit();\n+ LibraryVariableStorage.Enqueue(Location.Code);\n+ ItemCard.OpenView();\n+ ItemCard.GotoRecord(MainItem);\n+ ItemCard.\"&Create Stockkeeping Unit\".Invoke();\n+ ItemCard.OK().Invoke();\n+\n+ // [GIVEN] Modify Stockkeeping Unit Created for Main Item.\n+ SKUCardPage.OpenView();\n+ SKUCardPage.Filter.SetFilter(\"Item No.\", MainItem.\"No.\");\n+ SKUCardPage.Filter.SetFilter(\"Location Code\", Location.\"Code\");\n+ SKUCardPage.\"Replenishment System\".SetValue(\"Replenishment System\"::\"Prod. Order\");\n+ SKUCardPage.\"Reordering Policy\".SetValue(\"Reordering Policy\"::\"Lot-for-Lot\");\n+ SKUCardPage.\"Manufacturing Policy\".SetValue(\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ SKUCardPage.\"Production BOM No.\".SetValue(ProductionBOMHeader.\"No.\");\n+ SKUCardPage.Close();\n+\n+ // [WHEN] Create Sales order for Item and Location.\n+ Librarysales.CreateSalesDocumentWithItem(\n+ SalesHeader, SalesLine, SalesHeader.\"Document Type\"::Order, '', MainItem.\"No.\", 10, Location.\"Code\", WorkDate());\n+\n+ // [WHEN] Calculate regenerative plan in planning worksheet update Planning Worksheet.\n+ CalculateRegenerativePlanningWorksheet(CompItem, MainItem, WorkDate(), CalcDate('<1Y>', WorkDate()), true, false);\n+\n+ // [THEN] Verify Actual Count Match with Expected Result for Main Item Planning Worksheet Line.\n+ CountPlanningWorksheetLine(Requisitionline, ActualCount, MainItem.\"No.\", Location.\"Code\");\n+ Assert.AreEqual(1, ActualCount, MainItemErr);\n+\n+ // [THEN] Verify Actual Count Match with Expected Result for Component Item Planning Worksheet Line.\n+ CountPlanningWorksheetLine(Requisitionline, ActualCount, CompItem.\"No.\", Location.\"Code\");\n+ Assert.AreEqual(1, ActualCount, CompoItemErr);\n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -2143,6 +2236,32 @@ codeunit 137035 \"SCM PS Bugs-I\"\n Assert.AreEqual(DueDate, ProductionOrder.\"Due Date\", DueDateErr);\n end;\n \n+ local procedure CountPlanningWorksheetLine(Requisitionline: Record \"Requisition Line\"; var ActualCount: Integer; ItemNo: Code[20]; LocationCode: Code[10])\n+ begin\n+ Clear(ActualCount);\n+ Requisitionline.Reset();\n+ Requisitionline.SetRange(\"No.\", ItemNo);\n+ Requisitionline.SetRange(\"Location Code\", LocationCode);\n+ if Requisitionline.FindSet() then\n+ ActualCount := Requisitionline.Count;\n+ end;\n+\n+ local procedure CalculateRegenerativePlanningWorksheet(var CompItemRec: Record Item; var MainItemRec: Record Item; OrderDate: Date; ToDate: Date; RespectPlanningParameters: Boolean; Regenerative: Boolean)\n+ var\n+ TmpItemRec: Record Item;\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ CalculatePlanPlanWksh: Report \"Calculate Plan - Plan. Wksh.\";\n+ begin\n+ LibraryPlanning.SelectRequisitionWkshName(RequisitionWkshName, RequisitionWkshName.\"Template Type\"::Planning); // Find Requisition Worksheet Name to Calculate Plan.\n+ Commit();\n+ CalculatePlanPlanWksh.InitializeRequest(OrderDate, ToDate, RespectPlanningParameters, true, true, '', 0D, false);\n+ CalculatePlanPlanWksh.SetTemplAndWorksheet(RequisitionWkshName.\"Worksheet Template Name\", RequisitionWkshName.Name, Regenerative);\n+ TmpItemRec.SetFilter(\"No.\", '%1..%2', CompItemRec.\"No.\", MainItemRec.\"No.\");\n+ CalculatePlanPlanWksh.SetTableView(TmpItemRec);\n+ CalculatePlanPlanWksh.UseRequestPage(false);\n+ CalculatePlanPlanWksh.RunModal();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al\nindex e6df0fd1150e..bd56f5d829d5 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al\n@@ -8,6 +8,7 @@ using Microsoft.Inventory.Item;\n using Microsoft.Manufacturing.Document;\n using Microsoft.Manufacturing.ProductionBOM;\n using Microsoft.Manufacturing.Routing;\n+using Microsoft.Manufacturing.Setup;\n \n tableextension 99000759 \"Mfg. Stockkeeping Unit\" extends \"Stockkeeping Unit\"\n {\n@@ -62,6 +63,27 @@ tableextension 99000759 \"Mfg. Stockkeeping Unit\" extends \"Stockkeeping Unit\"\n Caption = 'Production BOM No.';\n DataClassification = CustomerContent;\n TableRelation = \"Production BOM Header\";\n+ trigger OnValidate()\n+ var\n+ Item: Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ MfgSetup: Record \"Manufacturing Setup\";\n+ ProdBOMHeader: Record \"Production BOM Header\";\n+ CalculateLowLevelCode: Codeunit \"Calculate Low-Level Code\";\n+ begin\n+ if (\"Production BOM No.\" <> '') and (\"Production BOM No.\" <> xRec.\"Production BOM No.\") then begin\n+ ProdBOMHeader.Get(\"Production BOM No.\");\n+ ItemUnitOfMeasure.Get(\"Item No.\", ProdBOMHeader.\"Unit of Measure Code\");\n+ if ProdBOMHeader.Status = ProdBOMHeader.Status::Certified then begin\n+ MfgSetup.Get();\n+ Item.Get(\"Item No.\");\n+ if MfgSetup.\"Dynamic Low-Level Code\" then begin\n+ Item.\"Low-Level Code\" := CalculateLowLevelCode.CalcLevels(1, Item.\"No.\", 0, 0);\n+ CalculateLowLevelCode.SetRecursiveLevelsOnBOM(ProdBOMHeader, Item.\"Low-Level Code\" + 1, false);\n+ end;\n+ end;\n+ end;\n+ end;\n }\n field(99000765; \"Planned Order Receipt (Qty.)\"; Decimal)\n {\n"} -{"metadata": {"area": "inventory", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223819", "base_commit": "61943a7dd68306f6b3913043e73e4654232a9476", "created_at": "2025-08-14", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Dimension"], "FAIL_TO_PASS": [{"codeunitID": 134474, "functionName": ["OverrideDimWithNewLocationsAndSalespersonOnItemJournalLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al b/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al\nindex 8e58207a24d3..3a47bcf8819f 100644\n--- a/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al\n+++ b/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al\n@@ -1232,6 +1232,64 @@ codeunit 134474 \"ERM Dimension Locations\"\n Assert.AreNotEqual(TransferHeader.\"Shortcut Dimension 2 Code\", TransferLine.\"Shortcut Dimension 2 Code\", DimensionsNotEqualErr);\n end;\n \n+ [Test]\n+ procedure OverrideDimWithNewLocationsAndSalespersonOnItemJournalLine()\n+ var\n+ DimensionValue: array[2] of Record \"Dimension Value\";\n+ Item: Record Item;\n+ LocationFrom: Record Location;\n+ LocationTo: Record Location;\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ SalespersonPurchaser: Record \"Salesperson/Purchaser\";\n+ begin\n+ // [SCENARIO 596687] In the Item Reclassification Journal is the Dimension value wrongly updated by adding a Sales Person to the line\n+ Initialize();\n+\n+ // [GIVEN] Global dimension 1 values \"V1\" and \"V2\".\n+ LibraryDimension.CreateDimensionValue(DimensionValue[1], LibraryERM.GetGlobalDimensionCode(1));\n+ LibraryDimension.CreateDimensionValue(DimensionValue[2], LibraryERM.GetGlobalDimensionCode(1));\n+\n+ // [GIVEN] Assign value \"V1\" to location \"BLUE\".\n+ // [GIVEN] Assign value \"V2\" to location \"RED\".\n+ LibraryInventory.CreateItem(Item);\n+ CreateLocationWithDefaultDimension(LocationFrom, DimensionValue[1]);\n+ CreateLocationWithDefaultDimension(LocationTo, DimensionValue[2]);\n+\n+ // [GIVEN] Create item reclassification journal line.\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Transfer);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJnlLineWithNoItem(\n+ ItemJournalLine, ItemJournalBatch, ItemJournalTemplate.Name, ItemJournalBatch.Name, \"Item Ledger Entry Type\"::Transfer);\n+ ItemJournalline.Validate(\"Item No.\", Item.\"No.\");\n+\n+ // [GIVEN] Set \"Location Code\" = \"BLUE\" on the item journal line.\n+ // [GIVEN] Verify that \"Shortcut Dimension 1 Code\" = \"V1\".\n+ // [GIVEN] Verify that \"Dimension Set ID\" includes value \"V1\".\n+ ItemJournalLine.Validate(\"Location Code\", LocationFrom.Code);\n+ ItemJournalLine.TestField(\"Shortcut Dimension 1 Code\", DimensionValue[1].Code);\n+ VerifyDimensionValue(ItemJournalLine.\"Dimension Set ID\", DimensionValue[1]);\n+\n+ // [WHEN] Set \"New Location Code\" = \"RED\".\n+ ItemJournalLine.Validate(\"New Location Code\", LocationTo.Code);\n+\n+ // [WHEN] Set \"Sales Person Purchaser\" = \"RED\".\n+ LibrarySales.CreateSalesperson(SalespersonPurchaser);\n+ CreateDefaultDimensionWithSpecCode(SalespersonPurchaser.Code, DATABASE::\"Salesperson/Purchaser\");\n+ ItemJournalLine.Validate(\"Salespers./Purch. Code\", SalespersonPurchaser.Code);\n+\n+ // [THEN] \"New Shortcut Dimension 1 Code\" = \"V2\".\n+ // [THEN] \"New Dimension Set ID\" includes value \"V2\".\n+ ItemJournalLine.TestField(\"New Shortcut Dimension 1 Code\", DimensionValue[2].Code);\n+ VerifyDimensionValue(ItemJournalLine.\"New Dimension Set ID\", DimensionValue[2]);\n+\n+ // [THEN] \"Shortcut Dimension 1 Code\" remains \"V1\".\n+ // [THEN] \"Dimension Set ID\" is not changed.\n+ ItemJournalLine.TestField(\"Shortcut Dimension 1 Code\", DimensionValue[1].Code);\n+ VerifyDimensionValue(ItemJournalLine.\"Dimension Set ID\", DimensionValue[1]);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"ERM Dimension Locations\");\n@@ -1340,6 +1398,25 @@ codeunit 134474 \"ERM Dimension Locations\"\n DefaultDimensionPriority.Modify(true);\n end;\n \n+ local procedure CreateDefaultDimensionWithSpecCode(AccountNo: Code[20]; TableID: Integer)\n+ var\n+ Dimension: Record Dimension;\n+ DimensionValue: Record \"Dimension Value\";\n+ DefaultDimension: Record \"Default Dimension\";\n+ begin\n+ LibraryDimension.CreateDimension(Dimension);\n+ CreateDimensionValueWithSpecCode(DimensionValue, AccountNo, Dimension.Code);\n+ LibraryDimension.CreateDefaultDimension(DefaultDimension, TableID, AccountNo, Dimension.Code, DimensionValue.Code);\n+ end;\n+\n+ local procedure CreateDimensionValueWithSpecCode(var DimensionValue: Record \"Dimension Value\"; DimensionValueCode: Code[20]; DimensionCode: Code[20])\n+ begin\n+ DimensionValue.Init();\n+ DimensionValue.Validate(\"Dimension Code\", DimensionCode);\n+ DimensionValue.Validate(Code, DimensionValueCode);\n+ DimensionValue.Insert(true);\n+ end;\n+\n [ModalPageHandler]\n procedure DefaultDimensionsMultipleModalPageHandler(var DefaultDimensionsMultiple: TestPage \"Default Dimensions-Multiple\")\n begin\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\nindex 7fc2d9853602..c0a52d871c5d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n@@ -2375,11 +2375,14 @@ table 83 \"Item Journal Line\"\n OnCreateDimOnBeforeUpdateGlobalDimFromDimSetID(Rec, xRec, CurrFieldNo, OldDimSetID, DefaultDimSource, InheritFromDimSetID, InheritFromTableNo);\n DimMgt.UpdateGlobalDimFromDimSetID(\"Dimension Set ID\", \"Shortcut Dimension 1 Code\", \"Shortcut Dimension 2 Code\");\n \n- if \"Entry Type\" = \"Entry Type\"::Transfer then begin\n- \"New Dimension Set ID\" := \"Dimension Set ID\";\n- \"New Shortcut Dimension 1 Code\" := \"Shortcut Dimension 1 Code\";\n- \"New Shortcut Dimension 2 Code\" := \"Shortcut Dimension 2 Code\";\n- end;\n+ if \"Entry Type\" = \"Entry Type\"::Transfer then\n+ if Rec.\"New Location Code\" <> '' then\n+ CreateNewDimFromDefaultDim(Rec.FieldNo(\"New Location Code\"))\n+ else begin\n+ \"New Dimension Set ID\" := \"Dimension Set ID\";\n+ \"New Shortcut Dimension 1 Code\" := \"Shortcut Dimension 1 Code\";\n+ \"New Shortcut Dimension 2 Code\" := \"Shortcut Dimension 2 Code\";\n+ end;\n end;\n \n /// \n"} -{"metadata": {"area": "sales", "image_count": 13}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-222092", "base_commit": "d4b9caabb22e77ab18779535aa89967bb58f89d9", "created_at": "2025-07-27", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134904, "functionName": ["DimensionsInGeneralLedgerEntriesWhenDimensionsModifiedInReminderBeforeIssuing"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al\nindex 47f98eaf54a8..99b8ac6fb838 100644\n--- a/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al\n@@ -324,6 +324,86 @@ codeunit 134904 \"ERM Reminder For Additinal Fee\"\n Assert.AreEqual(Dim2CodeValue, ShortcutDimCode[2], StrSubstNo(DimensionValueErr, Dim2CodeValue));\n end;\n \n+ [Test]\n+ procedure DimensionsInGeneralLedgerEntriesWhenDimensionsModifiedInReminderBeforeIssuing();\n+ var\n+ Customer: Record Customer;\n+ CustomerPostingGroup: Record \"Customer Posting Group\";\n+ DefaultDimension: array[2] of Record \"Default Dimension\";\n+ DimensionValue: Record \"Dimension Value\";\n+ GLAccount: Record \"G/L Account\";\n+ GLEntry: Record \"G/L Entry\";\n+ ReminderHeader: Record \"Reminder Header\";\n+ ReminderLevel: Record \"Reminder Level\";\n+ ReminderTerms: Record \"Reminder Terms\";\n+ SalesHeader: Record \"Sales Header\";\n+ GetShortcutDimValues: Codeunit \"Get Shortcut Dimension Values\";\n+ Dim1CodeValue: array[2] of Code[20];\n+ Dim2CodeValue: Code[20];\n+ IssuedReminderNo: Code[20];\n+ ShortcutDimCode: array[8] of Code[20];\n+ begin\n+ // [SCENARIO 590674] Dimensions assigned to General Ledger Entries when the Dimensions are modified in the Reminder before issuing it.\n+ Initialize();\n+\n+ // [GIVEN] Create two Dimension Values for Global Dimension 1 Code.\n+ Dim1CodeValue[1] := LibraryUtility.GenerateGUID();\n+ Dim1CodeValue[2] := Dim1CodeValue[1] + '1';\n+ LibraryDimension.CreateDimensionValueWithCode(DimensionValue, Dim1CodeValue[1], LibraryERM.GetGlobalDimensionCode(1));\n+ LibraryDimension.CreateDimensionValueWithCode(DimensionValue, Dim1CodeValue[2], LibraryERM.GetGlobalDimensionCode(1));\n+\n+ // [GIVEN] Create Dimension Value for Global Dimension 2 Code and assign it.\n+ Dim2CodeValue := LibraryUtility.GenerateGUID();\n+ LibraryDimension.CreateDimensionValueWithCode(DimensionValue, Dim2CodeValue, LibraryERM.GetGlobalDimensionCode(2));\n+\n+ // [GIVEN] Create Reminder Terms with Post Additional Fee = True.\n+ CreateReminderTerms(ReminderLevel, '');\n+ ReminderTerms.Get(ReminderLevel.\"Reminder Terms Code\");\n+ ReminderTerms.\"Post Additional Fee\" := true;\n+ ReminderTerms.Modify(true);\n+\n+ // [GIVEN] Create Customer with Reminder Terms and Customer Posting Group.\n+ Customer.Get(CreateCustomer(ReminderLevel.\"Reminder Terms Code\", ''));\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup);\n+\n+ // [GIVEN] Create Default Dimension for Customer with global Dimension 1 Code.\n+ LibraryDimension.CreateDefaultDimensionWithNewDimValue(\n+ DefaultDimension[1], DATABASE::Customer, Customer.\"No.\",\n+ DefaultDimension[1].\"Value Posting\"::\"Code Mandatory\");\n+\n+ // [GIVEN] Find GL Account for Additional Fee Account and assign Global Dimension 1 Code and Global Dimension 2 Code.\n+ GLAccount.Get(CustomerPostingGroup.\"Additional Fee Account\");\n+ GLAccount.ValidateShortcutDimCode(1, Dim1CodeValue[1]);\n+ GLAccount.ValidateShortcutDimCode(2, Dim2CodeValue);\n+ GLAccount.Modify(true);\n+\n+ // [GIVEN] Validate Customer Posting Group in Customer.\n+ Customer.Validate(\"Customer Posting Group\", CustomerPostingGroup.Code);\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Posted Sales Invoice and Run Suggested Reminder with Additional Fee line.\n+ CreateAndPostSalesInvoice(SalesHeader, Customer.\"No.\");\n+ ReminderHeader.Get(\n+ CreateAndSuggestReminder(\n+ SalesHeader.\"Sell-to Customer No.\",\n+ CalcDate('<1D>', CalcDate(ReminderLevel.\"Grace Period\", SalesHeader.\"Due Date\"))));\n+ ReminderHeader.Validate(\"Shortcut Dimension 1 Code\", Dim1CodeValue[2]);\n+ ReminderHeader.Modify(true);\n+\n+ // [WHEN] Reminder is issued\n+ IssuedReminderNo := IssueReminderAndGetIssuedNo(ReminderHeader.\"No.\");\n+\n+ // [THEN] Find G/L Entry for Reminder with GL Account.\n+ GLEntry.SetRange(\"Document Type\", GLEntry.\"Document Type\"::Reminder);\n+ GLEntry.SetRange(\"Document No.\", IssuedReminderNo);\n+ GLEntry.SetRange(\"G/L Account No.\", GLAccount.\"No.\");\n+ GLEntry.FindFirst();\n+\n+ // [THEN] G/L Entry contains Global Dimension 1 Code as updated in Reminder Header.\n+ GetShortcutDimValues.GetShortcutDimensions(GLEntry.\"Dimension Set ID\", ShortcutDimCode);\n+ Assert.AreEqual(Dim1CodeValue[2], ShortcutDimCode[1], StrSubstNo(DimensionValueErr, Dim1CodeValue[2]));\n+ end;\n+\n [Scope('OnPrem')]\n procedure InterestAmountWithBeginningText()\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\nindex 825eb23c9503..9ff59101df20 100644\n--- a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n@@ -270,8 +270,8 @@ codeunit 393 \"Reminder-Issue\"\n begin\n GenJnlLine2.\"Shortcut Dimension 1 Code\" := GlobalReminderHeader.\"Shortcut Dimension 1 Code\";\n GenJnlLine2.\"Shortcut Dimension 2 Code\" := GlobalReminderHeader.\"Shortcut Dimension 2 Code\";\n- DimSetIDArr[1] := GlobalReminderHeader.\"Dimension Set ID\";\n- DimSetIDArr[2] := TempGenJnlLine.\"Dimension Set ID\";\n+ DimSetIDArr[1] := TempGenJnlLine.\"Dimension Set ID\";\n+ DimSetIDArr[2] := GlobalReminderHeader.\"Dimension Set ID\";\n GenJnlLine2.\"Dimension Set ID\" :=\n DimMgt.GetCombinedDimensionSetID(\n DimSetIDArr, GenJnlLine2.\"Shortcut Dimension 1 Code\", GenJnlLine2.\"Shortcut Dimension 2 Code\");\n"} -{"metadata": {"area": "warehouse", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218062", "base_commit": "226d490962047079ac9870319a3690af8959e6ad", "created_at": "2025-06-15", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137294, "functionName": ["NoErrorOfAvailabilityWhenCreatePickFromPickWorkSheetForProductionOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al\nindex eaf731a270b2..178112c70e63 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al\n@@ -49,6 +49,7 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n NoOfPicksCreatedMsg: Label 'Number of Invt. Pick activities created';\n WhseHandlingRequiredErr: Label 'Warehouse handling is required';\n InventoryMovementIsNotRegisteredErr: Label 'Inventory Movement is not registered.';\n+ InventoryPickNotFoundErr: Label 'Warehouse Activity Header not found for Production Order Components.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2132,6 +2133,88 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n Assert.IsTrue(RegisteredInvMovementHdr.Count > 0, InventoryMovementIsNotRegisteredErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('DummyMessageHandler,ReservationPageHandler,PickSelectionPageHandlerSingleDoc,CreatePickPageHandlerForPerWhsDoc')]\n+ [Scope('OnPrem')]\n+ procedure NoErrorOfAvailabilityWhenCreatePickFromPickWorkSheetForProductionOrder()\n+ var\n+ Bin, Bin2, Bin3 : Record Bin;\n+ CompItem, ProdItem : Record Item;\n+ Location: Record Location;\n+ ProductionOrder: array[2] of Record \"Production Order\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ WareHouseActivityHeader: Record \"Warehouse Activity Header\";\n+ begin\n+ // [SCENARIO 575862] No availability error when creating pick from pick worksheet with location setup Bin mandatory and the item reserved on the related production order\n+ Initialize();\n+\n+ // [GIVEN] Reset Warehouse Employee Default Location.\n+ ResetWarehouseEmployeeDefaultLocation();\n+\n+ // [GIVEN] Create Location with WMS enabled Bin mandatory\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, false, false, false);\n+\n+ // [GIVEN] Create Warehouse Employee for Location.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create Bins for Location.\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, Bin.Code, '', '');\n+ LibraryWarehouse.CreateBin(Bin2, Location.Code, Bin2.Code, '', '');\n+ LibraryWarehouse.CreateBin(Bin3, Location.Code, Bin3.Code, '', '');\n+\n+ // [GIVEN] Set \"Prod. Consump. Whse. Handling\" = \"Warehouse Pick (mandatory)\" and assign Bins to \"To-Production Bin Code\" and \"From-Production Bin Code\".\n+ Location.Validate(\"Prod. Consump. Whse. Handling\", Location.\"Prod. Consump. Whse. Handling\"::\"Warehouse Pick (mandatory)\");\n+ Location.Validate(\"To-Production Bin Code\", Bin.Code);\n+ Location.Validate(\"From-Production Bin Code\", Bin2.Code);\n+ Location.Modify(true);\n+\n+ // [GIVEN] Create Component Item with \"Replenishment System\" = \"Purchase\" and \"Flushing Method\" = \"Manual\".\n+ LibraryInventory.CreateItem(CompItem);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::Manual);\n+ CompItem.Modify();\n+\n+ // [GIVEN] Create Production BOM for Component Item.\n+ LibraryInventory.CreateItem(ProdItem);\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Manufacturing Policy\", ProdItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProdItem.Validate(\"Flushing Method\", ProdItem.\"Flushing Method\"::Manual);\n+ ProdItem.Validate(\"Production BOM No.\", LibraryManufacturing.CreateCertifiedProductionBOM(ProductionBOMHeader, CompItem.\"No.\", 1));\n+ ProdItem.Modify();\n+\n+ // [GIVEN] Create Inventory for Component Item.\n+ CreateInventory(CompItem, 3, Location.Code, Bin3.Code, 0);\n+\n+ // [GIVEN] Create first Production Orders for Production Item of quantity 2\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder[1], ProductionOrder[1].Status::Released, ProductionOrder[1].\"Source Type\"::Item, ProdItem.\"No.\", 2);\n+ ProductionOrder[1].Validate(\"Location Code\", Location.Code);\n+ ProductionOrder[1].Modify(true);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder[1], false, true, true, true, false);\n+\n+ // [GIVEN] Reserve Component Item on Production Order 1\n+ ReserveQuantityOnComponent(CompItem.\"No.\", ProductionOrder[1].\"No.\");\n+\n+ // [GIVEN] Create second Production Order for Production Item of quantity 1\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder[2], ProductionOrder[2].Status::Released, ProductionOrder[2].\"Source Type\"::Item, ProdItem.\"No.\", 1);\n+ ProductionOrder[2].Validate(\"Location Code\", Location.Code);\n+ ProductionOrder[2].Modify(true);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder[2], false, true, true, true, false);\n+\n+ // [GIVEN] Reserve Component Item on Production Order 2\n+ ReserveQuantityOnComponent(CompItem.\"No.\", ProductionOrder[2].\"No.\");\n+\n+ // [WHEN] Create Pick Worksheet for Production Order Components.\n+ GetWarehouseDocumentFromPickWorksheet(ProductionOrder);\n+\n+ // [THEN] Verify Warehouse Activity Header for Production Order Components.\n+ WarehouseActivityHeader.SetRange(\"Location Code\", Location.Code);\n+ WareHouseActivityHeader.FindSet();\n+ Assert.IsTrue(WareHouseActivityHeader.Count = 2, InventoryPickNotFoundErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3796,6 +3879,50 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n VerifyInventoryPickLine(SalesOrderNo, LotNos[2], Lot2Qty);\n end;\n \n+ local procedure GetWarehouseDocumentFromPickWorksheet(ProductionOrder: array[2] of Record \"Production Order\")\n+ var\n+ PickWorksheet: TestPage \"Pick Worksheet\";\n+ begin\n+ LibraryVariableStorage.Enqueue(ProductionOrder[1].\"No.\"); // Enqueue for PickSelectionPageHandler.\n+ LibraryVariableStorage.Enqueue(ProductionOrder[1].\"Location Code\"); // Enqueue PickSelectionPageHandler.\n+ PickWorksheet.OpenEdit();\n+ PickWorksheet.\"Get Warehouse Documents\".Invoke();\n+\n+ LibraryVariableStorage.Enqueue(ProductionOrder[2].\"No.\"); // Enqueue for PickSelectionPageHandler.\n+ LibraryVariableStorage.Enqueue(ProductionOrder[2].\"Location Code\"); // Enqueue PickSelectionPageHandler.\n+ PickWorksheet.\"Get Warehouse Documents\".Invoke();\n+ Commit();\n+\n+ PickWorksheet.CreatePick.Invoke();\n+ PickWorksheet.OK().Invoke();\n+ end;\n+\n+ local procedure ReserveQuantityOnComponent(ItemNo: code[20]; ProdOrderno: Code[20])\n+ var\n+ ProdOrderComponents: TestPage \"Prod. Order Components\";\n+ begin\n+ ProdOrderComponents.OpenEdit();\n+ ProdOrderComponents.FILTER.SetFilter(\"Item No.\", ItemNo);\n+ ProdOrderComponents.FILTER.SetFilter(\"Prod. Order No.\", ProdOrderno);\n+ ProdOrderComponents.Reserve.Invoke();\n+ ProdOrderComponents.Close();\n+ end;\n+\n+ local procedure CreateInventory(Item: Record Item; Quantity: Decimal; LocationCode: Code[10]; BinCode: Code[20]; UnitAmount: Decimal)\n+ var\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.CreateItemJournalBatchByType(ItemJournalBatch, ItemJournalBatch.\"Template Type\"::Item);\n+\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalBatch, Item, LocationCode, '', WorkDate(),\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Quantity, UnitAmount);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify();\n+\n+ LibraryInventory.PostItemJournalBatch(ItemJournalBatch);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure DummyMessageHandler(Message: Text[1024])\n@@ -3817,5 +3944,36 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ReservationPageHandler(var Reservation: TestPage Reservation)\n+ begin\n+ Reservation.\"Reserve from Current Line\".Invoke();\n+ Reservation.OK().Invoke();\n+ end;\n+\n+ [RequestPageHandler]\n+ [Scope('OnPrem')]\n+ procedure CreatePickPageHandlerForPerWhsDoc(var CreatePick: TestRequestPage \"Create Pick\")\n+ begin\n+ CreatePick.PerWhseDoc.SetValue(true);\n+ CreatePick.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PickSelectionPageHandlerSingleDoc(var PickSelection: TestPage \"Pick Selection\")\n+ var\n+ DocumentNo: Variant;\n+ LocationCode: Variant;\n+ begin\n+ LibraryVariableStorage.Dequeue(DocumentNo); // Dequeue Variable.\n+ LibraryVariableStorage.Dequeue(LocationCode); // Dequeue Variable.\n+ PickSelection.Filter.SetFilter(\"Document No.\", DocumentNo);\n+ PickSelection.\"Document No.\".AssertEquals(DocumentNo);\n+ PickSelection.\"Location Code\".AssertEquals(LocationCode);\n+ PickSelection.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al\nindex 0b63877adb3b..32239d687e93 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al\n@@ -870,7 +870,9 @@ codeunit 7314 \"Warehouse Availability Mgt.\"\n end else\n AvailQtyBase := CalcInvtAvailQty(Item, Location, WhseWorksheetLine.\"Variant Code\", TempWhseActivLine);\n \n- if Location.\"Require Pick\" then\n+ if Location.\"Require Pick\" or\n+ (Location.\"Prod. Consump. Whse. Handling\" = Location.\"Prod. Consump. Whse. Handling\"::\"Warehouse Pick (mandatory)\")\n+ then\n QtyReservedOnPickShip := CalcReservQtyOnPicksShips(WhseWorksheetLine.\"Location Code\", WhseWorksheetLine.\"Item No.\", WhseWorksheetLine.\"Variant Code\", TempWhseActivLine);\n \n QtyReservedForCurrLine :=\n"} -{"metadata": {"area": "sales", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218253", "base_commit": "db3b5298f26de0882a366877931e512984bb1001", "created_at": "2025-06-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134389, "functionName": ["QuantityReducedInSalesInvoiceAfterGenShipmentLineReservesTrackingInformation"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\nindex a4fa97f4520d..bc57ae20d22e 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n@@ -17,6 +17,7 @@ codeunit 134389 \"ERM Customer Statistics\"\n LibraryERM: Codeunit \"Library - ERM\";\n LibraryRandom: Codeunit \"Library - Random\";\n LibraryApplicationArea: Codeunit \"Library - Application Area\";\n+ LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n LibraryUtility: Codeunit \"Library - Utility\";\n IsInitialized: Boolean;\n OverDueBalanceErr: Label 'Customer OverDue Balance is not correct';\n@@ -29,6 +30,7 @@ codeunit 134389 \"ERM Customer Statistics\"\n EntryNoMustMatchErr: Label 'Entry No. must match.';\n PaymentsLCYAndAmountLCYMustMatchErr: Label 'Payemnts (LCY) and Amount (LCY) must match.';\n CustomerCardFactboxTotalErr: Label 'Customer card factbox total is not Correct';\n+ LotNoErr: Label 'Lot No. should have value.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1003,6 +1005,83 @@ codeunit 134389 \"ERM Customer Statistics\"\n Assert.AreEqual(SalesLine.\"Amount Including VAT\", Customer.GetTotalAmountLCY(), CustomerCardFactboxTotalErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemTrackingLinesPageHandler,EnterQuantityToCreatePageHandler,GetShipmentLinesPageHandler')]\n+ procedure QuantityReducedInSalesInvoiceAfterGenShipmentLineReservesTrackingInformation()\n+ var\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ ItemTrackingCode: Record \"Item Tracking Code\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Quantity: Integer;\n+ begin\n+ // [SCENARIO 576049] When the quantity in a Sales Invoices was changed after using 'Get Shipment lines' and an item with item tracking lines and reserve always has the tracking information.\n+ Initialize();\n+\n+ // [GIVEN] Created New Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Item Tracking Code and Validate Trackings.\n+ LibraryInventory.CreateItemTrackingCode(ItemTrackingCode);\n+ ItemTrackingCode.Validate(\"Lot Specific Tracking\", false);\n+ ItemTrackingCode.Validate(\"SN Specific Tracking\", false);\n+ ItemTrackingCode.Validate(\"SN Sales Inbound Tracking\", true);\n+ ItemTrackingCode.Validate(\"SN Sales Outbound Tracking\", true);\n+ ItemTrackingCode.Validate(\"Lot Sales Inbound Tracking\", true);\n+ ItemTrackingCode.Validate(\"Lot Sales Outbound Tracking\", true);\n+ ItemTrackingCode.Modify(true);\n+\n+ // [GIVEN] Created New Item and Validate Item Tracking Code, Serial Nos, Reserve.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Item Tracking Code\", ItemTrackingCode.Code);\n+ Item.Validate(\"Lot Nos.\", LibraryERM.CreateNoSeriesCode());\n+ Item.Validate(\"Serial Nos.\", LibraryERM.CreateNoSeriesCode());\n+ Item.Validate(Reserve, Item.Reserve::Always);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Store quantity in Variable.\n+ Quantity := LibraryRandom.RandIntInRange(10, 10);\n+\n+ // [GIVEN] Created Item Inventory By Posting Item Journal.\n+ CreateItemInventory(Item, Quantity);\n+\n+ // [GIVEN] Create new Sales Header.\n+ CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\", WorkDate());\n+\n+ // [GIVEN] Create Sales line and Validate Unit Price.\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", Quantity);\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandDec(1000, 0));\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Enqueue Quantity and assign Tracking Lines\n+ LibraryVariableStorage.Enqueue(true);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ SalesLine.OpenItemTrackingLines();\n+\n+ // [GIVEN] Post Sales Order invoked with \"Shipped\" selected.\n+ LibrarySales.PostSalesDocument(SalesHeader, true, false);\n+\n+ // [GIVEN] Create New Sales Invoice And Get Shipment Line Through GetShipmentLines.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer.\"No.\");\n+ SalesLine.Validate(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.Validate(\"Document No.\", SalesHeader.\"No.\");\n+ LibrarySales.GetShipmentLines(SalesLine);\n+\n+ // [GIVEN] Find the Sales Line.\n+ SalesLine.SetRange(\"Document No.\", SalesHeader.\"No.\");\n+ SalesLine.SetRange(Type, SalesLine.Type::Item);\n+ SalesLine.FindFirst();\n+\n+ // [WHEN] Validate Quantity with random integer less than previous quanitity.\n+ SalesLine.Validate(Quantity, LibraryRandom.RandInt(5));\n+ SalesLine.Modify(true);\n+\n+ // [THEN] Tracking Lines is not deleted.\n+ LibraryVariableStorage.Enqueue(false);\n+ SalesLine.OpenItemTrackingLines();\n+ end;\n+\n local procedure Initialize()\n var\n Currency: Record Currency;\n@@ -1506,4 +1585,26 @@ codeunit 134389 \"ERM Customer Statistics\"\n begin\n GetShipmentLines.OK().Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ procedure ItemTrackingLinesPageHandler(var ItemTrackingLines: TestPage \"Item Tracking Lines\")\n+ var\n+ AssignSerial: Boolean;\n+ begin\n+ AssignSerial := LibraryVariableStorage.DequeueBoolean();\n+ if AssignSerial then\n+ ItemTrackingLines.\"Assign Serial No.\".Invoke();\n+\n+ if not AssignSerial then\n+ Assert.IsTrue(ItemTrackingLines.\"Lot No.\".Value() <> '', LotNoErr);\n+ ItemTrackingLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ procedure EnterQuantityToCreatePageHandler(var EnterQuantitytoCreate: TestPage \"Enter Quantity to Create\")\n+ begin\n+ EnterQuantitytoCreate.QtyToCreate.SetValue(LibraryVariableStorage.DequeueInteger());\n+ EnterQuantitytoCreate.CreateNewLotNo.SetValue(true);\n+ EnterQuantitytoCreate.OK().Invoke();\n+ end;\n }\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al\nindex 15a14be1bfcb..b95b0aa54eb2 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al\n@@ -1304,6 +1304,9 @@ codeunit 99000832 \"Sales Line-Reserve\"\n if (NewSalesLine.Type <> NewSalesLine.Type::Item) or (NewSalesLine.Quantity = 0) or (NewSalesLine.Reserve <> NewSalesLine.Reserve::Always) then\n exit(false);\n \n+ if ShipmentExists(NewSalesLine) then\n+ exit(false);\n+\n Item.SetLoadFields(\"Costing Method\");\n Item.Get(NewSalesLine.\"No.\");\n \n@@ -1313,6 +1316,15 @@ codeunit 99000832 \"Sales Line-Reserve\"\n exit(NewSalesLine.Quantity < OldSalesLine.Quantity);\n end;\n \n+ local procedure ShipmentExists(SalesLine: Record \"Sales Line\"): Boolean\n+ var\n+ SalesShipmentLine: Record \"Sales Shipment Line\";\n+ begin\n+ SalesShipmentLine.SetRange(\"Document No.\", SalesLine.\"Shipment No.\");\n+ SalesShipmentLine.SetRange(\"Line No.\", SalesLine.\"Shipment Line No.\");\n+ exit(not SalesShipmentLine.IsEmpty());\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterReservQuantity(SalesLine: Record \"Sales Line\"; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)\n begin\n"} -{"metadata": {"area": "project", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218995", "base_commit": "26bcb2715129beebf0d07da7f19e06fe66636119", "created_at": "2025-06-24", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136306, "functionName": ["PostPurchaseCreditMemoWithNonInventoryItemLinkedToProject"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\nindex 3f5a305f277c..8683b7e13047 100644\n--- a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n@@ -4082,6 +4082,47 @@ codeunit 136306 \"Job Invoicing\"\n Assert.IsFalse(JobPlanningLine.\"System-Created Entry\", ValueFalseErr);\n end;\n \n+ [Test]\n+ procedure PostPurchaseCreditMemoWithNonInventoryItemLinkedToProject()\n+ var\n+ Item: Record Item;\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ begin\n+ // [SCENARIO 580434] Error when posting a Purchase Credit Memo for 'Non-Inventory' item with Project No. selected\n+ Initialize();\n+\n+ // [GIVEN] Create Non-Inventory Item\n+ LibraryInventory.CreateNonInventoryTypeItem(Item);\n+\n+ // [GIVEN] Create Job with Customer\n+ CreateJobWithCustomer(Job);\n+\n+ // [GIVEN] Create Job Task\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+\n+ // [GIVEN] Create Vendor\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ // [GIVEN] Create Purchase Credit Memo\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::\"Credit Memo\", Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item.\"No.\", 1);\n+\n+ // [GIVEN] Set Job No., Job Task No. and Job Line Type as Billable\n+ PurchaseLine.Validate(\"Job No.\", Job.\"No.\");\n+ PurchaseLine.Validate(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ PurchaseLine.Validate(\"Job Line Type\", PurchaseLine.\"Job Line Type\"::Billable);\n+ PurchaseLine.Modify(true);\n+\n+ // [WHEN] Post Purchase Credit Memo\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true);\n+\n+ // [THEN] No error should come, as posting for Non-Inventory Item.\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al\nindex a913f1c1ea1b..bd54e22b3b45 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al\n@@ -478,6 +478,9 @@ codeunit 1001 \"Job Post-Line\"\n if IsHandled then\n exit;\n \n+ if PurchaseLine.IsNonInventoriableItem() then\n+ exit;\n+\n Job.Get(PurchaseLine.\"Job No.\");\n if Job.GetQuantityAvailable(PurchaseLine.\"No.\", PurchaseLine.\"Location Code\", PurchaseLine.\"Variant Code\", 0, 2) <\n -PurchaseLine.\"Return Qty. to Ship (Base)\"\n"} -{"metadata": {"area": "warehouse", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218786", "base_commit": "a0daccc2bd96d0bd4269d1b5eae4cc44ddd34673", "created_at": "2025-06-21", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137065, "functionName": ["WarehousePickUpdateQuantityInOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al\nindex 9251a2965f1f..fda235875212 100644\n--- a/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al\n@@ -58,6 +58,7 @@ codeunit 137065 \"SCM Reservation II\"\n PostJnlLinesMsg: Label 'Do you want to post the journal lines';\n SuggestedBackGroundRunQst: Label 'Would you like to run the low-level code calculation as a background job?';\n ActionMessageEntryExistErr: Label 'Action Message Entry exist for item %1', Comment = '%1 = Item No.';\n+ QuantityErr: Label 'Quantity must be equal to %1', Comment = '%1 = Quantity';\n \n [Test]\n [HandlerFunctions('ProdOrderComponentsHandler')]\n@@ -2997,6 +2998,84 @@ codeunit 137065 \"SCM Reservation II\"\n VerifyThereIsNoDamagedReservationEntryForSurplus(Database::\"Sales Line\", SalesHeader[2].\"No.\", ReservationEntry.\"Reservation Status\"::Surplus);//, -SalesLine[2].\"Quantity (Base)\");\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure WarehousePickUpdateQuantityInOrder()\n+ var\n+ Bin: array[8] of Record Bin;\n+ CompItem, ProdItem : Record Item;\n+ Location: Record Location;\n+ ProductionOrder: Record \"Production Order\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ Quantity: Decimal;\n+ UpdatedQuantity: Decimal;\n+ begin\n+ // [SCENARIO 581104] Manually change quantity of \"Take Line\" in Warehouse Pick changes the quantity of the correct \"Place Lines\"\n+ Initialize();\n+\n+ // [GIVEN] Set Quantity and UpdatedQuantity.\n+ Quantity := LibraryRandom.RandIntInRange(900, 1000);\n+ UpdatedQuantity := LibraryRandom.RandIntInRange(400, 500);\n+\n+ // [GIVEN] Reset Warehouse Employee Default Location.\n+ ResetWarehouseEmployeeDefaultLocation();\n+\n+ // [GIVEN] Create Location with WMS enabled Bin mandatory\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create Warehouse Employee for Location.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create Bins for Location.\n+ CreateBin(Bin, Location.Code);\n+\n+ // [GIVEN] Set \"Prod. Consump. Whse. Handling\" = \"Warehouse Pick (mandatory)\" and assign Bins to \"To-Production Bin Code\" and \"From-Production Bin Code\".\n+ Location.Validate(\"Prod. Consump. Whse. Handling\", Location.\"Prod. Consump. Whse. Handling\"::\"Warehouse Pick (mandatory)\");\n+ Location.Validate(\"To-Production Bin Code\", Bin[1].Code);\n+ Location.Validate(\"From-Production Bin Code\", Bin[2].Code);\n+ Location.Validate(\"Open Shop Floor Bin Code\", Bin[3].Code);\n+ Location.Modify(true);\n+\n+ // [GIVEN] Create Component Item with \"Replenishment System\" = \"Purchase\" and \"Flushing Method\" = \"Manual\".\n+ LibraryInventory.CreateItem(CompItem);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::\"Pick + Manual\");\n+ CompItem.Validate(\"Allow Whse. Overpick\", true);\n+ CompItem.Modify();\n+\n+ // [GIVEN] Create Production BOM for Component Item.\n+ LibraryInventory.CreateItem(ProdItem);\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Manufacturing Policy\", ProdItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProdItem.Validate(\"Flushing Method\", ProdItem.\"Flushing Method\"::Manual);\n+ ProdItem.Validate(\"Production BOM No.\", LibraryManufacturing.CreateCertifiedProductionBOM(ProductionBOMHeader, CompItem.\"No.\", 1));\n+ ProdItem.Modify();\n+\n+ // [GIVEN] Create Inventory for Component Item for five different Bins.\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[4].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[5].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[6].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[7].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[8].Code, 0);\n+\n+ // [GIVEN] Create Production Orders for Production Item of quantity Quantity * 5.\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder, ProductionOrder.Status::Released, ProductionOrder.\"Source Type\"::Item, ProdItem.\"No.\", Quantity * 5);\n+ ProductionOrder.Validate(\"Location Code\", Location.Code);\n+ ProductionOrder.Modify(true);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+\n+ // [GIVEN] Create Warehouse Pick from Production Order.\n+ LibraryWarehouse.CreateWhsePickFromProduction(ProductionOrder);\n+\n+ // [WHEN] Update quantity in Warehouse Pick Lines.\n+ UpdateQuantityWarehousePickFromPage(ProductionOrder.\"No.\", Location.Code, UpdatedQuantity);\n+\n+ // [THEN] Verify that the Warehouse Activity Lines are updated correctly.\n+ VerifyWareHouseActivityLinesForQuantity(ProductionOrder.\"No.\", Location, Quantity, UpdatedQuantity);\n+ end;\n+\n local procedure Initialize()\n var\n AllProfile: Record \"All Profile\";\n@@ -4693,6 +4772,72 @@ codeunit 137065 \"SCM Reservation II\"\n asserterror ReservationEntry.FindFirst();\n end;\n \n+ local procedure ResetWarehouseEmployeeDefaultLocation()\n+ var\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ begin\n+ WarehouseEmployee.SetRange(\"User ID\", UserId());\n+ WarehouseEmployee.SetRange(Default, true);\n+ WarehouseEmployee.ModifyAll(Default, false);\n+ end;\n+\n+ local procedure VerifyWareHouseActivityLinesForQuantity(ProductionOrderNo: Code[20]; Location: Record Location; Quantity: Decimal; UpdatedQuantity: Decimal)\n+ var\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ begin\n+ FindWarehouseActivityLine(WarehouseActivityLine, ProductionOrderNo, WarehouseActivityLine.\"Source Document\"::\"Prod. Consumption\", WarehouseActivityLine.\"Action Type\"::Place);\n+ WarehouseActivityLine.SetRange(\"Bin Code\", Location.\"To-Production Bin Code\");\n+ WarehouseActivityLine.FindFirst();\n+ Assert.IsTrue(WarehouseActivityLine.\"Qty. (Base)\" = Quantity, StrSubstNo(QuantityErr, Quantity));\n+\n+ WarehouseActivityLine.Reset();\n+ FindWarehouseActivityLine(WarehouseActivityLine, ProductionOrderNo, WarehouseActivityLine.\"Source Document\"::\"Prod. Consumption\", WarehouseActivityLine.\"Action Type\"::Place);\n+ WarehouseActivityLine.SetRange(\"Bin Code\", Location.\"To-Production Bin Code\");\n+ WarehouseActivityLine.FindLast();\n+ Assert.IsTrue(WarehouseActivityLine.\"Qty. (Base)\" = UpdatedQuantity, StrSubstNo(QuantityErr, UpdatedQuantity));\n+ end;\n+\n+ local procedure UpdateQuantityWarehousePickFromPage(ProductionOrderNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal)\n+ var\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ WarehousePickPage: TestPage \"Warehouse Pick\";\n+ begin\n+ WarehouseActivityLine.SetRange(\"Source Document\", WarehouseActivityHeader.\"Source Document\"::\"Prod. Consumption\");\n+ WarehouseActivityLine.SetRange(\"Source No.\", ProductionOrderNo);\n+ WarehouseActivityLine.SetRange(\"Location Code\", LocationCode);\n+ WarehouseActivityLine.FindFirst();\n+ WarehouseActivityHeader.Get(WarehouseActivityHeader.Type::Pick, WarehouseActivityLine.\"No.\");\n+ WarehousePickPage.OpenEdit();\n+ WarehousePickPage.GoToRecord(WarehouseActivityHeader);\n+ WarehousePickPage.WhseActivityLines.Last();\n+ WarehousePickPage.WhseActivityLines.Previous();\n+ WarehousePickPage.WhseActivityLines.Quantity.SetValue(Quantity);\n+ end;\n+\n+ local procedure CreateInventoryWithBin(Item: Record Item; Quantity: Decimal; LocationCode: Code[10]; BinCode: Code[20]; UnitAmount: Decimal)\n+ var\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.CreateItemJournalBatchByType(ItemJournalBatch, ItemJournalBatch.\"Template Type\"::Item);\n+\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalBatch, Item, LocationCode, '', WorkDate(),\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Quantity, UnitAmount);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify();\n+\n+ LibraryInventory.PostItemJournalBatch(ItemJournalBatch);\n+ end;\n+\n+ local procedure CreateBin(var Bin: array[8] of Record Bin; LocationCode: Code[10])\n+ var\n+ i: Integer;\n+ begin\n+ for i := 1 to arraylen(Bin) do\n+ LibraryWarehouse.CreateBin(Bin[i], LocationCode, Bin[i].Code, '', '');\n+ end;\n+\n [PageHandler]\n [Scope('OnPrem')]\n procedure ProdOrderComponentsHandler(var ProdOrderComponents: TestPage \"Prod. Order Components\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al b/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al\nindex 0b806569d9b4..a4b3f3fb5f23 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al\n@@ -3102,6 +3102,7 @@ table 5767 \"Warehouse Activity Line\"\n var\n Item: Record Item;\n WhseActivityLine: Record \"Warehouse Activity Line\";\n+ QuantityUpdated: Boolean;\n begin\n if CurrFieldNo = 0 then\n exit;\n@@ -3125,10 +3126,21 @@ table 5767 \"Warehouse Activity Line\"\n Item.Get(FromWhseActivityLine.\"Item No.\");\n Item.TestField(\"Allow Whse. Overpick\");\n \n+ SetFilterFromWhseActivityLineToUpdateQty(WhseActivityLine, FromWhseActivityLine, xWhseActivityLine, QuantityUpdated);\n+ if QuantityUpdated then\n+ WhseActivityLine.Modify(true);\n+ end;\n+\n+ local procedure SetFilterFromWhseActivityLineToUpdateQty(\n+ var WhseActivityLine: Record \"Warehouse Activity Line\";\n+ FromWhseActivityLine: Record \"Warehouse Activity Line\";\n+ xWhseActivityLine: Record \"Warehouse Activity Line\";\n+ var QuantityUpdated: Boolean)\n+ begin\n WhseActivityLine.SetLoadFields(\"Activity Type\", \"No.\", \"Line No.\", \"Item No.\", \"Variant Code\", \"Location Code\", \"Action Type\", Quantity, \"Lot No.\", \"Serial No.\", \"Source No.\", \"Source Line No.\", \"Source Document\");\n WhseActivityLine.SetRange(\"Activity Type\", FromWhseActivityLine.\"Activity Type\");\n WhseActivityLine.SetRange(\"No.\", FromWhseActivityLine.\"No.\");\n- WhseActivityLine.SetFilter(\"Line No.\", '<>%1', FromWhseActivityLine.\"Line No.\");\n+ WhseActivityLine.SetFilter(\"Line No.\", '>%1', FromWhseActivityLine.\"Line No.\");\n WhseActivityLine.SetRange(\"Item No.\", FromWhseActivityLine.\"Item No.\");\n WhseActivityLine.SetRange(\"Variant Code\", FromWhseActivityLine.\"Variant Code\");\n WhseActivityLine.SetRange(\"Location Code\", FromWhseActivityLine.\"Location Code\");\n@@ -3139,11 +3151,18 @@ table 5767 \"Warehouse Activity Line\"\n WhseActivityLine.SetRange(\"Source Document\", FromWhseActivityLine.\"Source Document\");\n WhseActivityLine.SetRange(\"Source No.\", FromWhseActivityLine.\"Source No.\");\n WhseActivityLine.SetRange(\"Source Line No.\", FromWhseActivityLine.\"Source Line No.\");\n+ if WhseActivityLine.FindFirst() then begin\n+ WhseActivityLine.Validate(Quantity, FromWhseActivityLine.Quantity);\n+ QuantityUpdated := true;\n+ exit;\n+ end;\n \n- WhseActivityLine.FindFirst();\n-\n- WhseActivityLine.Validate(Quantity, FromWhseActivityLine.Quantity);\n- WhseActivityLine.Modify(true);\n+ WhseActivityLine.SetRange(\"Line No.\");\n+ WhseActivityLine.SetFilter(\"Line No.\", '<>%1', FromWhseActivityLine.\"Line No.\");\n+ if WhseActivityLine.FindFirst() then begin\n+ WhseActivityLine.Validate(Quantity, FromWhseActivityLine.Quantity);\n+ QuantityUpdated := true;\n+ end\n end;\n \n [IntegrationEvent(false, false)]\n"} -{"metadata": {"area": "utilities", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-217974", "base_commit": "645334f664bea223d7a58bdcd730164852241728", "created_at": "2025-06-13", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137156, "functionName": ["MoveNegativeLines_SetsReturnOrderShipToAddressToCompany"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al\nindex 670a87576340..2c5a96d5e372 100644\n--- a/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al\n@@ -72,6 +72,7 @@ codeunit 137156 \"SCM Orders IV\"\n DocumentLineSourceNoErr: label 'Expected source on document line is %1 but found %2.', Comment = '%1 = Expected Source No., %2 = Actual Source No.';\n ReservationFromStockErr: Label 'Reservation from Stock must be %1 in %2.', Comment = '%1= Field Value, %2 =Table Caption.';\n PurchasingCodeOnSalesInvoiceErr: Label 'The Purchasing Code should be blank for item %1 on the sales invoice because it is used only for the drop shipment process.', Comment = '%1= Item No.';\n+ ShipToAddressErr: Label 'Ship-to Address on Return Order should be company address';\n \n #if not CLEAN25\n [Test]\n@@ -3553,6 +3554,43 @@ codeunit 137156 \"SCM Orders IV\"\n Assert.ExpectedError(StrSubstNo(PurchasingCodeOnSalesInvoiceErr, Item.\"No.\"));\n end;\n \n+ [Test]\n+ procedure MoveNegativeLines_SetsReturnOrderShipToAddressToCompany()\n+ var\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ CompanyInfo: Record \"Company Information\";\n+ begin\n+ // [SCENARIO 580640] Verify Ship to Address of Return Order when Move Negative Lines on the Sales Order.\n+ Initialize();\n+\n+ // [GIVEN] Create Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Sales Header with Document Type as Order.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+\n+ // [GIVEN] Create SalesLine with Negative Quantity.\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, LibraryInventory.CreateItem(Item), LibraryRandom.RandIntInRange(-5, -10));\n+\n+ // [WHEN] Move Negative Lines\n+ MoveNegativeLinesOnSalesOrder(SalesHeader);\n+\n+ // [GIVEN] Get company address\n+ CompanyInfo.Get();\n+\n+ // [THEN] Sales Return Order is created with Ship to Address as Company Address.\n+ SalesHeader.SetRange(\"Document Type\", SalesHeader.\"Document Type\"::\"Return Order\");\n+ SalesHeader.SetRange(\"Sell-to Customer No.\", Customer.\"No.\");\n+ SalesHeader.FindFirst();\n+ Assert.AreEqual(\n+ CompanyInfo.\"Ship-to Address\", SalesHeader.\"Ship-to Address\", ShipToAddressErr);\n+ Assert.AreEqual(\n+ CompanyInfo.\"Ship-to City\", SalesHeader.\"Ship-to City\", ShipToAddressErr);\n+ end;\n+\n local procedure Initialize()\n var\n PriceListLine: Record \"Price List Line\";\n@@ -5405,8 +5443,8 @@ codeunit 137156 \"SCM Orders IV\"\n begin\n WarehouseActivityLine.SetRange(\"Action Type\", ActionType);\n FindWarehouseActivityLine(\n- WarehouseActivityLine, WarehouseActivityLine.\"Source Document\"::\"Purchase Order\", SourceNo,\n- WarehouseActivityLine.\"Activity Type\"::\"Put-away\");\n+WarehouseActivityLine, WarehouseActivityLine.\"Source Document\"::\"Purchase Order\", SourceNo,\n+WarehouseActivityLine.\"Activity Type\"::\"Put-away\");\n WarehouseActivityLine.ModifyAll(\"Zone Code\", ZoneCode, true);\n WarehouseActivityLine.ModifyAll(\"Bin Code\", BinCode, true);\n end;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al b/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al\nindex 780de254f475..452e82783b47 100644\n--- a/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al\n@@ -747,6 +747,7 @@ codeunit 6620 \"Copy Document Mgt.\"\n begin\n FromSalesHeader.CalcFields(\"Work Description\");\n ToSalesHeader.TransferFields(FromSalesHeader, false);\n+ UpdateShipToAddress(ToSalesHeader);\n UpdateSalesHeaderWhenCopyFromSalesHeader(ToSalesHeader, OldSalesHeader, FromDocType);\n SetReceivedFromCountryCode(FromDocType, ToSalesHeader);\n OnAfterCopySalesHeader(ToSalesHeader, OldSalesHeader, FromSalesHeader, FromDocType);\n"} -{"metadata": {"area": "warehouse", "image_count": 10}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-222488", "base_commit": "34f4bd6914204e9f211b9f09a3b0c3a09954da33", "created_at": "2025-07-30", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137152, "functionName": ["RegisterPutAwayWithBreakBulkFilterShouldRegisterAllLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al\nindex d40ac8d858c1..e83bdf59b1cc 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al\n@@ -4302,6 +4302,63 @@ codeunit 137152 \"SCM Warehouse - Receiving\"\n VerifyWarehouseActivityLineWithBin(Item.\"No.\", Bin[3].Code, Bin[1].Code);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerTrue')]\n+ procedure RegisterPutAwayWithBreakBulkFilterShouldRegisterAllLines()\n+ var\n+ Item: Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ UOM: Record \"Unit of Measure\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ WarehouseEntry: Record \"Warehouse Entry\";\n+ PutAwayPage: TestPage \"Warehouse Put-away\";\n+ ExpectedLinesCount: Integer;\n+ begin\n+ // [SCENARIO 592107] Verify all put away lines are registered, when register a warehouse put away with the break bulk filter set to yes\n+ Initialize();\n+\n+ // [GIVEN] Create Warehouse Employee for location WHITE.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, LocationWhite.Code, true);\n+\n+ // [GIVEN] Create an Item and assign Put-away Unit of Measure Code.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Put-away Unit of Measure Code\", Item.\"Base Unit of Measure\");\n+ Item.Modify(true);\n+\n+ // [GIVEN] Create Unit of Measure and Item Unit of Measure with Qty. per Unit of Measure as 48.\n+ LibraryInventory.CreateUnitOfMeasureCode(UOM);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure, Item.\"No.\", UOM.Code, 48);\n+\n+ // [GIVEN] Create Purchase Order and Post Warehouse Receipt.\n+ CreatePurchaseOrderAndPostWarehouseReceipt(\n+ PurchaseHeader, LocationWhite.Code, Item.\"No.\", LibraryRandom.RandDec(10, 2), UOM.Code);\n+\n+ // [GIVEN] Find Warehouse Put-away\n+ WarehouseActivityLine.SetRange(\"Activity Type\", WarehouseActivityLine.\"Activity Type\"::\"Put-away\");\n+ WarehouseActivityLine.SetRange(\"Source Document\", WarehouseActivityLine.\"Source Document\"::\"Purchase Order\");\n+ WarehouseActivityLine.SetRange(\"Source No.\", PurchaseHeader.\"No.\");\n+ WarehouseActivityLine.FindSet();\n+ ExpectedLinesCount := WarehouseActivityLine.Count();\n+\n+ // [GIVEN] Open Warehouse Put-away page\n+ PutAwayPage.OpenEdit();\n+ PutAwayPage.FILTER.SetFilter(\"No.\", WarehouseActivityLine.\"No.\");\n+\n+ // [GIVEN] Set Break Bulk filter = Yes\n+ PutAwayPage.\"Breakbulk Filter\".SetValue(true);\n+\n+ // [WHEN] Register Warehouse Put-Away.\n+ PutAwayPage.\"&Register Put-away\".Invoke();\n+\n+ // [THEN] Verify Put-Away should be registered and all lines should be posted in Warehouse Entry table\n+ WarehouseEntry.SetRange(\"Entry Type\", WarehouseEntry.\"Entry Type\"::Movement);\n+ WarehouseEntry.SetRange(\"Source Document\", WarehouseEntry.\"Source Document\"::\"P. Order\");\n+ WarehouseEntry.SetRange(\"Source No.\", PurchaseHeader.\"No.\");\n+ Assert.RecordCount(WarehouseEntry, ExpectedLinesCount);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al b/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al\nindex 07db37f9fc83..680830c4c772 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al\n@@ -482,9 +482,17 @@ page 5771 \"Whse. Put-away Subform\"\n \n procedure RegisterPutAwayYesNo()\n var\n+ WhseActivityHeader: Record \"Warehouse Activity Header\";\n WhseActivLine: Record \"Warehouse Activity Line\";\n begin\n- WhseActivLine.Copy(Rec);\n+ WhseActivityHeader.Get(Rec.\"Activity Type\", Rec.\"No.\");\n+ if (Rec.\"Activity Type\"::\"Put-away\" = Rec.\"Activity Type\"::\"Put-away\") and WhseActivityHeader.\"Breakbulk Filter\" then begin\n+ WhseActivLine.SetRange(\"Activity Type\", WhseActivLine.\"Activity Type\"::\"Put-away\");\n+ WhseActivLine.SetRange(\"No.\", Rec.\"No.\");\n+ WhseActivLine.FindSet();\n+ end\n+ else\n+ WhseActivLine.Copy(Rec);\n WhseActivLine.FilterGroup(3);\n WhseActivLine.SetRange(Breakbulk);\n WhseActivLine.FilterGroup(0);\n"} -{"metadata": {"area": "warehouse", "image_count": 14}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-222484", "base_commit": "a60a6b56b858f370ae21d8d0241ed67f72d6202c", "created_at": "2025-07-30", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137260, "functionName": ["RegisterPickWithNoErrorForFEFOLocation"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al\nindex df8ad3bb4d4b..de51c3ce8532 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al\n@@ -47,6 +47,7 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n JournalPostedMsg: Label 'The journal lines were successfully posted.';\n CouldNotRegisterWhseActivityErr: Label 'Could not register Warehouse Activity.';\n OrderToOrderBindingOnSalesLineQst: Label 'Registering the pick will remove the existing order-to-order reservation for the sales order.\\Do you want to continue?';\n+ ILELotNotMatchedErr: Label 'Item Ledger Entry Lot No. %1 should be equal to the first lot with FEFO.', Comment = '%1 - Lot No.';\n \n [Test]\n [HandlerFunctions('WhseItemTrackingLinesPageHandler,RegisterWhseMessageHandler,ConfirmHandler')]\n@@ -2080,6 +2081,77 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n Assert.ExpectedError(StrSubstNo(CannotMatchItemTrackingErr, SalesLine.\"Document No.\", SalesLine.\"Line No.\", SalesLine.\"No.\", SalesLine.Description));\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemTrackingLinesPageHandler,ReservationFromCurrentLineHandler')]\n+ [Scope('OnPrem')]\n+ procedure RegisterPickWithNoErrorForFEFOLocation()\n+ var\n+ Location: Record Location;\n+ Bin: Record Bin;\n+ Item: Record Item;\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ SalesHeader: array[2] of Record \"Sales Header\";\n+ WarehouseShipmentHeader: Record \"Warehouse Shipment Header\";\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ ExpirationDate: Date;\n+ ShipmentBinCode: Code[20];\n+ LotNo: array[2] of Code[10];\n+ begin\n+\n+ // [SCENARIO 572962] No Error when Lot No. LOT0001 is available on inventory, when trying to register pick for item with reservation and item tracking with location set up FEFO\n+ Initialize();\n+\n+ // [GIVEN] Set up Expiration Date for the Lot No.\n+ ExpirationDate := CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', WorkDate());\n+\n+ // [GIVEN] Create Location with pick according to FEFO.\n+ CreateLocationWithPostingSetupAndPickAccordingTOFEFO(Location, ShipmentBinCode);\n+\n+ // [GIVEN] Item with Lot No. tracking.\n+ LibraryInventory.CreateTrackedItem(Item, '', '', CreateItemTrackingCode(false, true, true, false, true));\n+\n+ // [GIVEN] Positive adjustment with Lot = \"X\" and ExpirationDate = D1 , Lot = \"Y\" and ExpirationDate = D2 and D2 > D1.\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, LibraryUtility.GenerateGUID(), '', '');\n+ SelectItemJournalAndPostItemJournalLine(\n+ LotNo[1], Bin.Code, '', Item.\"No.\", Location.Code, '', 1, ExpirationDate,\n+ ItemJournalBatch.\"Template Type\"::Item, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", false);\n+ SelectItemJournalAndPostItemJournalLine(\n+ LotNo[2], Bin.Code, '', Item.\"No.\", Location.Code, '', 1,\n+ CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', ExpirationDate),\n+ ItemJournalBatch.\"Template Type\"::Item, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", false);\n+\n+ // [GIVEN] Create Sales order and reserve the first Lot No. \"LOT0001\" with Expiration Date = D1.\n+ CreateSOAndTrackInventory(SalesHeader[1], Item.\"No.\", Location.Code, 1);\n+\n+ // Create seconf sales order and reserve the second Lot No. \"LOT0002\" with Expiration Date = D2.\n+ CreateSOAndTrackInventory(SalesHeader[2], Item.\"No.\", Location.Code, 1);\n+\n+ // [GIVEN] Create Warehouse Shipment from Sales Order second.\n+ CreateWhseShipmentFromSO(WarehouseShipmentHeader, SalesHeader[2]);\n+\n+ // [WHEN] CreatePick From Warehouse Shipment.\n+ LibraryWarehouse.CreatePick(WarehouseShipmentHeader);\n+\n+ // [WHEN] Register Pick should not fail with error \"Lot No. is not available on inventory\" for the first Lot No. \"LOT0001\" with Expiration Date = D1.\n+ WarehouseActivityLine.SetRange(\"Item No.\", Item.\"No.\");\n+ WarehouseActivityLine.SetRange(\"Action Type\", WarehouseActivityLine.\"Action Type\"::Take);\n+ WarehouseActivityLine.FindFirst();\n+ WarehouseActivityHeader.Get(WarehouseActivityLine.\"Activity Type\", WarehouseActivityLine.\"No.\");\n+ LibraryWarehouse.RegisterWhseActivity(WarehouseActivityHeader);\n+\n+ // [WHEN] Post Warehouse Shipment.\n+ LibraryWarehouse.PostWhseShipment(WarehouseShipmentHeader, false);\n+\n+ // [THEN] Item Ledger Entry for the first Lot No. \"LOT0001\" with Expiration Date = D1 should be created.\n+ ItemLedgerEntry.SetRange(\"Entry Type\", ItemLedgerEntry.\"Entry Type\"::Sale);\n+ ItemLedgerEntry.SetRange(\"Item No.\", Item.\"No.\");\n+ ItemLedgerEntry.FindFirst();\n+ Assert.AreEqual(LotNo[1], ItemLedgerEntry.\"Lot No.\", StrSubstNo(ILELotNotMatchedErr, LotNo[1]));\n+ end;\n+\n local procedure Initialize()\n var\n InventorySetup: Record \"Inventory Setup\";\n@@ -3485,6 +3557,19 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n LibrarySales.UndoSalesShipmentLine(SalesShipmentLine);\n end;\n \n+ local procedure CreateSOAndTrackInventory(var SalesHeader: Record \"Sales Header\"; ItemNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal)\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, LibrarySales.CreateCustomerNo());\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, ItemNo, Quantity);\n+ SalesLine.Validate(\"Location Code\", LocationCode);\n+ LibraryVariableStorage.Enqueue(SalesLine.Quantity);\n+ SalesLine.Modify(true);\n+ SalesLine.ShowReservation();\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(ConfirmMessage: Text[1024]; var Reply: Boolean)\n@@ -3687,6 +3772,14 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n ProductionJournal.Post.Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ReservationFromCurrentLineHandler(var Reservation: TestPage Reservation)\n+ begin\n+ Reservation.\"Reserve from Current Line\".Invoke();\n+ Reservation.OK().Invoke();\n+ end;\n+\n local procedure AssignLotNos(var ItemTrackingLines: TestPage \"Item Tracking Lines\")\n var\n LinesToProcess: Integer;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al\nindex 06bc64083218..cc14d68c515b 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al\n@@ -2044,6 +2044,7 @@ codeunit 7307 \"Whse.-Activity-Register\"\n if Item.\"Reserved Qty. on Inventory\" > 0 then begin\n xReservedQty := Item.\"Reserved Qty. on Inventory\";\n WhseActivityItemTrackingSetup.CopyTrackingFromWhseActivityLine(WhseActivLine);\n+ RemoveNonSpecificreservations(WhseActivLine, WhseItemTrackingSetup, QtyToRelease);\n LateBindingMgt.ReleaseForReservation(\n WhseActivLine.\"Item No.\", WhseActivLine.\"Variant Code\", WhseActivLine.\"Location Code\",\n WhseActivityItemTrackingSetup, QtyToRelease);\n@@ -2127,6 +2128,40 @@ codeunit 7307 \"Whse.-Activity-Register\"\n until WarehouseActivityLine.Next() = 0;\n end;\n \n+ local procedure RemoveNonSpecificreservations(WhseActivLine: Record \"Warehouse Activity Line\"; WhseItemTrackingSetup: Record \"Item Tracking Setup\"; QtyToRelease: Decimal)\n+ var\n+ ReservationEntry: Record \"Reservation Entry\";\n+ SalesLine: Record \"Sales Line\";\n+ QtyToPick: Decimal;\n+ begin\n+ if not WhseItemTrackingSetup.TrackingRequired() then\n+ exit;\n+ if not (WhseActivLine.\"Source Type\" = Database::\"Sales Line\") then\n+ exit;\n+\n+ QtyToPick := QtyToRelease;\n+ SalesLine.Get(WhseActivLine.\"Source Subtype\", WhseActivLine.\"Source No.\", WhseActivLine.\"Source Line No.\");\n+ ReservationEntry.SetSourceFilter(WhseActivLine.\"Source Type\", WhseActivLine.\"Source Subtype\", WhseActivLine.\"Source No.\", WhseActivLine.\"Source Line No.\", true);\n+ ReservationEntry.SetRange(Positive, false);\n+ if ReservationEntry.FindSet() then\n+ repeat\n+ DeleteNonSpecificReservationEntries(ReservationEntry, SalesLine, QtyToPick);\n+ until (ReservationEntry.Next() = 0) or (QtyToPick >= 0);\n+ end;\n+\n+ local procedure DeleteNonSpecificReservationEntries(ReservationEntry: Record \"Reservation Entry\"; SalesLine: Record \"Sales Line\"; var QtyToPick: Decimal)\n+ var\n+ ReservationManagement: Codeunit \"Reservation Management\";\n+ begin\n+ if ReservationEntry.TrackingExists() then\n+ exit;\n+\n+ ReservationManagement.SetReservSource(SalesLine);\n+ ReservationManagement.DeleteReservEntries(false, ReservationEntry.\"Quantity (Base)\");\n+ QtyToPick += ReservationEntry.\"Quantity (Base)\"\n+ end;\n+\n+\n [IntegrationEvent(false, false)]\n local procedure OnBeforeCode(var WarehouseActivityLine: Record \"Warehouse Activity Line\")\n begin\n"} -{"metadata": {"area": "inventory", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220314", "base_commit": "96c641e94b94056dda25b90907bef9b77622e31d", "created_at": "2025-07-08", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137275, "functionName": ["ItemReclassJournalUnitOfMeasureUpdatedWhenItemChanged"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al\nindex 436478abba92..b3bf0372e39c 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al\n@@ -1800,6 +1800,54 @@ codeunit 137275 \"SCM Inventory Journals\"\n Codeunit.Run(Codeunit::\"Item Jnl.-Post Batch\", ItemJournalLine);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure ItemReclassJournalUnitOfMeasureUpdatedWhenItemChanged()\n+ var\n+ Item: array[2] of Record Item;\n+ UnitOfMeasure: array[2] of Record \"Unit of Measure\";\n+ ItemUnitOfMeasure: array[2] of Record \"Item Unit of Measure\";\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemReclassJournal: TestPage \"Item Reclass. Journal\";\n+ i: Integer;\n+ begin\n+ // [SCENARIO 581983] Unit of Measure Code should be updated automatically when Item No. is changed in Item Reclassification Journal\n+ Initialize();\n+\n+ // [GIVEN] Create two items with different base unit of measure codes\n+ for i := 1 to 2 do begin\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure[i]);\n+ LibraryInventory.CreateItem(Item[i]);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure[i], Item[i].\"No.\", UnitOfMeasure[i].Code, 1);\n+ Item[i].Validate(\"Base Unit of Measure\", UnitOfMeasure[i].Code);\n+ Item[i].Modify(true);\n+ end;\n+\n+ // [GIVEN] Setup Item Reclassification Journal template and batch\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Transfer);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type::Transfer, ItemJournalTemplate.Name);\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+\n+ // [WHEN] Open Item Reclassification Journal page\n+ ItemReclassJournal.OpenEdit();\n+ ItemReclassJournal.CurrentJnlBatchName.SetValue(ItemJournalBatch.Name);\n+\n+ // [WHEN] Enter first item no. and verify unit of measure is set\n+ ItemReclassJournal.\"Item No.\".SetValue(Item[1].\"No.\");\n+ ItemReclassJournal.\"Unit of Measure Code\".AssertEquals(UnitOfMeasure[1].Code);\n+\n+ // [WHEN] Change item no. to second item\n+ ItemReclassJournal.\"Item No.\".SetValue(Item[2].\"No.\");\n+\n+ // [THEN] Verify unit of measure code is updated to second item's base unit of measure\n+ ItemReclassJournal.\"Unit of Measure Code\".AssertEquals(UnitOfMeasure[2].Code);\n+\n+ // [THEN] Verify no error occurs when changing item number\n+ // This test verifies the fix for the bug where changing Item No. with different Unit of Measure Codes caused validation errors\n+ ItemReclassJournal.Close();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\nindex fb9253b7ae77..ad41ac368015 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n@@ -76,6 +76,7 @@ table 83 \"Item Journal Line\"\n if \"Item No.\" <> xRec.\"Item No.\" then begin\n \"Variant Code\" := '';\n \"Bin Code\" := '';\n+ \"Unit of Measure Code\" := '';\n if CurrFieldNo <> 0 then begin\n GetItem();\n if Item.IsInventoriableType() then\n"} -{"metadata": {"area": "sales", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-214926", "base_commit": "2ed9a2df09bf29573bbaf9e087313bec188ce69b", "created_at": "2025-05-07", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134389, "functionName": ["CheckCustomerCardStatisticsTotalOnFactBox"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\nindex 12e3e3ea3927..4ddc570573df 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n@@ -28,6 +28,7 @@ codeunit 134389 \"ERM Customer Statistics\"\n FieldIsNotHiddenErr: Label 'Field is hidden';\n EntryNoMustMatchErr: Label 'Entry No. must match.';\n PaymentsLCYAndAmountLCYMustMatchErr: Label 'Payemnts (LCY) and Amount (LCY) must match.';\n+ CustomerCardFactboxTotalErr: Label 'Customer card factbox total is not Correct';\n \n [Test]\n [Scope('OnPrem')]\n@@ -964,6 +965,44 @@ codeunit 134389 \"ERM Customer Statistics\"\n CustomerCard.Close();\n end;\n \n+ [Test]\n+ [HandlerFunctions('GetShipmentLinesPageHandler')]\n+ procedure CheckCustomerCardStatisticsTotalOnFactBox()\n+ var\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ // [SCENARIO 574648] Check Customer Card Statistics Total On FactBox When Sales Order Only Shiped and Sales Invoice \n+ // Created By GetShipmentLines without Posting.\n+ Initialize();\n+\n+ // [GIVEN] Created New Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Created New Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Created Item Inventory By Posting Item Journal With Qty 10.\n+ CreateItemInventory(Item, 10);\n+\n+ // [WHEN] Created New Sales Order With Qty 10.\n+ CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\", WorkDate());\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", 10);\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandDec(1000, 0));\n+ SalesLine.Modify(true);\n+\n+ // [WHEN] \"SO\" Post invoked with \"Shipped\" selected.\n+ LibrarySales.PostSalesDocument(SalesHeader, true, false);\n+\n+ // [WHEN] Create New Sales Invoice And Get Shipment Line Through GetShipmentLines.\n+ CreateAndReleaseSalesInvoiceUsingGetShipmentLines(SalesHeader.\"Sell-to Customer No.\");\n+\n+ // [THEN] Check Customer Card Statistics Total is Equal To SalesLine.\"Amount Including VAT\" and Not Multiply.\n+ Assert.AreEqual(SalesLine.\"Amount Including VAT\", Customer.GetTotalAmountLCY(), CustomerCardFactboxTotalErr);\n+ end;\n+\n local procedure Initialize()\n var\n Currency: Record Currency;\n@@ -1400,6 +1439,31 @@ codeunit 134389 \"ERM Customer Statistics\"\n DetailedCustLedgEntry.Insert();\n end;\n \n+ local procedure CreateAndReleaseSalesInvoiceUsingGetShipmentLines(CustomerNo: Code[20])\n+ var\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, CustomerNo);\n+ SalesLine.Validate(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.Validate(\"Document No.\", SalesHeader.\"No.\");\n+ LibrarySales.GetShipmentLines(SalesLine);\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+ end;\n+\n+ local procedure CreateItemInventory(var Item: Record Item; Qty: Decimal)\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Item);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type::Item, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", Qty);\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerYes(Message: Text; var Response: Boolean)\n@@ -1450,5 +1514,11 @@ codeunit 134389 \"ERM Customer Statistics\"\n CreditLimitNotification.CreditLimitDetails.OverdueBalance.AssertEquals(Customer.\"Balance Due (LCY)\");\n CreditLimitNotification.CreditLimitDetails.\"Credit Limit (LCY)\".AssertEquals(Customer.\"Credit Limit (LCY)\");\n end;\n+\n+ [ModalPageHandler]\n+ procedure GetShipmentLinesPageHandler(var GetShipmentLines: TestPage \"Get Shipment Lines\")\n+ begin\n+ GetShipmentLines.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\nindex ebeb6ca13f79..1fcc2d218ab3 100644\n--- a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n@@ -2353,6 +2353,8 @@ table 18 Customer\n AdditionalAmountLCY: Decimal;\n IsHandled: Boolean;\n TotalAmountLCY: Decimal;\n+ ShippedFromOrderLCY: Decimal;\n+ ShippedOutstandingInvoicesLCY: Decimal;\n begin\n IsHandled := false;\n OnBeforeGetTotalAmountLCYCommon(Rec, AdditionalAmountLCY, IsHandled);\n@@ -2362,10 +2364,13 @@ table 18 Customer\n SalesOutstandingAmountFromShipment := SalesLine.OutstandingInvoiceAmountFromShipment(\"No.\");\n InvoicedPrepmtAmountLCY := GetInvoicedPrepmtAmountLCY();\n RetRcdNotInvAmountLCY := GetReturnRcdNotInvAmountLCY();\n+ ShippedFromOrderLCY := GetShippedFromOrderLCYAmountLCY();\n+ ShippedOutstandingInvoicesLCY := GetShippedOutstandingInvoicesAmountLCY();\n \n TotalAmountLCY :=\n- \"Balance (LCY)\" + \"Outstanding Orders (LCY)\" + \"Shipped Not Invoiced (LCY)\" + \"Outstanding Invoices (LCY)\" +\n- SalesOutstandingAmountFromShipment - InvoicedPrepmtAmountLCY - RetRcdNotInvAmountLCY + AdditionalAmountLCY;\n+ \"Balance (LCY)\" + \"Outstanding Orders (LCY)\" + (\"Shipped Not Invoiced (LCY)\" - ShippedFromOrderLCY) +\n+ (\"Outstanding Invoices (LCY)\" - ShippedOutstandingInvoicesLCY) + SalesOutstandingAmountFromShipment -\n+ InvoicedPrepmtAmountLCY - RetRcdNotInvAmountLCY + AdditionalAmountLCY;\n \n OnAfterGetTotalAmountLCYCommon(Rec, TotalAmountLCY);\n exit(TotalAmountLCY);\n@@ -3451,6 +3456,33 @@ table 18 Customer\n OnAfterGetVATRegistrationNo(Rec, VATRegNo);\n end;\n \n+ procedure GetShippedOutstandingInvoicesAmountLCY(): Decimal\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ SalesLine.SetRange(\"Bill-to Customer No.\", \"No.\");\n+ SalesLine.SetRange(\"Document Type\", SalesLine.\"Document Type\"::Invoice);\n+ SalesLine.SetFilter(\"Shipment No.\", '<>%1', '');\n+ SalesLine.SetFilter(\"Shipment Line No.\", '<>%1', 0);\n+ SalesLine.CalcSums(\"Outstanding Amount (LCY)\");\n+ exit(SalesLine.\"Outstanding Amount (LCY)\");\n+ end;\n+\n+ procedure GetShippedFromOrderLCYAmountLCY(): Decimal\n+ var\n+ SalesShippedNotInvoicedLCY: Query \"Sales Shipped Not Invoiced LCY\";\n+ ShippedFromOrderLCY: Decimal;\n+ begin\n+ ShippedFromOrderLCY := 0;\n+ SalesShippedNotInvoicedLCY.SetRange(BillToCustomerNo, \"No.\");\n+ SalesShippedNotInvoicedLCY.SetFilter(OrderNo, '<>%1', '');\n+ SalesShippedNotInvoicedLCY.SetFilter(OrderLineNo, '<>%1', 0);\n+ if SalesShippedNotInvoicedLCY.Open() then\n+ while SalesShippedNotInvoicedLCY.Read() do\n+ ShippedFromOrderLCY += SalesShippedNotInvoicedLCY.ShippedNotInvoicedLCY;\n+ exit(ShippedFromOrderLCY);\n+ end;\n+\n [InherentPermissions(PermissionObjectType::TableData, Database::\"My Customer\", 'rm')]\n local procedure UpdateMyCustomer(CallingFieldNo: Integer)\n var\ndiff --git a/App/Layers/W1/BaseApp/Sales/Customer/SalesShippedNotInvoicedLCY.Query.al b/App/Layers/W1/BaseApp/Sales/Customer/SalesShippedNotInvoicedLCY.Query.al\nnew file mode 100644\nindex 000000000000..3640fed3530f\n--- /dev/null\n+++ b/App/Layers/W1/BaseApp/Sales/Customer/SalesShippedNotInvoicedLCY.Query.al\n@@ -0,0 +1,31 @@\n+namespace Microsoft.Sales.Customer;\n+\n+using Microsoft.Sales.Document;\n+using Microsoft.Sales.History;\n+\n+query 115 \"Sales Shipped Not Invoiced LCY\"\n+{\n+ Caption = 'Sales Shipped Not Invoiced (LCY)';\n+ QueryType = Normal;\n+ DataAccessIntent = ReadOnly;\n+\n+ elements\n+ {\n+ dataitem(SalesShipmentLine; \"Sales Shipment Line\")\n+ {\n+ column(BillToCustomerNo; \"Bill-to Customer No.\") { }\n+ column(OrderNo; \"Order No.\") { }\n+ column(OrderLineNo; \"Order Line No.\") { }\n+ filter(BillToCustomerNoFilter; \"Bill-to Customer No.\") { }\n+ filter(OrderNoFilter; \"Order No.\") { }\n+ filter(OrderLineNoFilter; \"Order Line No.\") { }\n+ dataitem(SalesLine; \"Sales Line\")\n+ {\n+ DataItemTableFilter = \"Document Type\" = const(Order);\n+ DataItemLink = \"Document No.\" = SalesShipmentLine.\"Order No.\",\n+ \"Line No.\" = SalesShipmentLine.\"Order Line No.\";\n+ column(ShippedNotInvoicedLCY; \"Shipped Not Invoiced (LCY)\") { }\n+ }\n+ }\n+ }\n+}\n\\ No newline at end of file\n"} -{"metadata": {"area": "inventory", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-215972", "base_commit": "09f92492d0cfe5dbba4cebef931acf5b33578799", "created_at": "2025-05-19", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137140, "functionName": ["ReservationShouldNotPossibleOnTransferOrderIfItemReserveSetAsNever"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al\nindex 6e9a6abd3cd6..3253f5221abc 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al\n@@ -41,6 +41,7 @@ codeunit 137140 \"SCM Inventory Documents\"\n SpecialEquipmentCodeShouldBeVisibleErr: Label 'Special Equipment Code should be visible.';\n DueDateBeforeWorkDateMsg: Label 'is before work date';\n TransferOrderErr: Label 'Transfer Order has not been posted successfully.';\n+ ReserveMustNotBeNeverErr: Label 'Reserve must not be Never';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2069,6 +2070,44 @@ codeunit 137140 \"SCM Inventory Documents\"\n Assert.IsTrue(DirectTransHeader.FindFirst(), TransferOrderErr);\n end;\n \n+ [Test]\n+ procedure ReservationShouldNotPossibleOnTransferOrderIfItemReserveSetAsNever()\n+ var\n+ Item: Record Item;\n+ LocationA: Record Location;\n+ LocationB: Record Location;\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ begin\n+ // [SCENARIO 578318] Reservation of an Item possible with in a Transfer order if the item is set to reserve=never\n+ Initialize();\n+\n+ // [GIVEN] Create Two locations: \"A\" and \"B\" without Warehouse Setup\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(LocationA);\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(LocationB);\n+\n+ // [GIVEN] Create an Item with Reserve = Never\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(Reserve, Item.Reserve::Never);\n+ Item.Modify();\n+\n+ // [GIVEN] Create and Post Item Journal Line\n+ CreateAndPostItemJournalLine(Item.\"No.\", LocationA.Code, '');\n+\n+ // [GIVEN] Create a Direct Transfer Order from Location \"A\" to location \"B\" and Reserve From Inventory\n+ CreateDirectTransferHeader(TransferHeader, LocationA.code, LocationB.Code);\n+ TransferHeader.Validate(\"Posting Date\", WorkDate());\n+ TransferHeader.Modify(true);\n+\n+ // [WHEN] Create transfer line with Item with Reserve set as Never and Show Reservation\n+ LibraryWarehouse.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", 10);\n+ asserterror TransferLine.ShowReservation();\n+\n+ // [THEN] Verify Reserve must not be Never error\n+ Assert.ExpectedErrorCode('TestField');\n+ Assert.ExpectedError(ReserveMustNotBeNeverErr);\n+ end;\n+\n local procedure PostWhseShipmentFromTO(DocumentNo: Code[20])\n var\n WhseShipmentLine: Record \"Warehouse Shipment Line\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al\nindex 9ab054c5f5c3..d012f240926e 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al\n@@ -1592,6 +1592,8 @@ table 5741 \"Transfer Line\"\n exit;\n \n TestField(\"Item No.\");\n+ Item.Get(\"Item No.\");\n+ Item.TestField(Reserve);\n Clear(Reservation);\n OptionNumber := StrMenu(Text011);\n if OptionNumber > 0 then begin\n"} -{"metadata": {"area": "inventory", "image_count": 20}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-216057", "base_commit": "eb4658a742a755d408f23b5f96668caaba44842b", "created_at": "2025-05-20", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137045, "functionName": ["NoDuplicateSurplusReservationEntriesOnRecalculateRequisitionWorksheet"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\nindex 70fa87435bd0..c841fa564264 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n@@ -1038,6 +1038,62 @@ codeunit 137045 \"SCM Bugfixes\"\n Assert.AreEqual(4, ActualCount, AssemblyCommentLineErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemTrackingLinesModalPageHandler')]\n+ procedure NoDuplicateSurplusReservationEntriesOnRecalculateRequisitionWorksheet()\n+ var\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Vendor: Record Vendor;\n+ RequisitionLine: Record \"Requisition Line\";\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ NewPurchOrderChoice: Option \" \",\"Make Purch. Orders\",\"Make Purch. Orders & Print\",\"Copy to Req. Wksh\";\n+ Qty: Decimal;\n+ begin\n+ // [SCENARIO 575040] When recalculating an item in a requisition or planning worksheet with no planning results lead to wrong surplus entries in the reservation table whic are added to the item tracking page.\n+ Initialize();\n+\n+ // [GIVEN] Created Lot Tracked Item with Reordering Policy:Lot-for-Lot.\n+ CreateTrackedItem(Item);\n+\n+ // [GIVEN] Created Sales Order with 1 Item and 100 quantity.\n+ Qty := 100;\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, '');\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", Qty);\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+\n+ // [GIVEN] Calculate requisition plan\n+ CalculateRequisitionPlan(RequisitionWkshName, Item);\n+\n+ // [GIVEN] Find Requisition Line\n+ FindRequisitionLine(RequisitionLine, RequisitionWkshName, RequisitionLine.\"Action Message\"::New);\n+\n+ // [GIVEN] Update Vendor No., Planning Flexibility with None and change the quantity to 150\n+ RequisitionLine.Validate(\"Vendor No.\", LibraryPurchase.CreateVendor(Vendor));\n+ RequisitionLine.Validate(\"Planning Flexibility\", RequisitionLine.\"Planning Flexibility\"::None);\n+ RequisitionLine.Validate(Quantity, 150);\n+ RequisitionLine.Modify(true);\n+\n+ // [GIVEN] Assign the Lot On Item tracking Line\n+ RequisitionLine.OpenItemTrackingLines();\n+\n+ // [GIVEN] Set \"Accept Action Message\" on all Requisition lines.\n+ LibraryPlanning.CarryOutPlanWksh(RequisitionLine, 0, NewPurchOrderChoice::\"Make Purch. Orders\", 0, 0, '', '', '', '');\n+\n+ // [GIVEN] Check at reservation entries for Purchase Order created, only 2 reservation entries should exist for the PO\n+ PurchaseHeader.SetRange(\"Buy-from Vendor No.\", Vendor.\"No.\");\n+ PurchaseHeader.FindLast();\n+ AssertReservationEntryCount(PurchaseHeader, 2);\n+\n+ // [WHEN] Calculate Plan again for same item from requisition worksheet\n+ CalculateRequisitionPlan(RequisitionWkshName, Item);\n+\n+ // [THEN] After recalculation, a new reservation entry should NOT be created for the PO\n+ AssertReservationEntryCount(PurchaseHeader, 2);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1740,6 +1796,15 @@ codeunit 137045 \"SCM Bugfixes\"\n CalculatePlanPlanWksh.RunModal();\n end;\n \n+ local procedure AssertReservationEntryCount(PurchaseHeader: Record \"Purchase Header\"; ExpectedCount: Integer)\n+ var\n+ ReservationEntry: Record \"Reservation Entry\";\n+ begin\n+ ReservationEntry.SetRange(\"Source Type\", Database::\"Purchase Line\");\n+ ReservationEntry.SetRange(\"Source ID\", PurchaseHeader.\"No.\");\n+ Assert.RecordCount(ReservationEntry, ExpectedCount);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListModalPageHandler(var ContactLookup: Page \"Contact List\"; var Response: Action)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\nindex ca1799815e42..c1b41b1585bc 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n@@ -11,6 +11,7 @@ using Microsoft.Inventory.Journal;\n using Microsoft.Inventory.Ledger;\n using Microsoft.Inventory.Location;\n using Microsoft.Inventory.Requisition;\n+using Microsoft.Purchases.Document;\n using Microsoft.Sales.Document;\n using Microsoft.Utilities;\n using Microsoft.Warehouse.Activity;\n@@ -1021,6 +1022,10 @@ table 337 \"Reservation Entry\"\n CreateReservEntry.TransferReservEntry(\n SourceType, SourceSubtype, SourceID, SourceBatchName, SourceProdOrderLine, SourceRefNo,\n QtyPerUOM, OldReservEntry, TransferQty);\n+\n+ if (OldReservEntry.\"Reservation Status\" = OldReservEntry.\"Reservation Status\"::Prospect) and (SourceType = Database::\"Purchase Line\") and (SourceSubtype in [1, 2]) then\n+ ChangeReservationStatusToSurplus(SourceType, SourceSubtype, SourceID, SourceRefNo);\n+\n OnTransferReservationsOnAfterSecondOldReservEntryLoop(OldReservEntry, NewReservEntry, SourceType, SourceSubtype, SourceID);\n until (OldReservEntry.Next() = 0) or (TransferQty = 0);\n end;\n@@ -1125,6 +1130,18 @@ table 337 \"Reservation Entry\"\n OnUpdateSourceCost(Rec, UnitCost);\n end;\n \n+ local procedure ChangeReservationStatusToSurplus(SourceType: Integer; SourceSubtype: Option; SourceID: Code[20]; SourceRefNo: Integer)\n+ var\n+ NewReservationEntry: Record \"Reservation Entry\";\n+ begin\n+ NewReservationEntry.SetSourceFilter(SourceType, SourceSubtype, SourceID, SourceRefNo, true);\n+ NewReservationEntry.SetRange(\"Reservation Status\", NewReservationEntry.\"Reservation Status\"::Prospect);\n+ if NewReservationEntry.FindFirst() then begin\n+ NewReservationEntry.\"Reservation Status\" := NewReservationEntry.\"Reservation Status\"::Surplus;\n+ NewReservationEntry.Modify(true);\n+ end;\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterCopyTrackingFromItemLedgEntry(var ReservationEntry: Record \"Reservation Entry\"; ItemLedgerEntry: Record \"Item Ledger Entry\")\n begin\n"} -{"metadata": {"area": "finance", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-216572", "base_commit": "74df6483b659ca304abb6f7adda003cda1424db7", "created_at": "2025-05-26", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134227, "functionName": ["CheckDimensionOfRecurringJournalImportAllocationFromAllocationAccount"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\nindex ff710ce5b0e2..aa89a458bd93 100644\n--- a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n@@ -19,6 +19,7 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n LibraryPurchase: Codeunit \"Library - Purchase\";\n LibrarySales: Codeunit \"Library - Sales\";\n+ LibraryDimension: Codeunit \"Library - Dimension\";\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n GenJnlDocType: Enum \"Gen. Journal Document Type\";\n GenJnlAccountType: Enum \"Gen. Journal Account Type\";\n@@ -31,6 +32,7 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n SkippedLineMsg: Label 'One or more lines has not been posted because the amount is zero.';\n DocumentOutOfBalanceErr: Label 'Document No. %1 is out of balance', Locked = true;\n AllocAccountImportWrongAccTypeErr: Label 'Import from Allocation Account is only allowed for G/L Account Destination account type.', Locked = true;\n+ AllocationDimensionErr: Label 'Allocation dimension is not correct';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1298,6 +1300,48 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n \n end;\n \n+ [Test]\n+ [HandlerFunctions('HandleEditDimensionSetEntriesPage,AllocationAccountListPageHandler,ConfirmHandlerYes')]\n+ procedure CheckDimensionOfRecurringJournalImportAllocationFromAllocationAccount()\n+ var\n+ AllocationAccount: Record \"Allocation Account\";\n+ FirstDimensionValue: Record \"Dimension Value\";\n+ GenJnlAllocation: Record \"Gen. Jnl. Allocation\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ SecondDimensionValue: Record \"Dimension Value\";\n+ GLAccounts: array[2] of Record \"G/L Account\";\n+ AllocationShares: array[2] of Decimal;\n+ DimensionSetID: array[2] of Integer;\n+ begin\n+ // [SCENARIO 579186] In Recurring General Journals Import from Allocation Accounts does not import dimensions.\n+ Initialize();\n+\n+ // [GIVEN] Create Recurring General Journal Batch.\n+ CreateRecurringGenJournalBatch(GenJournalBatch);\n+\n+ // [GIVEN] Create Recurring Journal with a line.\n+ CreateRecurringJnlLine(GenJournalLine, GenJournalBatch, WorkDate(), 0D, LibraryRandom.RandInt(10));\n+\n+ // [GIVEN] Create allocation for general journal line.\n+ LibraryERM.CreateGenJnlAllocation(GenJnlAllocation, GenJournalLine.\"Journal Template Name\", GenJournalLine.\"Journal Batch Name\", GenJournalLine.\"Line No.\");\n+\n+ // [GIVEN] Dimension With Value.\n+ CreateDimensionsWithValues(FirstDimensionValue, SecondDimensionValue);\n+\n+ // [GIVEN] Allocation Account \"XXX\" with 2 lines exists for different G/L Accounts and different Allocation Shares with Dimension.\n+ CreateAllocationAccountWithTwoGLAccLines(AllocationAccount, GLAccounts, AllocationShares, FirstDimensionValue, SecondDimensionValue, DimensionSetID);\n+\n+ // [WHEN] Invoke Import from Allocation Account. Handler chooses Allocation Account \"XXX\" in lookup\n+ LibraryVariableStorage.Enqueue(AllocationAccount.\"No.\");\n+ GenJnlAllocation.ChooseAndImportFromAllocationAccount();\n+ // UI Handled by handler\n+\n+ // [THEN] There are 2 Gen Journal Allocations with the same Dimension as in Allocation Account\n+ VerifyGenJnlAllocationDimension(GenJnlAllocation, GenJournalLine, GLAccounts[1], DimensionSetID[1]);\n+ VerifyGenJnlAllocationDimension(GenJnlAllocation, GenJournalLine, GLAccounts[2], DimensionSetID[2]);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"ERM PostRecurringJournal\");\n@@ -1769,6 +1813,79 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n VendorLedgerEntry.TestField(\"Due Date\", PostingDate + 1);\n end;\n \n+ local procedure CreateDimensionsWithValues(var FirstDimensionValue: Record \"Dimension Value\"; var SecondDimensionValue: Record \"Dimension Value\")\n+ var\n+ Dimension: Record Dimension;\n+ begin\n+ LibraryDimension.CreateDimension(Dimension);\n+ LibraryDimension.CreateDimensionValue(FirstDimensionValue, Dimension.Code);\n+ LibraryDimension.CreateDimensionValue(SecondDimensionValue, Dimension.Code);\n+ end;\n+\n+ local procedure CreateAllocationAccountWithTwoGLAccLines(var AllocationAccount: Record \"Allocation Account\"; var GLAccounts: array[2] of Record \"G/L Account\"; var AllocationShares: array[2] of Decimal; FirstDimensionValue: Record \"Dimension Value\"; SecondDimensionValue: Record \"Dimension Value\"; var DimensionSetID: array[2] of Integer)\n+ var\n+ AllocAccountDistribution: Record \"Alloc. Account Distribution\";\n+ AllocationAccountPage: TestPage \"Allocation Account\";\n+ FixedAllocationAccountCode: Code[20];\n+ begin\n+ FixedAllocationAccountCode := CreateAllocationAccountWithFixedDistribution(AllocationAccountPage);\n+ AddGLDestinationAccountForFixedDistributionWithDimension(AllocationAccountPage, GLAccounts[1]);\n+ AllocationShares[1] := LibraryRandom.RandDecInRange(1, 100, 2);\n+ AllocationAccountPage.FixedAccountDistribution.Share.SetValue(AllocationShares[1]);\n+ SetDimensionToCurrentVariableLine(AllocationAccountPage, FirstDimensionValue);\n+\n+ AllocAccountDistribution.SetRange(\"Allocation Account No.\", FixedAllocationAccountCode);\n+ AllocAccountDistribution.SetRange(\"Account Type\", AllocAccountDistribution.\"Account Type\"::Fixed);\n+ AllocAccountDistribution.SetRange(\"Destination Account Number\", GLAccounts[1].\"No.\");\n+ AllocAccountDistribution.FindFirst();\n+ DimensionSetID[1] := AllocAccountDistribution.\"Dimension Set ID\";\n+\n+ AllocationAccountPage.FixedAccountDistribution.New();\n+ AddGLDestinationAccountForFixedDistributionWithDimension(AllocationAccountPage, GLAccounts[2]);\n+ AllocationShares[2] := LibraryRandom.RandDecInRange(1, 100, 2);\n+ AllocationAccountPage.FixedAccountDistribution.Share.SetValue(AllocationShares[2]);\n+ SetDimensionToCurrentVariableLine(AllocationAccountPage, SecondDimensionValue);\n+\n+ AllocAccountDistribution.Reset();\n+ AllocAccountDistribution.SetRange(\"Allocation Account No.\", FixedAllocationAccountCode);\n+ AllocAccountDistribution.SetRange(\"Account Type\", AllocAccountDistribution.\"Account Type\"::Fixed);\n+ AllocAccountDistribution.SetRange(\"Destination Account Number\", GLAccounts[2].\"No.\");\n+ AllocAccountDistribution.FindFirst();\n+ AllocationAccountPage.FixedAccountDistribution.GoToRecord(AllocAccountDistribution);\n+ DimensionSetID[2] := AllocAccountDistribution.\"Dimension Set ID\";\n+\n+ AllocationAccountPage.Close();\n+\n+ AllocationAccount.Get(FixedAllocationAccountCode);\n+ end;\n+\n+ local procedure SetDimensionToCurrentVariableLine(var AllocationAcccount: TestPage \"Allocation Account\"; var DimensionValue: Record \"Dimension Value\")\n+ begin\n+ LibraryVariableStorage.Enqueue(DimensionValue.SystemId);\n+ AllocationAcccount.FixedAccountDistribution.Dimensions.Invoke();\n+ end;\n+\n+ local procedure AddGLDestinationAccountForFixedDistributionWithDimension(var AllocationAccountPage: TestPage \"Allocation Account\"; var GLAccount: Record \"G/L Account\")\n+ var\n+ DummyAllocAccountDistribution: Record \"Alloc. Account Distribution\";\n+ begin\n+ if GLAccount.\"No.\" = '' then\n+ GLAccount.Get(LibraryERM.CreateGLAccountNoWithDirectPosting());\n+\n+ AllocationAccountPage.FixedAccountDistribution.\"Destination Account Type\".SetValue(DummyAllocAccountDistribution.\"Destination Account Type\"::\"G/L Account\");\n+ AllocationAccountPage.FixedAccountDistribution.\"Destination Account Number\".SetValue(GLAccount.\"No.\");\n+ end;\n+\n+ local procedure VerifyGenJnlAllocationDimension(GenJnlAllocation: Record \"Gen. Jnl. Allocation\"; GenJournalLine: Record \"Gen. Journal Line\"; GLAccount: Record \"G/L Account\"; DimensionSetID: Integer)\n+ begin\n+ GenJnlAllocation.SetRange(\"Journal Template Name\", GenJournalLine.\"Journal Template Name\");\n+ GenJnlAllocation.SetRange(\"Journal Batch Name\", GenJournalLine.\"Journal Batch Name\");\n+ GenJnlAllocation.SetRange(\"Journal Line No.\", GenJournalLine.\"Line No.\");\n+ GenJnlAllocation.SetRange(\"Account No.\", GLAccount.\"No.\");\n+ GenJnlAllocation.FindFirst();\n+ Assert.AreEqual(GenJnlAllocation.\"Dimension Set ID\", DimensionSetID, AllocationDimensionErr);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean)\n@@ -1821,5 +1938,19 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n NameValueBuffer.ID := LibraryUtility.GetNewRecNo(NameValueBuffer, NameValueBuffer.FieldNo(ID));\n NameValueBuffer.Insert();\n end;\n+\n+ [ModalPageHandler]\n+ procedure HandleEditDimensionSetEntriesPage(var EditDimensionSetEntriesPage: TestPage \"Edit Dimension Set Entries\")\n+ var\n+ DimensionValue: Record \"Dimension Value\";\n+ DimensionValueSystemId: Text;\n+ begin\n+ DimensionValueSystemId := LibraryVariableStorage.DequeueText();\n+ DimensionValue.GetBySystemId(DimensionValueSystemId);\n+ EditDimensionSetEntriesPage.New();\n+ EditDimensionSetEntriesPage.\"Dimension Code\".SetValue(DimensionValue.\"Dimension Code\");\n+ EditDimensionSetEntriesPage.DimensionValueCode.SetValue(DimensionValue.Code);\n+ EditDimensionSetEntriesPage.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al\nindex 130b3e0f3456..7a287e4fb7f1 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al\n@@ -669,6 +669,10 @@ table 221 \"Gen. Jnl. Allocation\"\n begin\n Rec.Validate(\"Account No.\", AllocAccountDistribution.\"Destination Account Number\");\n Rec.Validate(\"Allocation %\", AllocAccountDistribution.Percent);\n+ Rec.Validate(\"Shortcut Dimension 1 Code\", AllocAccountDistribution.\"Global Dimension 1 Code\");\n+ Rec.Validate(\"Shortcut Dimension 2 Code\", AllocAccountDistribution.\"Global Dimension 2 Code\");\n+ Rec.Validate(\"Dimension Set ID\", AllocAccountDistribution.\"Dimension Set ID\");\n+ Rec.Modify(true);\n end;\n \n local procedure CheckGLAccount(var GLAccount: Record \"G/L Account\")\n"} -{"metadata": {"area": "inventory", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-217797", "base_commit": "055fbb3433b4edcc3fc5709cf9b0cf7e48a372ac", "created_at": "2025-06-11", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137009, "functionName": ["LookupItemAvailabilityByEventOnItemCardOpenTheCorrectPlanningWorksheetBatch"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al\nindex 63f145ed7b95..cce6dab13ec0 100644\n--- a/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al\n@@ -24,6 +24,7 @@ codeunit 137009 \"SCM Availability by Event\"\n LibraryPurchase: Codeunit \"Library - Purchase\";\n LibraryAssembly: Codeunit \"Library - Assembly\";\n LibraryPatterns: Codeunit \"Library - Patterns\";\n+ LibraryPlanning: Codeunit \"Library - Planning\";\n LibraryRandom: Codeunit \"Library - Random\";\n LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n@@ -531,6 +532,62 @@ codeunit 137009 \"SCM Availability by Event\"\n TempInvtPageData.TestField(\"Remaining Forecast\", -ForecastQty + SalesQty);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemAvailabilityByEventPageHandler,PlanningWorksheetModalPageHandler')]\n+ procedure LookupItemAvailabilityByEventOnItemCardOpenTheCorrectPlanningWorksheetBatch()\n+ var\n+ Item: Record Item;\n+ NewPlanningWorkSheetBatchName: Code[10];\n+ OldPlanningWorkSheetBatchName: Code[10];\n+ ItemCard: TestPage \"Item Card\";\n+ PlanningWorksheet: TestPage \"Planning Worksheet\";\n+ begin\n+ // [SCENARIO 575726] Verify that the 'Lookup Item Availability by Event' on the item card opens the correct planning worksheet batch.\n+ Initialize();\n+\n+ // [GIVEN] Create a Item.\n+ LibraryInventory.CreateItem(Item);\n+ LibraryVariableStorage.Enqueue(Item.\"No.\");\n+\n+ // [GIEVN] Get old planning worksheet batch name.\n+ OldPlanningWorkSheetBatchName := GetRequisitionWkshBatch();\n+\n+ // [GIVEN] Open planning worksheet batch.\n+ PlanningWorksheet.OpenEdit();\n+ PlanningWorksheet.New();\n+\n+ // [GIVEN] Set the old planning worksheet batch name.\n+ PlanningWorksheet.CurrentWkshBatchName.SetValue(OldPlanningWorkSheetBatchName);\n+ LibraryVariableStorage.Enqueue(OldPlanningWorkSheetBatchName);\n+\n+ // [GIVEN] Set the item number and quantity in the planning worksheet.\n+ PlanningWorksheet.\"No.\".SetValue(Item.\"No.\");\n+ PlanningWorksheet.Quantity.SetValue(LibraryRandom.RandIntInRange(10, 20));\n+ PlanningWorksheet.Close();\n+\n+ // [GIVEN] Set new planning worksheet batch.\n+ NewPlanningWorkSheetBatchName := CreateRequisitionWkshBatch();\n+ PlanningWorksheet.OpenEdit();\n+ PlanningWorksheet.CurrentWkshBatchName.SetValue(NewPlanningWorkSheetBatchName);\n+ PlanningWorksheet.Close();\n+\n+ // [THEN] Verify the current planning worksheet batch name.\n+ PlanningWorksheet.OpenView();\n+ Assert.Equal(NewPlanningWorkSheetBatchName, PlanningWorksheet.CurrentWkshBatchName.Value);\n+\n+ // [GIVEN] Open Item Card.\n+ ItemCard.OpenEdit();\n+ ItemCard.GoToRecord(Item);\n+\n+ // [WHEN] Invoke Item Availability by Event Action.\n+ ItemCard.\"\".Invoke();\n+ ItemCard.Close();\n+\n+ // [THEN] Verify Lookup Item Availability by Event on the item card opens the correct planning worksheet batch.\n+ // It was verified on the PlanningWorksheetModalPageHandler. \n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n local procedure AutoReservePurchaseLine(PurchaseLine: Record \"Purchase Line\")\n var\n ReservMgt: Codeunit \"Reservation Management\";\n@@ -671,6 +728,35 @@ codeunit 137009 \"SCM Availability by Event\"\n ProdOrderComponent.Insert();\n end;\n \n+ local procedure GetRequisitionWkshBatch(): Code[10]\n+ var\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ begin\n+ RequisitionWkshName.SetRange(\"Template Type\", RequisitionWkshName.\"Template Type\"::Planning);\n+ RequisitionWkshName.FindFirst();\n+\n+ exit(RequisitionWkshName.Name);\n+ end;\n+\n+ local procedure GetRequisitionWkshTemplate(): Code[10]\n+ var\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ begin\n+ RequisitionWkshName.SetRange(\"Template Type\", RequisitionWkshName.\"Template Type\"::Planning);\n+ RequisitionWkshName.FindFirst();\n+\n+ exit(RequisitionWkshName.\"Worksheet Template Name\");\n+ end;\n+\n+ local procedure CreateRequisitionWkshBatch(): Code[10]\n+ var\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ begin\n+ LibraryPlanning.CreateRequisitionWkshName(RequisitionWkshName, GetRequisitionWkshTemplate());\n+\n+ exit(RequisitionWkshName.Name);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ItemAvailabilityByLocationPageHandler(var ItemAvailabilitybyLocation: TestPage \"Item Availability by Location\")\n@@ -722,5 +808,28 @@ codeunit 137009 \"SCM Availability by Event\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ procedure ItemAvailabilityByEventPageHandler(var ItemAvailabilitybyEvent: TestPage \"Item Availability by Event\")\n+ var\n+ InventoryPageDataType: Enum \"Inventory Page Data Type\";\n+ begin\n+ ItemAvailabilitybyEvent.IncludePlanningSuggestions.SetValue(true);\n+ ItemAvailabilitybyEvent.Filter.SetFilter(Type, Format(InventoryPageDataType::Plan));\n+ ItemAvailabilitybyEvent.\"Show Document\".Invoke();\n+ ItemAvailabilitybyEvent.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ procedure PlanningWorksheetModalPageHandler(var PlanningWorksheet: TestPage \"Planning Worksheet\")\n+ var\n+ CurrentWkshBatchName: Variant;\n+ ItemNo: Variant;\n+ begin\n+ ItemNo := LibraryVariableStorage.DequeueText();\n+ CurrentWkshBatchName := LibraryVariableStorage.DequeueText();\n+ PlanningWorksheet.CurrentWkshBatchName.AssertEquals(CurrentWkshBatchName);\n+ PlanningWorksheet.\"No.\".AssertEquals(ItemNo);\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al b/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al\nindex 2eaf3fe58c79..986790155380 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al\n@@ -953,7 +953,7 @@ page 99000852 \"Planning Worksheet\"\n // if called from API (such as edit-in-excel), do not filter \n if ClientTypeManagement.GetCurrentClientType() = CLIENTTYPE::ODataV4 then\n exit;\n- OpenedFromBatch := (Rec.\"Journal Batch Name\" <> '') and (Rec.\"Worksheet Template Name\" = '');\n+ OpenedFromBatch := (Rec.\"Journal Batch Name\" <> '') and (Rec.\"Worksheet Template Name\" <> '');\n if OpenedFromBatch then begin\n CurrentWkshBatchName := Rec.\"Journal Batch Name\";\n ReqJnlManagement.OpenJnl(CurrentWkshBatchName, Rec);\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al\nindex a2b07ee7538a..033dc48d99c5 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al\n@@ -98,7 +98,10 @@ codeunit 330 ReqJnlManagement\n begin\n OnBeforeOpenJnl(CurrentJnlBatchName, ReqLine);\n \n- CheckTemplateName(ReqLine.GetRangeMax(\"Worksheet Template Name\"), CurrentJnlBatchName);\n+ if (ReqLine.\"Worksheet Template Name\" <> '') and (ReqLine.GetFilter(\"Journal Batch Name\") = '') then\n+ CheckTemplateName(ReqLine.\"Worksheet Template Name\", CurrentJnlBatchName)\n+ else\n+ CheckTemplateName(ReqLine.GetRangeMax(\"Worksheet Template Name\"), CurrentJnlBatchName);\n ReqLine.FilterGroup := 2;\n ReqLine.SetRange(\"Journal Batch Name\", CurrentJnlBatchName);\n ReqLine.FilterGroup := 0;\n"} -{"metadata": {"area": "inventory", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-214557", "base_commit": "72ed0651950681ae8b8c302d37d00d3b6f32692b", "created_at": "2025-05-01", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137075, "functionName": ["ReqLineIsNotCreatedWhenCalcRegenPlanForCompItemPresentInRelProdOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al\nindex 66bf5a9fce6e..d5d73bcc3bcc 100644\n--- a/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al\n@@ -861,6 +861,69 @@\n // [THEN] Order Tracking page is opened with 2 lines for Item \"I\" and quantity = 1(checked in OrderTrackingWithLinesModalPageHandler handler)\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure ReqLineIsNotCreatedWhenCalcRegenPlanForCompItemPresentInRelProdOrder()\n+ var\n+ Item: array[4] of Record Item;\n+ ProductionBOMHeader: array[2] of Record \"Production BOM Header\";\n+ productionBOMLine: array[3] of Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ RequisitionLine: Record \"Requisition Line\";\n+ begin\n+ // [SCENARIO 563946] Requition Line is not created when Stan runs Calculate Regenerative \n+ // Plan action for Component Item if the that Item is present in a Released Production Order \n+ // with required Quantity in its Prod. Order Line.\n+ Initialize();\n+\n+ // [GIVEN] Create four Items.\n+ CreateItem(Item[1]);\n+ CreateItem(Item[2]);\n+ CreateItem(Item[3]);\n+ CreateItem(Item[4]);\n+\n+ // [GIVEN] Create a Production BOM for Item [2] and Item [3].\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader[1], Item[2].\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader[1], ProductionBOMLine[1], '', ProductionBOMLine[1].Type::Item, Item[2].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader[1], ProductionBOMLine[2], '', ProductionBOMLine[2].Type::Item, Item[3].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Validate \"Status\" in Production BOM Header [1].\n+ ProductionBOMHeader[1].Validate(\"Status\", ProductionBOMHeader[1].Status::Certified);\n+ ProductionBOMHeader[1].Modify(true);\n+\n+ // [GIVEN] Create a Production BOM for Item [4].\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader[2], Item[4].\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader[2], ProductionBOMLine[3], '', ProductionBOMLine[3].Type::Item, Item[4].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Validate \"Status\" in Production BOM Header [2].\n+ ProductionBOMHeader[2].Validate(\"Status\", ProductionBOMHeader[2].Status::Certified);\n+ ProductionBOMHeader[2].Modify(true);\n+\n+ // [GIVEN] Validate \"Production BOM No.\" in Item [1].\n+ Item[1].Validate(\"Production BOM No.\", ProductionBOMHeader[1].\"No.\");\n+ Item[1].Modify(true);\n+\n+ // [GIVEN] Validate \"Production BOM No.\" in Item [2].\n+ Item[2].Validate(\"Production BOM No.\", ProductionBOMHeader[2].\"No.\");\n+ Item[2].Modify(true);\n+\n+ // [GIVEN] Validate \"Production BOM No.\" in Item [3].\n+ Item[3].Validate(\"Production BOM No.\", ProductionBOMHeader[2].\"No.\");\n+ Item[3].Modify(true);\n+\n+ // [GIVEN] Create and Refresh Released Production Order.\n+ CreateAndRefreshReleasedProductionOrder(ProductionOrder, Item[1].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Calculate Regenerative Plan for Planning Worksheet.\n+ CalculateRegenPlanForPlanningWorksheet(Item[4]);\n+\n+ // [WHEN] Find Requisition Line.\n+ RequisitionLine.SetRange(\"No.\", Item[4].\"No.\");\n+\n+ // [THEN] Requisition Line is not found.\n+ Assert.IsTrue(RequisitionLine.IsEmpty(), StrSubstNo(ReqLineShouldNotExistErr, ''));\n+ end;\n+\n local procedure Initialize()\n var\n RequisitionLine: Record \"Requisition Line\";\n@@ -1597,6 +1660,15 @@\n ReservationEntry.Insert();\n end;\n \n+ local procedure CreateItem(var Item: Record Item)\n+ begin\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Replenishment System\", Item.\"Replenishment System\"::\"Prod. Order\");\n+ Item.Validate(\"Reordering Policy\", Item.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ Item.Validate(\"Manufacturing Policy\", Item.\"Manufacturing Policy\"::\"Make-to-Order\");\n+ Item.Modify(true);\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure CalculatePlanPlanWkshRequestPageHandler(var CalculatePlanPlanWksh: TestRequestPage \"Calculate Plan - Plan. Wksh.\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al\nindex e3a6cf2ff5fb..2acbb26614e2 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al\n@@ -15,6 +15,7 @@ using Microsoft.Inventory.Planning;\n using Microsoft.Inventory.Requisition;\n using Microsoft.Inventory.Setup;\n using Microsoft.Inventory.Transfer;\n+using Microsoft.Manufacturing.Document;\n using Microsoft.Pricing.Calculation;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.Vendor;\n@@ -982,6 +983,9 @@ codeunit 99000854 \"Inventory Profile Offsetting\"\n CanBeRescheduled: Boolean;\n ItemInventoryExists: Boolean;\n begin\n+ if CheckDemandAndSupplyQuantityAreEqual(SupplyInvtProfile, DemandInvtProfile) then\n+ exit;\n+\n xDemandInvtProfile.CopyFilters(DemandInvtProfile);\n xSupplyInvtProfile.CopyFilters(SupplyInvtProfile);\n ItemInventoryExists := CheckItemInventoryExists(SupplyInvtProfile);\n@@ -1097,6 +1101,28 @@ codeunit 99000854 \"Inventory Profile Offsetting\"\n OnAfterMatchAttributes(SupplyInvtProfile, DemandInvtProfile, TempTrkgReservEntry);\n end;\n \n+ local procedure CheckDemandAndSupplyQuantityAreEqual(var SupplyInvtProfile: Record \"Inventory Profile\"; var DemandInvtProfile: Record \"Inventory Profile\"): Boolean\n+ var\n+ TotalDemandQty: Decimal;\n+ TotalSupplyQty: Decimal;\n+ begin\n+ if (SupplyInvtProfile.\"Source Type\" <> Database::\"Prod. Order Line\") or (DemandInvtProfile.\"Source Type\" <> Database::\"Prod. Order Component\") then\n+ exit(false);\n+\n+ if DemandInvtProfile.FindSet() then\n+ repeat\n+ TotalDemandQty += DemandInvtProfile.Quantity;\n+ until DemandInvtProfile.Next() = 0;\n+\n+ if SupplyInvtProfile.FindSet() then\n+ repeat\n+ TotalSupplyQty += SupplyInvtProfile.Quantity;\n+ until SupplyInvtProfile.Next() = 0;\n+\n+ if TotalSupplyQty = TotalDemandQty then\n+ exit(true);\n+ end;\n+\n local procedure DecreaseQtyForMaxQty(var SupplyInvtProfile: Record \"Inventory Profile\"; ReduceQty: Decimal)\n begin\n if ReduceQty > 0 then begin\n"} -{"metadata": {"area": "manufacturing", "image_count": 11}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-212355", "base_commit": "a7de1e6b1a271e60b86657a69a98e863b2b85d33", "created_at": "2025-04-06", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137154, "functionName": ["InputQtyAndStartingDateTimeIsRecalculatedWhenReplanProdOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\nindex 972aa5e52834..c2e1e71567ec 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n@@ -64,6 +64,8 @@ codeunit 137154 \"SCM Warehouse Management II\"\n ReceiptLinesNotCreatedErr: Label 'There are no warehouse receipt lines created.';\n ItemTrackingMode: Option \" \",\"Assign Lot No.\",\"Assign Multiple Lot No.\",\"Assign Serial No.\",\"Assign Lot And Serial\",\"Select Entries\",\"Blank Quantity Base\",\"Assign Lot No. & Expiration Date\",\"Assign Manual Lot Nos\",\"Show Entries\";\n DescriptionMustBeSame: Label 'Description must be same.';\n+ InputQtyErr: Label 'Input Quantity Must be %1 in %2', Comment = '1% = Remaining Quanity value, %2 = Prod. Order Routing Line';\n+ StartingDateTimeErr: Label 'Starting Date-Time must not be %1 in %2', Comment = '%1 = StartingDateTime value, %2 = Prod. Order Routing Line.';\n \n [Test]\n [HandlerFunctions('ReservationPageHandler')]\n@@ -3447,6 +3449,97 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryWarehouse.PostWhseShipment(WarehouseShipmentHeader, false);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ProductionJournalPageHandler,ConfirmHandlerYes,MessageHandlerNotext')]\n+ procedure InputQtyAndStartingDateTimeIsRecalculatedWhenReplanProdOrder()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ RoutingHeader: Record \"Routing Header\";\n+ ProductionOrder: Record \"Production Order\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProdOrderRoutingLine: Record \"Prod. Order Routing Line\";\n+ WorkCenter: Record \"Work Center\";\n+ Direction: Option Forward,Backward;\n+ CalcMethod: Option \"No Levels\",\"One level\",\"All levels\";\n+ StartingDateTime: DateTime;\n+ begin\n+ // [SCENARIO 565975] \"Input Quantity\" and \"Starting Date-Time\" in Prod. Order Routing Line is \n+ // recalculated when Production Journal is posted and Stan runs Replan Production Order Report.\n+ Initialize();\n+\n+ // [GIVEN] Create a Component Item and Validate \"Replenishment System\", \n+ // \"Manufacturing Policy\" and \"Flushing Method\".\n+ LibraryInventory.CreateItem(CompItem);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(\"Manufacturing Policy\", CompItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::\"Pick + Manual\");\n+ CompItem.Modify(true);\n+\n+ // [GIVEN] Create a Work Center.\n+ CreateWorkCenter(WorkCenter);\n+\n+ // [GIVEN] Create and Certify Routing.\n+ CreateAndCertifyRouting(RoutingHeader, WorkCenter);\n+\n+ // [GIVEN] Create and Certify Production BOM.\n+ CreateAndCertifyProductionBOM(ProductionBOMLine, CompItem, LibraryRandom.RandIntInRange(10, 10));\n+\n+ // [GIVEN] Create a Production Item and Validate \"Replenishment System\", \n+ // \"Manufacturing Policy\", \"Routing No.\" and \"Production BOM No.\".\n+ LibraryInventory.CreateItem(ProdItem);\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Manufacturing Policy\", ProdItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProdItem.Validate(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMLine.\"Production BOM No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Set Item Inventory.\n+ SetItemInventory(CompItem, LibraryRandom.RandIntInRange(500, 500));\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProductionOrder(ProductionOrder, ProdItem.\"No.\", LibraryRandom.RandIntInRange(50, 50));\n+\n+ // [GIVEN] Find Prod. Order Routing Line.\n+ ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdOrderRoutingLine.FindFirst();\n+\n+ // [GIVEN] Generate and save Starting Date-Time in a Variable.\n+ StartingDateTime := ProdOrderRoutingLine.\"Starting Date-Time\";\n+\n+ // [GIVEN] Open Production Journal.\n+ OpenProductionJournal(ProductionOrder.\"No.\");\n+\n+ // [GIVEN] Run Replan Production Order Report.\n+ LibraryManufacturing.RunReplanProductionOrder(ProductionOrder, Direction::Backward, CalcMethod::\"No Levels\");\n+\n+ // [GIVEN] Find Prod. Order Line.\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProductionOrder.\"No.\");\n+ ProdOrderLine.FindFirst();\n+\n+ // [WHEN] Find Prod. Order Routing Line.\n+ ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdOrderRoutingLine.FindFirst();\n+\n+ // [THEN] \"Input Quantity\" in Prod. Order Routing Line is equal to \"Remaining Quantity\" of Prod. Order Line.\n+ Assert.AreEqual(\n+ ProdOrderLine.\"Remaining Quantity\",\n+ ProdOrderRoutingLine.\"Input Quantity\",\n+ StrSubstNo(\n+ InputQtyErr,\n+ ProdOrderLine.\"Remaining Quantity\",\n+ ProdOrderRoutingLine.TableCaption()));\n+\n+ // [THEN] \"Starting Date-Time\" in Prod. Order Routing Line is equal to StartingDateTime.\n+ Assert.AreNotEqual(\n+ StartingDateTime,\n+ ProdOrderRoutingLine.\"Starting Date-Time\",\n+ StrSubstNo(\n+ StartingDateTimeErr,\n+ StartingDateTime,\n+ ProdOrderRoutingLine.TableCaption()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5174,6 +5267,71 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryInventory.PostItemJournalBatch(ItemJournalBatch);\n end;\n \n+ local procedure CreateAndRefreshProductionOrder(var ProductionOrder: Record \"Production Order\"; ItemNo: Code[20]; Quantity: Decimal)\n+ begin\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder, ProductionOrder.Status::Released, ProductionOrder.\"Source Type\"::Item, ItemNo, Quantity);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+ end;\n+\n+ local procedure SetItemInventory(Item: Record Item; Quantity: Decimal)\n+ var\n+ ItemJnlTemplate: Record \"Item Journal Template\";\n+ ItemJnlBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ Item.TestField(\"No.\");\n+\n+ LibraryInventory.CreateItemJournalTemplate(ItemJnlTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJnlBatch, ItemJnlTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJnlTemplate.Name, ItemJnlBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", Quantity);\n+\n+ LibraryInventory.PostItemJournalLine(ItemJnlTemplate.Name, ItemJnlBatch.Name);\n+ end;\n+\n+ local procedure OpenProductionJournal(No: Code[20])\n+ var\n+ ReleasedProductionOrder: TestPage \"Released Production Order\";\n+ begin\n+ ReleasedProductionOrder.OpenEdit();\n+ ReleasedProductionOrder.FILTER.SetFilter(\"No.\", No);\n+ ReleasedProductionOrder.ProdOrderLines.ProductionJournal.Invoke();\n+ end;\n+\n+ local procedure CreateWorkCenter(var WorkCenter: Record \"Work Center\")\n+ begin\n+ LibraryManufacturing.CreateWorkCenterWithCalendar(WorkCenter);\n+ WorkCenter.Validate(\"Unit Cost\", LibraryRandom.RandDec(100, 2));\n+ WorkCenter.Validate(Capacity, LibraryRandom.RandIntInRange(3, 3));\n+ WorkCenter.Validate(Efficiency, LibraryRandom.RandIntInRange(100, 100));\n+ WorkCenter.Modify(true);\n+ end;\n+\n+ local procedure CreateAndCertifyRouting(var RoutingHeader: Record \"Routing Header\"; WorkCenter: Record \"Work Center\")\n+ var\n+ RoutingLine: Record \"Routing Line\";\n+ begin\n+ LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial);\n+ LibraryManufacturing.CreateRoutingLine(RoutingHeader, RoutingLine, '', Format(LibraryRandom.RandIntInRange(10, 10)), RoutingLine.Type::\"Work Center\", WorkCenter.\"No.\");\n+ RoutingLine.Validate(\"Setup Time\", LibraryRandom.RandIntInRange(10, 10));\n+ RoutingLine.Validate(\"Run Time\", LibraryRandom.RandIntInRange(10, 10));\n+ RoutingLine.Modify(true);\n+\n+ RoutingHeader.Validate(Status, RoutingHeader.Status::Certified);\n+ RoutingHeader.Modify(true);\n+ end;\n+\n+ local procedure CreateAndCertifyProductionBOM(var ProductionBOMLine: Record \"Production BOM Line\"; Item: Record Item; Qty: Decimal)\n+ var\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ begin\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, Item.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, Item.\"No.\", Qty);\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify(true);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure EnterQuantityToCreatePageHandler(var EnterQuantityToCreate: TestPage \"Enter Quantity to Create\")\n@@ -5347,6 +5505,19 @@ codeunit 137154 \"SCM Warehouse Management II\"\n SourceDocumentFilterCard.Run.Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandler(var ProductionJournal: TestPage \"Production Journal\")\n+ begin\n+ ProductionJournal.First();\n+ ProductionJournal.Quantity.SetValue(LibraryRandom.RandIntInRange(200, 200));\n+ ProductionJournal.Next();\n+ ProductionJournal.\"Setup Time\".SetValue(LibraryRandom.RandIntInRange(10, 10));\n+ ProductionJournal.\"Run Time\".SetValue(LibraryRandom.RandIntInRange(10, 10));\n+ ProductionJournal.\"Output Quantity\".SetValue(LibraryRandom.RandIntInRange(20, 20));\n+ ProductionJournal.Post.Invoke();\n+ end;\n+\n [PageHandler]\n [Scope('OnPrem')]\n procedure GLPostingPreviewPageHandler(var ShowAllEntries: TestPage \"G/L Posting Preview\")\n@@ -5372,6 +5543,11 @@ codeunit 137154 \"SCM Warehouse Management II\"\n Assert.IsTrue(StrPos(Message, LocalMessage) > 0, Message);\n end;\n \n+ [MessageHandler]\n+ procedure MessageHandlerNotext(Message: Text[1024])\n+ begin\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(ConfirmMessage: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al b/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\nindex 33305adaa10c..25cb5cb00d64 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\n@@ -65,7 +65,7 @@ report 99001026 \"Replan Production Order\"\n \"Ending Time\" := \"Prod. Order Line\".\"Ending Time\";\n Modify();\n end;\n- CalcProdOrderRtngLine.CalculateRoutingLine(\"Prod. Order Routing Line\", Direction, true);\n+ CalcProdOrderRtngLine.ReplanRoutingLine(\"Prod. Order Routing Line\", Direction, true);\n end;\n Modify();\n end;\ndiff --git a/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\nindex c46c8c20688a..1481dab83903 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\n@@ -1261,6 +1261,7 @@ codeunit 99000774 \"Calculate Routing Line\"\n OnCalculateRoutingLineOnBeforeProdOrderCapNeedReset(ProdOrderRoutingLine, ProdOrderRoutingLine2);\n \n ProdOrderCapNeed.Reset();\n+ ProdOrderCapNeed.SetLoadFields(Status, \"Prod. Order No.\", \"Requested Only\", \"Routing No.\", \"Routing Reference No.\", \"Operation No.\");\n ProdOrderCapNeed.SetRange(Status, ProdOrderRoutingLine.Status);\n ProdOrderCapNeed.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n ProdOrderCapNeed.SetRange(\"Requested Only\", false);\n@@ -2114,6 +2115,118 @@ codeunit 99000774 \"Calculate Routing Line\"\n CalendarEntry.SetRange(\"Ending Date-Time\", 0DT, CreateDateTime(DateValue + 1, TimeValue));\n end;\n \n+ procedure ReplanRoutingLine(var ProdOrderRoutingLine2: Record \"Prod. Order Routing Line\"; Direction: Option Forward,Backward; CalcStartEndDate: Boolean)\n+ var\n+ ProdOrderCapacityNeed: Record \"Prod. Order Capacity Need\";\n+ MfgCostCalcMgt: Codeunit \"Mfg. Cost Calculation Mgt.\";\n+ ExpectedOperOutput: Decimal;\n+ ActualOperOutput: Decimal;\n+ TotalQtyPerOperation: Decimal;\n+ TotalCapacityPerOperation: Decimal;\n+ begin\n+ MfgSetup.Get();\n+\n+ ProdOrderRoutingLine := ProdOrderRoutingLine2;\n+\n+ WaitTimeOnly :=\n+ (ProdOrderRoutingLine.\"Setup Time\" = 0) and (ProdOrderRoutingLine.\"Run Time\" = 0) and\n+ (ProdOrderRoutingLine.\"Move Time\" = 0);\n+\n+ if ProdOrderRoutingLine.\"Ending Time\" = 0T then\n+ ProdOrderRoutingLine.\"Ending Time\" := 000000T;\n+\n+ if ProdOrderRoutingLine.\"Starting Time\" = 0T then\n+ ProdOrderRoutingLine.\"Starting Time\" := 000000T;\n+\n+ ProdOrderRoutingLine.\"Expected Operation Cost Amt.\" := 0;\n+ ProdOrderRoutingLine.\"Expected Capacity Ovhd. Cost\" := 0;\n+ ProdOrderRoutingLine.\"Expected Capacity Need\" := 0;\n+\n+ ProdOrderCapacityNeed.Reset();\n+ ProdOrderCapacityNeed.SetRange(Status, ProdOrderRoutingLine.Status);\n+ ProdOrderCapacityNeed.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Requested Only\", false);\n+ ProdOrderCapacityNeed.SetRange(\"Routing No.\", ProdOrderRoutingLine.\"Routing No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Routing Reference No.\", ProdOrderRoutingLine.\"Routing Reference No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Operation No.\", ProdOrderRoutingLine.\"Operation No.\");\n+ ProdOrderCapacityNeed.DeleteAll();\n+\n+ NextCapNeedLineNo := 1;\n+\n+ ProdOrderRoutingLine.TestField(\"Work Center No.\");\n+\n+ CurrentWorkCenterNo := '';\n+ Workcenter.Get(ProdOrderRoutingLine.\"Work Center No.\");\n+ if ProdOrderRoutingLine.Type = ProdOrderRoutingLine.Type::\"Machine Center\" then begin\n+ MachineCenter.Get(ProdOrderRoutingLine.\"No.\");\n+ Workcenter.\"Queue Time\" := MachineCenter.\"Queue Time\";\n+ Workcenter.\"Queue Time Unit of Meas. Code\" := MachineCenter.\"Queue Time Unit of Meas. Code\";\n+ end;\n+ if not CalcStartEndDate then\n+ Clear(Workcenter.\"Queue Time\");\n+ ProdOrder.Get(ProdOrderRoutingLine.Status, ProdOrderRoutingLine.\"Prod. Order No.\");\n+\n+ ProdOrderQty := 0;\n+ TotalScrap := 0;\n+ TotalLotSize := 0;\n+ ProdOrderLine.SetRange(Status, ProdOrderRoutingLine.Status);\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n+ ProdOrderLine.SetRange(\"Routing Reference No.\", ProdOrderRoutingLine.\"Routing Reference No.\");\n+ ProdOrderLine.SetRange(\"Routing No.\", ProdOrderRoutingLine.\"Routing No.\");\n+ ProdOrderLine.SetLoadFields(\"Quantity (Base)\", \"Scrap %\", \"Prod. Order No.\", \"Line No.\", Status, \"Routing No.\", \"Routing Version Code\", \"Ending Date\", \"Ending Time\");\n+ if ProdOrderLine.Find('-') then begin\n+ ExpectedOperOutput := 0;\n+ repeat\n+ ExpectedOperOutput := ExpectedOperOutput + ProdOrderLine.\"Quantity (Base)\";\n+ TotalScrap := TotalScrap + ProdOrderLine.\"Scrap %\";\n+ until ProdOrderLine.Next() = 0;\n+ ActualOperOutput := MfgCostCalcMgt.CalcActOutputQtyBase(ProdOrderLine, ProdOrderRoutingLine);\n+ ProdOrderQty := ExpectedOperOutput - ActualOperOutput;\n+ if ProdOrderQty < 0 then\n+ ProdOrderQty := 0;\n+ end;\n+\n+ MaxLotSize :=\n+ ProdOrderQty *\n+ (1 + ProdOrderRoutingLine.\"Scrap Factor % (Accumulated)\") *\n+ (1 + TotalScrap / 100) +\n+ ProdOrderRoutingLine.\"Fixed Scrap Qty. (Accum.)\";\n+\n+ ProdOrderRoutingLine.\"Input Quantity\" := MaxLotSize;\n+\n+ if ActualOperOutput > 0 then\n+ TotalQtyPerOperation :=\n+ ExpectedOperOutput *\n+ (1 + ProdOrderRoutingLine.\"Scrap Factor % (Accumulated)\") *\n+ (1 + TotalScrap / 100) +\n+ ProdOrderRoutingLine.\"Fixed Scrap Qty. (Accum.)\"\n+ else\n+ TotalQtyPerOperation := MaxLotSize;\n+\n+ TotalCapacityPerOperation :=\n+ Round(\n+ TotalQtyPerOperation *\n+ ProdOrderRoutingLine.RunTimePer() *\n+ CalendarMgt.QtyperTimeUnitofMeasure(\n+ ProdOrderRoutingLine.\"Work Center No.\", ProdOrderRoutingLine.\"Run Time Unit of Meas. Code\"),\n+ UOMMgt.QtyRndPrecision());\n+\n+ if MfgSetup.\"Cost Incl. Setup\" then\n+ CalcCostInclSetup(ProdOrderRoutingLine, TotalCapacityPerOperation);\n+\n+ CalcExpectedCost(ProdOrderRoutingLine, TotalQtyPerOperation, TotalCapacityPerOperation);\n+\n+ if ProdOrderRoutingLine.\"Schedule Manually\" then\n+ CalculateRoutingLineFixed()\n+ else\n+ if Direction = Direction::Backward then\n+ CalcRoutingLineBack(CalcStartEndDate)\n+ else\n+ CalcRoutingLineForward(CalcStartEndDate);\n+\n+ ProdOrderRoutingLine2 := ProdOrderRoutingLine;\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterCalcCostInclSetup(ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; var TotalCapacityPerOperation: Decimal)\n begin\n"} -{"metadata": {"area": "project", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-214825", "base_commit": "9a03d309156dd751b1a508767c678093c9516506", "created_at": "2025-05-06", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136350, "functionName": ["CheckUnavailableItemQtyWhenAddProjectPlanningLinesBeforeThePreviousOne"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al b/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\nindex bb7f40e246dc..8aac1963c2d5 100644\n--- a/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\n@@ -2248,6 +2248,36 @@ codeunit 136350 \"UT T Job\"\n Assert.IsFalse(PurchaseLine.IsEmpty, 'Purchase Line not created for Job Task' + JobTask.\"Job Task No.\");\n end;\n \n+ [Test]\n+ [HandlerFunctions('CheckPurchOrderFromJobModalPageHandlerHaveLines')]\n+ procedure CheckUnavailableItemQtyWhenAddProjectPlanningLinesBeforeThePreviousOne()\n+ var\n+ Item, Item2 : Record Item;\n+ JobPlanningLines: TestPage \"Job Planning Lines\";\n+ begin\n+ // [SCENARIO 574938] Create Purchase Order from Project not working as expected if we add Project Planning Lines before the previous ones.\n+ Initialize();\n+\n+ // [GIVEN] Create 2 New Item.\n+ LibraryInventory.CreateItem(Item);\n+ LibraryInventory.CreateItem(Item2);\n+\n+ // [GIVEN] Create Job X with Job Task and 2 Job Planning Lines.\n+ CreateJobAndJobTask();\n+ CreateJobPlanningLineWithItem(JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\", Item.\"No.\", LibraryRandom.RandInt(100));\n+ CreateJobPlanningLineBeforePreviousLine(JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\", Item2.\"No.\", LibraryRandom.RandInt(100));\n+\n+ // [WHEN] Open Job Planning Lines.\n+ JobPlanningLines.OpenEdit();\n+ JobPlanningLines.GoToRecord(JobPlanningLine);\n+ LibraryVariableStorage.Clear();\n+ LibraryVariableStorage.Enqueue(Item.\"No.\");\n+\n+ // [WHEN] Create Purchase Order from Job Planning Lines.\n+ JobPlanningLines.CreatePurchaseOrder.Invoke();//assert check\n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -2617,6 +2647,30 @@ codeunit 136350 \"UT T Job\"\n until DefaultDimension.Next() = 0;\n end;\n \n+ local procedure CreateJobPlanningLineBeforePreviousLine(LineType: Enum \"Job Planning Line Line Type\"; ItemNo: Code[20]; Quantity: Decimal)\n+ var\n+ JobPlanLine: Record \"Job Planning Line\";\n+ LineNo: Integer;\n+ begin\n+ JobPlanLine.SetRange(\"Job No.\", JobTask.\"Job No.\");\n+ JobPlanLine.SetRange(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ if JobPlanLine.FindFirst() then;\n+ LineNo := JobPlanLine.\"Line No.\" / 2;\n+ JobPlanningLine.Init();\n+ JobPlanningLine.Validate(\"Job No.\", JobTask.\"Job No.\");\n+ JobPlanningLine.Validate(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ JobPlanningLine.Validate(\"Line No.\", LineNo);\n+ JobPlanningLine.Insert(true);\n+\n+ JobPlanningLine.Validate(\"Planning Date\", WorkDate());\n+ JobPlanningLine.Validate(\"Line Type\", LineType);\n+ JobPlanningLine.Validate(Type, JobPlanningLine.Type::Item);\n+ JobPlanningLine.Validate(Description, LibraryUtility.GenerateGUID());\n+ JobPlanningLine.Validate(\"No.\", ItemNo);\n+ JobPlanningLine.Validate(Quantity, Quantity);\n+ JobPlanningLine.Modify(true);\n+ end;\n+\n [EventSubscriber(ObjectType::Table, Database::\"Job\", 'OnAfterModifyEvent', '', false, false)]\n local procedure InsertNameValueBufferOnJobModify(var Rec: Record Job; var xRec: Record Job; RunTrigger: Boolean)\n var\n@@ -2730,6 +2784,13 @@ codeunit 136350 \"UT T Job\"\n PurchOrderFromSalesOrder.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ procedure CheckPurchOrderFromJobModalPageHandlerHaveLines(var PurchOrderFromSalesOrder: TestPage \"Purch. Order From Sales Order\")\n+ begin\n+ //[THEN] Check Purch. Order From Sales Order Page have Record.\n+ PurchOrderFromSalesOrder.\"No.\".AssertEquals(LibraryVariableStorage.DequeueText());\n+ end;\n+\n [MessageHandler]\n procedure MessageHandler(Message: Text[1024])\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\nindex 604bb9158a26..2da4897165fb 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\n@@ -78,6 +78,7 @@ codeunit 1018 \"Purchase Doc. From Job\"\n JobPlanningLine.SetRange(\"Job Task No.\", JobTask.\"Job Task No.\");\n if JobPlanningLine.IsEmpty() then\n exit;\n+ JobPlanningLine.SetCurrentKey(\"Job Contract Entry No.\");\n JobPlanningLine.FindSet();\n RecRef.GetTable(JobPlanningLine);\n ContractEntryNoFilter := SelectionFilterMgt.GetSelectionFilter(RecRef, JobPlanningLine.FieldNo(\"Job Contract Entry No.\"));\n"} {"metadata": {"area": "subscription billing", "image_count": 0}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-4766", "base_commit": "700d04453d3f0851ce7b7e34eb50b283f7c10e52", "created_at": "2025-09-15T15:39:32Z", "environment_setup_version": "27.0", "project_paths": ["src\\Apps\\W1\\Subscription Billing\\App", "src\\Apps\\W1\\Subscription Billing\\Test"], "FAIL_TO_PASS": [{"codeunitID": 148155, "functionName": ["ContractLineDisconnectServiceOnNoChange"]}, {"codeunitID": 148154, "functionName": ["ContractLineDisconnectServiceOnNoChange"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al b/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\nindex 7e485c8c43..e945075fa8 100644\n--- a/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\n+++ b/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\n@@ -613,23 +613,62 @@ codeunit 148155 \"Contracts Test\"\n CustomerContractLine: Record \"Cust. Sub. Contract Line\";\n ServiceCommitment: Record \"Subscription Line\";\n ServiceObject: Record \"Subscription Header\";\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after Type has changed.', Locked = true;\n EntryNo: Integer;\n begin\n- // Test: Subscription Line should be disconnected from the contract when the line type changes\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the line type changes\n Initialize();\n \n+ // [GIVEN] A customer contract with a connected Subscription Line\n SetupNewContract(false, ServiceObject, CustomerContract);\n \n- CustomerContractLine.Reset();\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n CustomerContractLine.SetRange(\"Subscription Contract No.\", CustomerContract.\"No.\");\n CustomerContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n CustomerContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n CustomerContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n CustomerContractLine.FindFirst();\n EntryNo := CustomerContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The contract line type is changed from Item to Comment\n CustomerContractLine.Validate(\"Contract Line Type\", CustomerContractLine.\"Contract Line Type\"::Comment);\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n+ ServiceCommitment.Get(EntryNo);\n+ Assert.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('ExchangeRateSelectionModalPageHandler,MessageHandler')]\n+ procedure ContractLineDisconnectServiceOnNoChange()\n+ var\n+ CustomerContract: Record \"Customer Subscription Contract\";\n+ CustomerContractLine: Record \"Cust. Sub. Contract Line\";\n+ ServiceCommitment: Record \"Subscription Line\";\n+ ServiceObject: Record \"Subscription Header\";\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after No. has changed.', Locked = true;\n+ EntryNo: Integer;\n+ begin\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the Item No. is cleared\n+ Initialize();\n+\n+ // [GIVEN] A customer contract with a connected Subscription Line\n+ SetupNewContract(false, ServiceObject, CustomerContract);\n+\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n+ CustomerContractLine.SetRange(\"Subscription Contract No.\", CustomerContract.\"No.\");\n+ CustomerContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n+ CustomerContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n+ CustomerContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n+ CustomerContractLine.FindFirst();\n+ EntryNo := CustomerContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The Item No. is cleared on the contract line\n+ CustomerContractLine.Validate(\"No.\", '');\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n ServiceCommitment.Get(EntryNo);\n- ServiceCommitment.TestField(\"Subscription Contract No.\", '');\n+ Assert.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n end;\n \n [Test]\ndiff --git a/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al b/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\nindex c47f577102..b827f99217 100644\n--- a/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\n+++ b/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\n@@ -338,11 +338,15 @@ codeunit 148154 \"Vendor Contracts Test\"\n procedure ContractLineDisconnectServiceOnTypeChange()\n var\n EntryNo: Integer;\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after Type has changed.', Locked = true;\n begin\n- // Test: Subscription Line should be disconnected from the contract when the line type changes\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the line type changes\n Initialize();\n+\n+ // [GIVEN] A vendor contract with a connected Subscription Line\n SetupNewContract(false);\n \n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n VendorContractLine.Reset();\n VendorContractLine.SetRange(\"Subscription Contract No.\", VendorContract.\"No.\");\n VendorContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n@@ -350,9 +354,43 @@ codeunit 148154 \"Vendor Contracts Test\"\n VendorContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n VendorContractLine.FindFirst();\n EntryNo := VendorContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The contract line type is changed from Item to Comment\n VendorContractLine.Validate(\"Contract Line Type\", VendorContractLine.\"Contract Line Type\"::Comment);\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n+ ServiceCommitment.Get(EntryNo);\n+ AssertThat.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('ExchangeRateSelectionModalPageHandler,MessageHandler')]\n+ procedure ContractLineDisconnectServiceOnNoChange()\n+ var\n+ EntryNo: Integer;\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after No. has changed.', Locked = true;\n+ begin\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the Item No. is cleared\n+ Initialize();\n+\n+ // [GIVEN] A vendor contract with a connected Subscription Line\n+ SetupNewContract(false);\n+\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n+ VendorContractLine.Reset();\n+ VendorContractLine.SetRange(\"Subscription Contract No.\", VendorContract.\"No.\");\n+ VendorContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n+ VendorContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n+ VendorContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n+ VendorContractLine.FindFirst();\n+ EntryNo := VendorContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The Item No. is cleared on the contract line\n+ VendorContractLine.Validate(\"No.\", '');\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n ServiceCommitment.Get(EntryNo);\n- ServiceCommitment.TestField(\"Subscription Contract No.\", '');\n+ AssertThat.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n end;\n \n [Test]\n", "patch": "diff --git a/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al b/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\nindex 91f83b18b3..a092d10f19 100644\n--- a/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\n+++ b/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\n@@ -49,23 +49,25 @@ table 8062 \"Cust. Sub. Contract Line\"\n GLAccount: Record \"G/L Account\";\n TempCustomerContractLine: Record \"Cust. Sub. Contract Line\" temporary;\n begin\n- case \"Contract Line Type\" of\n- \"Contract Line Type\"::Item:\n- begin\n- if not Item.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n- if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n- Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n- end;\n- \"Contract Line Type\"::\"G/L Account\":\n- begin\n- if not GLAccount.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n- if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n- Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n- end;\n- end;\n+ if \"No.\" <> '' then\n+ case \"Contract Line Type\" of\n+ \"Contract Line Type\"::Item:\n+ begin\n+ if not Item.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n+ if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n+ Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n+ end;\n+ \"Contract Line Type\"::\"G/L Account\":\n+ begin\n+ if not GLAccount.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n+ if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n+ Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n+ end;\n+ end;\n \n+ CheckAndDisconnectContractLine();\n TempCustomerContractLine := Rec;\n Init();\n SystemId := TempCustomerContractLine.SystemId;\n@@ -170,6 +172,8 @@ table 8062 \"Cust. Sub. Contract Line\"\n ServiceObject: Record \"Subscription Header\";\n ServiceCommitment: Record \"Subscription Line\";\n begin\n+ if \"No.\" = '' then\n+ exit;\n CustomerContract.Get(\"Subscription Contract No.\");\n ServiceObject.InitForSourceNo(\"Contract Line Type\", \"No.\");\n ServiceObject.UpdateCustomerDataFromCustomerContract(CustomerContract);\ndiff --git a/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al b/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\nindex 533581b5a2..38ecf0e9c3 100644\n--- a/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\n+++ b/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\n@@ -46,23 +46,25 @@ table 8065 \"Vend. Sub. Contract Line\"\n GLAccount: Record \"G/L Account\";\n TempVendorContractLine: Record \"Vend. Sub. Contract Line\" temporary;\n begin\n- case \"Contract Line Type\" of\n- \"Contract Line Type\"::Item:\n- begin\n- if not Item.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n- if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n- Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n- end;\n- \"Contract Line Type\"::\"G/L Account\":\n- begin\n- if not GLAccount.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n- if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n- Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n- end;\n- end;\n+ if \"No.\" <> '' then\n+ case \"Contract Line Type\" of\n+ \"Contract Line Type\"::Item:\n+ begin\n+ if not Item.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n+ if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n+ Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n+ end;\n+ \"Contract Line Type\"::\"G/L Account\":\n+ begin\n+ if not GLAccount.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n+ if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n+ Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n+ end;\n+ end;\n \n+ CheckAndDisconnectContractLine();\n TempVendorContractLine := Rec;\n Init();\n SystemId := TempVendorContractLine.SystemId;\n@@ -161,6 +163,8 @@ table 8065 \"Vend. Sub. Contract Line\"\n ServiceObject: Record \"Subscription Header\";\n ServiceCommitment: Record \"Subscription Line\";\n begin\n+ if \"No.\" = '' then\n+ exit;\n VendorContract.Get(\"Subscription Contract No.\");\n ServiceObject.InitForSourceNo(\"Contract Line Type\", \"No.\");\n ServiceObject.\"Created in Contract line\" := true;\n"} -{"metadata": {"area": "service", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-210200", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-03-15", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136119, "functionName": ["ReservationEntryMustBeCreatedWhenReserveIsAlwaysInServiceLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al\nindex 7027c534363e..e65fb66d63d3 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al\n@@ -9,6 +9,8 @@ using Microsoft.Finance.GeneralLedger.Journal;\n using Microsoft.Finance.GeneralLedger.Ledger;\n using Microsoft.Finance.VAT.Ledger;\n using Microsoft.Inventory.Item;\n+using Microsoft.Inventory.Journal;\n+using Microsoft.Inventory.Location;\n using Microsoft.Projects.Resources.Ledger;\n using Microsoft.Sales.Customer;\n using Microsoft.Sales.Receivables;\n@@ -40,6 +42,7 @@ codeunit 136119 \"Service Standard Codes\"\n LibrarySales: Codeunit \"Library - Sales\";\n LibraryUtility: Codeunit \"Library - Utility\";\n LibraryERM: Codeunit \"Library - ERM\";\n+ LibraryWarehouse: Codeunit \"Library - Warehouse\";\n ServiceItemGroupCode2: Code[10];\n StandardServiceCode2: Code[10];\n isInitialized: Boolean;\n@@ -52,6 +55,7 @@ codeunit 136119 \"Service Standard Codes\"\n QuantityMustbePositive: Label '%1 must be positive in %2 %3=''%4'',%5=''%6''.';\n ServiceLineMustNotExist: Label 'There is no %1 within the filter.Filters: %2: %3, %4: %5';\n ExpectedConfirm: Label 'The Credit Memo doesn''t have a Corrected Invoice No. Do you want to continue?';\n+ ValueMustBeEqualErr: Label '%1 must be equal to %2 in %3', Comment = '%1 = Field Caption , %2 = Expected Value , %3 = Table Caption';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1026,6 +1030,75 @@ codeunit 136119 \"Service Standard Codes\"\n StandardServiceLine.TestField(\"No.\", Item.\"No.\");\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalFormHandlerServItemGroup')]\n+ procedure ReservationEntryMustBeCreatedWhenReserveIsAlwaysInServiceLine()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ Customer: Record Customer;\n+ ServiceItem: Record \"Service Item\";\n+ ServiceHeader: Record \"Service Header\";\n+ ServiceLine: Record \"Service Line\";\n+ ServiceItemLine: Record \"Service Item Line\";\n+ StandardServiceCode: Record \"Standard Service Code\";\n+ StandardServiceItemGrCode: Record \"Standard Service Item Gr. Code\";\n+ ExpectedQuantity: Integer;\n+ begin\n+ // [SCENARIO 566581] Verify Reservation Entry must be created When Item that has Reserve = Always in the Service Line.\n+ // when \"Get Std. Service Codes.\" is executed.\n+ Initialize();\n+\n+ // [GIVEN] Create a Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Location with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Create an item with Reserve = Always.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Reordering Policy\", Item.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ Item.Validate(Reserve, Item.Reserve::Always);\n+ Item.Modify();\n+\n+ // [GIVEN] Generate Quantity.\n+ ExpectedQuantity := LibraryRandom.RandInt(20);\n+\n+ // [GIVEN] Post inventory.\n+ SetItemInventory(Item, ExpectedQuantity, Location.Code);\n+\n+ // [GIVEN] Create Service Item.\n+ LibraryService.CreateServiceItem(ServiceItem, Customer.\"No.\");\n+\n+ // [GIVEN] Create Standard Service Code with Item and Quantity.\n+ LibraryService.CreateStandardServiceCode(StandardServiceCode);\n+ CreateStdServiceLineWithItem(StandardServiceCode.Code, Item.\"No.\", ExpectedQuantity);\n+\n+ // [GIVEN] Create Service Order with Location.\n+ LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ ServiceHeader.Validate(\"Location Code\", Location.Code);\n+ ServiceHeader.Modify();\n+\n+ // [GIVEN] Create Service Item Line.\n+ LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, '');\n+\n+ // [GIVEN] Delete Standard Service Group Code.\n+ StandardServiceItemGrCode.DeleteAll();\n+\n+ // [WHEN] Insert Service Line through Standard Service Code.\n+ ServiceItemGroupCode2 := '';\n+ StandardServiceCode2 := StandardServiceCode.Code;\n+ StandardServiceItemGrCode.InsertServiceLines(ServiceItemLine);\n+\n+ // [THEN] Verify \"Reserved Qty. (Base)\" must be updated in the Service Line.\n+ FindServiceLine(ServiceLine, ServiceHeader.\"Document Type\", ServiceHeader.\"No.\");\n+ ServiceLine.CalcFields(\"Reserved Qty. (Base)\");\n+ Assert.AreEqual(\n+ ExpectedQuantity,\n+ ServiceLine.\"Reserved Qty. (Base)\",\n+ StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption(\"Reserved Qty. (Base)\"), ExpectedQuantity, ServiceLine.TableCaption()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1597,6 +1670,33 @@ codeunit 136119 \"Service Standard Codes\"\n VATEntry.TestField(\"Posting Date\", PostingDate);\n end;\n \n+ local procedure SetItemInventory(Item: Record Item; Quantity: Decimal; LocationCode: Code[10])\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.CreateItemJournalTemplate(ItemJournalTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJournalBatch, ItemJournalTemplate.Name);\n+\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalTemplate.Name, ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", Quantity);\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Modify();\n+\n+ LibraryInventory.PostItemJournalLine(ItemJournalTemplate.Name, ItemJournalLine.\"Journal Batch Name\");\n+ end;\n+\n+ local procedure CreateStdServiceLineWithItem(StandardServiceCode: Code[10]; ItemNo: Code[20]; Quantity: Decimal)\n+ var\n+ StandardServiceLine: Record \"Standard Service Line\";\n+ begin\n+ LibraryService.CreateStandardServiceLine(StandardServiceLine, StandardServiceCode);\n+ StandardServiceLine.Validate(Type, StandardServiceLine.Type::Item);\n+ StandardServiceLine.Validate(\"No.\", ItemNo);\n+ StandardServiceLine.Validate(Quantity, Quantity);\n+ StandardServiceLine.Modify(true);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al b/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al\nindex 33f69be4c731..53eb121209b6 100644\n--- a/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al\n+++ b/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al\n@@ -159,6 +159,11 @@ table 5998 \"Standard Service Item Gr. Code\"\n ServLine.\"Line No.\" := ServLine.GetLineNo();\n OnBeforeInsertServLine(ServLine);\n ServLine.Insert(true);\n+\n+ if ServLine.Type = ServLine.Type::Item then\n+ if ServLine.Reserve = ServLine.Reserve::Always then\n+ ServLine.AutoReserve(false);\n+\n InsertExtendedText(ServLine);\n end;\n until StdServLine.Next() = 0;\n"} -{"metadata": {"area": "manufacturing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208649", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-03-03", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137088, "functionName": ["ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\nindex 7415eaa53ccd..2573227dbca7 100644\n--- a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n@@ -45,6 +45,8 @@ codeunit 137088 \"SCM Order Planning - III\"\n LineExistErr: Label 'Requistion line in %1 worksheet should exist for item %2';\n PurchaseLineQuantityBaseErr: Label '%1.%2 must be nearly equal to %3.', Comment = '%1 : Purchase Line, %2 : Quantity (Base), %3 : Value.';\n BOMFixedQtyCalcFormulaErr: Label 'BOM Fixed Quantity Calculation Formula should be used to calculate the values.';\n+ RelesedProdOrderComponentQtyPerRoundingErr: Label 'Relesed Production Order Item Component Quantity per %1 Not Match With Expected Result %2';\n+ RelesedProdOrderComponentExpQtyRoundingErr: Label 'Relesed Production Order Item Component Expected Quantity %1 Not Match With Expected Result %2';\n \n [Test]\n [HandlerFunctions('MakeSupplyOrdersPageHandler')]\n@@ -2988,6 +2990,73 @@ codeunit 137088 \"SCM Order Planning - III\"\n VerifyStartingTimeOnFirmPlannedProductionOrder(StartingTime, ChildItem.\"No.\", ProductionOrderNo);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalPageHandler,ErrorMessageHandler')]\n+ procedure ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking()\n+ var\n+ BaseItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ComponentItem: Record Item;\n+ ProdOrderComp: Record \"Prod. Order Component\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ ProductItem: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ ExpectedQty: Decimal;\n+ RelesedProdOrderNo: Code[20];\n+ Status: Enum \"Production Order Status\";\n+ begin\n+ // [SCENARIO 562766] If a component's Item UOM has a 'Quantity Rounding Precision' of 1, & a Finished Good consumes partial quantity, \n+ // the Prod. Order created from the Planning of a Sales Order pulls in the Component with a 'Qty. Per' and 'Exp. Qty.' of 0.\n+ Initialize();\n+\n+ // [GIVEN] Created Component Item\n+ LibraryInventory.CreateItem(ComponentItem);\n+ ComponentItem.Validate(\"Replenishment System\", ComponentItem.\"Replenishment System\"::Purchase);\n+ ComponentItem.Validate(\"Rounding Precision\", LibraryRandom.RandPrecision());\n+ ComponentItem.Validate(\"Reordering Policy\", ComponentItem.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ ComponentItem.Validate(\"Include Inventory\", true);\n+ ComponentItem.Modify(true);\n+\n+ // [GIVEN] Set Qty. Rounding Precision = 1 for Component Item\n+ BaseItemUnitOfMeasure.Get(ComponentItem.\"No.\", ComponentItem.\"Base Unit of Measure\");\n+ BaseItemUnitOfMeasure.Validate(\"Qty. Rounding Precision\", 1);\n+ BaseItemUnitOfMeasure.Modify();\n+\n+ // [GIVEN] Created Production Bom using Component Item\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ComponentItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, ComponentItem.\"No.\", LibraryRandom.RandDecInDecimalRange(0.01, 0.99, 2));\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify();\n+\n+ // [GIVEN] Created Master Item and Production Bom Assigned to Master Item\n+ LibraryInventory.CreateItem(ProductItem);\n+ ProductItem.Validate(\"Replenishment System\", ProductItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProductItem.Validate(\"Rounding Precision\", 1);\n+ ProductItem.Validate(\"Reordering Policy\", ProductItem.\"Reordering Policy\"::Order);\n+ ProductItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProductItem.Modify(true);\n+\n+ // [GIVEN] Created Sales Order Using Master Item Quantity - 1\n+ CreateSalesOrder(SalesHeader, ProductItem.\"No.\", '', 1, 1);\n+\n+ // [WHEN] Created Released Prod. Order From Sales Order Using Planning\n+ LibraryPlanning.CreateProdOrderUsingPlanning(ProductionOrder, Status::\"Firm Planned\", SalesHeader.\"No.\", ProductItem.\"No.\");\n+ RelesedProdOrderNo := LibraryManufacturing.ChangeStatusFirmPlanToReleased(ProductionOrder.\"No.\");\n+\n+ // [WHEN] Find Released Production Order Component\n+ FindProdOrderLine(ProdOrderLine, RelesedProdOrderNo);\n+ FindProdOrderComponent(ProdOrderComp, ProdOrderLine.\"Prod. Order No.\", ComponentItem.\"No.\");\n+\n+ // [WHEN] Getting Expected result using Component Rounding Precision\n+ ExpectedQty := Round(ProductionBOMLine.\"Quantity per\" * BaseItemUnitOfMeasure.\"Qty. Rounding Precision\" / BaseItemUnitOfMeasure.\"Qty. Rounding Precision\", ComponentItem.\"Rounding Precision\");\n+\n+ // [THEN] Expected Quantity must be Equal to Production Order Component \"Quantity per\" And \"Expected Quantity\"\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Quantity per\", StrSubstNo(RelesedProdOrderComponentQtyPerRoundingErr, ProdOrderComp.\"Quantity per\", ExpectedQty));\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Expected Quantity\", StrSubstNo(RelesedProdOrderComponentExpQtyRoundingErr, ProdOrderComp.\"Expected Quantity\", ExpectedQty));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3805,6 +3874,14 @@ codeunit 137088 \"SCM Order Planning - III\"\n Assert.IsTrue(ProductionOrder.\"Starting Time\" = StartingTime, '');\n end;\n \n+ local procedure FindProdOrderLine(var ProdOrderLine: Record \"Prod. Order Line\"; ProductionOrderNo: Code[20])\n+ begin\n+ ProdOrderLine.Reset();\n+ ProdOrderLine.SetRange(Status, ProdOrderLine.Status::Released);\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProductionOrderNo);\n+ ProdOrderLine.FindFirst();\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure MakeSupplyOrdersPageHandler(var MakeSupplyOrders: Page \"Make Supply Orders\"; var Response: Action)\n@@ -3911,5 +3988,16 @@ codeunit 137088 \"SCM Order Planning - III\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ procedure ModalPageHandler(var CreateOrderFromSales: Page \"Create Order From Sales\"; var Response: Action)\n+ begin\n+ Response := Action::Yes;\n+ end;\n+\n+ [MessageHandler]\n+ procedure ErrorMessageHandler(Message: Text[1024])\n+ begin\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\nindex 36930a9e2aaa..23674793f0e1 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n@@ -43,6 +43,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp: Record \"Prod. Order Component\";\n ProdOrderRoutingLine2: Record \"Prod. Order Routing Line\";\n ProdBOMLine: array[99] of Record \"Production BOM Line\";\n+ ProdLineItem: Record Item;\n UOMMgt: Codeunit \"Unit of Measure Management\";\n MfgCostCalcMgt: Codeunit \"Mfg. Cost Calculation Mgt.\";\n VersionMgt: Codeunit VersionManagement;\n@@ -297,6 +298,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp.Validate(\"Unit of Measure Code\", ProdBOMLine[Level].\"Unit of Measure Code\");\n if (ProdOrderComp.\"Item No.\" <> '') and Item2.Get(ProdOrderComp.\"Item No.\") then\n QtyRoundPrecision := UOMMgt.GetQtyRoundingPrecision(Item2, ProdBOMLine[Level].\"Unit of Measure Code\");\n+ CheckingRoundingPrecision(Item2, ProdLineItem, QtyRoundPrecision, Level);\n if QtyRoundPrecision <> 0 then\n ProdOrderComp.\"Quantity per\" := Round(ProdBOMLine[Level].\"Quantity per\" * LineQtyPerUOM / ItemQtyPerUOM, QtyRoundPrecision)\n else\n@@ -975,6 +977,21 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderLineToCheck.TestField(Quantity);\n end;\n \n+ local procedure CheckingRoundingPrecision(ChildItem: Record Item; ProdLineItem: Record Item; var QtyRoundPrecision: Decimal; Level: Integer)\n+ begin\n+ if (ChildItem.\"Rounding Precision\" = 0) or (QtyRoundPrecision = 0) then\n+ exit;\n+\n+ if (not ProdLineItem.Get(ProdOrderLine.\"Item No.\")) or (ProdLineItem.\"Replenishment System\" <> ProdLineItem.\"Replenishment System\"::\"Prod. Order\") then\n+ exit;\n+\n+ if (ChildItem.\"Base Unit of Measure\" <> ProdBOMLine[Level].\"Unit of Measure Code\") then\n+ exit;\n+ QtyRoundPrecision := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision\" := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision (Base)\" := ChildItem.\"Rounding Precision\";\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterInsertProdRoutingLine(var ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; ProdOrderLine: Record \"Prod. Order Line\")\n begin\n"} -{"metadata": {"area": "sales", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209496", "base_commit": "d080f087349d4713e1782f2f2630819714cb6738", "created_at": "2025-03-10", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134979, "functionName": ["AddTextforLanguageInReminderLevelCommunication"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\nindex ca7812c9329a..746513941686 100644\n--- a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n@@ -814,6 +814,30 @@ codeunit 134979 \"Reminder Automation Tests\"\n ReminderAutomationCard.Close();\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerFalse,ReminderLevelCommunicationPageHandler,LanguagesPageHandler')]\n+ procedure AddTextforLanguageInReminderLevelCommunication()\n+ var\n+ ReminderTerms: Record \"Reminder Terms\";\n+ ReminderLevel: Record \"Reminder Level\";\n+ ReminderTermSetupPage: TestPage \"Reminder Terms Setup\";\n+ begin\n+ // [SCENARIO 568005] Adding text for language in Reminder Level Communication.\n+ Initialize();\n+\n+ // [GIVEN] Create Reminder Term with levels\n+ LibraryErm.CreateReminderTerms(ReminderTerms);\n+ LibraryErm.CreateReminderLevel(ReminderLevel, ReminderTerms.Code);\n+\n+ // [WHEN] Open Reminder Term Setup page and add text for language\n+ ReminderTermSetupPage.OpenEdit();\n+ ReminderTermSetupPage.GoToRecord(ReminderTerms);\n+ ReminderTermSetupPage.ReminderLevelSetup.First();\n+\n+ // [THEN] Varify that the text for language is added in Reminder Level Communication.\n+ ReminderTermSetupPage.ReminderLevelSetup.CustomerCommunications.Invoke();\n+ end;\n+\n local procedure CreateReminderAttachmentText(ReminderTerms: Record \"Reminder Terms\"; LanguageCode: Code[10])\n var\n ReminderLevel: Record \"Reminder Level\";\n@@ -1211,6 +1235,25 @@ codeunit 134979 \"Reminder Automation Tests\"\n exit(true);\n end;\n \n+ [ConfirmHandler]\n+ procedure ConfirmHandlerFalse(QuestionText: Text[1024]; var Relpy: Boolean)\n+ begin\n+ Relpy := false;\n+ end;\n+\n+ [PageHandler]\n+ procedure ReminderLevelCommunicationPageHandler(var ReminderLevelCommunication: TestPage \"Reminder Level Communication\")\n+ begin\n+ ReminderLevelCommunication.\"Add New Language\".Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ procedure LanguagesPageHandler(var Languages: TestPage \"Languages\")\n+ begin\n+ Languages.Filter.SetFilter(\"Code\", 'ENG');\n+ Languages.OK().Invoke();\n+ end;\n+\n var\n LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n LibraryUtility: Codeunit \"Library - Utility\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al b/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al\nindex 10d284cc0688..23e132dc418b 100644\n--- a/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al\n@@ -304,17 +304,19 @@ page 835 \"Reminder Level Communication\"\n var\n ReminderAttachmentText: Record \"Reminder Attachment Text\";\n ReminderEmailText: Record \"Reminder Email Text\";\n+ ReminderLevel: Record \"Reminder Level\";\n begin\n if LanguageCode = '' then\n exit;\n \n CurrentLanguage.SetRange(Code, LanguageCode);\n CurrentLanguage.FindFirst();\n+ ReminderLevel.Get(Rec.\"Reminder Terms Code\", Rec.\"No.\");\n \n- if not ReminderAttachmentText.Get(Rec.\"Reminder Attachment Text\", CurrentLanguage.Code) then\n+ if not ReminderAttachmentText.Get(ReminderLevel.\"Reminder Attachment Text\", CurrentLanguage.Code) then\n if CreateNewEntry then begin\n- ReminderAttachmentText.SetDefaultContentForNewLanguage(Rec.\"Reminder Attachment Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n- ReminderEmailText.SetDefaultContentForNewLanguage(Rec.\"Reminder Email Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n+ ReminderAttachmentText.SetDefaultContentForNewLanguage(ReminderLevel.\"Reminder Attachment Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n+ ReminderEmailText.SetDefaultContentForNewLanguage(ReminderLevel.\"Reminder Email Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n end\n else\n Error(NoTextForSelectedLanguageErr, CurrentLanguage.Code);\n"} -{"metadata": {"area": "sales", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208748", "base_commit": "d080f087349d4713e1782f2f2630819714cb6738", "created_at": "2025-03-03", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134377, "functionName": ["CheckMultipleExtendedTextFromBlanketSalesOrderToSalesOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al\nindex da968e20f561..e56565d8c806 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al\n@@ -33,6 +33,7 @@ codeunit 134377 \"ERM Sales Blanket Order\"\n BlanketOrderLineNoFieldError: Label 'Blanket Order Line No. missing on related Sales Credit Memo';\n UnitPriceIsChangedErr: Label 'Unit Price is changed on Quantity update.';\n ValueMustBeEqualErr: Label '%1 must be equal to %2 in the %3.', Comment = '%1 = Field Caption , %2 = Expected Value, %3 = Table Caption';\n+ TotalRecordCountErr: Label 'Total record count must be equal to %1', Comment = '%1 = Record Count.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1377,10 +1378,45 @@ codeunit 134377 \"ERM Sales Blanket Order\"\n until SalesLine.Next() = 0;\n end;\n \n+ [Test]\n+ procedure CheckMultipleExtendedTextFromBlanketSalesOrderToSalesOrder()\n+ var\n+ BlanketSalesHeader: Record \"Sales Header\";\n+ SalesOrderLine: Record \"Sales Line\";\n+ NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n+ BlanketSalesOrder: TestPage \"Blanket Sales Order\";\n+ CustomerNo: Code[20];\n+ OrderNo: Code[20];\n+ begin\n+ // [SCENARIO 567891] Verify the multiple extended texts line when converting a blanket sales order to a sales order.\n+ Initialize();\n+\n+ // [GIVEN] Create Blanket Sales Order With Multiple Extended Items.\n+ CustomerNo := CreateBlanketSalesOrder(BlanketSalesOrder);\n+\n+ // [GIVEN] Find Blanket Sales Order.\n+ BlanketSalesHeader.SetRange(\"Sell-to Customer No.\", CustomerNo);\n+ BlanketSalesHeader.FindFirst();\n+\n+ // [WHEN] Convert the blanket sales order into a sales order.\n+ OrderNo := LibrarySales.BlanketSalesOrderMakeOrder(BlanketSalesHeader);\n+\n+ // [THEN] Calculate no. of Sales order line record.\n+ SalesOrderLine.SetRange(\"Document Type\", SalesOrderLine.\"Document Type\"::Order);\n+ SalesOrderLine.SetRange(\"Document No.\", OrderNo);\n+\n+ // [THEN] Verify the sales order line record count with the extended text records.\n+ Assert.AreEqual(\n+ SalesOrderLine.Count(), CalculateBlanketSalesOrderLineRecords(BlanketSalesHeader),\n+ StrSubstNo(TotalRecordCountErr, SalesOrderLine.Count()));\n+\n+ NotificationLifecycleMgt.RecallAllNotifications();\n+ end;\n+\n local procedure Initialize()\n var\n- LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"ERM Sales Blanket Order\");\n LibrarySetupStorage.Restore();\n@@ -1716,6 +1752,61 @@ codeunit 134377 \"ERM Sales Blanket Order\"\n exit(Purchasing.Code);\n end;\n \n+ local procedure CreateBlanketSalesOrder(var BlanketSalesOrder: TestPage \"Blanket Sales Order\"): Code[20]\n+ var\n+ Customer: Record Customer;\n+ Item: array[3] of Record Item;\n+ i: Integer;\n+ begin\n+ LibrarySales.CreateCustomer(Customer);\n+ BlanketSalesOrder.OpenNew();\n+ BlanketSalesOrder.\"Sell-to Customer No.\".SetValue(Customer.\"No.\");\n+ for i := 1 to LibraryRandom.RandIntInRange(3, 3) do begin\n+ CreateMultipleItemWithExtendedText(Item[i]);\n+ CreateBlanketSalesLineFromSubformPage(BlanketSalesOrder, Item[i]);\n+ end;\n+ BlanketSalesOrder.Close();\n+\n+ exit(Customer.\"No.\");\n+ end;\n+\n+ local procedure CreateMultipleItemWithExtendedText(var Item: Record Item)\n+ var\n+ ExtendedTextHeader: Record \"Extended Text Header\";\n+ ExtendedTextLine: Record \"Extended Text Line\";\n+ begin\n+ Item.Get(CreateItem());\n+ Item.Validate(\"Automatic Ext. Texts\", true);\n+ Item.Modify(true);\n+\n+ LibraryInventory.CreateExtendedTextHeaderItem(ExtendedTextHeader, Item.\"No.\");\n+ LibraryInventory.CreateExtendedTextLineItem(ExtendedTextLine, ExtendedTextHeader);\n+ ExtendedTextLine.Validate(Text, Item.\"No.\");\n+ ExtendedTextLine.Modify(true);\n+ end;\n+\n+ local procedure CreateBlanketSalesLineFromSubformPage(var BlanketSalesOrder: TestPage \"Blanket Sales Order\"; Item: Record Item)\n+ var\n+ SalesLineType: Enum \"Sales Line Type\";\n+ begin\n+ BlanketSalesOrder.SalesLines.New();\n+ BlanketSalesOrder.SalesLines.Type.SetValue(SalesLineType::Item);\n+ BlanketSalesOrder.SalesLines.\"No.\".SetValue(Item.\"No.\");\n+ BlanketSalesOrder.SalesLines.Quantity.SetValue(LibraryRandom.RandInt(10));\n+ Commit();\n+ BlanketSalesOrder.SalesLines.Next();\n+ end;\n+\n+ local procedure CalculateBlanketSalesOrderLineRecords(BlanketSalesOrder: Record \"Sales Header\"): Integer\n+ var\n+ BlanketSalesLine: Record \"Sales Line\";\n+ begin\n+ BlanketSalesLine.SetRange(\"Document Type\", BlanketSalesOrder.\"Document Type\");\n+ BlanketSalesLine.SetRange(\"Document No.\", BlanketSalesOrder.\"No.\");\n+\n+ exit(BlanketSalesLine.Count);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al\nindex afe6215fb8bd..c200af6e4f0f 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al\n@@ -203,7 +203,7 @@ codeunit 87 \"Blanket Sales Order to Order\"\n SalesLineOrder.\"Qty. to Asm. to Order (Base)\" := SalesLineOrder.\"Quantity (Base)\";\n end;\n SalesLineOrder.DefaultDeferralCode();\n- if IsSalesOrderLineToBeInserted(SalesLineOrder) then begin\n+ if IsSalesOrderLineToBeInserted(SalesLineOrder, SalesLineBlanketOrder) then begin\n OnBeforeInsertSalesOrderLine(SalesLineOrder, SalesHeaderOrder, SalesLineBlanketOrder, SalesHeaderBlanketOrder);\n SalesLineOrder.Insert();\n OnAfterInsertSalesOrderLine(SalesLineOrder, SalesHeaderOrder, SalesLineBlanketOrder, SalesHeaderBlanketOrder);\n@@ -447,15 +447,12 @@ codeunit 87 \"Blanket Sales Order to Order\"\n ItemCheckAvail.RaiseUpdateInterruptedError();\n end;\n \n- local procedure IsSalesOrderLineToBeInserted(SalesOrderLine: Record \"Sales Line\"): Boolean\n- var\n- AttachedToSalesLine: Record \"Sales Line\";\n+ local procedure IsSalesOrderLineToBeInserted(SalesOrderLine: Record \"Sales Line\"; BlanketSalesOrderLine: Record \"Sales Line\"): Boolean\n begin\n if not SalesOrderLine.IsExtendedText() then\n exit(true);\n- exit(\n- AttachedToSalesLine.Get(\n- SalesOrderLine.\"Document Type\", SalesOrderLine.\"Document No.\", SalesOrderLine.\"Attached to Line No.\"));\n+\n+ exit(BlanketSalesOrderLine.\"Attached to Line No.\" <> 0);\n end;\n \n [IntegrationEvent(false, false)]\n"} -{"metadata": {"area": "project", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209450", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-03-10", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136302, "functionName": ["PurchaseLineNotReservedWhenItemTypeNonInventoryOrService"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al b/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al\nindex 4e0f927efe26..2324fe2d413a 100644\n--- a/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al\n@@ -4339,6 +4339,73 @@ codeunit 136302 \"Job Consumption Purchase\"\n JobLedgerEntry.TestField(\"Lot No.\", LotNo);\n end;\n \n+ [Test]\n+ [HandlerFunctions('PurchaseOrderReserveFromCurrentLineHandler2')]\n+ procedure PurchaseLineNotReservedWhenItemTypeNonInventoryOrService()\n+ var\n+ Item: array[3] of Record Item;\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ JobTask: Record \"Job Task\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ PurchaseOrder: TestPage \"Purchase Order\";\n+ i: Integer;\n+ Quantity: Decimal;\n+ begin\n+ // [SCENARIO 563482] Verify that it is not possible to reserve a sales line when the item type is Non-Inventory or Service.\n+ Initialize();\n+ Quantity := LibraryRandom.RandIntInRange(100, 200);\n+\n+ // [GIVEN] Create Inventory, Non Inventory & Service type item.\n+ LibraryInventory.CreateItem(Item[1]);\n+ LibraryInventory.CreateNonInventoryTypeItem(Item[2]);\n+ LibraryInventory.CreateServiceTypeItem(Item[3]);\n+\n+ // [GIVEN] Create Job and Job Task.\n+ CreateJobWithJobTask(JobTask);\n+\n+ // [GIVEN] Create Purchase Header.\n+ LibraryPurchase.CreatePurchHeader(\n+ PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, LibraryPurchase.CreateVendorNo());\n+\n+ // [GIVEN] Set the Work Date to be later than the Purchase Document date.\n+ WorkDate := WorkDate() + 1;\n+\n+ for i := 1 to LibraryRandom.RandIntInRange(3, 3) do begin\n+ // [GIVEN] Create a job planning line for Inventory, Non-Inventory, and Service type items.\n+ CreateJobPlanningLine(\n+ JobPlanningLine, JobTask, JobPlanningLine.Type::Item, Item[i].\"No.\", Quantity, true);\n+ JobPlanningLine.Validate(Reserve, JobPlanningLine.Reserve::Optional);\n+ JobPlanningLine.Validate(\"Unit Cost\", LibraryRandom.RandDec(1000, 2));\n+ JobPlanningLine.Modify(true);\n+\n+ // [GIVEN] Create a purchase line for Inventory, Non-Inventory, and Service type items.\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item[i].\"No.\", Quantity);\n+\n+ Commit();\n+ // [GIVEN] Open Purchase Order Page\n+ PurchaseOrder.OpenEdit();\n+ PurchaseOrder.Filter.SetFilter(\"No.\", PurchaseHeader.\"No.\");\n+ PurchaseOrder.PurchLines.Filter.SetFilter(\"No.\", Item[i].\"No.\");\n+\n+ // [WHEN] Item type Inventory\n+ if Item[i].IsInventoriableType() then\n+ PurchaseOrder.PurchLines.Reserve.Invoke()\n+ else\n+ asserterror PurchaseOrder.PurchLines.Reserve.Invoke();\n+ PurchaseOrder.Close();\n+ end;\n+\n+ // [GIVEN] Post the Purchase Document\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false);\n+\n+ // [THEN] Verify Remaining Quantity on Item Ledger Entry.\n+ VerifyItemLedgerEntry(Item[1], Quantity); // Item Type Inventory.\n+ VerifyItemLedgerEntry(Item[2], 0); // Item Type Non Inventory.\n+ VerifyItemLedgerEntry(Item[3], 0); // Item Type Service.\n+ end;\n+\n local procedure Initialize()\n var\n WarehouseEmployee: Record \"Warehouse Employee\";\n@@ -6702,6 +6769,14 @@ codeunit 136302 \"Job Consumption Purchase\"\n CreateInvtPutawayPickMvmt.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PurchaseOrderReserveFromCurrentLineHandler2(var Reservation: TestPage Reservation)\n+ begin\n+ Reservation.\"Reserve from Current Line\".Invoke();\n+ Reservation.OK().Invoke();\n+ end;\n+\n local procedure UndoPurchReciptAndAdjustCostItemEntries(var PurchaseLine: Record \"Purchase Line\"; var Item: Record Item)\n begin\n UndoPurchRcpt(PurchaseLine);\n@@ -6790,5 +6865,20 @@ codeunit 136302 \"Job Consumption Purchase\"\n PostedWhseReceiptLine.SetRange(\"Source Line No.\", PurchaseLine.\"Line No.\");\n PostedWhseReceiptLine.FindFirst();\n end;\n+\n+ local procedure VerifyItemLedgerEntry(Item: Record Item; Quantity: Decimal)\n+ var\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ begin\n+ ItemLedgerEntry.SetRange(\"Item No.\", Item.\"No.\");\n+ ItemLedgerEntry.FindFirst();\n+ ItemLedgerEntry.CalcFields(\"Reserved Quantity\");\n+ if Item.IsInventoriableType() then\n+ Assert.AreEqual(ItemLedgerEntry.\"Reserved Quantity\", Quantity,\n+ StrSubstNo(ValueMustMatchErr, ItemLedgerEntry.\"Reserved Quantity\", Quantity))\n+ else\n+ Assert.AreEqual(ItemLedgerEntry.\"Reserved Quantity\", Quantity,\n+ StrSubstNo(ValueMustMatchErr, ItemLedgerEntry.\"Reserved Quantity\", Quantity))\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al\nindex bd599bfee8d8..b3988a5302d9 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al\n@@ -10,10 +10,11 @@ using Microsoft.Inventory.Planning;\n using Microsoft.Inventory.Requisition;\n using Microsoft.Inventory.Tracking;\n using Microsoft.Inventory.Ledger;\n-using Microsoft.Projects.Project.Job;\n using Microsoft.Foundation.Navigate;\n using Microsoft.Foundation.UOM;\n+using Microsoft.Projects.Project.Job;\n using Microsoft.Projects.Project.Ledger;\n+using Microsoft.Purchases.Document;\n \n codeunit 1032 \"Job Planning Line-Reserve\"\n {\n@@ -37,6 +38,7 @@ codeunit 1032 \"Job Planning Line-Reserve\"\n InvalidLineTypeErr: Label 'must be %1 or %2', Comment = '%1 and %2 are line type options, fx. Budget or Billable';\n SummaryTypeTxt: Label '%1, %2', Locked = true;\n SourceDoc2Txt: Label '%1 %2', Locked = true;\n+ NonInvReserveTypeErr: Label 'Non-inventory and service items cannot be reserved.';\n \n procedure CreateReservation(JobPlanningLine: Record \"Job Planning Line\"; Description: Text[100]; ExpectedReceiptDate: Date; Quantity: Decimal; QuantityBase: Decimal; ForReservEntry: Record \"Reservation Entry\")\n var\n@@ -848,6 +850,7 @@ codeunit 1032 \"Job Planning Line-Reserve\"\n if IsReserved then\n exit;\n \n+ CheckItemType(CalcReservEntry);\n JobPlanningLine.SetAutoCalcFields(\"Reserved Qty. (Base)\");\n JobPlanningLine.FilterLinesForReservation(\n CalcReservEntry, ReservSummEntryNo - 131, sender.GetAvailabilityFilter(AvailabilityDate), Positive);\n@@ -873,6 +876,23 @@ codeunit 1032 \"Job Planning Line-Reserve\"\n until (JobPlanningLine.Next(NextStep) = 0) or (RemainingQtyToReserveBase = 0);\n end;\n \n+ local procedure CheckItemType(CalcReservEntry: Record \"Reservation Entry\")\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ if (CalcReservEntry.\"Source Type\" <> Database::\"Purchase Line\") or (CalcReservEntry.\"Source Subtype\" <> CalcReservEntry.\"Source Subtype\"::\"1\") then\n+ exit;\n+\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseLine.\"Document Type\"::Order);\n+ PurchaseLine.SetRange(\"Document No.\", CalcReservEntry.\"Source ID\");\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);\n+ PurchaseLine.SetRange(\"No.\", CalcReservEntry.\"Item No.\");\n+ PurchaseLine.SetRange(\"Special Order\", false);\n+ if PurchaseLine.FindFirst() then\n+ if PurchaseLine.IsNonInventoriableItem() then\n+ Error(NonInvReserveTypeErr);\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterReservQuantity(JobPlanningLine: Record \"Job Planning Line\"; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)\n begin\n"} {"metadata": {"area": "shopify", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-201169", "base_commit": "2fe81026ed3d6c42bfc6e4de6a3c71b2f8fd3726", "created_at": "2024-11-26", "environment_setup_version": "26.0", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139581, "functionName": ["UnitTestLogItemEmptyDescription"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al b/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al\nindex 60adc2f06fad..063e50b4cbc1 100644\n--- a/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al\n+++ b/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al\n@@ -91,6 +91,35 @@ codeunit 139581 \"Shpfy Skipped Record Log Test\"\n LibraryAssert.AreEqual('Item is blocked or sales blocked.', SkippedRecord.\"Skipped Reason\", 'Skipped reason is not as expected');\n end;\n \n+ [Test]\n+\n+ [HandlerFunctions('AddItemToShopifyHandler')]\n+ procedure UnitTestLogItemEmptyDescription()\n+ var\n+\n+ Item: Record Item;\n+ SkippedRecord: Record \"Shpfy Skipped Record\";\n+ AddItemToShopify: Report \"Shpfy Add Item to Shopify\";\n+ begin\n+ // [SCENARIO] Log skipped record when item description is empty\n+ Initialize();\n+\n+ // [GIVEN] An item record that has empty description\n+ CreateItem(Item);\n+ Commit();\n+\n+ // [WHEN] Run report Add Items to Shopify\n+ Item.SetRange(\"No.\", Item.\"No.\");\n+ AddItemToShopify.SetShop(Shop.Code);\n+ AddItemToShopify.SetTableView(Item);\n+ AddItemToShopify.Run();\n+\n+ // [THEN] Related record is created in shopify skipped record table\n+ SkippedRecord.SetRange(\"Record ID\", Item.RecordId);\n+ LibraryAssert.IsTrue(SkippedRecord.FindFirst(), 'Skipped record is not created');\n+ LibraryAssert.AreEqual('Item description is empty.', SkippedRecord.\"Skipped Reason\", 'Skipped reason is not as expected');\n+ end;\n+\n [Test]\n procedure UnitTestLogItemVariantBlocked()\n var\n@@ -841,13 +870,19 @@ codeunit 139581 \"Shpfy Skipped Record Log Test\"\n SalesShipmentLine.Insert(false);\n end;\n \n- local procedure CreateBlockedItem(var Item: Record Item)\n+ local procedure CreateItem(var Item: Record Item)\n begin\n Item.Init();\n Item.\"No.\" := Any.AlphanumericText(20);\n+ Item.Insert(false);\n+ end;\n+\n+ local procedure CreateBlockedItem(var Item: Record Item)\n+ begin\n+ CreateItem(Item);\n Item.Blocked := true;\n Item.\"Sales Blocked\" := true;\n- Item.Insert(false);\n+ Item.Modify(false);\n end;\n \n local procedure CreateBlockedItemVariant(Item: Record Item; var ItemVariant: Record \"Item Variant\")\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al b/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al\nindex 38d77856d51a..965c1f8db398 100644\n--- a/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al\n+++ b/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al\n@@ -57,7 +57,9 @@ codeunit 30174 \"Shpfy Create Product\"\n ProductId := ProductApi.CreateProduct(TempShopifyProduct, TempShopifyVariant, TempShopifyTag)\n else\n ProductId := TempShopifyProduct.Id;\n- ProductExport.UpdateProductTranslations(ProductId, Item);\n+\n+ if ProductId <> 0 then\n+ ProductExport.UpdateProductTranslations(ProductId, Item);\n end;\n \n internal procedure CreateTempProduct(Item: Record Item; var TempShopifyProduct: Record \"Shpfy Product\" temporary; var TempShopifyVariant: Record \"Shpfy Variant\" temporary; var TempShopifyTag: Record \"Shpfy Tag\" temporary)\ndiff --git a/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al b/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al\nindex b99f15d3c8bc..7ede7561af67 100644\n--- a/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al\n+++ b/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al\n@@ -57,18 +57,24 @@ report 30106 \"Shpfy Add Item to Shopify\"\n var\n SkippedRecord: Codeunit \"Shpfy Skipped Record\";\n begin\n- if Item.Blocked or Item.\"Sales Blocked\" then\n- SkippedRecord.LogSkippedRecord(Item.RecordId, ItemIsBlockedLbl, ShopifyShop)\n- else begin\n- if GuiAllowed then begin\n- CurrItemNo := Item.\"No.\";\n- ProcessDialog.Update();\n- end;\n+ if Item.Blocked or Item.\"Sales Blocked\" then begin\n+ SkippedRecord.LogSkippedRecord(Item.RecordId, ItemIsBlockedLbl, ShopifyShop);\n+ exit;\n+ end;\n \n- ShopifyCreateProduct.Run(Item);\n+ if Item.Description = '' then begin\n+ SkippedRecord.LogSkippedRecord(Item.RecordId, ItemDescriptionIsEmptyLbl, ShopifyShop);\n+ exit;\n+ end;\n \n- ProductFilter += Format(ShopifyCreateProduct.GetProductId()) + '|';\n+ if GuiAllowed then begin\n+ CurrItemNo := Item.\"No.\";\n+ ProcessDialog.Update();\n end;\n+\n+ ShopifyCreateProduct.Run(Item);\n+\n+ ProductFilter += Format(ShopifyCreateProduct.GetProductId()) + '|';\n end;\n \n trigger OnPostDataItem()\n@@ -190,6 +196,7 @@ report 30106 \"Shpfy Add Item to Shopify\"\n ChangeDefaultLocationLbl: Label 'Change default location';\n ChangeSKUMappingLbl: Label 'Change SKU mapping';\n ItemIsBlockedLbl: Label 'Item is blocked or sales blocked.';\n+ ItemDescriptionIsEmptyLbl: Label 'Item description is empty.';\n \n /// \n /// Set Shop.\n"} -{"metadata": {"area": "inventory", "image_count": 10}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209835", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-12", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137045, "functionName": ["CarryOutPlanWkshActionMsgFilterCheckGenerateLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\nindex 70e088d9fb0c..6032fbc7e22b 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n@@ -35,6 +35,7 @@ codeunit 137045 \"SCM Bugfixes\"\n WrongSKUUnitCostErr: Label 'Stockkeeping unit''s unit cost must be equal to item unit cost';\n EmailNotAutomaticallySetErr: Label 'Expected BuyFromContactEmail to automatically be set to the email of the contact, but it wasnt.';\n UseInTransitLocationErr: Label 'You can use In-Transit location %1 for transfer orders only.', Comment = '%1: Location code';\n+ PurchaseOrderErr: Label 'Unexpected new purchase order created';\n \n [Test]\n [Scope('OnPrem')]\n@@ -929,6 +930,53 @@ codeunit 137045 \"SCM Bugfixes\"\n OpenOrderPromisingPage(SalesHeader.\"No.\")\n end;\n \n+ [Test]\n+ procedure CarryOutPlanWkshActionMsgFilterCheckGenerateLines()\n+ var\n+ Item: Record Item;\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ ReqLine: Record \"Requisition Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ NewPurchOrderChoice: Option \" \",\"Make Purch. Orders\",\"Make Purch. Orders & Print\",\"Copy to Req. Wksh\";\n+ ActualCount: Integer;\n+ begin\n+ // [SCENARIO 563852] When a Filter is set in the Planning Worksheet to a specific Action Message (e.g. Cancel) , Carry Out Action Message Only Process\n+ // Filtered Planning Worksheet Lines.\n+ Initialize();\n+\n+ // [GIVEN] New Item Created with Reordering Policy Order.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Reordering Policy\", Item.\"Reordering Policy\"::Order);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Created New Purchase Order with New Item with 4 Qty.\n+ CreatePurchaseOrder(PurchaseHeader, Item.\"No.\", 4);\n+\n+ // [GIVEN] Created New Sales Order with New Item with 4 Qty and Future Shipment Date.\n+ CreateSalesOrder(SalesHeader, Item.\"No.\", '', 4, SalesHeader.\"Document Type\"::Order);\n+ SalesLine.Get(SalesLine.\"Document Type\"::Order, SalesHeader.\"No.\", 10000);\n+ SalesLine.Validate(\"Shipment Date\", CalcDate('<1W>', WorkDate()));\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Calculate regenerative plan in planning worksheet update Planning Worksheet.\n+ CalculatePlanOnPlanningWorksheet(Item, WorkDate(), CalcDate('<1Y>', WorkDate()), true, false);\n+\n+ // [GIVEN] Set \"Accept Action Message\" on all Requisition lines.\n+ UpdatePlanningWorkSheetwithVendor(ReqLine, Item.\"No.\", PurchaseHeader.\"Buy-from Vendor No.\");\n+\n+ // [WHEN] Running Carry Out Action Message For Requisition lines \"Action Message\"::Cancel.\n+ ReqLine.SetRange(\"Action Message\", ReqLine.\"Action Message\"::Cancel);\n+ LibraryPlanning.CarryOutPlanWksh(ReqLine, 0, NewPurchOrderChoice::\"Make Purch. Orders\", 0, 0, '', '', '', '');\n+\n+ // [WHEN] Count Actual Purchase Lines.\n+ CountActualPurchaseLine(Item, PurchaseLine, ActualCount);\n+\n+ // [THEN] Verify Actual Count Match with Expected Result.\n+ Assert.AreEqual(0, ActualCount, PurchaseOrderErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1547,6 +1595,50 @@ codeunit 137045 \"SCM Bugfixes\"\n SalesOrder.SalesLines.OrderPromising.Invoke();\n end;\n \n+ local procedure CountActualPurchaseLine(Item: Record Item; PurchaseLine: Record \"Purchase Line\"; var ActualCount: Integer)\n+ begin\n+ Clear(ActualCount);\n+ PurchaseLine.Reset();\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseLine.\"Document Type\"::Order);\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);\n+ PurchaseLine.SetRange(\"No.\", Item.\"No.\");\n+ if PurchaseLine.FindSet() then\n+ ActualCount := PurchaseLine.Count;\n+ end;\n+\n+ local procedure CalculatePlanOnPlanningWorksheet(var ItemRec: Record Item; OrderDate: Date; ToDate: Date; RespectPlanningParameters: Boolean; Regenerative: Boolean)\n+ var\n+ TmpItemRec: Record Item;\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ CalculatePlanPlanWksh: Report \"Calculate Plan - Plan. Wksh.\";\n+ begin\n+ LibraryPlanning.SelectRequisitionWkshName(RequisitionWkshName, RequisitionWkshName.\"Template Type\"::Planning); // Find Requisition Worksheet Name to Calculate Plan.\n+ Commit();\n+ CalculatePlanPlanWksh.InitializeRequest(OrderDate, ToDate, RespectPlanningParameters, true, true, '', 0D, false);\n+ CalculatePlanPlanWksh.SetTemplAndWorksheet(RequisitionWkshName.\"Worksheet Template Name\", RequisitionWkshName.Name, Regenerative);\n+ if ItemRec.HasFilter then\n+ TmpItemRec.CopyFilters(ItemRec)\n+ else begin\n+ ItemRec.Get(ItemRec.\"No.\");\n+ TmpItemRec.SetRange(\"No.\", ItemRec.\"No.\");\n+ end;\n+ CalculatePlanPlanWksh.SetTableView(TmpItemRec);\n+ CalculatePlanPlanWksh.UseRequestPage(false);\n+ CalculatePlanPlanWksh.RunModal();\n+ end;\n+\n+ local procedure UpdatePlanningWorkSheetwithVendor(var RequisitionLine: Record \"Requisition Line\"; ItemNo: Code[20]; VendorNo: Code[20])\n+ begin\n+ RequisitionLine.SetRange(Type, RequisitionLine.Type::Item);\n+ RequisitionLine.SetRange(\"No.\", ItemNo);\n+ RequisitionLine.FindSet();\n+ repeat\n+ RequisitionLine.Validate(\"Vendor No.\", VendorNo);\n+ RequisitionLine.Validate(\"Accept Action Message\", true);\n+ RequisitionLine.Modify(true);\n+ until RequisitionLine.Next() = 0;\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListModalPageHandler(var ContactLookup: Page \"Contact List\"; var Response: Action)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al\nindex ef8b6ccb7c96..e302df62ef99 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al\n@@ -469,8 +469,10 @@ report 99001020 \"Carry Out Action Msg. - Plan.\"\n \"Requisition Line\".SetRange(\"Worksheet Template Name\", CurrReqWkshTemp);\n if CurrReqWkshTemp <> '' then\n \"Requisition Line\".SetRange(\"Journal Batch Name\", CurrReqWkshName);\n+ \"Requisition Line\".FilterGroup(2);\n \"Requisition Line\".SetRange(Type, \"Requisition Line\".Type::Item);\n \"Requisition Line\".SetFilter(\"Action Message\", '<>%1', \"Requisition Line\".\"Action Message\"::\" \");\n+ \"Requisition Line\".FilterGroup(0);\n OnAfterSetReqLineFilters(\"Requisition Line\");\n end;\n \n"} -{"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-211548", "base_commit": "90ae5af1c2b3627dcfb41b03c59fe32ddec31c6d", "created_at": "2025-03-28", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\General Journal"], "FAIL_TO_PASS": [{"codeunitID": 134832, "functionName": ["GeneralJournalPostingWithMultipleAllocationAccountLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al b/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al\nindex c48ce3167512..fd84cef1d0ad 100644\n--- a/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al\n+++ b/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al\n@@ -1362,9 +1362,52 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n VerifyGLEntryAmount(GLEntry, 0, 1);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerTrue,MessageHandler,GeneralJournalTemplateHandler')]\n+ procedure GeneralJournalPostingWithMultipleAllocationAccountLines()\n+ var\n+ DestinationGLAccount: Record \"G/L Account\";\n+ BalancingGLAccount: Record \"G/L Account\";\n+ AllocationAccount: array[2] of Record \"Allocation Account\";\n+ GLEntry: Record \"G/L Entry\";\n+ GeneralJournalPage: TestPage \"General Journal\";\n+ DocumentNumber: Code[10];\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO 569036] Issue with posting General Journals that contain Allocation Account lines with 10 entries resulting an error\n+ Initialize();\n+\n+ // [GIVEN] Create Destination and Balancing G/L Account\n+ DestinationGLAccount.Get(LibraryERM.CreateGLAccountNoWithDirectPosting());\n+ BalancingGLAccount.Get(LibraryERM.CreateGLAccountNoWithDirectPosting());\n+\n+ // [GIVEN] An Allocation Account with variable GL distributions\n+ CreateAllocationAccountwithSpecificNoOfFixedGLDistributionLines(AllocationAccount[1], DestinationGLAccount, LibraryRandom.RandIntInRange(10, 10));\n+ CreateAllocationAccountwithSpecificNoOfFixedGLDistributionLines(AllocationAccount[2], DestinationGLAccount, LibraryRandom.RandIntInRange(10, 10));\n+ Amount := LibraryRandom.RandDecInDecimalRange(10000, 10000, 0);\n+\n+ // [GIVEN] The General Journal line with Allocation Account\n+ CreateBalancingLinesOnGeneralJournalWithTwoAllocationAccount(\n+ DocumentNumber,\n+ GeneralJournalPage,\n+ AllocationAccount,\n+ BalancingGLAccount.\"No.\",\n+ Amount);\n+\n+ // [WHEN] The General Journal line is posted\n+ GeneralJournalPage.Post.Invoke();\n+\n+ // [THEN] Verify the General Journal Posted Successfylly\n+ GLEntry.SetRange(\"Document No.\", DocumentNumber);\n+ GLEntry.SetRange(\"G/L Account No.\", DestinationGLAccount.\"No.\");\n+ Assert.AreEqual(20, GLEntry.Count(), 'Wrong number of G/L Entries created for the destination account');\n+ GLEntry.CalcSums(Amount);\n+ Assert.AreEqual(Amount, GLEntry.Amount, 'The rounding amount was not distributed correctly');\n+ end;\n+\n local procedure CreateLineOnCashReceiptJournal(var DocumentNumber: Code[10]; var CashReceiptJournalPage: TestPage \"Cash Receipt Journal\"; AccountType: Enum \"Gen. Journal Account Type\"; AccountNo: Code[20];\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20])\n var\n GenJournalBatch: Record \"Gen. Journal Batch\";\n GenJournalTemplateType: Enum \"Gen. Journal Template Type\";\n@@ -1405,8 +1448,8 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n end;\n \n local procedure CreateLineOnSalesJournal(var DocumentNumber: Code[10]; var SalesJournalPage: TestPage \"Sales Journal\"; AccountType: Enum \"Gen. Journal Account Type\"; AccountNo: Code[20];\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20])\n var\n GenJournalBatch: Record \"Gen. Journal Batch\";\n GenJournalTemplateType: Enum \"Gen. Journal Template Type\";\n@@ -1429,8 +1472,8 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n end;\n \n local procedure CreateLineOnPurchaseJournal(var DocumentNumber: Code[10]; var PurchaseJournalPage: TestPage \"Purchase Journal\"; AccountType: Enum \"Gen. Journal Account Type\"; AccountNo: Code[20];\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20])\n var\n GenJournalBatch: Record \"Gen. Journal Batch\";\n GenJournalTemplateType: Enum \"Gen. Journal Template Type\";\n@@ -1869,15 +1912,15 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n var GenJournalLine: Record \"Gen. Journal Line\";\n AccountNo: Code[20];\n AccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20];\n- Amount: Decimal;\n- DocumentNo: Code[20];\n- GenJournalBatch: Record \"Gen. Journal Batch\";\n- VATBusPostingGroup: Code[20];\n- VATProdPostingGroup: Code[20];\n- CurrencyCode: Code[20];\n- SelectedAllocAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20];\n+ Amount: Decimal;\n+ DocumentNo: Code[20];\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ VATBusPostingGroup: Code[20];\n+ VATProdPostingGroup: Code[20];\n+ CurrencyCode: Code[20];\n+ SelectedAllocAccountNo: Code[20])\n begin\n LibraryJournals.CreateGenJournalLine(\n GenJournalLine,\n@@ -1898,6 +1941,59 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n GenJournalLine.Modify(true);\n end;\n \n+ local procedure CreateAllocationAccountwithSpecificNoOfFixedGLDistributionLines(\n+ var AllocationAccount: Record \"Allocation Account\";\n+ DestinationGLAccount: Record \"G/L Account\"; NoOfFixedAccountDistributionLines: Integer)\n+ var\n+ AllocationAccountPage: TestPage \"Allocation Account\";\n+ FixedAllocationAccountCode: Code[20];\n+ i: Integer;\n+ begin\n+ FixedAllocationAccountCode := CreateAllocationAccountWithFixedDistribution(AllocationAccountPage);\n+\n+ for i := 1 to NoOfFixedAccountDistributionLines do begin\n+ AddGLDestinationAccountForFixedDistribution(AllocationAccountPage, DestinationGLAccount);\n+ AllocationAccountPage.FixedAccountDistribution.Share.SetValue(LibraryRandom.RandDecInDecimalRange(10, 10, 0));\n+ if i <> NoOfFixedAccountDistributionLines then\n+ AllocationAccountPage.FixedAccountDistribution.New();\n+ end;\n+ AllocationAccountPage.Close();\n+\n+ AllocationAccount.Get(FixedAllocationAccountCode);\n+ end;\n+\n+ local procedure CreateBalancingLinesOnGeneralJournalWithTwoAllocationAccount(\n+ var DocumentNumber: Code[10];\n+ var GeneralJournalPage: TestPage \"General Journal\";\n+ AllocationAccount: array[2] of Record \"Allocation Account\";\n+ BalancingAccountNo: Code[20];\n+ Amount: Decimal)\n+ var\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ AccountType: Enum \"Gen. Journal Account Type\";\n+ i: Integer;\n+ begin\n+ CreateGeneralJournalBatch(GenJournalBatch);\n+ LibraryVariableStorage.Enqueue(GenJournalBatch.\"Journal Template Name\");\n+ GeneralJournalPage.OpenEdit();\n+ DocumentNumber := LibraryRandom.RandText(10);\n+ GeneralJournalPage.\"Document No.\".SetValue(DocumentNumber);\n+ GeneralJournalPage.\"Account Type\".SetValue(AccountType::\"G/L Account\");\n+ GeneralJournalPage.\"Account No.\".SetValue(BalancingAccountNo);\n+ GeneralJournalPage.Description.SetValue(DocumentNumber);\n+ GeneralJournalPage.Amount.SetValue(-Amount);\n+\n+ for i := 1 to ArrayLen(AllocationAccount) do begin\n+ GeneralJournalPage.New();\n+ GeneralJournalPage.\"Document No.\".SetValue(DocumentNumber);\n+ GeneralJournalPage.\"Account Type\".SetValue(AccountType::\"Allocation Account\");\n+ GeneralJournalPage.\"Account No.\".SetValue(AllocationAccount[i].\"No.\");\n+ GeneralJournalPage.Description.SetValue(DocumentNumber);\n+ GeneralJournalPage.Amount.SetValue(Amount / 2);\n+\n+ end;\n+ end;\n+\n [ModalPageHandler]\n procedure HandleEditDimensionSetEntriesPage(var EditDimensionSetEntriesPage: TestPage \"Edit Dimension Set Entries\")\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al b/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al\nindex fbe1c90d5d49..5d91bbcfd787 100644\n--- a/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al\n@@ -470,13 +470,13 @@ codeunit 2677 \"Gen. Journal Alloc. Acc. Mgt.\"\n exit(-1);\n \n if Increment >= 1000 then\n- exit(1000);\n+ exit(100);\n \n if Increment >= 100 then\n- exit(100);\n+ exit(10);\n \n if Increment >= 10 then\n- exit(10);\n+ exit(1);\n \n exit(Increment);\n end;\n"} -{"metadata": {"area": "sales", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209737", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-12", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137408, "functionName": ["InvDiscPctAndAmtInSOIsNotZeroWhenCreateAndShipInvPickFromSOHavingInvDiscPctAndAmt"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al\nindex c2a61ccd9648..7e9f79d98dc2 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al\n@@ -38,6 +38,7 @@ codeunit 137408 \"SCM Warehouse VI\"\n AbsoluteValueEqualToQuantityErr: Label 'Absolute value of %1.%2 must be equal to the test quantity.', Comment = '%1 - tablename, %2 - fieldname.';\n RegisteringPickInterruptedErr: Label 'Registering pick has been interrupted.';\n LotNoNotAvailableInInvtErr: Label 'Lot No. %1 is not available in inventory, it has already been reserved for another document, or the quantity available is lower than the quantity to handle specified on the line.', Comment = '%1: Lot No.';\n+ InvtPickCreatedTxt: Label 'Number of Invt. Pick activities created';\n \n [Test]\n [HandlerFunctions('ItemTrackingLinesHandler,ItemTrackingSummaryHandler,MessageHandler,WhseItemTrackingLinesHandler,ConfirmHandlerTrue')]\n@@ -4143,6 +4144,115 @@ codeunit 137408 \"SCM Warehouse VI\"\n VerifyWarehouseJournalLineWithReasonCode(WarehouseJournalBatch, WarehouseJournalLine, ReasonCode.Code);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ [Scope('OnPrem')]\n+ procedure InvDiscPctAndAmtInSOIsNotZeroWhenCreateAndShipInvPickFromSOHavingInvDiscPctAndAmt()\n+ var\n+ Bin: Record Bin;\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ Location: Record Location;\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ WhseActivityPost: Codeunit \"Whse.-Activity-Post\";\n+ SalesOrder: TestPage \"Sales Order\";\n+ InvDiscountPct: Decimal;\n+ begin\n+ // [SCENARIO 256471] It should not be allowed to change location code in an inventory pick that has lines\n+ Initialize();\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create a Location.\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create a Bin.\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, Bin.Code, '', '');\n+\n+ // [GIVEN] Create a Warehouse Employee.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create a Customer and Validate \"Currency Code\".\n+ LibrarySales.CreateCustomer(Customer);\n+ Customer.Validate(\"Currency Code\", CreateCurrency());\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Create an Item Journal Line and Post it.\n+ CreateItemJournalLine(ItemJournalLine, Item.\"No.\", Location.Code, LibraryRandom.RandIntInRange(20, 20), WorkDate(), Bin.Code, Item.\"Base Unit of Measure\");\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+\n+ // [GIVEN] Update Work Date.\n+ WorkDate(CalcDate('', WorkDate()));\n+\n+ // [GIVEN] Create a Sales Header.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ SalesHeader.Validate(\"Currency Factor\", LibraryRandom.RandIntInRange(2, 2));\n+ SalesHeader.Modify(true);\n+\n+ // [GIVEN] Create a Sales Line and Validate \"Location Code\" and \"Unit Price\".\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", LibraryRandom.RandInt(0));\n+ SalesLine.Validate(\"Location Code\", Location.Code);\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandIntInRange(1000, 1000));\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Generate and save Invoice Discount % in a Variable.\n+ InvDiscountPct := LibraryRandom.RandIntInRange(10, 10);\n+\n+ // [GIVEN] Open Sales Order page and Set Invoice Disc. Pct.\n+ SalesOrder.OpenEdit();\n+ SalesOrder.GoToRecord(SalesHeader);\n+ SalesOrder.SalesLines.\"Invoice Disc. Pct.\".SetValue(InvDiscountPct);\n+ SalesOrder.Close();\n+\n+ // [GIVEN] Find Sales Header.\n+ SalesHeader.Get(SalesHeader.\"Document Type\", SalesHeader.\"No.\");\n+\n+ // [GIVEN] Release Sales Order.\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+\n+ // [GIVEN] Create Invt. Pick from Sales Order.\n+ LibraryVariableStorage.Enqueue(InvtPickCreatedTxt);\n+ LibraryWarehouse.CreateInvtPutPickMovement(\n+ WarehouseActivityHeader.\"Source Document\"::\"Sales Order\", SalesHeader.\"No.\", false, true, false);\n+\n+ // [GIVEN] Find Warehouse Activity Line.\n+ FindWarehouseActivityLine(\n+ WarehouseActivityLine, WarehouseActivityLine.\"Source Document\"::\"Sales Order\", SalesHeader.\"No.\",\n+ WarehouseActivityLine.\"Activity Type\"::\"Invt. Pick\");\n+\n+ // [GIVEN] Find Warehouse Activity Header and Validate \"Posting Date\".\n+ WarehouseActivityHeader.Get(WarehouseActivityLine.\"Activity Type\", WarehouseActivityLine.\"No.\");\n+ WarehouseActivityHeader.Validate(\"Posting Date\", CalcDate('', WorkDate()));\n+ WarehouseActivityHeader.Modify(true);\n+\n+ // [GIVEN] Validate \"Qty. to Handle\" in Warehouse Activity Line.\n+ WarehouseActivityLine.Validate(\"Qty. to Handle\", WarehouseActivityLine.Quantity);\n+ WarehouseActivityLine.Modify(true);\n+\n+ // [GIVEN] Update Work Date.\n+ WorkDate(WarehouseActivityHeader.\"Posting Date\");\n+\n+ // [GIVEN] Post Inventory Pick.\n+ WhseActivityPost.Run(WarehouseActivityLine);\n+\n+ // [GIVEN] Find Sales Header.\n+ SalesHeader.Get(SalesHeader.\"Document Type\", SalesHeader.\"No.\");\n+\n+ // [WHEN] Open Sales Order page.\n+ SalesOrder.OpenEdit();\n+ SalesOrder.GoToRecord(SalesHeader);\n+\n+ // [THEN] Invoice Disc. Pct. is equal to InvDiscountPct.\n+ SalesOrder.SalesLines.\"Invoice Disc. Pct.\".AssertEquals(InvDiscountPct);\n+ SalesOrder.Close();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -6187,6 +6297,65 @@ codeunit 137408 \"SCM Warehouse VI\"\n RunCalculateCountingPeriodFromWarehousePhysicalInventoryJournalReasonCode(WarehouseJournalBatch, LocationCode, ReasonCode);\n end;\n \n+ local procedure CreateItemJournalLine(var ItemJournalLine: Record \"Item Journal Line\"; ItemNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal; PostingDate: Date; BinCode: Code[20]; UnitOfMeasureCode: Code[10])\n+ begin\n+ LibraryInventory.CreateItemJnlLine(\n+ ItemJournalLine, ItemJournalLine.\"Entry Type\"::Purchase, PostingDate, ItemNo,\n+ Quantity, LocationCode);\n+ ItemJournalLine.Validate(\"Unit of Measure Code\", UnitOfMeasureCode);\n+ if BinCode <> '' then\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n+ local procedure FindWarehouseActivityLine(var WarehouseActivityLine: Record \"Warehouse Activity Line\"; SourceDocument: Enum \"Warehouse Activity Source Document\"; SourceNo: Code[20]; ActivityType: Enum \"Warehouse Activity Type\")\n+ begin\n+ FilterWarehouseActivityLine(WarehouseActivityLine, SourceDocument, SourceNo, ActivityType);\n+ WarehouseActivityLine.FindFirst();\n+ end;\n+\n+ local procedure FilterWarehouseActivityLine(var WarehouseActivityLine: Record \"Warehouse Activity Line\"; SourceDocument: Enum \"Warehouse Activity Source Document\"; SourceNo: Code[20]; ActivityType: Enum \"Warehouse Activity Type\")\n+ begin\n+ WarehouseActivityLine.SetRange(\"Source Document\", SourceDocument);\n+ if SourceNo <> '' then\n+ WarehouseActivityLine.SetRange(\"Source No.\", SourceNo);\n+ WarehouseActivityLine.SetRange(\"Activity Type\", ActivityType);\n+ end;\n+\n+ local procedure CreateCurrency(): Code[10]\n+ var\n+ Currency: Record Currency;\n+ begin\n+ LibraryERM.CreateCurrency(Currency);\n+ LibraryERM.SetCurrencyGainLossAccounts(Currency);\n+ Currency.Validate(\"Residual Gains Account\", Currency.\"Realized Gains Acc.\");\n+ Currency.Validate(\"Residual Losses Account\", Currency.\"Realized Losses Acc.\");\n+ Currency.Validate(\"Currency Factor\", LibraryRandom.RandDecInDecimalRange(1.176471, 1.176471, 0));\n+ Currency.Modify(true);\n+ CreateCurrExchangeRate(Currency.Code, CalcDate('', WorkDate()), LibraryRandom.RandDecInDecimalRange(0.5, 0.5, 0));\n+ CreateCurrExchangeRate(Currency.Code, CalcDate('', WorkDate()), LibraryRandom.RandDecInDecimalRange(0.75, 0.75, 0));\n+ CreateCurrExchangeRate(Currency.Code, CalcDate('', WorkDate()), LibraryRandom.RandDecInDecimalRange(0.85, 0.85, 0));\n+ exit(Currency.Code);\n+ end;\n+\n+ procedure CreateCurrExchangeRate(CurrencyCode: Code[10]; StartingDate: Date; RelExchRateAmt: Decimal)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ CurrencyExchangeRate.Init();\n+ CurrencyExchangeRate.Validate(\"Currency Code\", CurrencyCode);\n+ CurrencyExchangeRate.Validate(\"Starting Date\", StartingDate);\n+ CurrencyExchangeRate.Insert(true);\n+\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", LibraryRandom.RandDecInDecimalRange(1.0, 1.0, 0));\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", LibraryRandom.RandDecInDecimalRange(1.0, 1.0, 0));\n+\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", RelExchRateAmt);\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", RelExchRateAmt);\n+ CurrencyExchangeRate.Validate(\"Fix Exchange Rate Amount\", CurrencyExchangeRate.\"Fix Exchange Rate Amount\"::Currency);\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Whse.-Activity-Register\", 'OnBeforeAutoReserveForSalesLine', '', false, false)]\n local procedure InvokeErrorOnRegisteringWarehousePick(var TempWhseActivLineToReserve: Record \"Warehouse Activity Line\" temporary; var IsHandled: Boolean)\n begin\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\nindex 46625d5d87be..a6b8616014e4 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n@@ -4483,7 +4483,8 @@ table 36 \"Sales Header\"\n SalesLine.Validate(\"Shipment Date\", \"Shipment Date\");\n FieldNo(\"Currency Factor\"):\n if SalesLine.Type <> SalesLine.Type::\" \" then begin\n- SalesLine.Validate(\"Unit Price\");\n+ if SalesLine.\"Line Discount %\" <> 0 then\n+ SalesLine.Validate(\"Unit Price\");\n SalesLine.Validate(\"Unit Cost (LCY)\");\n if SalesLine.\"Job No.\" <> '' then\n JobTransferLine.FromSalesHeaderToPlanningLine(SalesLine, \"Currency Factor\");\n"} -{"metadata": {"area": "crm", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-211521", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-28", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Marketing"], "FAIL_TO_PASS": [{"codeunitID": 136201, "functionName": ["TaskListPageHasFixedSystemTaskTypeFilterAsOrganiserOrContactAttendee"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al b/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al\nindex 415be9b03958..5d64f93de20a 100644\n--- a/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al\n+++ b/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al\n@@ -6029,6 +6029,39 @@ codeunit 136201 \"Marketing Contacts\"\n Assert.AreEqual(VerifyInteractionLogEntry.\"Duration (Min.)\", DurationMin, ValueMustMatch);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalPageHandlerForTask')]\n+ procedure TaskListPageHasFixedSystemTaskTypeFilterAsOrganiserOrContactAttendee()\n+ var\n+ Contact: Record Contact;\n+ Task: Record \"To-do\";\n+ TempTask: Record \"To-do\" temporary;\n+ ContactCard: TestPage \"Contact Card\";\n+ TaskList: TestPage \"Task List\";\n+ begin\n+ // [SCENARIO 568324] Task List page has a fixed System Task Type filter as 'Organizer|Contact Attendee' when Next Task Date Drilldown on Contact card\n+ Initialize();\n+\n+ // [GIVEN] Create Contact\n+ LibraryMarketing.CreateCompanyContact(Contact);\n+\n+ // [GIVEN] Create Task for Contact\n+ Task.SetRange(\"Contact No.\", Contact.\"No.\");\n+ TempTask.CreateTaskFromTask(Task);\n+\n+ // [WHEN] Open Contact Card and Drilldonw 'Next Task Date' also Trap Task List\n+ ContactCard.OpenView();\n+ ContactCard.GoToRecord(Contact);\n+ TaskList.Trap();\n+ ContactCard.\"Next Task Date\".Drilldown();\n+\n+ // [THEN] Verify Correct filter has been set on the page\n+ TaskList.\"Contact No.\".AssertEquals(Contact.\"No.\");\n+ Assert.AreEqual(\n+ StrSubstNo('%1|%2', Task.\"System To-do Type\"::Organizer, Task.\"System To-do Type\"::\"Contact Attendee\"),\n+ TaskList.Filter.GetFilter(\"System To-do Type\"), 'Wrong filter was set');\n+ end;\n+\n local procedure Initialize()\n var\n MarketingSetup: Record \"Marketing Setup\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al b/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al\nindex 0abd1f7a2168..9afd469a9661 100644\n--- a/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al\n+++ b/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al\n@@ -567,7 +567,7 @@ table 5050 Contact\n CalcFormula = min(\"To-do\".Date where(\"Contact Company No.\" = field(\"Company No.\"),\n \"Contact No.\" = field(filter(\"Lookup Contact No.\")),\n Closed = const(false),\n- \"System To-do Type\" = const(\"Contact Attendee\")));\n+ \"System To-do Type\" = filter(Organizer | \"Contact Attendee\")));\n Caption = 'Next Task Date';\n Editable = false;\n FieldClass = FlowField;\n"} -{"metadata": {"area": "inventory", "image_count": 13}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213683", "base_commit": "2c11d98aa3150d7339d436f8d55436c71d8219ac", "created_at": "2025-04-21", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134385, "functionName": ["RenameItemNoExistsInValueEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al\nindex 6a941857a14b..e7111913cd47 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al\n@@ -55,6 +55,7 @@\n AmountNotMatchedErr: Label 'Amount not matched.';\n AmountMustSameErr: Label 'Amount must be same';\n QtyHandleMustSameErr: Label 'Qty to handle must equal';\n+ CannotRenameItemErr: Label 'You cannot rename %1 in a %2 because it is used in Sales Document lines.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -4819,6 +4820,57 @@\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure RenameItemNoExistsInValueEntry()\n+ var\n+ Item: Record Item;\n+ Item2: Record Item;\n+ ItemVariant: Record \"Item Variant\";\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ NewItemCode: Code[20];\n+ begin\n+ // [SCENARIO 574250] Verify Rename Item No. After Posting and Generating Value Entries with Variant Codes and blank Variant Code.\n+ Initialize();\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create an Item Variant for Item.\n+ LibraryInventory.CreateItemVariant(ItemVariant, Item.\"No.\");\n+\n+ // [GIVEN] Create and Post Item Journal with and without Variant Code.\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Item);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type::Item, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", LibraryRandom.RandDecInRange(10, 20, 2));\n+ ItemJournalLine.Validate(\"Variant Code\", ItemVariant.Code);\n+ ItemJournalLine.Modify(true);\n+\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", LibraryRandom.RandDecInRange(10, 20, 2));\n+\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+\n+ // [GIVEN] Create and Post Sales Invoice with Variant Code.\n+ LibrarySales.CreateSalesInvoice(SalesHeader, SalesLine, Item, '', ItemVariant.Code, LibraryRandom.RandDecInRange(5, 10, 2), WorkDate(), LibraryRandom.RandDecInRange(100, 200, 2));\n+ LibrarySales.PostSalesDocument(SalesHeader, true, true);\n+\n+ // [WHEN] Rename Item No. on Item. \n+ NewItemCode := LibraryUtility.GenerateRandomCode(Item.FieldNo(\"No.\"), Database::Item);\n+ Item2.Get(Item.\"No.\");\n+ Item2.Rename(NewItemCode);\n+\n+ // [THEN] Verify Item No. should be renamed with new Item No.\n+ Assert.AreEqual(NewItemCode, Item2.\"No.\", StrSubstNo(CannotRenameItemErr, Item2.FieldCaption(\"No.\"), Item2.TableCaption()));\n+ end;\n+\n local procedure Initialize()\n var\n AllProfile: Record \"All Profile\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al\nindex 9735e4b2417a..b22bbc4e706e 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al\n@@ -161,7 +161,7 @@ codeunit 99000795 \"Mfg. Item Integration\"\n end;\n \n [EventSubscriber(ObjectType::Table, Database::\"Item Variant\", 'OnBeforeRenameEvent', '', false, false)]\n- local procedure OnBeforeRenameItemVariant(var Rec: Record \"Item Variant\"; var xRec: Record \"Item Variant\")\n+ local procedure OnBeforeRenameItemVariant(var Rec: Record \"Item Variant\"; var xRec: Record \"Item Variant\"; RunTrigger: Boolean)\n var\n BOMComponent: Record \"BOM Component\";\n AssemblyHeader: Record \"Assembly Header\";\n@@ -176,6 +176,9 @@ codeunit 99000795 \"Mfg. Item Integration\"\n ItemLedgerEntry: Record \"Item Ledger Entry\";\n ProdOrderLine: Record \"Prod. Order Line\";\n begin\n+ if not RunTrigger then\n+ exit;\n+\n if xRec.\"Item No.\" <> Rec.\"Item No.\" then begin\n ProdOrderLine.SetRange(\"Item No.\", xRec.\"Item No.\");\n ProdOrderLine.SetRange(\"Variant Code\", xRec.Code);\n"} -{"metadata": {"area": "crm", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213671", "base_commit": "ca1a8ca2e11612d9b6b4876b9f855ed854b79aa4", "created_at": "2025-04-19", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Marketing"], "FAIL_TO_PASS": [{"codeunitID": 136209, "functionName": ["BuildCaptionLengthIssueOnOpportunitiesListPage"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al b/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al\nindex 435658251b18..e8a08e0f2c3f 100644\n--- a/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al\n+++ b/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al\n@@ -1818,6 +1818,45 @@ codeunit 136209 \"Marketing Opportunity Mgmt\"\n Opportunity.CloseOpportunity();\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure BuildCaptionLengthIssueOnOpportunitiesListPage()\n+ var\n+ Opportunity: Record Opportunity;\n+ Contact: Record Contact;\n+ OpportunityList: TestPage \"Opportunity List\";\n+ FilterText: Text;\n+ i: Integer;\n+ begin\n+ // [SCENARIO 574639] The length of the string is XX but it must be less than or equal to 20 characters when working with Opportunities\n+ Initialize();\n+\n+ // [GIVEN] Create contact and it's opportunity\n+ LibraryMarketing.CreateCompanyContact(Contact);\n+ LibraryMarketing.CreateOpportunity(Opportunity, Contact.\"No.\");\n+\n+ // [GIVEN] Prepare Filter Text with Salesperson Code\n+ for i := 1 to LibraryRandom.RandIntInRange(20, 20) do\n+ FilterText += Opportunity.\"Salesperson Code\" + '|';\n+ FilterText += Opportunity.\"Salesperson Code\";\n+\n+ // [THEN] Open Opportunities list page and apply salesperson code filter without issue\n+ Clear(FilterText);\n+ OpportunityList.OpenView();\n+ OpportunityList.Filter.SetFilter(\"Salesperson Code\", FilterText);\n+ OpportunityList.Close();\n+\n+ // [GIVEN] Prepare Filter Text with Contact No\n+ for i := 1 to LibraryRandom.RandIntInRange(20, 20) do\n+ FilterText += Contact.\"No.\" + '|';\n+ FilterText += Contact.\"No.\";\n+\n+ // [THEN] Open Opportunities list page and contacts filter without issue\n+ OpportunityList.OpenView();\n+ OpportunityList.Filter.SetFilter(\"Contact No.\", FilterText);\n+ OpportunityList.Close();\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"Marketing Opportunity Mgmt\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al b/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al\nindex c70c6c1e7b4f..816671802677 100644\n--- a/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al\n+++ b/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al\n@@ -630,7 +630,7 @@ page 5123 \"Opportunity List\"\n if Filter <> '' then begin\n RecRef.GetTable(RecVar);\n IndexFieldRef := RecRef.Field(IndexFieldNo);\n- IndexFieldRef.SetRange(Filter);\n+ IndexFieldRef.SetFilter(Filter);\n if RecRef.FindFirst() then begin\n TextFieldRef := RecRef.Field(TextFieldNo);\n CaptionText := CopyStr(Format(IndexFieldRef.Value) + ' ' + Format(TextFieldRef.Value), 1, MaxStrLen(CaptionText));\n"} {"metadata": {"area": "subscription billing", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-215645", "base_commit": "b9e347e7aad6087240fd3d30e0b566e35d96697f", "created_at": "2025-05-15", "environment_setup_version": "26.3", "project_paths": ["App\\Apps\\W1\\SubscriptionBilling\\App", "App\\Apps\\W1\\SubscriptionBilling\\Test"], "FAIL_TO_PASS": [{"codeunitID": 148155, "functionName": ["SalesInvoiceShowsSubtotalForServCommItem"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al b/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al\nindex af155cbc15d6..571455d8853c 100644\n--- a/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al\n+++ b/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al\n@@ -1116,9 +1116,10 @@ codeunit 148155 \"Contracts Test\"\n SalesLine: Record \"Sales Line\";\n SalesQuote: TestPage \"Sales Quote\";\n begin\n+ // [SCENARIO] Sales Quote containing Items with \"Subscription Option\" = \"Subscription Item\" excludes such items from document totals\n Initialize();\n \n- // [GIVEN] Sales Document with Sales Line and Item with \"Subscription Option\" = \"Subscription Item\"\n+ // [GIVEN] Sales Quote with Sales Line and Item with \"Subscription Option\" = \"Subscription Item\"\n LibrarySales.CreateSalesHeader(SalesHeader, Enum::\"Sales Document Type\"::Quote, '');\n ContractTestLibrary.CreateItemWithServiceCommitmentOption(Item, Enum::\"Item Service Commitment Type\"::\"Service Commitment Item\");\n ContractTestLibrary.UpdateItemUnitCostAndPrice(Item, LibraryRandom.RandDec(1000, 2), LibraryRandom.RandDec(1000, 2), true);\n@@ -1136,6 +1137,38 @@ codeunit 148155 \"Contracts Test\"\n SalesQuote.Close();\n end;\n \n+ [Test]\n+ procedure SalesInvoiceShowsSubtotalForServCommItem()\n+ var\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ SubContractsItemManagement: Codeunit \"Sub. Contracts Item Management\";\n+ SalesInvoice: TestPage \"Sales Invoice\";\n+ begin\n+ // [SCENARIO] Sales Invoice containing Items with \"Subscription Option\" = \"Subscription Item\" excludes such items from document totals\n+ Initialize();\n+\n+ // [GIVEN] Sales Invoice with Sales Line and Item with \"Subscription Option\" = \"Subscription Item\"\n+ LibrarySales.CreateSalesHeader(SalesHeader, Enum::\"Sales Document Type\"::Invoice, '');\n+ ContractTestLibrary.CreateItemWithServiceCommitmentOption(Item, Enum::\"Item Service Commitment Type\"::\"Service Commitment Item\");\n+ ContractTestLibrary.UpdateItemUnitCostAndPrice(Item, LibraryRandom.RandDec(1000, 2), LibraryRandom.RandDec(1000, 2), true);\n+\n+ SubContractsItemManagement.SetAllowInsertOfInvoicingItem(true);\n+ \n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", LibraryRandom.RandDec(10, 2));\n+\n+ // [THEN] Total Amount should be filled in Sales Invoice page\n+ SalesLine.TestField(\"Line Amount\");\n+ SalesLine.TestField(\"Exclude from Doc. Total\", false);\n+\n+ // Sales Line Total in Sales Quote should not have a value\n+ SalesInvoice.OpenView();\n+ SalesInvoice.GoToRecord(SalesHeader);\n+ SalesInvoice.SalesLines.\"Total Amount Excl. VAT\".AssertEquals(Item.\"Unit Price\" * SalesLine.Quantity);\n+ SalesInvoice.Close();\n+ end;\n+\n [Test]\n [HandlerFunctions('ConfirmHandler,ExchangeRateSelectionModalPageHandler,MessageHandler')]\n procedure TestChangeOfHarmonizedBillingFieldInContractType()\n", "patch": "diff --git a/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al b/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al\nindex 92df07efd5e2..8e828e4915df 100644\n--- a/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al\n+++ b/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al\n@@ -265,8 +265,9 @@ tableextension 8054 \"Sales Line\" extends \"Sales Line\"\n if Rec.IsTypeServiceObject() then\n Rec.Validate(\"Exclude from Doc. Total\", IsContractRenewalLocal);\n end else\n- if (Rec.Type = Rec.Type::Item) and (Rec.\"No.\" <> '') and (not Rec.IsLineAttachedToBillingLine()) then\n- Rec.Validate(\"Exclude from Doc. Total\", ItemManagement.IsServiceCommitmentItem(Rec.\"No.\"));\n+ if Rec.IsSalesDocumentTypeWithServiceCommitments() then\n+ if ((Rec.Type = Rec.Type::Item) and (Rec.\"No.\" <> '')) then\n+ Rec.Validate(\"Exclude from Doc. Total\", ItemManagement.IsServiceCommitmentItem(Rec.\"No.\"));\n end;\n \n internal procedure IsLineWithServiceObject(): Boolean\n"} {"metadata": {"area": "shopify", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220452", "base_commit": "7fa3b4c98fd61863789ab144cce8af4062900df2", "created_at": "2025-07-09", "environment_setup_version": "27.0", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139648, "functionName": ["UnitTestSuggestShopifyPaymentsDocumentLink"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\nindex cf234743596b..aed3df1a0d5c 100644\n--- a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n+++ b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n@@ -26,7 +26,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(10000, 20000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n@@ -59,7 +59,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(20000, 30000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n@@ -86,6 +86,60 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n until SuggestPayment.Next() = 0;\n end;\n \n+ [Test]\n+ procedure UnitTestSuggestShopifyPaymentsDocumentLink()\n+ var\n+ Item: Record Item;\n+ Customer: Record Customer;\n+ OrderTransaction: Record \"Shpfy Order Transaction\";\n+ SuggestPayment: Record \"Shpfy Suggest Payment\";\n+ DocLinkToDoc: Record \"Shpfy Doc. Link To Doc.\";\n+ SuggestPayments: Report \"Shpfy Suggest Payments\";\n+ OrderId1: BigInteger;\n+ OrderId2: BigInteger;\n+ SalesInvoiceNo: Code[20];\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO] Suggest Shopify payments to create Cash Receipt Journal line for linked Sales Invoice\n+ // [GIVEN] Invoice is posted\n+ Initialize();\n+ Amount := Any.IntegerInRange(10000, 99999);\n+ OrderId1 := Any.IntegerInRange(30000, 40000);\n+ OrderId2 := Any.IntegerInRange(40000, 50000);\n+ CreateItem(Item, Amount);\n+ LibrarySales.CreateCustomer(Customer);\n+ SalesInvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 2, 0);\n+\n+ // [GIVEN] Shopify transactions are imported\n+ CreateOrderTransaction(OrderId1, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId2, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+\n+ // [GIVEN] Link to Sales Invoice is set\n+ DocLinkToDoc.\"Shopify Document Type\" := DocLinkToDoc.\"Shopify Document Type\"::\"Shopify Shop Order\";\n+ DocLinkToDoc.\"Shopify Document Id\" := OrderId1;\n+ DocLinkToDoc.\"Document Type\" := DocLinkToDoc.\"Document Type\"::\"Posted Sales Invoice\";\n+ DocLinkToDoc.\"Document No.\" := SalesInvoiceNo;\n+ DocLinkToDoc.Insert();\n+ DocLinkToDoc.\"Shopify Document Id\" := OrderId2;\n+ DocLinkToDoc.Insert();\n+\n+ // [WHEN] Create Shopify transactions are run\n+#pragma warning disable AA0210\n+ OrderTransaction.SetFilter(\"Shopify Order Id\", '%1|%2', OrderId1, OrderId2);\n+#pragma warning restore AA0210\n+ OrderTransaction.FindSet();\n+ repeat\n+ SuggestPayments.GetOrderTransactions(OrderTransaction);\n+ until OrderTransaction.Next() = 0;\n+\n+ // [THEN] Temporary suggest payment records are created\n+ SuggestPayments.GetTempSuggestPayment(SuggestPayment);\n+ SuggestPayment.FindSet();\n+ repeat\n+ LibraryAssert.AreEqual(SuggestPayment.Amount, Amount, 'Amounts should match');\n+ until SuggestPayment.Next() = 0;\n+ end;\n+\n [HandlerFunctions('SuggestShopifyPaymentsRequestPageHandler')]\n [Test]\n procedure UnitTestSuggestShopifyPaymentsFailedTransaction()\n@@ -103,7 +157,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(50000, 60000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n@@ -143,9 +197,9 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId1 := Any.IntegerInRange(10000, 99999);\n- OrderId2 := Any.IntegerInRange(10000, 99999);\n- OrderId3 := Any.IntegerInRange(10000, 99999);\n+ OrderId1 := Any.IntegerInRange(60000, 70000);\n+ OrderId2 := Any.IntegerInRange(70000, 80000);\n+ OrderId3 := Any.IntegerInRange(80000, 90000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId1);\n@@ -185,7 +239,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(90000, 99999);\n RefundId := Any.IntegerInRange(10000, 99999);\n CreateRefund(OrderId, RefundId, Amount);\n CreateItem(Item, Amount);\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\nindex 62d92a55c036..cd9c900bf53e 100644\n--- a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n+++ b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n@@ -211,8 +211,8 @@ report 30118 \"Shpfy Suggest Payments\"\n var\n SalesInvoiceHeader: Record \"Sales Invoice Header\";\n SalesCreditMemoHeader: Record \"Sales Cr.Memo Header\";\n- CustLedgerEntry: Record \"Cust. Ledger Entry\";\n RefundHeader: Record \"Shpfy Refund Header\";\n+ DocLinkToDoc: Record \"Shpfy Doc. Link To Doc.\";\n AmountToApply: Decimal;\n Applied: Boolean;\n begin\n@@ -221,27 +221,28 @@ report 30118 \"Shpfy Suggest Payments\"\n case OrderTransaction.Type of\n OrderTransaction.Type::Capture, OrderTransaction.Type::Sale:\n begin\n- SalesInvoiceHeader.SetLoadFields(\"No.\", \"Shpfy Order Id\");\n+ SalesInvoiceHeader.SetLoadFields(\"No.\", \"Shpfy Order Id\", Closed);\n SalesInvoiceHeader.SetRange(\"Shpfy Order Id\", OrderTransaction.\"Shopify Order Id\");\n SalesInvoiceHeader.SetRange(Closed, false);\n- if SalesInvoiceHeader.FindSet() then begin\n+ if SalesInvoiceHeader.FindSet() then\n repeat\n- CustLedgerEntry.SetAutoCalcFields(\"Remaining Amount\");\n- CustLedgerEntry.SetRange(\"Open\", true);\n- CustLedgerEntry.SetRange(\"Applies-to ID\", '');\n- CustLedgerEntry.SetRange(\"Document Type\", CustLedgerEntry.\"Document Type\"::Invoice);\n- CustLedgerEntry.SetRange(\"Document No.\", SalesInvoiceHeader.\"No.\");\n- if CustLedgerEntry.FindSet() then begin\n- Applied := true;\n- repeat\n- CreateSuggestPaymentDocument(CustLedgerEntry, AmountToApply, true);\n- until CustLedgerEntry.Next() = 0;\n- end;\n- until SalesInvoiceHeader.Next() = 0;\n-\n- if Applied and (AmountToApply > 0) then\n- CreateSuggestPaymentGLAccount(AmountToApply, true);\n+ ApplyCustomerLedgerEntries(SalesInvoiceHeader.\"No.\", \"Gen. Journal Document Type\"::Invoice, AmountToApply, Applied);\n+ until SalesInvoiceHeader.Next() = 0\n+ else begin\n+ DocLinkToDoc.SetRange(\"Shopify Document Type\", DocLinkToDoc.\"Shopify Document Type\"::\"Shopify Shop Order\");\n+ DocLinkToDoc.SetRange(\"Shopify Document Id\", OrderTransaction.\"Shopify Order Id\");\n+ DocLinkToDoc.SetRange(\"Document Type\", DocLinkToDoc.\"Document Type\"::\"Posted Sales Invoice\");\n+ if DocLinkToDoc.FindSet() then\n+ repeat\n+ SalesInvoiceHeader.Get(DocLinkToDoc.\"Document No.\");\n+ if SalesInvoiceHeader.Closed then\n+ continue;\n+ ApplyCustomerLedgerEntries(SalesInvoiceHeader.\"No.\", \"Gen. Journal Document Type\"::Invoice, AmountToApply, Applied);\n+ until DocLinkToDoc.Next() = 0;\n end;\n+\n+ if Applied and (AmountToApply > 0) then\n+ CreateSuggestPaymentGLAccount(AmountToApply, true);\n end;\n OrderTransaction.Type::Refund:\n begin\n@@ -254,17 +255,7 @@ report 30118 \"Shpfy Suggest Payments\"\n SalesCreditMemoHeader.SetRange(Paid, false);\n if SalesCreditMemoHeader.FindSet() then\n repeat\n- CustLedgerEntry.SetAutoCalcFields(\"Remaining Amount\");\n- CustLedgerEntry.SetRange(\"Open\", true);\n- CustLedgerEntry.SetRange(\"Applies-to ID\", '');\n- CustLedgerEntry.SetRange(\"Document Type\", CustLedgerEntry.\"Document Type\"::\"Credit Memo\");\n- CustLedgerEntry.SetRange(\"Document No.\", SalesCreditMemoHeader.\"No.\");\n- if CustLedgerEntry.FindSet() then begin\n- Applied := true;\n- repeat\n- CreateSuggestPaymentDocument(CustLedgerEntry, AmountToApply, false);\n- until CustLedgerEntry.Next() = 0;\n- end;\n+ ApplyCustomerLedgerEntries(SalesCreditMemoHeader.\"No.\", \"Gen. Journal Document Type\"::\"Credit Memo\", AmountToApply, Applied);\n until SalesCreditMemoHeader.Next() = 0;\n until RefundHeader.Next() = 0;\n \n@@ -275,6 +266,23 @@ report 30118 \"Shpfy Suggest Payments\"\n end;\n end;\n \n+ local procedure ApplyCustomerLedgerEntries(DocumentNo: Code[20]; DocumentType: Enum \"Gen. Journal Document Type\"; var AmountToApply: Decimal; var Applied: Boolean)\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ begin\n+ CustLedgerEntry.SetAutoCalcFields(\"Remaining Amount\");\n+ CustLedgerEntry.SetRange(\"Open\", true);\n+ CustLedgerEntry.SetRange(\"Applies-to ID\", '');\n+ CustLedgerEntry.SetRange(\"Document Type\", DocumentType);\n+ CustLedgerEntry.SetRange(\"Document No.\", DocumentNo);\n+ if CustLedgerEntry.FindSet() then begin\n+ Applied := true;\n+ repeat\n+ CreateSuggestPaymentDocument(CustLedgerEntry, AmountToApply, DocumentType = \"Gen. Journal Document Type\"::Invoice);\n+ until CustLedgerEntry.Next() = 0;\n+ end;\n+ end;\n+\n local procedure CreateSuggestPaymentDocument(var CustLedgerEntry: Record \"Cust. Ledger Entry\"; var AmountToApply: Decimal; IsInvoice: Boolean)\n begin\n TempSuggestPayment.Init();\n"} -{"metadata": {"area": "inventory", "image_count": 1}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-206135", "base_commit": "cb96582bf92b7e7c5ad99abd5b8138b4c1f4634b", "created_at": "2025-02-03", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137154, "functionName": ["WarehouseShipmentPageRemainsOpenWhenRunPreviewPostAndCloseGLPostingPreviewPage"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\nindex 507d0c55edc6..d844f818a807 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n@@ -3345,6 +3345,61 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('CloseGLPostingPreviewPageHandler')]\n+ procedure WarehouseShipmentPageRemainsOpenWhenRunPreviewPostAndCloseGLPostingPreviewPage()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ WarehouseShipmentHeader: Record \"Warehouse Shipment Header\";\n+ WarehouseShipment: TestPage \"Warehouse Shipment\";\n+ Quatity: Decimal;\n+ begin\n+ // [SCENARIO 563377] When Preview Posts Warehouse Shipment and closes G/L Posting Preview page then\n+ // Warehouse Shipment page remains open.\n+ Initialize();\n+\n+ // [GIVEN] Create a location with Require Receive and Require Shipment.\n+ CreateAndUpdateLocation(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create Warehouse Employee.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, false);\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create Quantity.\n+ Quatity := LibraryRandom.RandInt(10);\n+\n+ // [GIVEN] Post Positive Adjustment for the Item and Location.\n+ LibraryInventory.PostPositiveAdjustment(Item, Location.Code, '', '', Quatity, WorkDate(), Quatity);\n+\n+ // [GIVEN] Create and Release Transfer Order.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, Location.Code, LocationYellow.Code, LocationInTransit.Code);\n+ LibraryInventory.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", Quatity);\n+ LibraryInventory.ReleaseTransferOrder(TransferHeader);\n+\n+ // [GIVEN] Create Warehouse Shipment from Transfer Order.\n+ LibraryWarehouse.CreateWhseShipmentFromTO(TransferHeader);\n+\n+ // [GIVEN] Find Warehouse Shipment Header.\n+ WarehouseShipmentHeader.SetRange(\"Location Code\", Location.Code);\n+ WarehouseShipmentHeader.FindFirst();\n+ Commit();\n+\n+ // [WHEN] Open Warehouse Shipment page and run Preview Posting action.\n+ WarehouseShipment.OpenEdit();\n+ WarehouseShipment.GoToRecord(WarehouseShipmentHeader);\n+ WarehouseShipment.PreviewPosting.Invoke();\n+\n+ // [THEN] Warehouse Shipment remains Open.\n+ WarehouseShipment.\"No.\".AssertEquals(Format(WarehouseShipmentHeader.\"No.\"));\n+ end;\n+\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al\nindex ce405d49e7d3..a6dc48170492 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al\n@@ -192,7 +192,7 @@ codeunit 5704 \"TransferOrder-Post Shipment\"\n if WhseShip then\n WhseShptLine.LockTable();\n TransHeader.LockTable();\n- if WhseShip then begin\n+ if WhseShip and (not PreviewMode) then begin\n WhsePostShpt.PostUpdateWhseDocuments(WhseShptHeader);\n TempWhseShptHeader.Delete();\n end;\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al\nindex 497b9a81930d..df69dac3bdac 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al\n@@ -326,6 +326,7 @@ codeunit 5748 \"Transfer Whse. Post Shipment\"\n else begin\n TransferOrderPostShipment.SetWhseShptHeader(WhseShptHeader);\n TransferOrderPostShipment.SetSuppressCommit(WhsePostParameters.\"Suppress Commit\" or WhsePostParameters.\"Preview Posting\");\n+ TransferOrderPostShipment.SetPreviewMode(WhsePostParameters.\"Preview Posting\");\n TransferOrderPostShipment.RunWithCheck(TransHeader);\n CounterSourceDocOK := CounterSourceDocOK + 1;\n end;\n"} {"metadata": {"area": "finance", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-217104", "base_commit": "f1558c6f6f5278f463c0193d05a43182953067a7", "created_at": "2025-06-02", "environment_setup_version": "27.0", "project_paths": ["App\\Apps\\W1\\AutomaticAccountCodes\\app", "App\\Apps\\W1\\AutomaticAccountCodes\\test"], "FAIL_TO_PASS": [{"codeunitID": 139598, "functionName": ["PostGenJnlLineWithAmountDivisionWithAccGroup"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al b/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al\nindex 6626b2b43cdf..7cc4e5edb615 100644\n--- a/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al\n+++ b/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al\n@@ -26,8 +26,8 @@ codeunit 139598 \"AAC Auto. Acc. Group Posting\"\n CopyFromOption: Option AccGroup,GenJournal,AccGroupAndGenJnl;\n DimensionDoesNotExistsErr: Label 'Dimension value %1 %2 does not exists for G/L Entry No. %3.', Comment = '%1 = Dimension Code, %2 = DimensionValue Code, %3 = GLEntry Entry No';\n WrongValueErr: Label 'Wrong value of field %1 in table %2, entry no. %3.', Comment = '%1 = Additional-Currency Amount, %2 = GLEntry TableCaption, %3 = GLEntry Entry No';\n-\n WrongAmountGLEntriesErr: Label 'Wrong Amount in G/L Entry.';\n+ GLEntryCountErr: Label 'Posted g/l entry count not match with expected count';\n \n [Test]\n [Scope('OnPrem')]\n@@ -756,6 +756,31 @@ codeunit 139598 \"AAC Auto. Acc. Group Posting\"\n VerifyCopiedGenJnlLines(GenJournalBatch, GenJournalBatch, 2);\n end;\n \n+ [Test]\n+ procedure PostGenJnlLineWithAmountDivisionWithAccGroup()\n+ var\n+ GenJnlLine: Record \"Gen. Journal Line\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ AutoAccGroupNo: Code[10];\n+ CurrencyCode: Code[10];\n+ GLAccountNo: array[3] of Code[20];\n+ begin\n+ // [SCENARIO 575346] Rounding issue leading to \"Inconsistency\" error when trying to post with different currency and automatic accounting in Swedish localisation.\n+ Initialize();\n+\n+ // [GIVEN] Currency with specific exchange rates.\n+ CurrencyCode := CreateCurrencyAndExchangeRate(1, 10.97223, WorkDate());\n+\n+ // [GIVEN] Created Auto Account Group With 3 GL Account with Allocation 50,50,-100.\n+ AutoAccGroupNo := CreateAutoAccGroupWithThreeLines(GLAccountNo[1], GLAccountNo[2], GLAccountNo[3]);\n+\n+ // [WHEN] \"General Journal Line\" - \"GJL\", GJL.\"Auto Acc. Group\" = AAG, GJL.\"Amount\" = \"A\"\n+ CreateAndPostTwoGenJnlLineWithAutoAccGroup(CurrencyCode, GenJournalBatch, GenJnlLine, AutoAccGroupNo, GLAccountNo[2], GLAccountNo[3]);\n+\n+ // [THEN] Check Posted GL Entry count Match with Expected.\n+ CountGLEntryLines(GenJnlLine);//assert\n+ end;\n+\n local procedure Initialize()\n begin\n LibrarySetupStorage.Restore();\n@@ -1538,6 +1563,82 @@ codeunit 139598 \"AAC Auto. Acc. Group Posting\"\n until PostedGenJournalLine.Next() = 0;\n end;\n \n+ local procedure CreateCurrencyAndExchangeRate(Rate: Decimal; RelationalRate: Decimal; FromDate: Date): Code[10]\n+ var\n+ Currency: Record Currency;\n+ begin\n+ LibraryERM.CreateCurrency(Currency);\n+ LibraryERM.SetCurrencyGainLossAccounts(Currency);\n+ Currency.Validate(\"Residual Gains Account\", Currency.\"Realized Gains Acc.\");\n+ Currency.Validate(\"Residual Losses Account\", Currency.\"Realized Losses Acc.\");\n+ Currency.Modify(true);\n+ CreateExchangeRate(Currency.Code, Rate, RelationalRate, FromDate);\n+ exit(Currency.Code);\n+ end;\n+\n+ local procedure CreateExchangeRate(CurrencyCode: Code[10]; Rate: Decimal; RelationalRate: Decimal; FromDate: Date)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ LibraryERM.CreateExchRate(CurrencyExchangeRate, CurrencyCode, FromDate);\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", Rate);\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", Rate);\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", RelationalRate);\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", RelationalRate);\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n+ local procedure CreateAndPostTwoGenJnlLineWithAutoAccGroup(CurrencyCode: Code[20]; var GenJournalBatch: Record \"Gen. Journal Batch\"; var GenJnlLine: Record \"Gen. Journal Line\"; AutoAccGroupNo: Code[10]; GLAccountNo2: Code[20]; GLAccountNo3: Code[20])\n+ var\n+ DocNo: Code[20];\n+ begin\n+ CreateGenJournalTemplateAndBatch(GenJournalBatch);\n+ LibraryJournals.CreateGenJournalLine(GenJnlLine, GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name, GenJnlLine.\"Document Type\"::Invoice,\n+ GenJnlLine.\"Account Type\"::\"G/L Account\", GLAccountNo2, GenJnlLine.\"Bal. Account Type\"::\"G/L Account\", '', 480);\n+ GenJnlLine.Validate(\"Automatic Account Group\", AutoAccGroupNo);\n+ GenJnlLine.Validate(\"Currency Code\", CurrencyCode);\n+ GenJnlLine.Modify(true);\n+ DocNo := GenJnlLine.\"Document No.\";\n+\n+ LibraryJournals.CreateGenJournalLine(GenJnlLine, GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name, GenJnlLine.\"Document Type\"::Invoice,\n+ GenJnlLine.\"Account Type\"::\"G/L Account\", GLAccountNo3, GenJnlLine.\"Bal. Account Type\"::\"G/L Account\", '', -480);\n+ GenJnlLine.Validate(\"Document No.\", DocNo);\n+ GenJnlLine.Validate(\"Currency Code\", CurrencyCode);\n+ GenJnlLine.Modify(true);\n+\n+ LibraryERM.PostGeneralJnlLine(GenJnlLine);\n+ end;\n+\n+ local procedure CreateAutoAccGroupWithThreeLines(var GLAccountNo1: Code[20]; var GLAccountNo2: Code[20]; var GLAccountNo3: Code[20]) AutoAccGroupNo: Code[10]\n+ begin\n+ GLAccountNo1 := LibraryERM.CreateGLAccountNo();\n+ GLAccountNo2 := LibraryERM.CreateGLAccountNo();\n+ GLAccountNo3 := LibraryERM.CreateGLAccountNo();\n+ AutoAccGroupNo := CreateAutomaticAccGroupWithTwoLinesAndBalanceLine(GLAccountNo1, GLAccountNo2, GLAccountNo3);\n+ end;\n+\n+ local procedure CreateAutomaticAccGroupWithTwoLinesAndBalanceLine(GLAccountNo1: Code[20]; GLAccountNo2: Code[20]; GLAccountNo3: Code[20]): Code[10]\n+ var\n+ AutomaticAccountHeader: Record \"Automatic Account Header\";\n+ begin\n+ LibraryAAC.CreateAutomaticAccountHeader(AutomaticAccountHeader);\n+\n+ CreateAutoAccLine(AutomaticAccountHeader.\"No.\", GLAccountNo1, 50, '');\n+ CreateAutoAccLine(AutomaticAccountHeader.\"No.\", GLAccountNo2, 50, '');\n+ CreateAutoAccLine(AutomaticAccountHeader.\"No.\", GLAccountNo3, -100, '');\n+ Commit();\n+ exit(AutomaticAccountHeader.\"No.\");\n+ end;\n+\n+ local procedure CountGLEntryLines(GenJnlLine: Record \"Gen. Journal Line\")\n+ var\n+ GLEntry: Record \"G/L Entry\";\n+ begin\n+ GLEntry.SetRange(\"Document No.\", GenJnlLine.\"Document No.\");\n+ GLEntry.FindSet();\n+ Assert.AreEqual(5, GLEntry.Count, GLEntryCountErr);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure CopyGenJournalParametersHandler(var CopyGenJournalParameters: TestPage \"Copy Gen. Journal Parameters\")\n", "patch": "diff --git a/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al b/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al\nindex 0e4bcfe3e0a6..ccaef63d9ca9 100644\n--- a/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al\n+++ b/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al\n@@ -72,12 +72,14 @@ codeunit 4850 \"AA Codes Posting Helper\"\n NoOfAutoAccounts: Decimal;\n TotalAmount: Decimal;\n TotalAltAmount: Decimal;\n+ TotalAltAmountLCY: Decimal;\n SourceCurrBaseAmount: Decimal;\n AccLine: Integer;\n begin\n GLSetup.Get();\n GenJnlLine.TestField(\"Account Type\", GenJnlLine.\"Account Type\"::\"G/L Account\");\n Clear(TotalAmount);\n+ Clear(TotalAltAmountLCY);\n AccLine := 0;\n TotalAmount := 0;\n AutoAccHeader.Get(GenJnlLine.\"Automatic Account Group\");\n@@ -117,10 +119,13 @@ codeunit 4850 \"AA Codes Posting Helper\"\n AccLine := AccLine + 1;\n TotalAmount := TotalAmount + GenJnlLine2.Amount;\n TotalAltAmount := TotalAltAmount + GenJnlLine2.\"Source Currency Amount\";\n+ TotalAltAmountLCY := TotalAltAmountLCY + GenJnlLine2.\"Amount (LCY)\";\n if (AccLine = NoOfAutoAccounts) and (TotalAmount <> 0) then\n GenJnlLine2.Validate(Amount, GenJnlLine2.Amount - TotalAmount);\n if (AccLine = NoOfAutoAccounts) and (TotalAltAmount <> 0) then\n GenJnlLine2.Validate(\"Source Currency Amount\", GenJnlLine2.\"Source Currency Amount\" - TotalAltAmount);\n+ if (AccLine = NoOfAutoAccounts) and (TotalAltAmountLCY <> 0) and (TotalAmount = 0) then\n+ GenJnlLine2.Validate(\"Amount (LCY)\", GenJnlLine2.\"Amount (LCY)\" - TotalAltAmountLCY);\n GenJnlCheckLine.RunCheck(GenJnlLine2);\n \n sender.InitGLEntry(GenJnlLine2, GLEntry,\n"} -{"metadata": {"area": "inventory", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207247", "base_commit": "c15e5b3fd9ea5d42fbff7dffad96160f5c6838dd", "created_at": "2025-02-17", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137067, "functionName": ["CommentOnProdBOMCompTransferredToCompLinesForFirmPlannedProdOrderWhenPositionFieldUsed"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al\nindex 4391387a6954..dcbb2cc63126 100644\n--- a/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al\n@@ -61,6 +61,7 @@\n QuantityErr: Label '%1 must be %2 in %3', Comment = '%1 = Quantity, %2 = Minimum Order Quanity, %3 = Requisition Line';\n MPSOrderErr: Label '%1 must be true', Comment = '%1 = MPS Order';\n PlanningComponentMustNotBeFoundErr: Label 'Planning Component must not be found.';\n+ BOMLineCommnetAndFirmProdOrderBOMLineCommentMustMatchErr: Label 'BOM Line Comment and Firm Prod. Order BOM Line Comment must match.';\n \n [Test]\n [HandlerFunctions('MessageHandler')]\n@@ -4904,6 +4905,72 @@\n Assert.AreEqual(StockkeepingUnit[2].\"Order Multiple\", RequisitionLine.Quantity, '');\n end;\n \n+ [Test]\n+ procedure CommentOnProdBOMCompTransferredToCompLinesForFirmPlannedProdOrderWhenPositionFieldUsed()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: array[2] of Record \"Production BOM Line\";\n+ ProductionBOMCommentLine: array[2] of Record \"Production BOM Comment Line\";\n+ ProdOrderCompCmtLine: array[2] of Record \"Prod. Order Comp. Cmt Line\";\n+ RequisitionLine: Record \"Requisition Line\";\n+ Salesheader: Record \"Sales Header\";\n+ UnitOfMeasure: Record \"Unit of Measure\";\n+ begin\n+ // [SCENARIO 563855] When Comment store on a production order line that includes the same component in different positions, transferred to the Component Lines \n+ // for the Firm Planned Production Order via Planning Worksheet.\n+ Initialize();\n+\n+ // [GIVEN] Create Unit of Measure Code.\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure);\n+\n+ // [GIVEN] Create Component Items.\n+ CreateItemWithReorderPolicy(CompItem, UnitOfMeasure, ItemUnitOfMeasure, CompItem.\"Replenishment System\"::Purchase, CompItem.\"Reordering Policy\"::\" \");\n+\n+ // [GIVEN] Create Production Item.\n+ CreateItemWithReorderPolicy(ProdItem, UnitOfMeasure, ItemUnitOfMeasure, ProdItem.\"Replenishment System\"::\"Prod. Order\", ProdItem.\"Reordering Policy\"::Order);\n+\n+ // [GIVEN] Create Production BOM Header.\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ProdItem.\"Base Unit of Measure\");\n+\n+ // [GIVEN] Create Production BOM Lines.\n+ CreateProductionBOMLineInSpecifiedPosition(ProductionBOMHeader, ProductionBOMLine[1], CompItem.\"No.\", LibraryRandom.RandInt(0));\n+ CreateProductionBOMLineInSpecifiedPosition(ProductionBOMHeader, ProductionBOMLine[2], CompItem.\"No.\", LibraryRandom.RandInt(0));\n+\n+ // [GIVEN] Create Production BOM Comment Line for Production BOM Line.\n+ LibraryManufacturing.CreateProductionBOMCommentLine(ProductionBOMLine[1]);\n+ LibraryManufacturing.CreateProductionBOMCommentLine(ProductionBOMLine[2]);\n+\n+ // [GIVEN] Update Production BOM Status.\n+ LibraryManufacturing.UpdateProductionBOMStatus(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+\n+ // [GIVEN] Validate Production BOM No. in Production Item.\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Create and Release Sales Order.\n+ CreateSalesOrder(Salesheader, ProdItem);\n+ LibrarySales.ReleaseSalesDocument(Salesheader);\n+\n+ // [GIVEN] Run Calculate Regenerative Plan.\n+ RunCalculateRegenerativePlan(ProdItem.\"No.\", '');\n+\n+ // [GIVEN] Accept Action Message on Requisition Line.\n+ AcceptActionMessageOnReqLine(RequisitionLine, ProdItem.\"No.\");\n+\n+ // [GIVEN] Run Carry Out Action Plan.\n+ CarryOutActionPlanForFirmPlannedProdOrder(RequisitionLine);\n+\n+ // [WHEN] Find Prod. Order Comp. Cmt Line for both Position.\n+ GetProductionBOMCommnetLine(ProductionBOMLine[1], ProductionBOMCommentLine[1], ProdOrderCompCmtLine[1]);\n+ GetProductionBOMCommnetLine(ProductionBOMLine[2], ProductionBOMCommentLine[2], ProdOrderCompCmtLine[2]);\n+\n+ // [VERIFY] Comment in Production BOM Comment Line and Prod. Order Comp. Cmt Line is same.\n+ Assert.AreEqual(ProductionBOMCommentLine[1].Comment, ProdOrderCompCmtLine[1].Comment, BOMLineCommnetAndFirmProdOrderBOMLineCommentMustMatchErr);\n+ Assert.AreEqual(ProductionBOMCommentLine[2].Comment, ProdOrderCompCmtLine[2].Comment, BOMLineCommnetAndFirmProdOrderBOMLineCommentMustMatchErr);\n+ end;\n+\n local procedure Initialize()\n var\n AllProfile: Record \"All Profile\";\n@@ -6649,6 +6716,48 @@ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name\n StockkeepingUnit.Modify(true);\n end;\n \n+ local procedure CreateProductionBOMLineInSpecifiedPosition(var ProductionBOMHeader: Record \"Production BOM Header\"; var ProductionBOMLine: Record \"Production BOM Line\"; ItemNo: Code[20]; QuantityPer: Decimal)\n+ begin\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, ItemNo, QuantityPer);\n+ ProductionBOMLine.Validate(Position, LibraryUtility.GenerateGUID());\n+ ProductionBOMLine.Modify(true);\n+ end;\n+\n+ local procedure CarryOutActionPlanForFirmPlannedProdOrder(var ReqLine: Record \"Requisition Line\")\n+ var\n+ MfgUserTemplate: Record \"Manufacturing User Template\";\n+ CarryOutActionMsgPlan: Report \"Carry Out Action Msg. - Plan.\";\n+ begin\n+ MfgUserTemplate.Init();\n+ MfgUserTemplate.Validate(\"Create Production Order\", MfgUserTemplate.\"Create Production Order\"::\"Firm Planned\");\n+\n+ ReqLine.SetRecFilter();\n+ CarryOutActionMsgPlan.UseRequestPage(false);\n+ CarryOutActionMsgPlan.SetDemandOrder(ReqLine, MfgUserTemplate);\n+ CarryOutActionMsgPlan.RunModal();\n+ end;\n+\n+ local procedure GetProductionBOMCommnetLine(ProductionBOMLine: record \"Production BOM Line\"; var ProductionBOMCommentLine: Record \"Production BOM Comment Line\"; var ProdOrderCompCmtLine: Record \"Prod. Order Comp. Cmt Line\")\n+ var\n+ ProductionOrderComp: Record \"Prod. Order Component\";\n+ begin\n+ ProductionOrderComp.SetRange(\"Status\", ProductionOrderComp.Status::\"Firm Planned\");\n+ ProductionOrderComp.SetRange(\"Item No.\", ProductionBOMLine.\"No.\");\n+ ProductionOrderComp.SetRange(Position, ProductionBOMLine.Position);\n+ ProductionOrderComp.FindFirst();\n+\n+ ProductionBOMCommentLine.SetRange(\"Production BOM No.\", ProductionBOMLine.\"Production BOM No.\");\n+ ProductionBOMCommentLine.SetRange(\"BOM Line No.\", ProductionOrderComp.\"Line No.\");\n+ ProductionBOMCommentLine.FindFirst();\n+\n+ ProdOrderCompCmtLine.SetRange(\"Status\", ProductionOrderComp.Status::\"Firm Planned\");\n+ ProdOrderCompCmtLine.SetRange(\"Prod. Order No.\", ProductionOrderComp.\"Prod. Order No.\");\n+ ProdOrderCompCmtLine.SetRange(\"Prod. Order Line No.\", ProductionOrderComp.\"Prod. Order Line No.\");\n+ ProdOrderCompCmtLine.SetRange(\"Prod. Order BOM Line No.\", ProductionOrderComp.\"Line No.\");\n+ ProdOrderCompCmtLine.FindFirst();\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure CalculatePlanPlanWkshRequestPageHandler(var CalculatePlanPlanWksh: TestRequestPage \"Calculate Plan - Plan. Wksh.\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al\nindex bd370429da5f..50bcb4c52bdc 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al\n@@ -1541,6 +1541,7 @@ codeunit 99000813 \"Carry Out Action\"\n ProductionBOMLine.SetRange(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n ProductionBOMLine.SetRange(Type, ProductionBOMLine.Type::Item);\n ProductionBOMLine.SetRange(\"No.\", ProdOrderComponent.\"Item No.\");\n+ ProductionBOMLine.SetRange(Position, ProdOrderComponent.Position);\n if ProductionBOMLine.FindSet() then\n repeat\n ProductionBOMCommentLine.SetRange(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n"} -{"metadata": {"area": "inventory", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207177", "base_commit": "64e8e373597b75054ede11d7304783567504707e", "created_at": "2025-02-16", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137413, "functionName": ["VerifyNoBlankEntryInsertedInItemAttributeValue"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al\nindex f743727e528e..cdba6765ce88 100644\n--- a/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al\n@@ -2551,6 +2551,39 @@ codeunit 137413 \"SCM Item Attributes\"\n Assert.AreNotEqual(0, ItemAttributeValue.\"Numeric Value\", NumericValueShouldNotBeZeroErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemAttributeValueListHandler')]\n+ procedure VerifyNoBlankEntryInsertedInItemAttributeValue()\n+ var\n+ Item: Record Item;\n+ ItemAttribute: Record \"Item Attribute\";\n+ ItemAttributeValue: Record \"Item Attribute Value\";\n+ ItemCard: TestPage \"Item Card\";\n+ begin\n+ // [SCENARIO 565898] An empty attribute value was not created through the item Card\n+ Initialize();\n+\n+ // [GIVEN] An item and a set of item attributes\n+ CreateTestOptionItemAttributes();\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Open the Item Card\n+ ItemCard.OpenEdit();\n+ ItemCard.GotoRecord(Item);\n+\n+ // [WHEN] The user assigns some attribute values to the item \n+ ItemAttribute.FindFirst();\n+ AssignItemAttributeViaItemCard(ItemAttribute, ItemAttributeValue, ItemCard);\n+\n+ // [THEN] No blank Item attribute Value Inserted in the table\n+ ItemAttributeValue.SetRange(\"Attribute ID\", ItemAttribute.ID);\n+ ItemAttributeValue.SetRange(Value, '');\n+ asserterror ItemAttributeValue.FindFirst();\n+\n+ // [THEN] Verify there is nothing inside the filter\n+ Assert.AssertNothingInsideFilter();\n+ end;\n+\n local procedure Initialize()\n var\n ItemAttribute: Record \"Item Attribute\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al b/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al\nindex a84b05588031..4d5435ff41d6 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al\n@@ -33,7 +33,6 @@ page 7504 \"Item Attribute Value List\"\n trigger OnValidate()\n var\n ItemAttributeValue: Record \"Item Attribute Value\";\n- ItemAttributeValueMapping: Record \"Item Attribute Value Mapping\";\n ItemAttribute: Record \"Item Attribute\";\n begin\n OnBeforeCheckAttributeName(Rec, RelatedRecordCode);\n@@ -42,19 +41,10 @@ page 7504 \"Item Attribute Value List\"\n DeleteItemAttributeValueMapping(ItemAttribute.ID);\n end;\n \n- if not Rec.FindAttributeValue(ItemAttributeValue) then\n+ if (Rec.Value <> '') and not Rec.FindAttributeValue(ItemAttributeValue) then\n Rec.InsertItemAttributeValue(ItemAttributeValue, Rec);\n \n- if ItemAttributeValue.Get(ItemAttributeValue.\"Attribute ID\", ItemAttributeValue.ID) then begin\n- ItemAttributeValueMapping.Reset();\n- ItemAttributeValueMapping.Init();\n- ItemAttributeValueMapping.\"Table ID\" := Database::Item;\n- ItemAttributeValueMapping.\"No.\" := RelatedRecordCode;\n- ItemAttributeValueMapping.\"Item Attribute ID\" := ItemAttributeValue.\"Attribute ID\";\n- ItemAttributeValueMapping.\"Item Attribute Value ID\" := ItemAttributeValue.ID;\n- OnBeforeItemAttributeValueMappingInsert(ItemAttributeValueMapping, ItemAttributeValue, Rec);\n- ItemAttributeValueMapping.Insert();\n- end;\n+ InsertItemAttributeValueMapping(ItemAttributeValue);\n end;\n }\n field(Value; Rec.Value)\n@@ -74,6 +64,7 @@ page 7504 \"Item Attribute Value List\"\n if not Rec.FindAttributeValue(ItemAttributeValue) then\n Rec.InsertItemAttributeValue(ItemAttributeValue, Rec);\n \n+ InsertItemAttributeValueMapping(ItemAttributeValue);\n ItemAttributeValueMapping.SetRange(\"Table ID\", Database::Item);\n ItemAttributeValueMapping.SetRange(\"No.\", RelatedRecordCode);\n ItemAttributeValueMapping.SetRange(\"Item Attribute ID\", ItemAttributeValue.\"Attribute ID\");\n@@ -154,6 +145,24 @@ page 7504 \"Item Attribute Value List\"\n ItemAttribute.RemoveUnusedArbitraryValues();\n end;\n \n+ local procedure InsertItemAttributeValueMapping(ItemAttributeValue: Record \"Item Attribute Value\")\n+ var\n+ ItemAttributeValueMapping: Record \"Item Attribute Value Mapping\";\n+ begin\n+ if not ItemAttributeValue.Get(ItemAttributeValue.\"Attribute ID\", ItemAttributeValue.ID) or\n+ ItemAttributeValueMapping.Get(Database::Item, RelatedRecordCode, ItemAttributeValue.\"Attribute ID\") then\n+ exit;\n+\n+ ItemAttributeValueMapping.Reset();\n+ ItemAttributeValueMapping.Init();\n+ ItemAttributeValueMapping.\"Table ID\" := Database::Item;\n+ ItemAttributeValueMapping.\"No.\" := RelatedRecordCode;\n+ ItemAttributeValueMapping.\"Item Attribute ID\" := ItemAttributeValue.\"Attribute ID\";\n+ ItemAttributeValueMapping.\"Item Attribute Value ID\" := ItemAttributeValue.ID;\n+ OnBeforeItemAttributeValueMappingInsert(ItemAttributeValueMapping, ItemAttributeValue, Rec);\n+ ItemAttributeValueMapping.Insert();\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterItemAttributeValueMappingDelete(AttributeToDeleteID: Integer; RelatedRecordCode: Code[20]; ItemAttributeValueSelection: Record \"Item Attribute Value Selection\")\n begin\n"} -{"metadata": {"area": "sales", "image_count": 10}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207236", "base_commit": "b63e4162ab18e1a516cafcc0771489065f902c43", "created_at": "2025-02-17", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134391, "functionName": ["BatchPostSaleInvoiceWithReplacePostingDateAndCurrencyCode"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al\nindex 5bc6879cc7c4..59ee4c8edca0 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al\n@@ -1573,6 +1573,37 @@ codeunit 134391 \"ERM Sales Batch Posting\"\n VerifyPostedSalesOrder(SalesHeader.\"No.\", SalesHeader.\"Posting Date\" + 1, false);\n end;\n \n+ [Test]\n+ [HandlerFunctions('RequestPageHandlerBatchPostSalesInvoicesWithReplaceAllDates,MessageHandler')]\n+ [Scope('OnPrem')]\n+ procedure BatchPostSaleInvoiceWithReplacePostingDateAndCurrencyCode()\n+ var\n+ Currency: Record Currency;\n+ SalesHeader: Record \"Sales Header\";\n+ LibraryJobQueue: Codeunit \"Library - Job Queue\";\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO 562713] Post sales invoice with currency code via Post Batch, but the posted data has not been changed.\n+ Initialize();\n+\n+ // [GIVEN] Set Post with Job queue on Sales & Receivables Setup\n+ LibrarySales.SetPostWithJobQueue(true);\n+\n+ // [GIVEN] Bind subscription and do not handle Job queue event as true\n+ BindSubscription(LibraryJobQueue);\n+ LibraryJobQueue.SetDoNotHandleCodeunitJobQueueEnqueueEvent(true);\n+\n+ // [GIVEN] Create Sales Invoice with Currency Code.\n+ Amount := CreateSalesDocumentWithCurrency(SalesHeader, Currency, SalesHeader.\"Document Type\"::Invoice, false);\n+\n+ // [WHEN] Run Post Batch with Replace Posting Date, Replace Document Date & Replace VAT Date options.\n+ RunBatchPostSales(SalesHeader.\"Document Type\", SalesHeader.\"No.\", SalesHeader.\"Posting Date\" + 10, false);\n+ LibraryJobQueue.FindAndRunJobQueueEntryByRecordId(SalesHeader.RecordId);\n+\n+ // [THEN] The amount was not changed in the posted sales invoice line\n+ VerifyPostedSalesInvoiceAmount(SalesHeader.\"No.\", SalesHeader.\"Posting Date\" + 10, Amount);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1890,6 +1921,52 @@ codeunit 134391 \"ERM Sales Batch Posting\"\n Assert.RecordCount(JobQueueEntry, 1);\n end;\n \n+ local procedure CreateSalesDocumentWithCurrency(var SalesHeader: Record \"Sales Header\"; var Currency: Record Currency; DocumentType: Enum \"Sales Document Type\"; InvDisc: Boolean): Decimal\n+ var\n+ Item: Record Item;\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, DocumentType, CreateCustomer(InvDisc));\n+ CreateCurrencyWithExchangeRate(Currency);\n+ SalesHeader.Validate(\"Currency Code\", Currency.Code);\n+ SalesHeader.Modify(true);\n+\n+ LibraryInventory.CreateItem(Item);\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", LibraryRandom.RandInt(10));\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandInt(100));\n+ SalesLine.Validate(\"Line Discount %\", LibraryRandom.RandInt(20));\n+ SalesLine.Modify(true);\n+\n+ exit(SalesLine.\"Amount Including VAT\");\n+ end;\n+\n+ local procedure CreateCurrencyWithExchangeRate(var Currency: Record Currency)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ Currency.Get(LibraryERM.CreateCurrencyWithGLAccountSetup());\n+\n+ LibraryERM.CreateExchRate(CurrencyExchangeRate, Currency.Code, WorkDate());\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n+ local procedure VerifyPostedSalesInvoiceAmount(PreAssignedNo: Code[20]; PostingDate: Date; Amount: Decimal)\n+ var\n+ SalesInvoiceHeader: Record \"Sales Invoice Header\";\n+ SalesInvoiceLine: Record \"Sales Invoice Line\";\n+ begin\n+ SalesInvoiceHeader.SetRange(\"Pre-Assigned No.\", PreAssignedNo);\n+ SalesInvoiceHeader.FindFirst();\n+ Assert.Equal(SalesInvoiceHeader.\"Posting Date\", PostingDate);\n+ SalesInvoiceLine.SetFilter(\"Document No.\", SalesInvoiceHeader.\"No.\");\n+ SalesInvoiceLine.FindFirst();\n+ Assert.Equal(Amount, SalesInvoiceLine.\"Amount Including VAT\");\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure RequestPageHandlerBatchPostSalesInvoices(var BatchPostSalesInvoices: TestRequestPage \"Batch Post Sales Invoices\")\n@@ -2195,5 +2272,26 @@ codeunit 134391 \"ERM Sales Batch Posting\"\n Assert.AreEqual(PostBatchForm.PrintDoc.AsBoolean(), true, 'Expected value to be restored.');\n end;\n end;\n+\n+ [RequestPageHandler]\n+ procedure RequestPageHandlerBatchPostSalesInvoicesWithReplaceAllDates(var BatchPostSalesInvoices: TestRequestPage \"Batch Post Sales Invoices\")\n+ var\n+ SalesHeader: Record \"Sales Header\";\n+ DocumentNoFilter: Variant;\n+ PostingDate: Variant;\n+ RunReplacePostingDate: Boolean;\n+ begin\n+ LibraryVariableStorage.Dequeue(DocumentNoFilter);\n+ LibraryVariableStorage.Dequeue(PostingDate);\n+\n+ BatchPostSalesInvoices.\"Sales Header\".SetFilter(\"No.\", DocumentNoFilter);\n+ BatchPostSalesInvoices.\"Sales Header\".SetFilter(\"Document Type\", Format(SalesHeader.\"Document Type\"::Invoice));\n+\n+ BatchPostSalesInvoices.PostingDate.SetValue(PostingDate);\n+ RunReplacePostingDate := Format(PostingDate) <> '';\n+ BatchPostSalesInvoices.ReplacePostingDate.SetValue(RunReplacePostingDate);\n+ BatchPostSalesInvoices.ReplaceVATDate.SetValue(RunReplacePostingDate);\n+ BatchPostSalesInvoices.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\nindex fbf39fce2b5f..9f88c95dbfc2 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n@@ -4154,7 +4154,7 @@ table 36 \"Sales Header\"\n \n if UpdateCurrencyExchangeRates.ExchangeRatesForCurrencyExist(CurrencyDate, \"Currency Code\") then begin\n \"Currency Factor\" := CurrExchRate.ExchangeRate(CurrencyDate, \"Currency Code\");\n- if \"Currency Code\" <> xRec.\"Currency Code\" then\n+ if (\"Currency Code\" <> xRec.\"Currency Code\") and (xRec.\"No.\" <> '') then\n RecreateSalesLines(FieldCaption(\"Currency Code\"));\n end else\n UpdateCurrencyExchangeRates.ShowMissingExchangeRatesNotification(\"Currency Code\");\n@@ -7038,7 +7038,10 @@ table 36 \"Sales Header\"\n exit;\n \n \"Posting Date\" := PostingDateReq;\n- Validate(\"Currency Code\");\n+ if \"Currency Code\" <> '' then begin\n+ UpdateCurrencyFactor();\n+ UpdateSalesLinesByFieldNo(SalesHeader.FieldNo(\"Currency Factor\"), false);\n+ end;\n \n if ReplaceVATDate then\n \"VAT Reporting Date\" := VATDateReq;\ndiff --git a/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al\nindex e5855273a6ae..f1849388fe0e 100644\n--- a/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al\n@@ -138,22 +138,25 @@ codeunit 1371 \"Sales Batch Post Mgt.\"\n \n local procedure PrepareSalesHeader(var SalesHeader: Record \"Sales Header\"; var BatchConfirm: Option)\n var\n- CalcInvoiceDiscont: Boolean;\n+ CalcInvoiceDiscount: Boolean;\n ReplacePostingDate, ReplaceVATDate, ReplaceDocumentDate : Boolean;\n+ ManualReopen: Boolean;\n PostingDate, VATDate : Date;\n begin\n- BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Calculate Invoice Discount\", CalcInvoiceDiscont);\n+ BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Calculate Invoice Discount\", CalcInvoiceDiscount);\n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Replace Posting Date\", ReplacePostingDate);\n BatchProcessingMgt.GetDateParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Posting Date\", PostingDate);\n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Replace VAT Date\", ReplaceVATDate);\n BatchProcessingMgt.GetDateParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"VAT Date\", VATDate);\n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Replace Document Date\", ReplaceDocumentDate);\n \n- if CalcInvoiceDiscont then\n+ if CalcInvoiceDiscount then\n CalculateInvoiceDiscount(SalesHeader);\n \n SalesHeader.BatchConfirmUpdateDeferralDate(BatchConfirm, ReplacePostingDate, PostingDate, ReplaceVATDate, VATDate);\n+ PerformManualReleaseOrReopenSalesHeader(SalesHeader, ManualReopen, ReplacePostingDate);\n SalesHeader.BatchConfirmUpdatePostingDate(ReplacePostingDate, PostingDate, ReplaceVATDate, VATDate, ReplaceDocumentDate);\n+ PerformManualReleaseOrReopenSalesHeader(SalesHeader, ManualReopen, ReplacePostingDate);\n OnPrepareSalesHeaderOnAfterBatchConfirmUpdateDeferralDate(SalesHeader, BatchProcessingMgt);\n \n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::Ship, SalesHeader.Ship);\n@@ -310,6 +313,23 @@ codeunit 1371 \"Sales Batch Post Mgt.\"\n JobQueueEntry.Insert(true);\n end;\n \n+ local procedure PerformManualReleaseOrReopenSalesHeader(var SalesHeader: Record \"Sales Header\"; var ManualReopen: Boolean; ReplacePostingDate: Boolean)\n+ var\n+ ReleaseSalesDoc: Codeunit \"Release Sales Document\";\n+ begin\n+ if (not ReplacePostingDate) or (SalesHeader.\"Currency Code\" = '') then\n+ exit;\n+ if not SalesHeader.Invoice and not (SalesHeader.\"Document Type\" = SalesHeader.\"Document Type\"::Invoice) then\n+ exit;\n+\n+ if ManualReopen then\n+ ReleaseSalesHeader(SalesHeader)\n+ else begin\n+ ReleaseSalesDoc.PerformManualReopen(SalesHeader);\n+ ManualReopen := true;\n+ end;\n+ end;\n+\n [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Batch Processing Mgt.\", 'OnBeforeBatchProcessing', '', false, false)]\n local procedure PrepareSalesHeaderOnBeforeBatchProcessing(var RecRef: RecordRef; var BatchConfirm: Option)\n var\n"} -{"metadata": {"area": "assembly", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-206977", "base_commit": "9832a8d1748921e7eeff9d8c3c6e55af9c562260", "created_at": "2025-02-13", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Assembly"], "FAIL_TO_PASS": [{"codeunitID": 137096, "functionName": ["ShowDocumentOnAssemblyLinesForBlanketOrderPageShouldOpenCorrectPage"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al b/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al\nindex 7629f2ebe001..3e0eab3eb6a9 100644\n--- a/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al\n@@ -5510,6 +5510,54 @@ codeunit 137096 \"SCM Kitting - ATO\"\n Assert.IsTrue(AssembleToOrderLink.IsEmpty(), ATOLinkShouldNotBeFoundErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MsgHandler')]\n+ procedure ShowDocumentOnAssemblyLinesForBlanketOrderPageShouldOpenCorrectPage()\n+ var\n+ AssembleToOrderLink: Record \"Assemble-to-Order Link\";\n+ AssemblyHeader: Record \"Assembly Header\";\n+ AssemblyLine: Record \"Assembly Line\";\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ AssemblyLines: TestPage \"Assembly Lines\";\n+ BlanketAssemblyOrder: TestPage \"Blanket Assembly Order\";\n+ begin\n+ // [SCENARIO 564531] Show document in Assembly order line page opens the wrong page when the Assembly order line belongs a blanket assembly order.\n+ Initialize();\n+\n+ // [GIVEN] Assembled item \"I\".\n+ CreateAssembledItem(Item, \"Assembly Policy\"::\"Assemble-to-Order\", 2, 0, 0, 1, Item.\"Costing Method\"::FIFO);\n+\n+ // [GIVEN] Create sales blanket order with item \"I\", set \"Qty. to Assemble to Order\" = \"Quantity\".\n+ // [GIVEN] A linked assembly blanket order is created in the background.\n+ LibrarySales.CreateSalesDocumentWithItem(\n+ SalesHeader, SalesLine, SalesHeader.\"Document Type\"::\"Blanket Order\",\n+ '', Item.\"No.\", LibraryRandom.RandInt(10), '', WorkDate());\n+ SetQtyToAssembleToOrder(SalesLine, SalesLine.Quantity);\n+\n+ // [GIVEN] Clear \"Qty. to Assemble to Order\".\n+ // [GIVEN] That deletes the assembly blanket order together the Assemble-to-Order link.\n+ SetQtyToAssembleToOrder(SalesLine, 0);\n+ Assert.IsFalse(AssembleToOrderLink.AsmExistsForSalesLine(SalesLine), '');\n+\n+ // [WHEN] Set \"Qty. to Assemble to Order\" back to \"Quantity\".\n+ SetQtyToAssembleToOrder(SalesLine, SalesLine.Quantity);\n+\n+ // [THEN] A new linked assembly blanket order is created.\n+ FindLinkedAssemblyOrder(AssemblyHeader, SalesHeader.\"Document Type\", SalesHeader.\"No.\");\n+ FindAssemblyLine(AssemblyHeader, AssemblyLine);\n+\n+ // [WHEN] Open Assembly Lines Page and invoke show document action\n+ AssemblyLines.OpenEdit();\n+ BlanketAssemblyOrder.Trap();\n+ AssemblyLines.GoToRecord(AssemblyLine);\n+ AssemblyLines.\"Show Document\".Invoke();\n+\n+ // [THEN] Verify Blanket Assembly Order Page opened\n+ BlanketAssemblyOrder.\"No.\".AssertEquals(AssemblyHeader.\"No.\");\n+ end;\n+\n local procedure VerifyAssembleToOrderLinesPageOpened(SalesHeader: Record \"Sales Header\"; QtyAssembleToOrder: Decimal)\n var\n SalesQuote: TestPage \"Sales Quote\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\nindex 9ae5cd9eb8eb..1aa3ac9b5ca2 100644\n--- a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n@@ -2060,6 +2060,21 @@ table 901 \"Assembly Line\"\n end;\n end;\n \n+ internal procedure ShowAssemblyDocument()\n+ var\n+ AssemblyHeader: Record \"Assembly Header\";\n+ begin\n+ AssemblyHeader.Get(Rec.\"Document Type\", Rec.\"Document No.\");\n+ case AssemblyHeader.\"Document Type\" of\n+ AssemblyHeader.\"Document Type\"::Quote:\n+ Page.Run(Page::\"Assembly Quote\", AssemblyHeader);\n+ AssemblyHeader.\"Document Type\"::Order:\n+ Page.Run(Page::\"Assembly Order\", AssemblyHeader);\n+ AssemblyHeader.\"Document Type\"::\"Blanket Order\":\n+ Page.Run(Page::\"Blanket Assembly Order\", AssemblyHeader);\n+ end;\n+ end;\n+\n procedure SuspendDeletionCheck(Suspend: Boolean)\n begin\n CalledFromHeader := Suspend;\ndiff --git a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al\nindex 0877c357bc37..9c9e4b15045c 100644\n--- a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al\n+++ b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al\n@@ -157,11 +157,8 @@ page 903 \"Assembly Lines\"\n ToolTip = 'Open the document that the information on the line comes from.';\n \n trigger OnAction()\n- var\n- AssemblyHeader: Record \"Assembly Header\";\n begin\n- AssemblyHeader.Get(Rec.\"Document Type\", Rec.\"Document No.\");\n- PAGE.Run(PAGE::\"Assembly Order\", AssemblyHeader);\n+ Rec.ShowAssemblyDocument();\n end;\n }\n action(\"Reservation Entries\")\n"} {"metadata": {"area": "finance", "image_count": 1}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-191624", "base_commit": "ca83d8b5c6ef9be7a2965d4ac40dc55884f12551", "created_at": "2024-08-15", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\ExcelReports\\app", "App\\Apps\\W1\\ExcelReports\\test"], "FAIL_TO_PASS": [{"codeunitID": 139545, "functionName": ["FirstTimeOpeningRequestPageOfFixedAssetAnalysisShouldInsertPostingTypes"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/ExcelReports/test/src/FixedAssetExcelReports.Codeunit.al b/App/Apps/W1/ExcelReports/test/src/FixedAssetExcelReports.Codeunit.al\nnew file mode 100644\nindex 000000000000..3ee86701f253\n--- /dev/null\n+++ b/App/Apps/W1/ExcelReports/test/src/FixedAssetExcelReports.Codeunit.al\n@@ -0,0 +1,43 @@\n+namespace Microsoft.Finance.ExcelReports.Test;\n+using Microsoft.FixedAssets.Posting;\n+using Microsoft.Finance.ExcelReports;\n+\n+codeunit 139545 \"Fixed Asset Excel Reports\"\n+{\n+ Subtype = Test;\n+ TestPermissions = Disabled;\n+\n+ var\n+ Assert: Codeunit Assert;\n+\n+ [Test]\n+ [HandlerFunctions('EXRFixedAssetAnalysisExcelHandler')]\n+ procedure FirstTimeOpeningRequestPageOfFixedAssetAnalysisShouldInsertPostingTypes()\n+ var\n+ RequestPageXml: Text;\n+ begin\n+ // [SCENARIO 544231] First time opening the Fixed Asset Analysis Excel report requestpage should insert the FixedAssetTypes required by the report\n+ // [GIVEN] There is no FA Posting Type\n+ CleanupFixedAssetData();\n+ Commit();\n+ Assert.TableIsEmpty(Database::\"FA Posting Type\");\n+ // [WHEN] Opening the requestpage of the Fixed Asset Analysis report\n+ RequestPageXml := Report.RunRequestPage(Report::\"EXR Fixed Asset Analysis Excel\", RequestPageXml);\n+ // [THEN] The default FA Posting Type's are inserted\n+ Assert.TableIsNotEmpty(Database::\"FA Posting Type\");\n+ end;\n+\n+ local procedure CleanupFixedAssetData()\n+ var\n+ FAPostingType: Record \"FA Posting Type\";\n+ begin\n+ FAPostingType.DeleteAll();\n+ end;\n+\n+ [RequestPageHandler]\n+ procedure EXRFixedAssetAnalysisExcelHandler(var EXRFixedAssetAnalysisExcel: TestRequestPage \"EXR Fixed Asset Analysis Excel\")\n+ begin\n+ EXRFixedAssetAnalysisExcel.OK().Invoke();\n+ end;\n+\n+}\n\\ No newline at end of file\n", "patch": "diff --git a/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al b/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al\nindex 686231b5140a..35b007c8373b 100644\n--- a/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al\n+++ b/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al\n@@ -124,6 +124,7 @@ report 4412 \"EXR Fixed Asset Analysis Excel\"\n trigger OnOpenPage()\n var\n DepreciationBook: Record \"Depreciation Book\";\n+ FixedAssetPostingType: Record \"FA Posting Type\";\n FASetup: Record \"FA Setup\";\n begin\n EndingDate := WorkDate();\n@@ -135,6 +136,7 @@ report 4412 \"EXR Fixed Asset Analysis Excel\"\n if FASetup.\"Default Depr. Book\" <> '' then\n DepreciationBookCode := FASetup.\"Default Depr. Book\";\n end;\n+ FixedAssetPostingType.CreateTypes();\n end;\n }\n rendering\n"} {"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-195193", "base_commit": "170e0b11453b4f93d5f38cb92c0e288988df7cb7", "created_at": "2024-09-23", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\ExcelReports\\app", "App\\Apps\\W1\\ExcelReports\\test"], "FAIL_TO_PASS": [{"codeunitID": 139544, "functionName": ["TrialBalanceBufferNetChangeSplitsIntoDebitAndCreditWhenCalledSeveralTimes"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al b/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al\nindex 1a7bf318b260..734e4fdd4242 100644\n--- a/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al\n+++ b/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al\n@@ -298,6 +298,56 @@ codeunit 139544 \"Trial Balance Excel Reports\"\n asserterror LibraryReportDataset.RunReportAndLoad(Report::\"EXR Consolidated Trial Balance\", Variant, RequestPageXml);\n end;\n \n+ [Test]\n+ procedure TrialBalanceBufferNetChangeSplitsIntoDebitAndCreditWhenCalledSeveralTimes()\n+ var\n+ EXRTrialBalanceBuffer: Record \"EXR Trial Balance Buffer\";\n+ ValuesToSplitInCreditAndDebit: array[3] of Decimal;\n+ begin\n+ // [SCENARIO 547558] Trial Balance Buffer data split into Debit and Credit correctly, even if called multiple times.\n+ // [GIVEN] Trial Balance Buffer filled with positive Balance/Net Change\n+ ValuesToSplitInCreditAndDebit[1] := 837;\n+ // [GIVEN] Trial Balance Buffer filled with negative Balance/Net Change\n+ ValuesToSplitInCreditAndDebit[2] := -110;\n+ // [GIVEN] Trial Balance Buffer filled with positive Balance/Net Change\n+ ValuesToSplitInCreditAndDebit[3] := 998;\n+ // [WHEN] Trial Balance Buffer entries are inserted\n+ EXRTrialBalanceBuffer.\"G/L Account No.\" := 'A';\n+ EXRTrialBalanceBuffer.Validate(\"Net Change\", ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Validate(Balance, ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Validate(\"Net Change (ACY)\", ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Validate(\"Balance (ACY)\", ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Insert();\n+ EXRTrialBalanceBuffer.\"G/L Account No.\" := 'B';\n+ EXRTrialBalanceBuffer.Validate(\"Net Change\", ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Validate(Balance, ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Validate(\"Net Change (ACY)\", ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Validate(\"Balance (ACY)\", ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Insert();\n+ EXRTrialBalanceBuffer.\"G/L Account No.\" := 'C';\n+ EXRTrialBalanceBuffer.Validate(\"Net Change\", ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Validate(Balance, ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Validate(\"Net Change (ACY)\", ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Validate(\"Balance (ACY)\", ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Insert();\n+ // [THEN] All Entries have the right split in Credit and Debit\n+ EXRTrialBalanceBuffer.FindSet();\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit)\" + EXRTrialBalanceBuffer.\"Net Change (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Balance (Debit)\" + EXRTrialBalanceBuffer.\"Balance (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Net Change (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Balance (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Balance (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ EXRTrialBalanceBuffer.Next();\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit)\" + EXRTrialBalanceBuffer.\"Net Change (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Balance (Debit)\" + EXRTrialBalanceBuffer.\"Balance (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Net Change (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Balance (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Balance (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ EXRTrialBalanceBuffer.Next();\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit)\" + EXRTrialBalanceBuffer.\"Net Change (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Balance (Debit)\" + EXRTrialBalanceBuffer.\"Balance (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Net Change (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Balance (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Balance (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ end;\n+\n local procedure CreateSampleBusinessUnits(HowMany: Integer)\n var\n BusinessUnit: Record \"Business Unit\";\n", "patch": "diff --git a/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al b/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al\nindex 00c238ae4020..3359f9e94814 100644\n--- a/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al\n+++ b/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al\n@@ -44,10 +44,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Net Change\" > 0) then\n- Validate(\"Net Change (Debit)\", \"Net Change\")\n- else\n+ if (\"Net Change\" > 0) then begin\n+ Validate(\"Net Change (Debit)\", \"Net Change\");\n+ Validate(\"Net Change (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Net Change (Credit)\", -\"Net Change\");\n+ Validate(\"Net Change (Debit)\", 0);\n+ end;\n end;\n }\n field(11; \"Net Change (Debit)\"; Decimal)\n@@ -64,10 +68,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Balance\" > 0) then\n- Validate(\"Balance (Debit)\", \"Balance\")\n- else\n+ if (\"Balance\" > 0) then begin\n+ Validate(\"Balance (Debit)\", \"Balance\");\n+ Validate(\"Balance (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Balance (Credit)\", -\"Balance\");\n+ Validate(\"Balance (Debit)\", 0);\n+ end;\n end;\n }\n field(14; \"Balance (Debit)\"; Decimal)\n@@ -100,10 +108,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Net\" > 0) then\n- Validate(\"Last Period Net (Debit)\", \"Last Period Net\")\n- else\n+ if (\"Last Period Net\" > 0) then begin\n+ Validate(\"Last Period Net (Debit)\", \"Last Period Net\");\n+ Validate(\"Last Period Net (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Net (Credit)\", -\"Last Period Net\");\n+ Validate(\"Last Period Net (Debit)\", 0);\n+ end;\n end;\n }\n field(51; \"Last Period Net (Debit)\"; Decimal)\n@@ -120,10 +132,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Bal.\" > 0) then\n- Validate(\"Last Period Bal. (Debit)\", \"Last Period Bal.\")\n- else\n+ if (\"Last Period Bal.\" > 0) then begin\n+ Validate(\"Last Period Bal. (Debit)\", \"Last Period Bal.\");\n+ Validate(\"Last Period Bal. (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Bal. (Credit)\", -\"Last Period Bal.\");\n+ Validate(\"Last Period Bal. (Debit)\", 0);\n+ end;\n end;\n }\n field(61; \"Last Period Bal. (Debit)\"; Decimal)\n@@ -156,10 +172,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Net Change\" > 0) then\n- Validate(\"Net Change (Debit) (ACY)\", \"Net Change (ACY)\")\n- else\n+ if (\"Net Change\" > 0) then begin\n+ Validate(\"Net Change (Debit) (ACY)\", \"Net Change (ACY)\");\n+ Validate(\"Net Change (Credit) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Net Change (Credit) (ACY)\", -\"Net Change (ACY)\");\n+ Validate(\"Net Change (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(111; \"Net Change (Debit) (ACY)\"; Decimal)\n@@ -176,10 +196,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Balance\" > 0) then\n- Validate(\"Balance (Debit) (ACY)\", \"Balance (ACY)\")\n- else\n+ if (\"Balance\" > 0) then begin\n+ Validate(\"Balance (Debit) (ACY)\", \"Balance (ACY)\");\n+ Validate(\"Balance (Credit) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Balance (Credit) (ACY)\", -\"Balance (ACY)\");\n+ Validate(\"Balance (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(114; \"Balance (Debit) (ACY)\"; Decimal)\n@@ -196,10 +220,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Net\" > 0) then\n- Validate(\"Last Period Net (Debit) (ACY)\", \"Last Period Net (ACY)\")\n- else\n+ if (\"Last Period Net\" > 0) then begin\n+ Validate(\"Last Period Net (Debit) (ACY)\", \"Last Period Net (ACY)\");\n+ Validate(\"Last Period Net (Credit) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Net (Credit) (ACY)\", -\"Last Period Net (ACY)\");\n+ Validate(\"Last Period Net (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(151; \"Last Period Net (Debit) (ACY)\"; Decimal)\n@@ -216,10 +244,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Bal.\" > 0) then\n- Validate(\"Last Period Bal. (Debit) (ACY)\", \"Last Period Bal. (ACY)\")\n- else\n+ if (\"Last Period Bal.\" > 0) then begin\n+ Validate(\"Last Period Bal. (Debit) (ACY)\", \"Last Period Bal. (ACY)\");\n+ Validate(\"Last Period Bal. (Cred.) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Bal. (Cred.) (ACY)\", -\"Last Period Bal. (ACY)\");\n+ Validate(\"Last Period Bal. (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(161; \"Last Period Bal. (Debit) (ACY)\"; Decimal)\ndiff --git a/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al b/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al\nindex 7cf0915e376f..2e171cf03e3e 100644\n--- a/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al\n+++ b/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al\n@@ -119,6 +119,7 @@ codeunit 4410 \"Trial Balance\"\n \n local procedure InsertTrialBalanceDataForGLAccountWithFilters(var GLAccount: Record \"G/L Account\"; Dimension1ValueCode: Code[20]; Dimension2ValueCode: Code[20]; BusinessUnitCode: Code[20]; var TrialBalanceData: Record \"EXR Trial Balance Buffer\"; var Dimension1Values: Record \"Dimension Value\" temporary; var Dimension2Values: Record \"Dimension Value\" temporary)\n begin\n+ Clear(TrialBalanceData);\n GlAccount.CalcFields(\"Net Change\", \"Balance at Date\", \"Additional-Currency Net Change\", \"Add.-Currency Balance at Date\", \"Budgeted Amount\", \"Budget at Date\");\n TrialBalanceData.\"G/L Account No.\" := GlAccount.\"No.\";\n TrialBalanceData.\"Dimension 1 Code\" := Dimension1ValueCode;\n"} -{"metadata": {"area": "assembly", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207878", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-02-24", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Dimension"], "FAIL_TO_PASS": [{"codeunitID": 134381, "functionName": ["AvailWarningAssemblyOrdersConsideringDueDates"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al b/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al\nindex 2628814efa25..b2bfa55eddbe 100644\n--- a/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al\n+++ b/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al\n@@ -25,9 +25,20 @@ codeunit 134381 \"ERM Dimension Priority\"\n LibraryWarehouse: Codeunit \"Library - Warehouse\";\n LibraryManufacturing: Codeunit \"Library - Manufacturing\";\n SystemActionTriggers: Codeunit \"System Action Triggers\";\n+ LibraryAssembly: Codeunit \"Library - Assembly\";\n+ NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n isInitialized: Boolean;\n WrongDimValueCodeErr: Label 'Wrong dimension value code.';\n DefaultDimPrioritiesNotificationIdTxt: Label '69CE42D9-0580-4907-8BC9-0EEB59DA96C9', Locked = true;\n+ ItemAvaibilityIsLowNotificationIdTxt: Label '2712ad06-c48b-4c20-820e-347a60c9ad00', Locked = true;\n+ AvailWarningYesMsg: Label 'Avail. warning should be Yes';\n+ AvailWarningNoMsg: Label 'Avail. warning should be No';\n+ DueDateBeforeWDFromLineMsg: Label 'Due Date %1 is before work date %2.';\n+ DueDateBeforeWDFromHeaderMsg: Label 'Due Date %1 is before work date %2 in one or more of the assembly lines.';\n+ NewLineDueDate: Date;\n+ TestMethodName: Text[30];\n+ Step: Integer;\n+ TestVSTF257960A: Label 'VSTF257960A';\n \n [Test]\n [Scope('OnPrem')]\n@@ -758,6 +769,105 @@ codeunit 134381 \"ERM Dimension Priority\"\n Assert.IsFalse(ProdOrderLine.\"Shortcut Dimension 1 Code\" = ProdOrderComponent.\"Shortcut Dimension 1 Code\", 'Dimensions are equal.');\n end;\n \n+ [Test]\n+ [HandlerFunctions('DueDateBeforeWorkDateMsgHandler')]\n+ procedure AvailWarningAssemblyOrdersConsideringDueDates()\n+ var\n+ AsmHeader: Record \"Assembly Header\";\n+ AsmHeader2: Record \"Assembly Header\";\n+ AsmLine: Record \"Assembly Line\";\n+ AssemblySetup: Record \"Assembly Setup\";\n+ BOMComponent: Record \"BOM Component\";\n+ ComponentItem: Record Item;\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ Location: Record Location;\n+ ManufacturingSetup: Record \"Manufacturing Setup\";\n+ MyNotifications: Record \"My Notifications\";\n+ ProductItem: Record Item;\n+ Newworkdate: Date;\n+ begin\n+ // [SCENARIO 565695] Avail. Warning on Assembly Orders are now considering Demand for the Component only for selected Assembly Order.\n+ Initialize();\n+\n+ // [GIVEN] Set Item Avaibility Is Low Notification Enabled.\n+ SetMyNotificationsSetup(MyNotifications);\n+\n+ // [GIVEN] Create New Location.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Validate \"Default Location for Orders\" in Assembly Setup for New Created Location.\n+ AssemblySetup.Get();\n+ AssemblySetup.Validate(\"Default Location for Orders\", Location.Code);\n+ AssemblySetup.Modify(true);\n+\n+ // [GIVEN] Validate \"Components at Location\" in Manufacturing Setup for New Created Location.\n+ ManufacturingSetup.Get();\n+ ManufacturingSetup.Validate(\"Components at Location\", Location.Code);\n+ ManufacturingSetup.Modify(true);\n+\n+ // [GIVEN] Created Component Item\n+ LibraryInventory.CreateItem(ComponentItem);\n+\n+ // [GIVEN] Created Master Item and Assembly Component for Master Item\n+ LibraryInventory.CreateItem(ProductItem);\n+ ProductItem.Validate(\"Replenishment System\", ProductItem.\"Replenishment System\"::Purchase);\n+ ProductItem.Validate(\"Manufacturing Policy\", ProductItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProductItem.Modify(true);\n+ LibraryAssembly.CreateAssemblyListComponent(BOMComponent.Type::Item, ComponentItem.\"No.\", ProductItem.\"No.\", '', 0, 2, true);\n+\n+ // [GIVEN] Created 1st Assembly Order\n+ MakeAsmOrder(AsmHeader, ProductItem, 1, WorkDate(), Location.Code);\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity \n+ AsmLine.Get(AsmHeader.\"Document Type\", AsmHeader.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 1st Check \"Avail. Warning\" on Assemblyline for 1st Assembly Order\n+ Assert.IsTrue(AsmLine.\"Avail. Warning\", AvailWarningYesMsg);\n+\n+\n+ // [GIVEN] Created and Post Item Journal for Component Item\n+ LibraryInventory.CreateItemJournalLineInItemTemplate(ItemJournalLine, ComponentItem.\"No.\", Location.Code, '', 2);\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity for 1st Assembly Order\n+ AsmLine.Get(AsmHeader.\"Document Type\", AsmHeader.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 2nd Check \"Avail. Warning\" on Assemblyline for 1st Assembly Order\n+ Assert.IsFalse(AsmLine.\"Avail. Warning\", AvailWarningNoMsg);\n+\n+ // [GIVEN] Recall All Notifications\n+ NotificationLifecycleMgt.RecallAllNotifications();\n+\n+ // [GIVEN] Set 2nd New Work Date.\n+ Newworkdate := CalcDate('<1W>', WorkDate());\n+ WorkDate(Newworkdate);\n+\n+ // [GIVEN] Make 2nd Assembly Order \n+ MakeAsmOrder(AsmHeader2, ProductItem, 3, Newworkdate, Location.Code);\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity for 2nd Assembly Order\n+ AsmLine.Get(AsmHeader2.\"Document Type\", AsmHeader2.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 1st Check \"Avail. Warning\" on Assemblyline for 2nd Assembly Order\n+ Assert.IsTrue(AsmLine.\"Avail. Warning\", AvailWarningYesMsg);\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity for 1st Assembly Order\n+ AsmLine.Get(AsmHeader.\"Document Type\", AsmHeader.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 3rd Check \"Avail. Warning\" on Assemblyline for 1st Assembly Order\n+ Assert.IsFalse(AsmLine.\"Avail. Warning\", AvailWarningNoMsg);\n+\n+ NotificationLifecycleMgt.RecallAllNotifications();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1312,6 +1422,27 @@ codeunit 134381 \"ERM Dimension Priority\"\n CreateDefaultDimensionPriority(SourceCode, DATABASE::\"G/L Account\", 2);\n end;\n \n+ local procedure SetMyNotificationsSetup(var MyNotifications: Record \"My Notifications\")\n+ begin\n+ if MyNotifications.Get(UserId, ItemAvaibilityIsLowNotificationIdTxt) then begin\n+ MyNotifications.Validate(Enabled, true);\n+ MyNotifications.Modify(true);\n+ end else\n+ MyNotifications.InsertDefault(ItemAvaibilityIsLowNotificationIdTxt, '', '', true);\n+ end;\n+\n+ local procedure MakeAsmOrder(var AsmHeader: Record \"Assembly Header\"; ParentItem: Record Item; Qty: Decimal; DueDate: Date; LocationCode: Code[10])\n+ begin\n+ Clear(AsmHeader);\n+ AsmHeader.\"Document Type\" := AsmHeader.\"Document Type\"::Order;\n+ AsmHeader.Insert(true);\n+ AsmHeader.Validate(\"Due Date\", DueDate);\n+ AsmHeader.Validate(\"Location Code\", LocationCode);\n+ AsmHeader.Validate(\"Item No.\", ParentItem.\"No.\");\n+ AsmHeader.Validate(Quantity, Qty);\n+ AsmHeader.Modify(true);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text)\n@@ -1541,5 +1672,36 @@ codeunit 134381 \"ERM Dimension Priority\"\n begin\n RequestPage.OK().Invoke();\n end;\n+\n+ [MessageHandler]\n+ procedure DueDateBeforeWorkDateMsgHandler(Msg: Text[1024])\n+ var\n+ MessageTextFromHeader: Text[1024];\n+ MessageTextFromLine: Text[1024];\n+ begin\n+ MessageTextFromHeader := StrSubstNo(DueDateBeforeWDFromHeaderMsg, NewLineDueDate, WorkDate());\n+ MessageTextFromLine := StrSubstNo(DueDateBeforeWDFromLineMsg, NewLineDueDate, WorkDate());\n+ case TestMethodName of\n+ TestVSTF257960A:\n+ case Step of\n+ 1, 9:\n+ begin\n+ Assert.IsTrue(\n+ StrPos(Msg, MessageTextFromHeader) > 0, StrSubstNo('Wrong message: %1 \\Expected: %2', Msg, MessageTextFromHeader));\n+ exit;\n+ end;\n+ 10:\n+ begin\n+ Assert.IsTrue(\n+ StrPos(Msg, MessageTextFromLine) > 0, StrSubstNo('Wrong message: %1 \\Expected: %2', Msg, MessageTextFromLine));\n+ exit;\n+ end;\n+ end;\n+ else\n+ exit; // for other test methods.\n+ end;\n+\n+ Assert.Fail(StrSubstNo('Message at Step %1 not expected.', Step));\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\nindex 62ba45edddc6..2f9a548804d4 100644\n--- a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n@@ -1575,10 +1575,13 @@ table 901 \"Assembly Line\"\n EarliestDate);\n \n if ExpectedInventory < \"Remaining Quantity (Base)\" then begin\n- if ExpectedInventory < 0 then\n- AbleToAssemble := 0\n- else\n- AbleToAssemble := Round(ExpectedInventory / \"Quantity per\", UOMMgt.QtyRndPrecision(), '<')\n+ if ExpectedInventory < 0 then begin\n+ AbleToAssemble := 0;\n+ if AvailableInventory >= \"Remaining Quantity (Base)\" then\n+ AbleToAssemble := AssemblyHeader.\"Remaining Quantity\";\n+ end else\n+ AbleToAssemble := Round(ExpectedInventory / \"Quantity per\", UOMMgt.QtyRndPrecision(), '<');\n+\n end else begin\n AbleToAssemble := AssemblyHeader.\"Remaining Quantity\";\n EarliestDate := 0D;\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al\nindex 26f5dfa5f2ae..710350355238 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al\n@@ -28,6 +28,7 @@ codeunit 311 \"Item-Check Avail.\"\n AvailableToPromise: Codeunit \"Available to Promise\";\n NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n UOMMgt: Codeunit \"Unit of Measure Management\";\n+ AssemblyLineDueDateGlobal: Date;\n ItemNo: Code[20];\n UnitOfMeasureCode: Code[10];\n ItemLocationCode: Code[10];\n@@ -331,9 +332,8 @@ codeunit 311 \"Item-Check Avail.\"\n if IsHandled then\n exit;\n \n- AvailableToPromise.CalcQtyAvailabletoPromise(\n- Item, GrossReq, SchedRcpt, Item.GetRangeMax(\"Date Filter\"),\n- CompanyInfo.\"Check-Avail. Time Bucket\", CompanyInfo.\"Check-Avail. Period Calc.\");\n+ AvailableToPromise.CalcQtyAvailabletoPromise(Item, GrossReq, SchedRcpt, CheckAvailabilityDate(Item, AssemblyLineDueDateGlobal),\n+ CompanyInfo.\"Check-Avail. Time Bucket\", CompanyInfo.\"Check-Avail. Period Calc.\");\n InventoryQty := ConvertQty(AvailableToPromise.CalcAvailableInventory(Item) - OldItemNetResChange);\n GrossReq := ConvertQty(GrossReq);\n ReservedReq := ConvertQty(AvailableToPromise.CalcReservedRequirement(Item) + OldItemNetResChange);\n@@ -485,6 +485,7 @@ codeunit 311 \"Item-Check Avail.\"\n OldItemNetChange := 0;\n \n OldAssemblyLine := AssemblyLine;\n+ AssemblyLineDueDateGlobal := OldAssemblyLine.\"Due Date\";\n \n if OldAssemblyLine.Find() then begin // Find previous quantity\n ShouldCheckQty :=\n@@ -767,6 +768,14 @@ codeunit 311 \"Item-Check Avail.\"\n UseOrderPromise := NewUseOrderPromise;\n end;\n \n+ local procedure CheckAvailabilityDate(var Item: Record Item; AssemblyLineDueDate: Date): Date\n+ begin\n+ if AssemblyLineDueDate = 0D then\n+ exit(Item.GetRangeMax(\"Date Filter\"))\n+ else\n+ exit(0D);\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterCalculate(var Item: Record Item; var InitialQtyAvailable: Decimal; OldItemNetChange: Decimal; QtyPerUnitOfMeasure: Decimal; var ContextInfo: Dictionary of [Text, Text])\n begin\n"} -{"metadata": {"area": "finance", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-185792", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-06-07", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136305, "functionName": ["ProjectAmountUpdatedWhenAmountLCYIsInserted"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\nindex faf365eeaa53..f2ff7c96db82 100644\n--- a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n@@ -41,6 +41,7 @@ codeunit 136305 \"Job Journal\"\n AmountErr: Label 'Amount must be right';\n CurrencyDateConfirmTxt: Label 'The currency dates on all planning lines will be updated based on the invoice posting date because there is a difference in currency exchange rates. Recalculations will be based on the Exch. Calculation setup for the Cost and Price values for the project. Do you want to continue?';\n ControlNotFoundErr: Label 'Expected control not found on the page';\n+ ProjectTotalCostErr: Label 'Project Total Cost(LCY) must be updated.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2886,6 +2887,58 @@ codeunit 136305 \"Job Journal\"\n Assert.RecordCount(JobPlanningLine, 1);\n end;\n \n+ [Test]\n+ procedure ProjectAmountUpdatedWhenAmountLCYIsInserted()\n+ var\n+ JobTask: Record \"Job Task\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ GLAccount: Record \"G/L Account\";\n+ BankAccount: Record \"Bank Account\";\n+ Currency: Record Currency;\n+ PreviousProjectTotalCostLCY: Decimal;\n+ begin\n+ // [SCENARIO 537315] The Project G/L Ledgers line after changing the \"Amount (LCY)\" value changes Project Total Cost(LCY).\n+ Initialize();\n+\n+ // [GIVEN] Create a Job and job Task.\n+ CreateJobWithJobTask(JobTask);\n+\n+ // [GIVEN] Create a Job Journal Batch.\n+ CreateAndUpdateJobJournalBatch(GenJournalBatch);\n+\n+ // [GIVEN] Create a GL Account.\n+ LibraryERM.CreateGLAccount(GLAccount);\n+\n+ // [GIVEN] Create a Bank Account.\n+ LibraryERM.CreateBankAccount(BankAccount);\n+\n+ // [GIVEN] Get any existing Currency.\n+ LibraryERM.FindCurrency(Currency);\n+\n+ // [GIVEN] Create General Journal Line.\n+ LibraryERM.CreateGeneralJnlLine(\n+ GenJournalLine, GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name, GenJournalLine.\"Document Type\"::Invoice,\n+ GenJournalLine.\"Account Type\"::\"G/L Account\", GLAccount.\"No.\", LibraryRandom.RandDec(100, 2));\n+\n+ //[GIVEN] Validate Balancing Accounts.\n+ GenJournalLine.Validate(\"Bal. Account Type\", GenJournalLine.\"Bal. Account Type\"::\"Bank Account\");\n+ GenJournalLine.Validate(\"Bal. Account No.\", BankAccount.\"No.\");\n+ GenJournalLine.Validate(\"Currency Code\", Currency.Code);\n+ GenJournalLine.Validate(\"Job Line Type\", GenJournalLine.\"Job Line Type\"::\"Both Budget and Billable\");\n+ GenJournalLine.Validate(\"Job No.\", JobTask.\"Job No.\");\n+ GenJournalLine.Validate(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ GenJournalLine.Validate(\"Job Quantity\", LibraryRandom.RandDec(10, 2));\n+\n+ // [GIVEN] Store Project Total Cost LCY and Validate Amount (LCY) to new Amount.\n+ PreviousProjectTotalCostLCY := GenJournalLine.\"Job Total Cost (LCY)\";\n+ GenJournalLine.Validate(\"Amount (LCY)\", LibraryRandom.RandDec(12, 2));\n+ GenJournalLine.Modify(true);\n+\n+ // [THEN] Project Total Cost (LCY) must be updated.\n+ Assert.AreNotEqual(GenJournalLine.\"Job Total Cost (LCY)\", PreviousProjectTotalCostLCY, ProjectTotalCostErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\nindex 84ae0e69ac8e..3c462d43423f 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n@@ -590,6 +590,11 @@ table 81 \"Gen. Journal Line\"\n Validate(\"Bal. VAT %\");\n UpdateLineBalance();\n end;\n+\n+ if JobTaskIsSet() then begin\n+ CreateTempJobJnlLine();\n+ UpdatePricesFromJobJnlLine();\n+ end;\n end;\n }\n field(17; \"Balance (LCY)\"; Decimal)\n"} -{"metadata": {"area": "workflow", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-185488", "base_commit": "41efbd81ba3146b79667f1b9ce1194697dda34c6", "created_at": "2024-06-03", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Workflow"], "FAIL_TO_PASS": [{"codeunitID": 134184, "functionName": ["CanRequestApprovalPurchaseQuoteWithNotifySender"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al b/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al\nindex eec702f0b7ed..c683ab7e3d58 100644\n--- a/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al\n+++ b/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al\n@@ -169,6 +169,48 @@ codeunit 134184 \"WF Demo Purch Quote Approvals\"\n Assert.ExpectedError(StrSubstNo(RecordIsRestrictedErr, Format(PurchaseHeader.RecordId, 0, 1)));\n end;\n \n+ [Test]\n+ procedure CanRequestApprovalPurchaseQuoteWithNotifySender()\n+ var\n+ PurchaseHeader: Record \"Purchase Header\";\n+ WorkflowStepInstance: Record \"Workflow Step Instance\";\n+ WorkflowStepArgument: Record \"Workflow Step Argument\";\n+ ApprovalEntry: Record \"Approval Entry\";\n+ WorkflowResponseHandling: Codeunit \"Workflow Response Handling\";\n+ Variant: Variant;\n+ begin\n+ // [SCENARIO] When ExecuteResponse is called with a purchase header as argument and setup to Create a notification entry code, no error is thrown.\n+ // [GIVEN] The approval workflow for purchase quotes is enabled.\n+ // [WHEN] The user wants to Release the purchase quote.\n+ // [THEN] The user will get an error that he cannot release the purchase quote that is not approved.\n+\n+ // Setup\n+ Initialize();\n+\n+ // [GIVEN] A purchase quote that should be approved\n+ CreatePurchaseQuote(PurchaseHeader);\n+\n+ // [GIVEN] An approval for the purchase quote\n+ if ApprovalEntry.FindLast() then;\n+ ApprovalEntry.\"Entry No.\" += 1;\n+ ApprovalEntry.\"Record ID to Approve\" := PurchaseHeader.RecordId;\n+ ApprovalEntry.Insert();\n+\n+ // [GIVEN] A workflow step for sending a notification\n+ WorkflowStepArgument.ID := CreateGuid();\n+ WorkflowStepArgument.\"Notify Sender\" := true;\n+ WorkflowStepArgument.Insert();\n+\n+ WorkflowStepInstance.ID := CreateGuid();\n+ WorkflowStepInstance.Argument := WorkflowStepArgument.ID;\n+ WorkflowStepInstance.\"Function Name\" := WorkflowResponseHandling.CreateNotificationEntryCode();\n+ WorkflowStepInstance.Insert();\n+\n+ // [WHEN] Executing the notification step\n+ // [THEN] No error is thrown\n+ WorkflowResponseHandling.ExecuteResponse(Variant, WorkflowStepInstance, PurchaseHeader);\n+ end;\n+\n [Test]\n [HandlerFunctions('MessageHandler')]\n [Scope('OnPrem')]\n", "patch": "diff --git a/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al b/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al\nindex bcd82095b12b..b00fddb95709 100644\n--- a/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al\n@@ -86,7 +86,7 @@ codeunit 1521 \"Workflow Response Handling\"\n ApplyNewValuesTxt: Label 'Apply the new values.';\n DiscardNewValuesTxt: Label 'Discard the new values.';\n EnableJobQueueEntryResponseDescTxt: Label 'Enable the job queue entry.';\n-\n+ UnknownRecordErr: Label 'Unknown record type.';\n // Telemetry strings\n WorkflowResponseStartTelemetryTxt: Label 'Workflow response: Start Scope', Locked = true;\n WorkflowResponseEndTelemetryTxt: Label 'Workflow response: End Scope', Locked = true;\n@@ -108,8 +108,8 @@ codeunit 1521 \"Workflow Response Handling\"\n AddResponseToLibrary(PostDocumentCode(), 0, PostDocumentTxt, 'GROUP 0');\n AddResponseToLibrary(PostDocumentAsyncCode(), 0, BackgroundDocumentPostTxt, 'GROUP 0');\n \n- AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocAsyncCode(), DATABASE::\"Purch. Inv. Header\", CreatePmtLineAsyncTxt, 'GROUP 1');\n- AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocCode(), DATABASE::\"Purch. Inv. Header\", CreatePmtLineTxt, 'GROUP 1');\n+ AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocAsyncCode(), Database::\"Purch. Inv. Header\", CreatePmtLineAsyncTxt, 'GROUP 1');\n+ AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocCode(), Database::\"Purch. Inv. Header\", CreatePmtLineTxt, 'GROUP 1');\n \n AddResponseToLibrary(CreateOverdueNotificationCode(), 0, CreateOverdueNotifTxt, 'GROUP 2');\n AddResponseToLibrary(CheckCustomerCreditLimitCode(), 0, CheckCustomerCreditLimitTxt, 'GROUP 0');\n@@ -624,22 +624,45 @@ codeunit 1521 \"Workflow Response Handling\"\n begin\n end;\n \n- local procedure CreateNotificationEntry(WorkflowStepInstance: Record \"Workflow Step Instance\"; ApprovalEntry: Record \"Approval Entry\")\n+ local procedure CreateNotificationEntry(WorkflowStepInstance: Record \"Workflow Step Instance\"; var Variant: Variant)\n var\n+ ApprovalEntry: Record \"Approval Entry\";\n WorkflowStepArgument: Record \"Workflow Step Argument\";\n NotificationEntry: Record \"Notification Entry\";\n+ RecRef: RecordRef;\n IsHandled: Boolean;\n begin\n- IsHandled := false;\n- OnBeforeCreateNotificationEntry(WorkflowStepInstance, ApprovalEntry, IsHandled);\n- if IsHandled then\n- exit;\n+ RecRef.GetTable(Variant);\n+ case RecRef.Number of\n+ Database::\"Approval Entry\":\n+ begin\n+ ApprovalEntry := Variant;\n+ IsHandled := false;\n+ OnBeforeCreateNotificationEntry(WorkflowStepInstance, ApprovalEntry, IsHandled);\n+ if IsHandled then\n+ exit;\n \n- if WorkflowStepArgument.Get(WorkflowStepInstance.Argument) then\n- NotificationEntry.CreateNotificationEntry(\n- WorkflowStepArgument.\"Notification Entry Type\",\n- WorkflowStepArgument.GetNotificationUserID(ApprovalEntry), ApprovalEntry, WorkflowStepArgument.\"Link Target Page\",\n- WorkflowStepArgument.\"Custom Link\", UserID);\n+ if WorkflowStepArgument.Get(WorkflowStepInstance.Argument) then\n+ NotificationEntry.CreateNotificationEntry(WorkflowStepArgument.\"Notification Entry Type\", WorkflowStepArgument.GetNotificationUserID(ApprovalEntry), ApprovalEntry, WorkflowStepArgument.\"Link Target Page\", WorkflowStepArgument.\"Custom Link\", CopyStr(UserId(), 1, 50));\n+ end;\n+ Database::\"Incoming Document\",\n+ Database::\"Gen. Journal Line\",\n+ Database::\"Purchase Header\",\n+ Database::\"Purch. Inv. Header\":\n+ if WorkflowStepArgument.Get(WorkflowStepInstance.Argument) then\n+ if WorkflowStepArgument.\"Notify Sender\" then\n+ NotificationEntry.CreateNotificationEntry(WorkflowStepArgument.\"Notification Entry Type\", CopyStr(UserId(), 1, 50), Variant, WorkflowStepArgument.\"Link Target Page\", WorkflowStepArgument.\"Custom Link\", CopyStr(UserId(), 1, 50))\n+ else\n+ NotificationEntry.CreateNotificationEntry(WorkflowStepArgument.\"Notification Entry Type\", WorkflowStepArgument.\"Notification User ID\", Variant, WorkflowStepArgument.\"Link Target Page\", WorkflowStepArgument.\"Custom Link\", CopyStr(UserId(), 1, 50));\n+ else begin\n+ ApprovalEntry.SetRange(\"Record ID to Approve\", RecRef.RecordId);\n+ if ApprovalEntry.FindFirst() then begin\n+ Variant := ApprovalEntry;\n+ CreateNotificationEntry(WorkflowStepInstance, Variant);\n+ end else\n+ Error(UnknownRecordErr);\n+ end;\n+ end;\n end;\n \n local procedure ReleaseDocument(var Variant: Variant)\n@@ -657,25 +680,25 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n TargetRecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n Variant := TargetRecRef;\n ReleaseDocument(Variant);\n end;\n- DATABASE::\"Workflow Webhook Entry\":\n+ Database::\"Workflow Webhook Entry\":\n begin\n WorkflowWebhookEntry := Variant;\n TargetRecRef.Get(WorkflowWebhookEntry.\"Record ID\");\n Variant := TargetRecRef;\n ReleaseDocument(Variant);\n end;\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n ReleasePurchaseDocument.PerformManualCheckAndRelease(Variant);\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n ReleaseSalesDocument.PerformManualCheckAndRelease(Variant);\n- DATABASE::\"Incoming Document\":\n+ Database::\"Incoming Document\":\n ReleaseIncomingDocument.PerformManualRelease(Variant);\n else begin\n OnReleaseDocument(RecRef, Handled);\n@@ -699,25 +722,25 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n TargetRecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n Variant := TargetRecRef;\n OpenDocument(Variant);\n end;\n- DATABASE::\"Workflow Webhook Entry\":\n+ Database::\"Workflow Webhook Entry\":\n begin\n WorkflowWebhookEntry := Variant;\n TargetRecRef.Get(WorkflowWebhookEntry.\"Record ID\");\n Variant := TargetRecRef;\n OpenDocument(Variant);\n end;\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n ReleasePurchaseDocument.Reopen(Variant);\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n ReleaseSalesDocument.Reopen(Variant);\n- DATABASE::\"Incoming Document\":\n+ Database::\"Incoming Document\":\n ReleaseIncomingDocument.Reopen(Variant);\n else begin\n OnOpenDocument(RecRef, Handled);\n@@ -782,7 +805,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n ApprovalsMgmt.SendApprovalRequestFromApprovalEntry(Variant, WorkflowStepInstance);\n else\n ApprovalsMgmt.SendApprovalRequestFromRecord(RecRef, WorkflowStepInstance);\n@@ -798,7 +821,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n@@ -818,7 +841,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n@@ -838,7 +861,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n@@ -859,13 +882,13 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n begin\n PurchaseHeader := Variant;\n PurchaseHeader.TestField(Status, PurchaseHeader.Status::Released);\n JobQueueEntry.ScheduleJobQueueEntry(CODEUNIT::\"Purchase Post via Job Queue\", PurchaseHeader.RecordId);\n end;\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n begin\n SalesHeader := Variant;\n SalesHeader.TestField(Status, SalesHeader.Status::Released);\n@@ -884,9 +907,9 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n CODEUNIT.Run(CODEUNIT::\"Purch.-Post\", Variant);\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n CODEUNIT.Run(CODEUNIT::\"Sales-Post\", Variant);\n else begin\n IsHandled := false;\n@@ -923,7 +946,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n begin\n SalesHeader := Variant;\n SalesHeader.CheckAvailableCreditLimit();\n@@ -939,7 +962,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Gen. Journal Batch\":\n+ Database::\"Gen. Journal Batch\":\n begin\n GenJournalBatch := Variant;\n GenJournalBatch.CheckBalance();\n@@ -955,9 +978,9 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n ApprovalsMgmt.CreateAndAutomaticallyApproveRequest(RecRef, WorkflowStepInstance);\n- DATABASE::Customer:\n+ Database::Customer:\n ApprovalsMgmt.CreateAndAutomaticallyApproveRequest(RecRef, WorkflowStepInstance);\n end;\n end;\n@@ -997,30 +1020,30 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n RecordRestrictionMgt.AllowRecordUsage(Variant);\n RecRef.SetTable(ApprovalEntry);\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n AllowRecordUsage(RecRef);\n end;\n- DATABASE::\"Workflow Webhook Entry\":\n+ Database::\"Workflow Webhook Entry\":\n begin\n RecRef.SetTable(WorkflowWebhookEntry);\n RecRef.Get(WorkflowWebhookEntry.\"Record ID\");\n AllowRecordUsage(RecRef);\n end;\n- DATABASE::\"Gen. Journal Batch\":\n+ Database::\"Gen. Journal Batch\":\n begin\n RecRef.SetTable(GenJournalBatch);\n RecordRestrictionMgt.AllowGenJournalBatchUsage(GenJournalBatch);\n end;\n- DATABASE::\"Item Journal Batch\":\n+ Database::\"Item Journal Batch\":\n begin\n RecRef.SetTable(ItemJournalBatch);\n RecordRestrictionMgt.AllowItemJournalBatchUsage(ItemJournalBatch);\n end;\n- DATABASE::\"FA Journal Batch\":\n+ Database::\"FA Journal Batch\":\n begin\n RecRef.SetTable(FAJournalBatch);\n RecordRestrictionMgt.AllowFAJournalBatchUsage(FAJournalBatch);\n@@ -1306,7 +1329,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(VariantRecord);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := VariantRecord;\n RecRef := ApprovalEntry.\"Record ID to Approve\".GetRecord();\n"} -{"metadata": {"area": "purchases", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-192565", "base_commit": "2c4e6d219aac9b612e09224312d199d48212cead", "created_at": "2024-08-27", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134282, "functionName": ["ChangingDirectUnitCostToZeroChangesNonDeductibleVAT"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\nindex 355bce76f10f..b8424b6d859b 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n@@ -179,6 +179,34 @@ codeunit 134282 \"Non-Deductible UT\"\n Assert.ExpectedError(StrSubstNo(DifferentNonDedVATRatesSameVATIdentifierErr, VATPostingSetup.\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\"));\n end;\n \n+ [Test]\n+ procedure ChangingDirectUnitCostToZeroChangesNonDeductibleVAT()\n+ var\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ // [SCENARIO 546032] Changeing the direct unit cost to zero also changes the Non-Deductible VAT of the purchase document\n+\n+ Initialize();\n+ // [GIVEN] VAT Posting Setup with \"VAT Identifier\" = \"X\", \"Allow Non-Deductible VAT\" is enabled and \"Non-Deductible VAT %\" is specified\n+ LibraryNonDeductibleVAT.CreateNonDeductibleNormalVATPostingSetup(VATPostingSetup);\n+ // [GIVEN] Purchase invoice with Non-Deductible VAT posting setup and a single line with direct unit cost\n+ LibraryPurchase.CreatePurchHeader(\n+ PurchaseHeader, PurchaseHeader.\"Document Type\"::Invoice,\n+ LibraryPurchase.CreateVendorWithVATBusPostingGroup(VATPostingSetup.\"VAT Bus. Posting Group\"));\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item,\n+ LibraryInventory.CreateItemWithVATProdPostingGroup(VATPostingSetup.\"VAT Prod. Posting Group\"), LibraryRandom.RandInt(100));\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandDec(100, 2));\n+\n+ // [WHEN] Change \"Direct Unit Cost\" to 0 in the purchase line\n+ PurchaseLine.Validate(\"Direct Unit Cost\", 0);\n+ // [THEN] \"Non-Deductible VAT Base\" and \"Non-Deductible VAT Amount\" are 0 in the purchase line\n+ PurchaseLine.TestField(\"Non-Deductible VAT Base\", 0);\n+ PurchaseLine.TestField(\"Non-Deductible VAT Amount\", 0);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Non-Deductible UT\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al b/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al\nindex fb45dbcf51a0..09b9b67c9b09 100644\n--- a/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al\n@@ -5365,6 +5365,7 @@ table 39 \"Purchase Line\"\n Amount := 0;\n \"VAT Base Amount\" := 0;\n \"Amount Including VAT\" := 0;\n+ NonDeductibleVAT.ClearNonDeductibleVAT(Rec);\n OnUpdateVATAmountsOnBeforePurchLineModify(Rec, PurchLine2);\n if (Quantity = 0) and (xRec.Quantity <> 0) and (xRec.Amount <> 0) then begin\n if \"Line No.\" <> 0 then\n"} -{"metadata": {"area": "workflow", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-181900", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-04-21", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\General Journal"], "FAIL_TO_PASS": [{"codeunitID": 134321, "functionName": ["ShowImposedRestrictionBatchStatusForWorkflowUserGroupIfFirstApprovalEntryIsApproved"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al b/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al\nindex 686a4b745e40..7b4a1c13b2e5 100644\n--- a/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al\n+++ b/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al\n@@ -935,7 +935,7 @@ codeunit 134321 \"General Journal Batch Approval\"\n \n // [THEN] Verify error message\n Assert.ExpectedError(PreventModifyRecordWithOpenApprovalEntryMsg);\n- end; \n+ end;\n \n [Test]\n procedure ShowImposedRestrictionBatchStatusIfUserModifyGenJournalLineForApprovedApprovalRequest()\n@@ -976,6 +976,41 @@ codeunit 134321 \"General Journal Batch Approval\"\n Assert.AreEqual(ImposedRestrictionLbl, GeneralJournal.GenJnlBatchApprovalStatus.Value(), 'Imposed restriction is not shown');\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ procedure ShowImposedRestrictionBatchStatusForWorkflowUserGroupIfFirstApprovalEntryIsApproved()\n+ var\n+ Workflow: Record Workflow;\n+ CurrentUserSetup: Record \"User Setup\";\n+ IntermediateApproverUserSetup: Record \"User Setup\";\n+ FinalApproverUserSetup: Record \"User Setup\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GeneralJournal: TestPage \"General Journal\";\n+ begin\n+ // [SCENARIO 526988] Show Imposed restriction batch status for Workflow User Group if first approval entry is auto approved\n+ Initialize();\n+\n+ // [GIVEN] Copy Workflow Template\n+ LibraryWorkflow.CopyWorkflowTemplate(Workflow, WorkflowSetup.GeneralJournalBatchApprovalWorkflowCode());\n+\n+ // [GIVEN] Setup - Create 3 user setups, create workflow user group and set the group for the workflow\n+ LibraryDocumentApprovals.CreateUserSetupsAndGroupOfApproversForWorkflow(\n+ Workflow, CurrentUserSetup, IntermediateApproverUserSetup, FinalApproverUserSetup);\n+ LibraryWorkflow.EnableWorkflow(Workflow);\n+\n+ // [GIVEN] Non-empty Gen. Journal Batch\n+ CreateGeneralJournalBatchWithOneJournalLine(GenJournalBatch, GenJournalLine);\n+\n+ // [WHEN] Approval request has been sent for Gen. Journal Batch\n+ SendApprovalRequestBatch(GenJournalBatch.Name);\n+\n+ // [THEN] Verify result\n+ GeneralJournal.OpenView();\n+ GeneralJournal.CurrentJnlBatchName.SetValue(GenJournalBatch.Name);\n+ Assert.AreEqual(ImposedRestrictionLbl, GeneralJournal.GenJnlBatchApprovalStatus.Value(), 'Imposed restriction is not shown');\n+ end;\n+\n local procedure Initialize()\n var\n Workflow: Record Workflow;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al b/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al\nindex 42799bec2311..8cd1a961d386 100644\n--- a/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al\n@@ -463,8 +463,17 @@ codeunit 1535 \"Approvals Mgmt.\"\n exit(ApprovalEntry.FindFirst());\n end;\n \n+ procedure FindLastApprovalEntryForCurrUser(var ApprovalEntry: Record \"Approval Entry\"; RecordID: RecordID): Boolean\n+ begin\n+ ApprovalEntry.SetRange(\"Table ID\", RecordID.TableNo);\n+ ApprovalEntry.SetRange(\"Record ID to Approve\", RecordID);\n+ ApprovalEntry.SetRange(\"Approver ID\", UserId);\n+ exit(ApprovalEntry.FindLast());\n+ end;\n+\n procedure FindApprovalEntryByRecordId(var ApprovalEntry: Record \"Approval Entry\"; RecordID: RecordID): Boolean\n begin\n+ ApprovalEntry.Reset();\n ApprovalEntry.SetRange(\"Table ID\", RecordID.TableNo);\n ApprovalEntry.SetRange(\"Record ID to Approve\", RecordID);\n exit(ApprovalEntry.FindLast());\n@@ -2483,8 +2492,11 @@ codeunit 1535 \"Approvals Mgmt.\"\n if not GenJournalBatch.Get(GenJournalLine.\"Journal Template Name\", GenJournalLine.\"Journal Batch Name\") then\n exit;\n \n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) then\n- GenJnlBatchApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalBatch);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalBatch.RecordId) then\n+ GenJnlBatchApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalBatch)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) then\n+ GenJnlBatchApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalBatch);\n end;\n \n procedure GetGenJnlLineApprovalStatus(GenJournalLine: Record \"Gen. Journal Line\"; var GenJnlLineApprovalStatus: Text[20]; EnabledGenJnlLineWorkflowsExist: Boolean)\n@@ -2495,8 +2507,11 @@ codeunit 1535 \"Approvals Mgmt.\"\n if not EnabledGenJnlLineWorkflowsExist then\n exit;\n \n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) then\n- GenJnlLineApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalLine);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalLine.RecordId) then\n+ GenJnlLineApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalLine)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) then\n+ GenJnlLineApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalLine);\n end;\n \n local procedure GetApprovalStatusFromApprovalEntry(var ApprovalEntry: Record \"Approval Entry\"; GenJournalBatch: Record \"Gen. Journal Batch\"): Text[20]\n@@ -2572,12 +2587,18 @@ codeunit 1535 \"Approvals Mgmt.\"\n begin\n if GenJournalBatch.Get(GenJournalLine.\"Journal Template Name\", GenJournalLine.\"Journal Batch Name\") then\n if IsGeneralJournalBatchApprovalsWorkflowEnabled(GenJournalBatch) then\n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n- GenJnlBatchApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalBatch.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlBatchApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlBatchApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n \n if IsGeneralJournalLineApprovalsWorkflowEnabled(GenJournalLine) then\n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n- GenJnlLineApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalLine.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlLineApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlLineApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n end;\n \n local procedure FindOpenApprovalEntryForSequenceNo(RecRef: RecordRef; WorkflowStepInstance: Record \"Workflow Step Instance\"; SequenceNo: Integer): Boolean\n"} -{"metadata": {"area": "finance", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-182354", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-04-26", "environment_setup_version": "24.2", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134924, "functionName": ["TotalOverdueLCYInFinanceCue"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al\nindex 12edc29d5fd3..8f0836e38d21 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al\n@@ -13,8 +13,6 @@ codeunit 134924 \"ERM Cues\"\n Assert: Codeunit Assert;\n LibraryTimeSheet: Codeunit \"Library - Time Sheet\";\n LibraryService: Codeunit \"Library - Service\";\n- WrongValueErr: Label 'Wrong value of the field %1 in table %2.';\n- AverageDaysDelayedErr: Label 'Average Days Delayed is calculated incorrectly.';\n LibraryUtility: Codeunit \"Library - Utility\";\n LibraryRandom: Codeunit \"Library - Random\";\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n@@ -24,6 +22,8 @@ codeunit 134924 \"ERM Cues\"\n ShipStatus: Option Full,Partial,\"Not Shipped\";\n WrongNumberOfDelayedOrdersErr: Label 'Wrong number of delayed Sales Orders.';\n RedundantSalesOnListErr: Label 'List of delayed Sales Order contains redundant documents.';\n+ WrongValueErr: Label 'Wrong value of the field %1 in table %2.', Comment = '%1 = Field name, %2 = Table name';\n+ AverageDaysDelayedErr: Label 'Average Days Delayed is calculated incorrectly.';\n IsInitialized: Boolean;\n \n [Test]\n@@ -699,6 +699,49 @@ codeunit 134924 \"ERM Cues\"\n Assert.IsFalse(SalesOrderList.Previous(), '');\n end;\n \n+ [Test]\n+ procedure TotalOverdueLCYInFinanceCue()\n+ var\n+ DetailedCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n+ CustomerLedgerEntries: TestPage \"Customer Ledger Entries\";\n+ AccountReceivablesKPIs: TestPage \"Account Receivables KPIs\";\n+ TotalOverDueLCYErr: Label 'The total overdue LCY amount is not calculated correctly.', Locked = true;\n+ DateFilterTxt: Label '<=%1', Locked = true, Comment = '%1 = Date';\n+ begin\n+ // [FEATURE] [Finance Cue] [Accounts Receivables Overview]\n+ // [SCENARIO 506725] Total overdue LCY cue in Finance Cue displays the amount of open overdue cust. ledger entries where due date filter is today\n+ Initialize();\n+\n+ // [GIVEN] Create customer ledger entries and detailed customer ledger entries\n+ // [GIVEN] Cust. ledger entry 1, due date = today - 10days, open = true, amount (LCY) = 100.34, remaining amount (LCY) = 50.17 (detailed cust. ledger entry 1 amount (LCY) = 100.34, detailed cust. ledger entry 2 amount (LCY) = 50.17)\n+ // [GIVEN] Cust. ledger entry 2, due date = today, open = false, amount (LCY) = 120.23, remaining amount (LCY) = 0 (detailed cust. ledger entry 1 amount (LCY) = 120.23, detailed cust. ledger entry 2 amount (LCY) = 120.23)\n+ // [GIVEN] Cust. ledger entry 3, due date = today + 20days, open = true, amount (LCY) = 150.82, remaining amount (LCY) = 150.82 (detailed cust. ledger entry 1 amount (LCY) = 150.82, detailed cust. ledger entry 2 amount (LCY) = 150.82)\n+ CreateCustomerLedgerEntry(CalcDate('<-10D>', Today), true, 100.34, 50.17);\n+ CreateCustomerLedgerEntry(Today, false, 120.23, 120.23);\n+ CreateCustomerLedgerEntry(CalcDate('<+20D>', Today), true, 150.82, 0);\n+\n+ // [WHEN] Open Account Receivables KPIs page with overdue date filter\n+ AccountReceivablesKPIs.OpenView();\n+ AccountReceivablesKPIs.Filter.SetFilter(\"Overdue Date Filter\", StrSubstNo(DateFilterTxt, Today()));\n+\n+ // [WHEN] Calculate total overdue LCY amount\n+ DetailedCustLedgEntry.SetFilter(\"Initial Entry Due Date\", '<=%1', Today());\n+ DetailedCustLedgEntry.CalcSums(\"Amount (LCY)\");\n+\n+ // [THEN] Verify the total overdue amount is correct\n+ Assert.AreEqual(Format(DetailedCustLedgEntry.\"Amount (LCY)\"), AccountReceivablesKPIs.\"Sales - Total Overdue (LCY)\".Value, TotalOverDueLCYErr);\n+\n+ // [WHEN] DrillDown to \"Sales - Total Overdue (LCY)\" cue\n+ CustomerLedgerEntries.Trap();\n+ AccountReceivablesKPIs.\"Sales - Total Overdue (LCY)\".Drilldown();\n+\n+ // [THEN] Only Cust. ledger entry 1 is shown on Cust. ledger entries page\n+ CustomerLedgerEntries.First();\n+ Assert.AreEqual(Format(CustomerLedgerEntries.\"Remaining Amt. (LCY)\"), AccountReceivablesKPIs.\"Sales - Total Overdue (LCY)\".Value, TotalOverDueLCYErr);\n+ Assert.IsFalse(CustomerLedgerEntries.Next(), '');\n+ CustomerLedgerEntries.Close();\n+ end;\n+\n local procedure Initialize()\n var\n SalesHeader: Record \"Sales Header\";\n@@ -711,6 +754,8 @@ codeunit 134924 \"ERM Cues\"\n ServiceContractLine: Record \"Service Contract Line\";\n PostedWhseShipmentHeader: Record \"Posted Whse. Shipment Header\";\n VendorLedgerEntry: Record \"Vendor Ledger Entry\";\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ DetailedCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n SalesCue: Record \"Sales Cue\";\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"ERM Cues\");\n@@ -724,6 +769,9 @@ codeunit 134924 \"ERM Cues\"\n ServiceContractLine.DeleteAll();\n PostedWhseShipmentHeader.DeleteAll();\n VendorLedgerEntry.DeleteAll();\n+ CustLedgerEntry.DeleteAll();\n+ DetailedCustLedgEntry.DeleteAll();\n+\n if SalesCue.Get() then begin\n SalesCue.\"Avg. Days Delayed Updated On\" := 0DT;\n SalesCue.Modify();\n@@ -924,6 +972,35 @@ codeunit 134924 \"ERM Cues\"\n SalesLine.Modify(true);\n end;\n \n+ local procedure CreateCustomerLedgerEntry(DueDate: Date; Open: Boolean; Amount1: Decimal; Amount2: Decimal)\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ begin\n+ CustLedgerEntry.\"Entry No.\" := CustLedgerEntry.GetLastEntryNo() + 1;\n+ CustLedgerEntry.\"Document Type\" := CustLedgerEntry.\"Document Type\"::Invoice;\n+ CustLedgerEntry.\"Due Date\" := DueDate;\n+ CustLedgerEntry.Open := Open;\n+ CustLedgerEntry.Insert();\n+\n+ CreateDetailedCustLedgEntry(CustLedgerEntry.\"Entry No.\", DueDate, Amount1, CustLedgerEntry.\"Document Type\", true);\n+ CreateDetailedCustLedgEntry(CustLedgerEntry.\"Entry No.\", DueDate, -Amount2, CustLedgerEntry.\"Document Type\", false);\n+ end;\n+\n+ local procedure CreateDetailedCustLedgEntry(CustEntryNo: Integer; PostingDate: Date; AmountLCY: Decimal; DocumentType: Enum \"Gen. Journal Document Type\"; LedgerEntryAmount: Boolean)\n+ var\n+ DetailedCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n+ begin\n+ DetailedCustLedgEntry.\"Entry No.\" := DetailedCustLedgEntry.GetLastEntryNo() + 1;\n+ DetailedCustLedgEntry.\"Cust. Ledger Entry No.\" := CustEntryNo;\n+ DetailedCustLedgEntry.\"Posting Date\" := PostingDate;\n+ DetailedCustLedgEntry.\"Amount (LCY)\" := AmountLCY;\n+ DetailedCustLedgEntry.\"Document Type\" := DocumentType;\n+ DetailedCustLedgEntry.\"Initial Document Type\" := DocumentType;\n+ DetailedCustLedgEntry.\"Initial Entry Due Date\" := PostingDate;\n+ DetailedCustLedgEntry.\"Ledger Entry Amount\" := LedgerEntryAmount;\n+ DetailedCustLedgEntry.Insert();\n+ end;\n+\n local procedure VerifySalesCueFlowFields()\n var\n SalesCue: Record \"Sales Cue\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al b/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al\nindex 737182d0ac93..f685f4977ef3 100644\n--- a/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al\n+++ b/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al\n@@ -27,8 +27,7 @@ page 1318 \"Account Receivables KPIs\"\n CustomerLedgerEntries: Page \"Customer Ledger Entries\";\n begin\n CustLedgerEntry.SetRange(Open, true);\n- CustLedgerEntry.SetFilter(\"Remaining Amount\", '>%1', 0);\n- CustLedgerEntry.SetFilter(\"Due Date\", '<=%1', WorkDate());\n+ CustLedgerEntry.SetFilter(\"Due Date\", '<=%1', Today());\n CustomerLedgerEntries.SetTableView(CustLedgerEntry);\n CustomerLedgerEntries.Run();\n end;\n@@ -43,7 +42,6 @@ page 1318 \"Account Receivables KPIs\"\n CustomerLedgerEntries: Page \"Customer Ledger Entries\";\n begin\n CustLedgerEntry.SetRange(Open, true);\n- CustLedgerEntry.SetFilter(\"Remaining Amount\", '>%1', 0);\n CustomerLedgerEntries.SetTableView(CustLedgerEntry);\n CustomerLedgerEntries.Run();\n end;\n@@ -93,12 +91,12 @@ page 1318 \"Account Receivables KPIs\"\n SalesInvoicesDueNextWeekStyleExpr: Text;\n AverageCollectionDays: Decimal;\n \n- trigger OnInit()\n+ trigger OnOpenPage()\n var\n CuesAndKPIs: Codeunit \"Cues And KPIs\";\n SalesInvoicesDueNextWeekStyle: Enum \"Cues And KPIs Style\";\n begin\n- Rec.SetRange(\"Overdue Date Filter\", 0D, WorkDate());\n+ Rec.SetRange(\"Overdue Date Filter\", 0D, Today());\n if not Rec.Get() then begin\n Clear(Rec);\n Rec.Insert();\n@@ -113,11 +111,7 @@ page 1318 \"Account Receivables KPIs\"\n CuesAndKPIs.SetCueStyle(Database::\"Activities Cue\", ActivitiesCue.FieldNo(\"Sales Invoices Due Next Week\"), ActivitiesCue.\"Sales Invoices Due Next Week\", SalesInvoicesDueNextWeekStyle);\n SalesInvoicesDueNextWeekStyleExpr := Format(SalesInvoicesDueNextWeekStyle);\n Rec.\"AR Accounts Balance\" := ActivitiesMgt.CalcARAccountsBalances();\n- Rec.Modify();\n- end;\n \n- trigger OnOpenPage()\n- begin\n AverageCollectionDays := ActivitiesMgt.CalcAverageCollectionDays();\n end;\n }\n\\ No newline at end of file\n"} -{"metadata": {"area": "finance", "image_count": 11}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-205825", "base_commit": "8a2cfe76e431fe32a28a3d7026b394fe107da284", "created_at": "2025-01-29", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134237, "functionName": ["ShipToCodeConnectionAltCustVATSetupOfBillToCustomer"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al b/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al\nindex 87257d5a7940..d1f8ce9750a8 100644\n--- a/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al\n@@ -768,6 +768,44 @@ codeunit 134237 \"Alt. Cust. VAT. Doc. Tests\"\n LibraryLowerPermissions.SetOutsideO365Scope();\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandler,MessageHandler,NoNotificationOtherThanShipToAddressSendNotificationHandler')]\n+ procedure ShipToCodeConnectionAltCustVATSetupOfBillToCustomer()\n+ var\n+ ShipToAddress: Record \"Ship-to Address\";\n+ AltCustVATReg: Record \"Alt. Cust. VAT Reg.\";\n+ SalesHeader: Record \"Sales Header\";\n+ Customer, BillToCustomer : Record Customer;\n+ begin\n+ // [SCENARIO 563939] VAT Registration data is copied to the sales header from the Alternative Customer VAT Registration setup\n+ // [SCENARIO 563939] when ship-to address connected to the Alternative Customer VAT Registration setup for the Bill-To Customer\n+\n+ Initialize();\n+ // [GIVEN] Sell-To Customer with country \"X\", \"VAT Registration No.\" = \"X1234567890\", \"Gen. Bus. Posting Group\" = \"CUSTBUS\", \"VAT Bus. Posting Group\" = \"CUSTVAT\"\n+ LibrarySales.CreateCustomerWithCountryCodeAndVATRegNo(Customer);\n+ // [GIVEN] Bill-To Customer with country \"Z\", \"VAT Registration No.\" = \"Z1234567890\", \"Gen. Bus. Posting Group\" = \"BILLCUSTBUS\", \"VAT Bus. Posting Group\" = \"BILLCUSTVAT\"\n+ LibrarySales.CreateCustomerWithCountryCodeAndVATRegNo(BillToCustomer);\n+ // [GIVEN] Ship-To Address with country \"Y\"\n+ LibrarySales.CreateShipToAddressWithRandomCountryCode(ShipToAddress, Customer.\"No.\");\n+ // [GIVEN] Bill-To Customer and Ship-To Code are assigned to the Sell-To Customer\n+ Customer.Validate(\"Bill-to Customer No.\", BillToCustomer.\"No.\");\n+ Customer.Validate(\"Ship-to Code\", ShipToAddress.Code);\n+ Customer.Modify(true);\n+ LibraryLowerPermissions.SetO365Setup();\n+ LibraryLowerPermissions.AddSalesDocsCreate();\n+ // [GIVEN] Alternative Customer VAT Reg. for Bill-To Customer with country \"Y\", \"VAT Registration No.\" = \"Y1234567890\", \"Gen. Bus. Posting Group\" = \"SHIPTOBUS\", \"VAT Bus. Posting Group\" = \"SHIPTOVAT\"\n+ LibraryAltCustVATReg.CreateAlternativeCustVATReg(AltCustVATReg, BillToCustomer.\"No.\", ShipToAddress.\"Country/Region Code\");\n+ // [WHEN] Create sales order for Sell-To Customer (Bill-To Customer and Ship-To Code are taken from the card)\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ // [THEN] Sales order has \"VAT Registration No.\" = \"Y1234567890\", \"Gen. Bus. Posting Group\" = \"SHIPTOBUS\", \"VAT Bus. Posting Group\" = \"SHIPTOVAT\", \"Country/Region Code\" = \"Y\"\n+ VerifyVATRegDataInSalesHeader(SalesHeader, AltCustVATReg.\"VAT Bus. Posting Group\", AltCustVATReg.\"Gen. Bus. Posting Group\", AltCustVATReg.\"VAT Registration No.\", AltCustVATReg.\"VAT Country/Region Code\");\n+ // [THEN] Sales order has \"Alt. VAT Registration No.\", \"Alt. Gen. Bus Posting Group\", \"Alt. VAT Bus Posting Group\" options\n+ LibraryAltCustVATReg.VerifySalesDocAltVATReg(SalesHeader, true);\n+ LibraryVariableStorage.AssertEmpty();\n+\n+ LibraryLowerPermissions.SetOutsideO365Scope();\n+ end;\n+\n local procedure Initialize()\n begin\n LibrarySetupStorage.Restore();\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al\nindex 9b4af6be278e..d41581d178d2 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al\n@@ -124,6 +124,7 @@ codeunit 205 \"Alt. Cust. VAT Reg. Doc. Impl.\" implements \"Alt. Cust. VAT Reg. Do\n procedure UpdateSetupOnBillToCustomerChangeInSalesHeader(var SalesHeader: Record \"Sales Header\"; xSalesHeader: Record \"Sales Header\"; BillToCustomer: Record Customer)\n var\n GLSetup: Record \"General Ledger Setup\";\n+ AltCustVATReg: Record \"Alt. Cust. VAT Reg.\";\n begin\n GLSetup.Get();\n if GLSetup.\"Bill-to/Sell-to VAT Calc.\" <> GLSetup.\"Bill-to/Sell-to VAT Calc.\"::\"Bill-to/Pay-to No.\" then\n@@ -135,6 +136,10 @@ codeunit 205 \"Alt. Cust. VAT Reg. Doc. Impl.\" implements \"Alt. Cust. VAT Reg. Do\n CopyFromCustomer(SalesHeader, xSalesHeader, BillToCustomer);\n exit;\n end;\n+ if AltCustVATRegFacade.GetAlternativeCustVATReg(AltCustVATReg, BillToCustomer.\"No.\", SalesHeader.\"Ship-to Country/Region Code\") then begin\n+ SalesHeader.Validate(\"VAT Country/Region Code\", AltCustVATReg.\"VAT Country/Region Code\");\n+ exit;\n+ end;\n if (SalesHeader.\"VAT Bus. Posting Group\" <> '') and (SalesHeader.\"VAT Bus. Posting Group\" <> BillToCustomer.\"VAT Bus. Posting Group\") then\n SalesHeader.Validate(\"VAT Bus. Posting Group\", BillToCustomer.\"VAT Bus. Posting Group\")\n else\n"} -{"metadata": {"area": "pricing", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-185696", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-06-06", "environment_setup_version": "24.2", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134123, "functionName": ["VariantCodeMustBeBlankWhenInsertNewRecord"]}], "PASS_TO_PASS": [{"codeunitID": 134123, "functionName": ["VerifyProductNoIsNotDeletedOnCreatingNewPriceLineFromItemWithVariant"]}], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al b/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al\nindex eebac8020258..77237aa5fd31 100644\n--- a/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al\n@@ -44,6 +44,7 @@ codeunit 134123 \"Price List Line UT\"\n AssignToNoErr: Label 'Invalid Assign-to No.';\n VATProdPostingGroupErr: Label 'VAT Product Posting Group are not equal.';\n AmountTypeNotAllowedForSourceTypeErr: Label '%1 is not allowed for %2.', Comment = '%1 - Price or Discount, %2 - Source Type';\n+ VariantCodeErr: Label 'Variant Code must be empty when new record is inserted.';\n \n [Test]\n [HandlerFunctions('ItemUOMModalHandler')]\n@@ -3337,12 +3338,9 @@ codeunit 134123 \"Price List Line UT\"\n SalesPriceList.Filter.SetFilter(Code, PriceListHeader.Code);\n CreateNewSalesPriceListLine(SalesPriceList, Item.\"No.\", ItemVariant.Code);\n \n- // [WHEN] Create new Price List line with same Item No.\n+ // [GIVEN] Create new Price List line with same Item No.\n CreateNewSalesPriceListLine(SalesPriceList, Item.\"No.\", '');\n \n- // [THEN] Verify Variant Code is automatically inserted in second line\n- SalesPriceList.Lines.\"Variant Code\".AssertEquals(ItemVariant.Code);\n-\n // [WHEN] Create New Price Line from Action \n CreateNewSalesPriceListLine(SalesPriceList, Item2.\"No.\", '');\n \n@@ -3716,6 +3714,53 @@ codeunit 134123 \"Price List Line UT\"\n PriceListHeader.\"Source Type\"));\n end;\n \n+ [Test]\n+ procedure VariantCodeMustBeBlankWhenInsertNewRecord()\n+ var\n+ Item: Record Item;\n+ ItemVariant: Record \"Item Variant\";\n+ PriceListHeader: Record \"Price List Header\";\n+ PriceListLine: Record \"Price List Line\";\n+ SalesPriceList: TestPage \"Sales Price List\";\n+ begin\n+ // [SCENARIO 537505] When creating a new price for variant items the variant code does not automatically display in the price list based on the previously created line.\n+ Initialize(true);\n+\n+ // [GIVEN] Create a Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create Item Variant.\n+ LibraryInventory.CreateItemVariant(ItemVariant, Item.\"No.\");\n+\n+ // [GIVEN] Create Sales Price Header with Price Type Sales and Source Type All Customers.\n+ LibraryPriceCalculation.CreatePriceHeader(\n+ PriceListHeader,\n+ PriceListHeader.\"Price Type\"::Sale,\n+ PriceListHeader.\"Source Type\"::\"All Customers\",\n+ '');\n+\n+ // [GIVEN] Create a Price Line.\n+ LibraryPriceCalculation.CreatePriceListLine(\n+ PriceListLine,\n+ PriceListHeader,\n+ \"Price Amount Type\"::Price,\n+ \"Price Asset Type\"::Item,\n+ Item.\"No.\");\n+\n+ // [GIVEN] Validate a Variant Code.\n+ PriceListLine.Validate(\"Variant Code\", ItemVariant.Code);\n+ PriceListLine.Modify();\n+\n+ // [GIVEN] Open Sales Price List Page and insert new Line.\n+ SalesPriceList.OpenEdit();\n+ SalesPriceList.GoToRecord(PriceListHeader);\n+ SalesPriceList.Lines.New();\n+ SalesPriceList.Lines.\"Product No.\".SetValue(Item.\"No.\");\n+\n+ // [THEN] The value of Variant Code in new line must be empty.\n+ Assert.AreEqual('', SalesPriceList.Lines.\"Variant Code\".Value(), VariantCodeErr);\n+ end;\n+\n local procedure Initialize()\n begin\n Initialize(false);\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al\nindex bb986d659922..878710ff4e3e 100644\n--- a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al\n+++ b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al\n@@ -303,6 +303,7 @@ page 7001 \"Price List Lines\"\n Rec.\"Currency Code\" := PriceListHeader.\"Currency Code\";\n end;\n Rec.\"Amount Type\" := ViewAmountType;\n+ Rec.SetNewRecord(true);\n Rec.Validate(\"Asset Type\", xRec.\"Asset Type\");\n UpdateSourceType();\n end;\ndiff --git a/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al b/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al\nindex 2ef8d1aedaac..f2e15e4b9634 100644\n--- a/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al\n+++ b/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al\n@@ -300,6 +300,7 @@ page 7011 \"Purchase Price List Lines\"\n Rec.\"Currency Code\" := PriceListHeader.\"Currency Code\";\n end;\n Rec.\"Amount Type\" := ViewAmountType;\n+ Rec.SetNewRecord(true);\n Rec.Validate(\"Asset Type\", xRec.\"Asset Type\");\n UpdateSourceType();\n end;\n"} -{"metadata": {"area": "inventory", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176426", "base_commit": "e66d3aeb3bbf39912d6108e40442d2cfbf77e983", "created_at": "2024-02-27", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137391, "functionName": ["RolledUpMaterialAndCapacityCostWithRoutingAndNoBOM"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al\nindex b8748ee00c6b..d226736c56e9 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al\n@@ -652,6 +652,45 @@ codeunit 137391 \"SCM - BOM Cost Shares Report\"\n BOMCostShares.Close();\n end;\n \n+ [Test]\n+ procedure RolledUpMaterialAndCapacityCostWithRoutingAndNoBOM()\n+ var\n+ FinalItem: Record Item;\n+ InterimItem: Record Item;\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ BOMBuffer: Record \"BOM Buffer\";\n+ BOMCostShares: TestPage \"BOM Cost Shares\";\n+ TotalLeafsRolledUpCapacityCost: Decimal;\n+ QtyPer: Decimal;\n+ begin\n+ // [FEATURE] [BOM Cost Share]\n+ // [SCENARIO 500356] Rolled-up Material Cost and Rolled-up Capacity Cost for a interim production item with no BOM.\n+ Initialize();\n+ QtyPer := LibraryRandom.RandIntInRange(5, 10);\n+\n+ LibraryAssembly.CreateItem(InterimItem, InterimItem.\"Costing Method\"::FIFO, InterimItem.\"Replenishment System\"::\"Prod. Order\", '', '');\n+ InterimItem.Validate(\"Unit Cost\", LibraryRandom.RandDecInRange(50, 100, 2));\n+ InterimItem.Modify(true);\n+ LibraryAssembly.CreateRouting(InterimItem, LibraryRandom.RandInt(2));\n+ UpdateRoutingCostValues(InterimItem.\"Routing No.\");\n+\n+ LibraryAssembly.CreateItem(FinalItem, FinalItem.\"Costing Method\"::FIFO, FinalItem.\"Replenishment System\"::\"Prod. Order\", '', '');\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, FinalItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, InterimItem.\"No.\", QtyPer);\n+ LibraryManufacturing.UpdateProductionBOMStatus(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+ FinalItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ FinalItem.Modify(true);\n+\n+ BOMCostShares.Trap();\n+ RunBOMCostSharesPage(FinalItem);\n+ TotalLeafsRolledUpCapacityCost += GetRolledUpCapacityCostValue(BOMCostShares, BOMBuffer.Type::\"Machine Center\");\n+ TotalLeafsRolledUpCapacityCost += GetRolledUpCapacityCostValue(BOMCostShares, BOMBuffer.Type::\"Work Center\");\n+ VerifyParentItemMaterialAndCapacityCost(BOMCostShares, InterimItem.\"No.\", InterimItem.\"Unit Cost\" * QtyPer, TotalLeafsRolledUpCapacityCost);\n+ BOMCostShares.Close();\n+ end;\n+\n local procedure CreateRoutingWithWorkCenter(WorkCenterNo: Code[20]; SetupTime: Decimal; RunTime: Decimal; LotSize: Decimal): Code[20]\n var\n RoutingHeader: Record \"Routing Header\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al b/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al\nindex ab93f2c20bf4..c74223865e6f 100644\n--- a/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al\n@@ -872,6 +872,20 @@ table 5870 \"BOM Buffer\"\n OnAfterGetItemCosts(Rec, Item);\n end;\n \n+ procedure GetItemUnitCost()\n+ var\n+ Item: Record Item;\n+ begin\n+ TestField(Type, Type::Item);\n+ Item.Get(\"No.\");\n+\n+ \"Unit Cost\" := Item.\"Unit Cost\";\n+ \"Single-Level Material Cost\" :=\n+ RoundUnitAmt(Item.\"Unit Cost\", UOMMgt.GetQtyPerUnitOfMeasure(Item, \"Unit of Measure Code\") * \"Qty. per Top Item\");\n+ \"Rolled-up Material Cost\" :=\n+ RoundUnitAmt(Item.\"Unit Cost\", UOMMgt.GetQtyPerUnitOfMeasure(Item, \"Unit of Measure Code\") * \"Qty. per Top Item\");\n+ end;\n+\n procedure GetResCosts()\n var\n Res: Record Resource;\ndiff --git a/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al\nindex d639a56247c2..647d066cfea8 100644\n--- a/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al\n@@ -714,9 +714,11 @@ codeunit 5870 \"Calculate BOM Tree\"\n end;\n BOMBuffer.RoundCosts(1 / LotSize);\n end else\n- if HasBomStructure(BOMBuffer.\"No.\") then begin\n+ if IsProductionOrAssemblyItem(BOMBuffer.\"No.\") then begin\n BOMBuffer.CalcOvhdCost();\n BOMBuffer.RoundCosts(1 / LotSize);\n+ if not HasBomStructure(BOMBuffer.\"No.\") then\n+ BOMBuffer.GetItemUnitCost();\n end else\n if BOMBuffer.Type = BOMBuffer.Type::Item then begin\n BOMBuffer.RoundCosts(1 / LotSize);\n@@ -998,6 +1000,16 @@ codeunit 5870 \"Calculate BOM Tree\"\n end;\n end;\n \n+ local procedure IsProductionOrAssemblyItem(ItemNo: Code[20]): Boolean\n+ var\n+ Item: Record Item;\n+ begin\n+ if not Item.Get(ItemNo) then\n+ exit(false);\n+\n+ exit(Item.IsMfgItem() or Item.IsAssemblyItem());\n+ end;\n+\n procedure SetItemFilter(var Item: Record Item)\n begin\n ItemFilter.CopyFilters(Item);\n"} -{"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-180484", "base_commit": "adb5a68cf897c6367b0a4e8dd4e53dbc18e2d199", "created_at": "2024-04-05", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Data Exchange"], "FAIL_TO_PASS": [{"codeunitID": 139154, "functionName": ["StatusRemainsCreatedIfHasLinkedDocWhenReopenIncomingDoc"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al b/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al\nindex 354a3c190d4e..b626696591a7 100644\n--- a/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al\n@@ -51,6 +51,9 @@ codeunit 139154 \"Incoming Doc. To Data Exch.UT\"\n NothingToReleaseErr: Label 'There is nothing to release for the incoming document';\n NoDocCreatedForChoiceErr: Label 'The given key was not present in the dictionary.';\n UnknownChoiceErr: Label 'Unknown choice %1.', Comment = '%1=Choice (number)';\n+ PEPPOLINVOICELbl: Label 'PEPPOLINVOICE';\n+ PEPPOLLbl: Label 'PEPPOL';\n+ StatusErr: Label '%1 must be %2 in %3';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1472,6 +1475,72 @@ codeunit 139154 \"Incoming Doc. To Data Exch.UT\"\n end;\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ [Scope('OnPrem')]\n+ procedure StatusRemainsCreatedIfHasLinkedDocWhenReopenIncomingDoc()\n+ var\n+ DataExchDef: Record \"Data Exch. Def\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesInvoiceHeader: Record \"Sales Invoice Header\";\n+ IncomingDocument: Record \"Incoming Document\";\n+ DataExchangeType: Record \"Data Exchange Type\";\n+ IncomingDocumentCard: TestPage \"Incoming Document\";\n+ XmlPath: Text;\n+ begin\n+ // [SCENARIO 487620] When Stan runs Reopen action on an Incoming Document hvaing Status as Created, then Status remains as Created if a document is linked to it.\n+ Initialize();\n+\n+ // [GIVEN] Create a Sales Invoice.\n+ SalesHeader.Get(\n+ SalesHeader.\"Document Type\"::Invoice,\n+ CreateSalesDocument(\n+ SalesHeader.\"Document Type\"::Invoice,\n+ false));\n+\n+ // [GIVEN] Post Sales Invoice.\n+ SalesInvoiceHeader.Get(LibrarySales.PostSalesDocument(SalesHeader, true, true));\n+\n+ // [GIVEN] Generate and save XmlPath of Sales Invoice.\n+ XmlPath := ExportPEPPOLInvoice(SalesInvoiceHeader);\n+\n+ // [GIVEN] Setup Company Information for Sales Invoice Import.\n+ SetupCompanyForInvoiceImport(SalesInvoiceHeader);\n+\n+ // [GIVEN] Find Data Exchange Def.\n+ DataExchDef.Get(PEPPOLINVOICELbl);\n+\n+ // [GIVEN] Create Data Exchange Type.\n+ CreateDataExchangeType(DataExchangeType, DataExchDef);\n+\n+ // [GIVEN] Create Incoming Document and Validate Data Exchange Type.\n+ LibraryIncomingDocuments.CreateNewIncomingDocument(IncomingDocument);\n+ IncomingDocument.\"Data Exchange Type\" := DataExchangeType.Code;\n+ IncomingDocument.Modify(true);\n+\n+ // [GIVEN] Import Incoming Document.\n+ ImportAttachToIncomingDoc(IncomingDocument, XmlPath);\n+\n+ // [GIVEN] Open Incoming Document Card page and run Create Document action.\n+ LibraryVariableStorage.Enqueue(DocCreatedMsg);\n+ IncomingDocumentCard.OpenView();\n+ IncomingDocumentCard.GotoRecord(IncomingDocument);\n+ IncomingDocumentCard.CreateDocument.Invoke();\n+\n+ // [WHEN] Run Reopen action.\n+ IncomingDocumentCard.Reopen.Invoke();\n+\n+ // [VERIFY] Status of Incoming Document remains as Created.\n+ Assert.AreEqual(\n+ Format(IncomingDocument.Status::Created),\n+ IncomingDocumentCard.StatusField.Value,\n+ StrSubstNo(\n+ StatusErr,\n+ IncomingDocumentCard.StatusField.Caption(),\n+ Format(IncomingDocument.Status::Created),\n+ IncomingDocument.TableCaption()));\n+ end;\n+\n local procedure CreateDataExchDefSalesInvoiceAndLinesWithNamespaces(var DataExchDef: Record \"Data Exch. Def\")\n var\n SalesHeaderDataExchLineDef: Record \"Data Exch. Line Def\";\n@@ -2788,6 +2857,19 @@ codeunit 139154 \"Incoming Doc. To Data Exch.UT\"\n IncomingDocumentsSetup.Insert();\n end;\n \n+ local procedure CreateDataExchangeType(var DataExchangeType: Record \"Data Exchange Type\"; DataExchDef: Record \"Data Exch. Def\")\n+ begin\n+ DataExchDef.SetLoadFields(Code);\n+\n+ DataExchangeType.SetLoadFields(Code, \"Data Exch. Def. Code\");\n+ DataExchangeType.SetRange(\"Data Exch. Def. Code\", DataExchDef.Code);\n+ if not DataExchangeType.FindFirst() then begin\n+ DataExchangeType.Code := PEPPOLLbl;\n+ DataExchangeType.\"Data Exch. Def. Code\" := DataExchDef.Code;\n+ DataExchangeType.Insert();\n+ end;\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Msg: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al b/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al\nindex 4e5ba08c9623..473de43b9844 100644\n--- a/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al\n@@ -44,11 +44,15 @@ codeunit 132 \"Release Incoming Document\"\n #pragma warning restore AA0470\n \n procedure Reopen(var IncomingDocument: Record \"Incoming Document\")\n+ var\n+ RelatedRecord: Variant;\n begin\n if IncomingDocument.Status = IncomingDocument.Status::New then\n exit;\n ClearReleaseFields(IncomingDocument);\n- IncomingDocument.Status := IncomingDocument.Status::New;\n+\n+ if not ((IncomingDocument.Status = IncomingDocument.Status::Created) and (IncomingDocument.GetRecord(RelatedRecord))) then\n+ IncomingDocument.Status := IncomingDocument.Status::New;\n \n IncomingDocument.Modify(true);\n end;\n"} -{"metadata": {"area": "finance", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-183399", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-05-09", "environment_setup_version": "24.2", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134918, "functionName": ["DocumentAmountInPurchJnlAcceptsMaxThreeDecimalPlacesValue"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al\nindex a7905ad0b622..1c700b31886a 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al\n@@ -1359,6 +1359,42 @@ codeunit 134918 \"ERM Sales/Purchase Application\"\n VerifyCustomerLedgerEntry(Customer.\"No.\");\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure DocumentAmountInPurchJnlAcceptsMaxThreeDecimalPlacesValue()\n+ var\n+ Vendor: Record Vendor;\n+ PurchaseJournal: TestPage \"Purchase Journal\";\n+ DocumentAmount: Decimal;\n+ begin\n+ // [SCENARIO 534464] Document Amount field in Purchase Journal accepts a value of maximum 3 decimal places.\n+ Initialize();\n+\n+ // [GIVEN] Create a Vendor.\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ // [GIVEN] Open Purchase Journal.\n+ PurchaseJournal.OpenView();\n+ PurchaseJournal.New();\n+ PurchaseJournal.\"Account Type\".SetValue(\"Gen. Journal Account Type\"::Vendor);\n+ PurchaseJournal.\"Account No.\".SetValue(Vendor.\"No.\");\n+\n+ // [GIVEN] Generate and save Document Amount in a Variable.\n+ DocumentAmount := LibraryRandom.RandDecInRange(1, 4, 3);\n+\n+ // [WHEN] Set value of 3 decimal places in Document Amount field in Purchase Journal.\n+ PurchaseJournal.DocumentAmount.SetValue(DocumentAmount);\n+\n+ // [THEN] Document Amount in Purchase Journal has a value of 3 decimal places.\n+ Assert.AreEqual(\n+ DocumentAmount,\n+ PurchaseJournal.DocumentAmount.AsDecimal(),\n+ StrSubstNo(\n+ DocumentAmountLogicErr,\n+ DocumentAmount,\n+ PurchaseJournal.DocumentAmount.AsDecimal()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\nindex 553ae9c0726d..bf8ed7e92221 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n@@ -255,6 +255,7 @@ page 254 \"Purchase Journal\"\n {\n ApplicationArea = Basic, Suite;\n AutoFormatExpression = Rec.\"Currency Code\";\n+ DecimalPlaces = 0 : 3;\n Caption = 'Document Amount';\n ToolTip = 'Specifies the total amount (including VAT) that the journal line consists of.';\n \n"} -{"metadata": {"area": "sales", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-174794", "base_commit": "756f85a4eec20b0b7b28b0c7fe0d63d8b08659a1", "created_at": "2024-02-12", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134911, "functionName": ["IssueFinChargeMemoCreatesGLEntryOfAltCustPostingGrpIfAllowMultiPostingGrps"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al\nindex 95a8024d1290..07fdee93db4b 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al\n@@ -28,6 +28,7 @@ codeunit 134911 \"ERM Create Finance Charge Memo\"\n PrintDocRef: Option \" \",Print,Email;\n EmailTxt: Label 'abc@microsoft.com', Locked = true;\n ProceedOnIssuingWithInvRoundingQst: Label 'The invoice rounding amount will be added to the finance charge memo when it is posted according to invoice rounding setup.\\Do you want to continue?';\n+ GLEntryMustNotBeEmpty: Label 'GL Entry must not be empty.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -465,6 +466,71 @@ codeunit 134911 \"ERM Create Finance Charge Memo\"\n \n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure IssueFinChargeMemoCreatesGLEntryOfAltCustPostingGrpIfAllowMultiPostingGrps()\n+ var\n+ Customer: Record Customer;\n+ CustomerPostingGroup: Record \"Customer Posting Group\";\n+ CustomerPostingGroup2: Record \"Customer Posting Group\";\n+ FinanceChargeMemoHeader: Record \"Finance Charge Memo Header\";\n+ FinanceChargeMemoLine: Record \"Finance Charge Memo Line\";\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ IssueFinChargeMemoHeader: Record \"Issued Fin. Charge Memo Header\";\n+ GLEntry: Record \"G/L Entry\";\n+ FinChargeTermsCode: Code[10];\n+ begin\n+ // [SCENARIO 498604] When stan Issue a Finance Charge Memo having Alternate Customer Posting Group of Customer having Allow Multiple Posting Groups as true then it creates GL Entry of Alternate Customer Posting Group's Receivables Account.\n+ Initialize();\n+\n+ // [GIVEN] Validate Allow Multiple Posting Groups in Sales & Receivables Setup.\n+ SalesReceivablesSetup.Get();\n+ SalesReceivablesSetup.Validate(\"Allow Multiple Posting Groups\", true);\n+ SalesReceivablesSetup.Modify(true);\n+\n+ // [GIVEN] Create Finance Charge Terms.\n+ FinChargeTermsCode := CreateFinanceChargeTerms(LibraryRandom.RandInt(0));\n+\n+ // [GIVEN] Create Customer Posting Group.\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup2);\n+\n+ // [GIVEN] Create Customer Posting group 2.\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup);\n+\n+ // [GIVEN] Create Alternate Customer Posting Group.\n+ LibrarySales.CreateAltCustomerPostingGroup(CustomerPostingGroup.Code, CustomerPostingGroup2.Code);\n+\n+ // [GIVEN] Create Customer and Validate Customer Posting Group,\n+ // Allow Multiple Posting Groups and Fin. Charge Terms Code.\n+ LibrarySales.CreateCustomer(Customer);\n+ Customer.Validate(\"Customer Posting Group\", CustomerPostingGroup.Code);\n+ Customer.Validate(\"Allow Multiple Posting Groups\", true);\n+ Customer.Validate(\"Fin. Charge Terms Code\", FinChargeTermsCode);\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Create Finance Charge Memo Header and Validate Customer Posting Group.\n+ LibraryERM.CreateFinanceChargeMemoHeader(FinanceChargeMemoHeader, Customer.\"No.\");\n+ FinanceChargeMemoHeader.Validate(\"Customer Posting Group\", CustomerPostingGroup2.Code);\n+ FinanceChargeMemoHeader.Modify(true);\n+\n+ // [GIVEN] Create Finance Charge Memo Line.\n+ CreateFinChargeMemoLineForInvRounding(FinanceChargeMemoLine, FinanceChargeMemoHeader, LibraryRandom.RandInt(0));\n+\n+ // [GIVEN] Issue Finance Charge Memo.\n+ LibraryERM.IssueFinanceChargeMemo(FinanceChargeMemoHeader);\n+\n+ // [GIVEN] Find Issued Fin. Charge Memo Header.\n+ IssueFinChargeMemoHeader.SetRange(\"Customer No.\", Customer.\"No.\");\n+ IssueFinChargeMemoHeader.FindFirst();\n+\n+ // [WHEN] Find GL Entry.\n+ GLEntry.SetRange(\"Document No.\", IssueFinChargeMemoHeader.\"No.\");\n+ GLEntry.SetRange(\"G/L Account No.\", CustomerPostingGroup2.\"Receivables Account\");\n+\n+ // [VERIFY] GL Entry has Receivables Account of Customer Posting Group 2 in GL Account No. \n+ Assert.IsFalse(GLEntry.IsEmpty(), GLEntryMustNotBeEmpty);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al b/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al\nindex b941d50ca23b..952f98211c5e 100644\n--- a/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al\n@@ -278,6 +278,7 @@ codeunit 395 \"FinChrgMemo-Issue\"\n TempGenJnlLine.\"Account Type\" := AccType;\n TempGenJnlLine.\"Account No.\" := AccNo;\n TempGenJnlLine.Validate(\"Account No.\");\n+ TempGenJnlLine.\"Posting Group\" := FinChrgMemoHeader.\"Customer Posting Group\";\n if TempGenJnlLine.\"Account Type\" = TempGenJnlLine.\"Account Type\"::\"G/L Account\" then begin\n TempGenJnlLine.\"Gen. Posting Type\" := TempGenJnlLine.\"Gen. Posting Type\"::Sale;\n TempGenJnlLine.\"Gen. Bus. Posting Group\" := FinChrgMemoHeader.\"Gen. Bus. Posting Group\";\n"} -{"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-203923", "base_commit": "8a2cfe76e431fe32a28a3d7026b394fe107da284", "created_at": "2025-01-06", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134288, "functionName": ["NonDeductibleVATShouldShowAsNonDeductibleOnDoingFullVAT"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al\nindex 32fd94753bc2..e741895af851 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al\n@@ -20,6 +20,7 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n IsInitialized: Boolean;\n ReverseEntriesQst: Label 'Do you want to reverse the entries';\n EntriesReversedLbl: Label 'The entries were successfully reversed';\n+ NonDeductiableVATAmountMustBeEqualErr: Label 'Non-Deductable VAT Amount must be %1 in VAT Entries', Comment = '%1 = Expected Non-Deductible VAT Amount';\n \n [Test]\n [Scope('OnPrem')]\n@@ -177,7 +178,7 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n GLEntry.SetRange(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n GLEntry.FindFirst();\n // [THEN] \"Non-Deductible VAT Amount\" is zero in all non-VAT G/L entries\n-\t\t// Bug 523795: Bal. Non-Deductible VAT amount is not correct \n+ // Bug 523795: Bal. Non-Deductible VAT amount is not correct \n GLEntry.TestField(\"Non-Deductible VAT Amount\", Round(GenJournalLine.\"Bal. VAT Amount\" * VATPostingSetup.\"Non-Deductible VAT %\" / 100));\n GLEntry.SetRange(\"VAT Bus. Posting Group\", '');\n GLEntry.SetRange(\"VAT Prod. Posting Group\", '');\n@@ -215,6 +216,44 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n GenJournalLine.TestField(\"Bal. Non-Ded. VAT %\", VATPostingSetup.\"Non-Deductible VAT %\");\n end;\n \n+ [Test]\n+ procedure NonDeductibleVATShouldShowAsNonDeductibleOnDoingFullVAT()\n+ var\n+ GLAccount: Record \"G/L Account\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ VATEntry: Record \"VAT Entry\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ NonDeductableVATAmount: Decimal;\n+ begin\n+ // [SCENARIO 537128] On posting Non-Deductible full VAT amount should be display in Non-Deductable VAT field of VAT Entry. \n+ Initialize();\n+\n+ // [GIVEN] Create Non-Deductible VAT Posting Setup with \"Non-Deductible VAT %\" = 100.\n+ LibraryNonDeductibleVAT.CreatVATPostingSetupAllowedForNonDeductibleVAT(VATPostingSetup, VATPostingSetup.\"VAT Calculation Type\"::\"Full VAT\", 100);\n+ VATPostingSetup.Validate(\"Purchase VAT Account\", LibraryERM.CreateGLAccountWithVATPostingSetup(VATPostingSetup, GLAccount.\"Gen. Posting Type\"::Purchase));\n+ VATPostingSetup.Validate(\"Non-Deductible VAT %\", 100);\n+ VATPostingSetup.Modify(true);\n+\n+ // [GIVEN] General Journal Line with Non-Deductible VAT Posting Setup and \"Account No\" = VATPostingSetup.\"Purchase VAT Account\".\n+ LibraryJournals.CreateGenJournalLineWithBatch(\n+ GenJournalLine, GenJournalLine.\"Document Type\"::\" \", GenJournalLine.\"Account Type\"::\"G/L Account\",\n+ VATPostingSetup.\"Purchase VAT Account\", LibraryRandom.RandDec(100, 2));\n+ GenJournalLine.Validate(\"Bal. Account No.\", LibraryERM.CreateGLAccountNo());\n+\n+ // [GIVEN] Validate VAT Bus. & Prod. Posting Group fields.\n+ GenJournalLine.Validate(\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ GenJournalLine.Validate(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n+ GenJournalLine.Modify(true);\n+ NonDeductableVATAmount := GenJournalLine.Amount;\n+\n+ // [WHEN] Post the General Journal.\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+\n+ // [THEN] Verify that \"Non-Deductible VAT Amount\" field must have the value in VAT Entry.\n+ FindVATEntryByVATPostingSetup(VATEntry, VATPostingSetup);\n+ Assert.AreEqual(NonDeductableVATAmount, VATEntry.\"Non-Deductible VAT Amount\", StrSubstNo(NonDeductiableVATAmountMustBeEqualErr, NonDeductableVATAmount));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -244,6 +283,13 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n VATEntry.Testfield(\"Non-Deductible VAT Amount\", NDAmount);\n end;\n \n+ local procedure FindVATEntryByVATPostingSetup(var VATENtry: Record \"VAT Entry\"; VATPostingSetup: Record \"VAT Posting Setup\")\n+ begin\n+ VATEntry.SetRange(\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ VATEntry.SetRange(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n+ VATEntry.FindLast();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex a4336dd72bcc..795e790c227f 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -95,7 +95,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n NonDeductibleVAT.OnBeforeGetNonDeductibleVATPct(NonDeductibleVATPct, VATPostingSetup, GeneralPostingType, IsHandled);\n if IsHandled then\n exit(NonDeductibleVATPct);\n- if not (VATPostingSetup.\"VAT Calculation Type\" in [VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\", VATPostingSetup.\"VAT Calculation Type\"::\"Reverse Charge VAT\"]) then\n+ if not (VATPostingSetup.\"VAT Calculation Type\" in [VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\", VATPostingSetup.\"VAT Calculation Type\"::\"Reverse Charge VAT\", VATPostingSetup.\"VAT Calculation Type\"::\"Full VAT\"]) then\n exit(0);\n if (VATPostingSetup.\"Allow Non-Deductible VAT\" = VATPostingSetup.\"Allow Non-Deductible VAT\"::\"Do not allow\") or (GeneralPostingType <> GeneralPostingType::Purchase) then\n exit(0);\n@@ -720,7 +720,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n NonDeductibleVAT.OnBeforeCalcNonDedAmountsInGenJnlLine(GenJournalLine, Currency, IsHandled);\n if IsHandled then\n exit;\n- if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\"]) then\n+ if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Full VAT\"]) then\n exit;\n if not VATPostingSetup.Get(GenJournalLine.\"VAT Bus. Posting Group\", GenJournalLine.\"VAT Prod. Posting Group\") then\n exit;\n@@ -1078,7 +1078,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n NonDeductibleVAT.OnBeforeGetNonDedVATPctForGenJnlLine(NonDeductibleVATPct, GenJournalLine, IsHandled);\n if IsHandled then\n exit(NonDeductibleVATPct);\n- if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\"]) then\n+ if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Full VAT\"]) then\n exit(0);\n if not VATPostingSetup.Get(GenJournalLine.\"VAT Bus. Posting Group\", GenJournalLine.\"VAT Prod. Posting Group\") then\n exit(0);\n"} -{"metadata": {"area": "finance", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-204450", "base_commit": "8a2cfe76e431fe32a28a3d7026b394fe107da284", "created_at": "2025-01-13", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134287, "functionName": ["PurchaseInvoiceInCurrencyIsPostedWhenChangeVATAmountOnStatisticIfNDVATPctIs100"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al\nindex 9780fc9969b7..4060fd099d20 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al\n@@ -16,8 +16,11 @@ codeunit 134287 \"Non-Deductible VAT Statistics\"\n LibraryPurchase: Codeunit \"Library - Purchase\";\n LibraryInventory: Codeunit \"Library - Inventory\";\n LibraryRandom: Codeunit \"Library - Random\";\n+ LibraryUtility: Codeunit \"Library - Utility\";\n+ LibraryERM: Codeunit \"Library - ERM\";\n Assert: Codeunit Assert;\n isInitialized: Boolean;\n+ GLEntryConsistentErr: Label 'G/L Entry is inconsistent';\n \n [Test]\n [HandlerFunctions('PurchaseStatisticsChangeVATAmountModalPageHandler')]\n@@ -640,6 +643,60 @@ codeunit 134287 \"Non-Deductible VAT Statistics\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('PurchaseStatisticsChangeVATAmountModalPageHandler')]\n+ procedure PurchaseInvoiceInCurrencyIsPostedWhenChangeVATAmountOnStatisticIfNDVATPctIs100()\n+ var\n+ Currency: Record Currency;\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchInvHeader: Record \"Purch. Inv. Header\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ PurchaseInvoicePage: TestPage \"Purchase Invoice\";\n+ GenPostingType: Enum \"General Posting Type\";\n+ GLAccountNo: Code[20];\n+ ChangeVATAmount: Decimal;\n+ begin\n+ // [SCENARIO 560355] Purchase Invoice with currency code gets posted when Non-Deductible VAT is 100 Percent\n+ // And Non-Deductible VAT and the VAT Amount was previously modified in the Statistics.\n+ Initialize();\n+\n+ // [GIVEN] \"Allow VAT Difference\" is enabled in Purchases Setup.\n+ LibraryPurchase.SetAllowVATDifference(true);\n+\n+ // [GIVEN] Create Currency with Exchange Rate.\n+ CreateCurrencyWithExchangeRate(Currency);\n+\n+ // [GIVEN] Set \"Max. VAT Difference Allowed\" in Currency.\n+ SetMaxVATDifferenceAllowInCurrency(LibraryRandom.RandIntInRange(1000, 1000), Currency);\n+\n+ // [GIVEN] Generate VAT Amount to Change.\n+ ChangeVATAmount := LibraryRandom.RandIntInRange(150, 150);\n+\n+ // [GIVEN] Create Normal VAT Posting Setup with \"VAT %\" = 20 and Non-Deductible VAT %\" = 100. \n+ LibraryNonDeductibleVAT.CreateVATPostingSetupWithNonDeductibleDetail(VATPostingSetup, 20, 100);\n+\n+ // [GIVEN] Create a G/L Account.\n+ GLAccountNo := LibraryERM.CreateGLAccountWithVATPostingSetup(VATPostingSetup, GenPostingType::Purchase);\n+\n+ // [GIVEN] Create a Purchase Invoice.\n+ CreatePurchaseInvoiceWithCurrencyCode(PurchaseHeader, VATPostingSetup.\"VAT Bus. Posting Group\", Currency.Code, GLAccountNo);\n+ LibraryVariableStorage.Enqueue(ChangeVATAmount);\n+ LibraryVariableStorage.Enqueue(ChangeVATAmount);\n+\n+ // [GIVEN] Open Purchase Invoice page.\n+ PurchaseInvoicePage.OpenEdit();\n+ PurchaseInvoicePage.Filter.SetFilter(\"No.\", PurchaseHeader.\"No.\");\n+\n+ // [GIVEN] Open statistics of the invoice.\n+ PurchaseInvoicePage.Statistics.Invoke();\n+\n+ // [WHEN] Purchase Invoice is Posted.\n+ PurchInvHeader.Get(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true));\n+\n+ // [THEN] Verify G/L Entry is Consistent.\n+ VerifyGLEntryByDocumentNo(PurchInvHeader.\"No.\", 0);\n+ end;\n+\n local procedure SetAllowVATDifference(MaxVATDifference: Decimal)\n var\n PurchasesSetup: Record \"Purchases & Payables Setup\";\n@@ -672,6 +729,61 @@ codeunit 134287 \"Non-Deductible VAT Statistics\"\n GLEntry.TestField(Amount, ExpectedAmount);\n end;\n \n+ local procedure CreateCurrencyWithExchangeRate(var Currency: Record Currency)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ Currency.Get(LibraryERM.CreateCurrencyWithGLAccountSetup());\n+\n+ LibraryERM.CreateExchRate(CurrencyExchangeRate, Currency.Code, WorkDate());\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n+ local procedure SetMaxVATDifferenceAllowInCurrency(MaxVATDifference: Decimal; Currency: Record Currency)\n+ begin\n+ Currency.Validate(\"Max. VAT Difference Allowed\", MaxVATDifference);\n+ Currency.Modify(true);\n+ end;\n+\n+ local procedure CreatePurchaseInvoiceWithCurrencyCode(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ VATBusPostingGroup: Code[20];\n+ CurrencyCode: Code[20];\n+ GLAccountNo: Code[20])\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ LibraryPurchase.CreatePurchHeader(\n+ PurchaseHeader,\n+ PurchaseHeader.\"Document Type\"::Invoice,\n+ LibraryPurchase.CreateVendorWithVATBusPostingGroup(VATBusPostingGroup));\n+ PurchaseHeader.Validate(\"Vendor Invoice No.\", LibraryUtility.GenerateGUID());\n+ PurchaseHeader.Validate(\"Currency Code\", CurrencyCode);\n+ PurchaseHeader.Modify(true);\n+\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::\"G/L Account\",\n+ GLAccountNo,\n+ LibraryRandom.RandInt(0));\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandIntInRange(1000, 1000));\n+ PurchaseLine.Modify(true);\n+ end;\n+\n+ local procedure VerifyGLEntryByDocumentNo(DocumentNo: Code[20]; ExpectedAmount: Decimal)\n+ var\n+ GLEntry: Record \"G/L Entry\";\n+ begin\n+ GLEntry.SetRange(\"Document No.\", DocumentNo);\n+ GLEntry.CalcSums(Amount);\n+ Assert.AreEqual(ExpectedAmount, GLEntry.Amount, GLEntryConsistentErr);\n+ end;\n+\n [ModalPageHandler]\n procedure PurchaseStatisticsChangeVATAmountModalPageHandler(var PurchaseStatisticsPage: TestPage \"Purchase Statistics\")\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex 795e790c227f..bab527724d87 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -648,7 +648,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n \n if PurchaseLine.\"Non-Deductible VAT %\" = 100 then begin\n PurchaseLine.\"Non-Deductible VAT Base\" := PurchaseLine.\"VAT Base Amount\";\n- PurchaseLine.\"Non-Deductible VAT Amount\" := PurchaseLine.\"Amount Including VAT\" - PurchaseLine.\"VAT Base Amount\" - PurchaseLine.\"VAT Difference\";\n+ PurchaseLine.\"Non-Deductible VAT Amount\" := PurchaseLine.\"Amount Including VAT\" - PurchaseLine.\"VAT Base Amount\";\n exit;\n end;\n PurchaseLine.\"Non-Deductible VAT Base\" :=\n"} -{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-175577", "base_commit": "aebdede0933c2e90c7d60098c88186f48bb3c278", "created_at": "2024-02-19", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136323, "functionName": ["OneSalesInvoiceIsCreatedForJobTasksWithMultipleCustomersBillingMethodAndSameCustomerAndCurrencyData"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\nindex cbe0b59640ef..75d9d5805088 100644\n--- a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n@@ -1236,6 +1236,67 @@ codeunit 136323 \"Jobs - Multiple Customers\"\n LibrarySales.PostSalesDocument(SalesHeaders[2], true, true);\n end;\n \n+ [Test]\n+ [HandlerFunctions('JobCreateSalesInvoiceHandler,MessageHandler')]\n+ procedure OneSalesInvoiceIsCreatedForJobTasksWithMultipleCustomersBillingMethodAndSameCustomerAndCurrencyData()\n+ var\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ JobTasks: array[2] of Record \"Job Task\";\n+ Customers: array[2] of Record Customer;\n+ SalesHeaders: array[4] of Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ JobCreateSalesInvoice: Report \"Job Create Sales Invoice\";\n+ Qty: Decimal;\n+ OneInvoicesAreCreatedMsg: Label '1 invoice is created.';\n+ begin\n+ // [SCENARIO 501468] One Sales Invoice is Created for Job Tasks with Multiple Customers Billing Method and Same Customer and Currency Data\n+ Initialize();\n+\n+ // [GIVEN] Set Multiple Customers on Project Setup\n+ SetMultiupleCustomersOnProjectSetup();\n+\n+ // [GIVEN] Create Customers\n+ LibrarySales.CreateCustomer(Customers[1]);\n+ LibrarySales.CreateCustomer(Customers[2]);\n+\n+ // [GIVEN] Create new Project\n+ LibraryJob.CreateJob(Job, Customers[1].\"No.\");\n+\n+ // [GIVEN] Create Project Task 1 with Customer 1 and Bill-to Customer 2\n+ LibraryJob.CreateJobTask(Job, JobTasks[1]);\n+ JobTasks[1].Validate(\"Bill-to Customer No.\", Customers[2].\"No.\");\n+ JobTasks[1].Modify(true);\n+\n+ // [GIVEN] Create Project Task 2 with Customer 1 and Bill-to Customer 2\n+ LibraryJob.CreateJobTask(Job, JobTasks[2]);\n+ JobTasks[2].Validate(\"Bill-to Customer No.\", Customers[2].\"No.\");\n+ JobTasks[2].Modify(true);\n+\n+ // [GIVEN] Create Job Planning Line with Qty to Transfer to Invoice\n+ Qty := LibraryRandom.RandInt(10);\n+ CreateJobPlanningLineWithQtyToTransferToInvoice(JobPlanningLine, JobTasks[1], Qty, Qty);\n+ CreateJobPlanningLineWithQtyToTransferToInvoice(JobPlanningLine, JobTasks[2], Qty, Qty);\n+\n+ // [GIVEN] Enqueue data\n+ LibraryVariableStorage.Enqueue(OneInvoicesAreCreatedMsg);\n+\n+ // [WHEN] Run batch job \"Create Job Sales Invoice\" for Job Tasks\n+ Commit(); // Commit required for batch report.\n+ JobTask.SetFilter(\"Job No.\", '%1', Job.\"No.\");\n+ JobCreateSalesInvoice.SetTableView(JobTask);\n+ JobCreateSalesInvoice.Run();\n+\n+ // [GIVEN] Find Sales Invoice\n+ FindSalesHeader(SalesHeaders[1], Customers[1].\"No.\", Customers[2].\"No.\", SalesHeaders[1].\"Document Type\"::Invoice);\n+ SalesLine.SetRange(\"Document Type\", SalesHeaders[1].\"Document Type\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeaders[1].\"No.\");\n+\n+ // [THEN] Verify results\n+ Assert.RecordCount(SalesLine, 2);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Jobs - Multiple Customers\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al\nindex 1e465e1669af..77ad8ede08e5 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al\n@@ -15,6 +15,7 @@ using Microsoft.Sales.Document;\n using Microsoft.Sales.History;\n using Microsoft.Sales.Setup;\n using System.Reflection;\n+using System.Text;\n \n codeunit 1002 \"Job Create-Invoice\"\n {\n@@ -29,6 +30,7 @@ codeunit 1002 \"Job Create-Invoice\"\n SalesHeader2: Record \"Sales Header\";\n SalesLine: Record \"Sales Line\";\n TempJobPlanningLine: Record \"Job Planning Line\" temporary;\n+ TempJobPlanningLine2: Record \"Job Planning Line\" temporary;\n TransferExtendedText: Codeunit \"Transfer Extended Text\";\n JobInvCurrency: Boolean;\n UpdateExchangeRates: Boolean;\n@@ -320,9 +322,11 @@ codeunit 1002 \"Job Create-Invoice\"\n if CreateNewInvoice(JobTask, InvoicePerTask, OldJobNo, OldJobTaskNo, LastJobTask) then begin\n Job.Get(TempJobPlanningLine.\"Job No.\");\n Cust.Get(ReturnBillToCustomerNoDependingOnTaskBillingMethod(Job, JobTask2));\n- NoOfInvoices := NoOfInvoices + 1;\n SalesHeader2.\"Document Type\" := SalesHeader2.\"Document Type\"::Invoice;\n- CreateSalesHeader(Job, PostingDate, DocumentDate, TempJobPlanningLine);\n+ if not SalesInvoiceExistForMultipleCustomerBillingMethod(Job) then begin\n+ CreateSalesHeader(Job, PostingDate, DocumentDate, TempJobPlanningLine);\n+ NoOfInvoices := NoOfInvoices + 1;\n+ end;\n OnCreateSalesInvoiceJobTaskOnBeforeTempJobPlanningLineFind(JobTask, SalesHeader, InvoicePerTask, TempJobPlanningLine);\n if TempJobPlanningLine.Find('-') then\n repeat\n@@ -378,6 +382,11 @@ codeunit 1002 \"Job Create-Invoice\"\n if TransferLine(JobPlanningLine) then begin\n TempJobPlanningLine := JobPlanningLine;\n TempJobPlanningLine.Insert();\n+\n+ if Job.\"Task Billing Method\" = Job.\"Task Billing Method\"::\"Multiple customers\" then begin\n+ TempJobPlanningLine2 := JobPlanningLine;\n+ TempJobPlanningLine2.Insert();\n+ end;\n end;\n until JobPlanningLine.Next() = 0;\n end;\n@@ -483,6 +492,44 @@ codeunit 1002 \"Job Create-Invoice\"\n SalesHeader.Modify(true);\n end;\n \n+ local procedure SalesInvoiceExistForMultipleCustomerBillingMethod(Job: Record Job): Boolean\n+ var\n+ JobTask: Record \"Job Task\";\n+ JobTask2: Record \"Job Task\";\n+ JobPlanningLineInvoice: Record \"Job Planning Line Invoice\";\n+ TempJobPlanningLine3: Record \"Job Planning Line\" temporary;\n+ SelectionFilterMgt: Codeunit SelectionFilterManagement;\n+ RecRef: RecordRef;\n+ JobTaskFilter: Text;\n+ begin\n+ if Job.\"Task Billing Method\" = Job.\"Task Billing Method\"::\"One customer\" then\n+ exit;\n+\n+ TempJobPlanningLine3.Copy(TempJobPlanningLine2, true);\n+ TempJobPlanningLine3.Reset();\n+ TempJobPlanningLine3.SetFilter(\"Job Contract Entry No.\", '<>%1', TempJobPlanningLine.\"Job Contract Entry No.\");\n+ RecRef.GetTable(TempJobPlanningLine3);\n+ JobTaskFilter := SelectionFilterMgt.GetSelectionFilter(RecRef, TempJobPlanningLine3.FieldNo(\"Job Task No.\"));\n+ if JobTaskFilter = '' then\n+ exit;\n+\n+ if JobTask.Get(TempJobPlanningLine.\"Job No.\", TempJobPlanningLine.\"Job Task No.\") then begin\n+ JobTask2.SetRange(\"Job No.\", Job.\"No.\");\n+ JobTask2.SetFilter(\"Job Task No.\", JobTaskFilter);\n+ JobTask2.SetRange(\"Sell-to Customer No.\", JobTask.\"Sell-to Customer No.\");\n+ JobTask2.SetRange(\"Bill-to Customer No.\", JobTask.\"Bill-to Customer No.\");\n+ JobTask2.SetRange(\"Invoice Currency Code\", JobTask.\"Invoice Currency Code\");\n+ if JobTask2.FindFirst() then begin\n+ JobPlanningLineInvoice.SetRange(\"Job No.\", Job.\"No.\");\n+ JobPlanningLineInvoice.SetRange(\"Job Task No.\", JobTask2.\"Job Task No.\");\n+ if JobPlanningLineInvoice.FindFirst() then begin\n+ SalesHeader.Get(SalesHeader.\"Document Type\"::Invoice, JobPlanningLineInvoice.\"Document No.\");\n+ exit(true);\n+ end;\n+ end;\n+ end;\n+ end;\n+\n local procedure GetCustomerNo(Job: Record Job; JobPlanningLine: Record \"Job Planning Line\"; SellToCustomerNo: Boolean): Code[20]\n var\n JobTask: Record \"Job Task\";\n"} -{"metadata": {"area": "manufacturing", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176150", "base_commit": "85238b294e452f1fc0e21a94a5d0e8feec6bcc46", "created_at": "2024-02-23", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137072, "functionName": ["PreviewPostingOfProductionJournalPostsCorrectConsumptionILE"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al\nindex 4369f0c8683d..6ca685e45568 100644\n--- a/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al\n@@ -67,6 +67,7 @@ codeunit 137072 \"SCM Production Orders II\"\n TimeShiftedOnParentLineMsg: Label 'The production starting date-time of the end item has been moved forward because a subassembly is taking longer than planned.';\n DateConflictInReservErr: Label 'The change leads to a date conflict with existing reservations.';\n QuantityErr: Label '%1 must be %2 in %3', Comment = '%1: Quantity, %2: Consumption Quantity Value, %3: Item Ledger Entry';\n+ ILENoOfRecordsMustNotBeZeroErr: Label 'Item Ledger Entry No. of Records must not be zero.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -4312,6 +4313,59 @@ codeunit 137072 \"SCM Production Orders II\"\n ItemLedgerEntry.TableCaption()));\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('ProductionJournalPageHandler,GLPostingPreviewPageHandler')]\n+ procedure PreviewPostingOfProductionJournalPostsCorrectConsumptionILE()\n+ var\n+ Item, Item2 : Record Item;\n+ ProductionOrder, ProductionOrder2 : Record \"Production Order\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ReleasedProdOrder: TestPage \"Released Production Order\";\n+ begin\n+ // [SCENARIO 501883] When Preview Post or Post Production Journal From a Released Production Order, it creates correct Item Ledger Entries even if there is a Consumption Journal Line of completely different Production Order No. in Consumption Journal.\n+ Initialize();\n+\n+ // [GIVEN] Create Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProductionOrder(\n+ ProductionOrder,\n+ ProductionOrder.Status::Released,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10),\n+ '',\n+ '');\n+\n+ // [GIVEN] Create Item 2.\n+ LibraryInventory.CreateItem(Item2);\n+\n+ // [GIVEN] Create and Refresh Production Order 2.\n+ CreateAndRefreshProductionOrder(\n+ ProductionOrder2,\n+ ProductionOrder2.Status::Released,\n+ Item2.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10),\n+ '',\n+ '');\n+\n+ // [GIVEN] Create Consumption Journal Line for Production Order 2.\n+ CreateConsumptionJournalLine(\n+ ItemJournalLine,\n+ ProductionOrder2.\"No.\",\n+ Item2.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ // [WHEN] Open Released Production Order page and run Production Journal action.\n+ ReleasedProdOrder.OpenEdit();\n+ ReleasedProdOrder.GoToRecord(ProductionOrder);\n+ ReleasedProdOrder.ProdOrderLines.ProductionJournal.Invoke();\n+\n+ // [VERIFY] Item Ledger Entry No. of Records in Posting Preview is not zero.\n+ Assert.AreNotEqual(0, LibraryVariableStorage.DequeueInteger(), ILENoOfRecordsMustNotBeZeroErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -6045,6 +6099,43 @@ codeunit 137072 \"SCM Production Orders II\"\n LibraryManufacturing.UpdateRoutingStatus(RoutingHeader, RoutingHeader.Status::Certified);\n end;\n \n+ local procedure CreateConsumptionJournalLine(\n+ var ItemJournalLine: Record \"Item Journal Line\";\n+ ProdOrderNo: Code[20];\n+ ItemNo: Code[20];\n+ Qty: Decimal)\n+ var\n+ ItemJnlTemplate: Record \"Item Journal Template\";\n+ ItemJnlBatch: Record \"Item Journal Batch\";\n+ begin\n+ InitItemJournalBatch(ItemJnlBatch, ItemJnlBatch.\"Template Type\"::Consumption);\n+ ItemJournalLine.Init();\n+ ItemJournalLine.\"Entry Type\" := ItemJournalLine.\"Entry Type\"::Consumption;\n+\n+ ItemJnlTemplate.Get(ItemJnlBatch.\"Journal Template Name\");\n+ LibraryInventory.CreateItemJnlLineWithNoItem(\n+ ItemJournalLine,\n+ ItemJnlBatch,\n+ ItemJnlTemplate.Name,\n+ ItemJnlBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::Consumption);\n+\n+ ItemJournalLine.Validate(\"Order Type\", ItemJournalLine.\"Order Type\"::Production);\n+ ItemJournalLine.Validate(\"Order No.\", ProdOrderNo);\n+ ItemJournalLine.Validate(\"Item No.\", ItemNo);\n+ ItemJournalLine.Validate(Quantity, Qty);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n+ local procedure InitItemJournalBatch(var ItemJnlBatch: Record \"Item Journal Batch\"; TemplateType: Enum \"Item Journal Template Type\")\n+ var\n+ ItemJnlTemplate: Record \"Item Journal Template\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJnlTemplate, TemplateType);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJnlBatch, TemplateType, ItemJnlTemplate.Name);\n+ LibraryInventory.ClearItemJournal(ItemJnlTemplate, ItemJnlBatch);\n+ end;\n+\n [ModalPageHandler]\n procedure ProductionJournalModalPageHandler(var ProductionJournal: TestPage \"Production Journal\")\n begin\n@@ -6143,6 +6234,21 @@ codeunit 137072 \"SCM Production Orders II\"\n ProductionJournal.Post.Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandler(var ProductionJournal: TestPage \"Production Journal\")\n+ begin\n+ ProductionJournal.PreviewPosting.Invoke();\n+ end;\n+\n+ [PageHandler]\n+ [Scope('OnPrem')]\n+ procedure GLPostingPreviewPageHandler(var ShowAllEntries: TestPage \"G/L Posting Preview\")\n+ begin\n+ ShowAllEntries.Filter.SetFilter(\"Table Name\", 'Item Ledger Entry');\n+ LibraryVariableStorage.Enqueue(ShowAllEntries.\"No. of Records\".AsInteger());\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al b/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al\nindex 55d3fbadd560..3b65f2ca204f 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al\n@@ -1015,7 +1015,7 @@ page 5510 \"Production Journal\"\n \n protected procedure MarkRelevantRec(var ItemJournalLine: Record \"Item Journal Line\")\n begin\n- ItemJournalLine := Rec;\n+ ItemJournalLine.CopyFilters(Rec);\n if ItemJournalLine.FindSet() then begin\n repeat\n case ItemJournalLine.\"Entry Type\" of\n"} -{"metadata": {"area": "inventory", "image_count": 1}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-175765", "base_commit": "367956511110141ab18a506a72cf2f7c3255bcbf", "created_at": "2024-02-20", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137038, "functionName": ["AdjustCostOfUndoneTransferShipment"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\nindex ade329a726ce..e0b3ba5f0bf7 100644\n--- a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n@@ -3595,6 +3595,66 @@\n PostedTranferReceipt.Close();\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerYes')]\n+ [Scope('OnPrem')]\n+ procedure AdjustCostOfUndoneTransferShipment()\n+ var\n+ Item: Record Item;\n+ InTransitLocation: Record Location;\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ ItemLedgerEntryNo: Integer;\n+ LocationFromCode, LocationTOCode : Code[10];\n+ OldCost, NewCost : Decimal;\n+ begin\n+ // [FEATURE] [Transfer] [Undo Shipment] [Costing] [Adjust Cost - Item Entries]\n+ // [SCENARIO 496575] Item ledger entry for undone transfer shipment is adjusted with the correct cost.\n+ Initialize();\n+ OldCost := LibraryRandom.RandDec(100, 2);\n+ NewCost := LibraryRandom.RandDecInDecimalRange(101, 200, 2);\n+\n+ // [GIVEN] Item \"I\".\n+ // [GIVEN] Locations \"From\" and \"To\".\n+ LibraryInventory.CreateItem(Item);\n+ CreateLocations(LocationFromCode, LocationToCode);\n+ LibraryWarehouse.CreateInTransitLocation(InTransitLocation);\n+\n+ // [GIVEN] Post inventory adjustment of \"I\" to location \"From\". Unit Cost = 10.\n+ CreateAndPostItemJnlWithCostLocationVariant(\n+ \"Item Ledger Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", 1, OldCost, LocationFromCode, '');\n+ ItemLedgerEntryNo := FindLastILENo(Item.\"No.\");\n+\n+ // [GIVEN] Create transfer order from \"From\" to \"To\".\n+ // [GIVEN] Ship the transfer order.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, LocationFromCode, LocationToCode, InTransitLocation.Code);\n+ LibraryInventory.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", 1);\n+ LibraryInventory.PostTransferHeader(TransferHeader, true, false);\n+\n+ // [GIVEN] Revaluate the item entry for the inventory adjustment, new cost = 12.\n+ CreateAndPostRevaluationJournal(Item.\"No.\", ItemLedgerEntryNo, 1, NewCost);\n+\n+ // [GIVEN] Adjust cost.\n+ LibraryCosting.AdjustCostItemEntries(Item.\"No.\", '');\n+\n+ // [WHEN] Undo the transfer shipment and run the cost adjustment.\n+ LibraryInventory.UndoTransferShipments(TransferHeader.\"No.\");\n+ LibraryCosting.AdjustCostItemEntries(Item.\"No.\", '');\n+\n+ // [THEN] Unit cost of \"I\" = 12.\n+ Item.Find();\n+ Item.TestField(\"Unit Cost\", NewCost);\n+\n+ // [THEN] Item ledger entry for the undone transfer shipment is adjusted. Unit Cost = 12.\n+ ItemLedgerEntry.Get(FindLastILENo(Item.\"No.\"));\n+ ItemLedgerEntry.TestField(\"Entry Type\", ItemLedgerEntry.\"Entry Type\"::Transfer);\n+ ItemLedgerEntry.TestField(\"Location Code\", LocationFromCode);\n+ ItemLedgerEntry.TestField(Positive, true);\n+ ItemLedgerEntry.CalcFields(\"Cost Amount (Actual)\");\n+ ItemLedgerEntry.TestField(\"Cost Amount (Actual)\", NewCost);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3708,6 +3768,26 @@\n UpdateLocation(LocationCode[5], true, HandlingTime2, HandlingTime2);\n end;\n \n+ local procedure CreateAndPostRevaluationJournal(ItemNo: Code[20]; AppliesToEntry: Integer; InventoryValueRevalued: Decimal; UnitCostRevalued: Decimal)\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Revaluation);\n+ LibraryInventory.CreateItemJournalBatch(ItemJournalBatch, ItemJournalTemplate.Name);\n+ ItemJournalLine.Validate(\"Journal Template Name\", ItemJournalBatch.\"Journal Template Name\");\n+ ItemJournalLine.Validate(\"Journal Batch Name\", ItemJournalBatch.Name);\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\" \", ItemNo, 0);\n+ ItemJournalLine.Validate(\"Value Entry Type\", ItemJournalLine.\"Value Entry Type\"::Revaluation);\n+ ItemJournalLine.Validate(\"Applies-to Entry\", AppliesToEntry);\n+ ItemJournalLine.Validate(\"Inventory Value (Revalued)\", InventoryValueRevalued);\n+ ItemJournalLine.Validate(\"Unit Cost (Revalued)\", UnitCostRevalued);\n+ ItemJournalLine.Modify(true);\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+ end;\n+\n local procedure PostTransferShipmentPartiallyWithBlockedItem(DirectTransfer: Boolean)\n var\n Location: array[3] of Record Location;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\nindex 7eff49508788..7e739c297201 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n@@ -7182,6 +7182,19 @@ codeunit 22 \"Item Jnl.-Post Line\"\n Error(Text027);\n end;\n \n+ procedure MarkAppliedInboundItemEntriesForAdjustment(OutboundItemLedgerEntryNo: Integer)\n+ var\n+ InboundItemLedgerEntry: Record \"Item Ledger Entry\";\n+ ItemApplicationEntry: Record \"Item Application Entry\";\n+ begin\n+ if ItemApplicationEntry.GetInboundEntriesTheOutbndEntryAppliedTo(OutboundItemLedgerEntryNo) then\n+ repeat\n+ InboundItemLedgerEntry.SetLoadFields(\"Applied Entry to Adjust\");\n+ InboundItemLedgerEntry.Get(ItemApplicationEntry.\"Inbound Item Entry No.\");\n+ InboundItemLedgerEntry.SetAppliedEntryToAdjust(true);\n+ until ItemApplicationEntry.Next() = 0;\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnVerifyInvoicedQtyOnAfterGetSalesShipmentHeader(ItemLedgEntry2: Record \"Item Ledger Entry\"; var IsHandled: Boolean)\n begin\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al\nindex b47fc326b34d..14b98317476f 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al\n@@ -332,13 +332,18 @@ codeunit 9030 \"Undo Transfer Shipment\"\n until TempItemEntryRelation.Next() = 0;\n end;\n \n- local procedure GetShptEntries(TransShptLine: Record \"Transfer Shipment Line\"; var ItemLedgEntry: Record \"Item Ledger Entry\"): Boolean\n+ local procedure GetShptEntries(TransShptLine: Record \"Transfer Shipment Line\"; var ItemLedgEntry: Record \"Item Ledger Entry\") Found: Boolean\n begin\n ItemLedgEntry.SetCurrentKey(\"Document No.\", \"Document Type\", \"Document Line No.\");\n ItemLedgEntry.SetRange(\"Document Type\", ItemLedgEntry.\"Document Type\"::\"Transfer Shipment\");\n ItemLedgEntry.SetRange(\"Document No.\", TransShptLine.\"Document No.\");\n ItemLedgEntry.SetRange(\"Document Line No.\", TransShptLine.\"Line No.\");\n- exit(ItemLedgEntry.FindSet());\n+ Found := ItemLedgEntry.FindSet();\n+\n+ if Found then\n+ repeat\n+ ItemJnlPostLine.MarkAppliedInboundItemEntriesForAdjustment(ItemLedgEntry.\"Entry No.\");\n+ until ItemLedgEntry.Next() = 0;\n end;\n \n local procedure MakeInventoryAdjustment()\n"} -{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-179733", "base_commit": "e5aa32e995fb795e9ee046e61b8f7ca8574be337", "created_at": "2024-03-26", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136323, "functionName": ["CopyTotalsProjectTasksTypeIntoProjectsWithMultipleCustomerBillingOption"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\nindex bf797dc801c0..b0c36dc1d842 100644\n--- a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n@@ -1520,6 +1520,53 @@ codeunit 136323 \"Jobs - Multiple Customers\"\n SalesLine.TestField(\"Document No.\", SalesHeader.\"No.\");\n end;\n \n+ [Test]\n+ procedure CopyTotalsProjectTasksTypeIntoProjectsWithMultipleCustomerBillingOption()\n+ var\n+ JobTasks: array[3] of Record \"Job Task\";\n+ Jobs: array[2] of Record Job;\n+ Customers: array[2] of Record Customer;\n+ CopyJob: Codeunit \"Copy Job\";\n+ begin\n+ // [SCENARIO 522645] Copy Totals Project Tasks Type into Projects with Multiple Customer Billing Option\n+ Initialize();\n+\n+ // [GIVEN] Set One Customer Billing option on Project Setup\n+ SetOneCustomerBillingMethodOnProjectSetup();\n+\n+ // [GIVEN] Create Customer\n+ LibrarySales.CreateCustomer(Customers[1]);\n+\n+ // [GIVEN] Create new Project\n+ LibraryJob.CreateJob(Jobs[1], Customers[1].\"No.\");\n+\n+ // [GIVEN] Create new Project Task of Type Begin Total\n+ LibraryJob.CreateJobTask(Jobs[1], JobTasks[1]);\n+ JobTasks[1].\"Job Task Type\" := JobTasks[1].\"Job Task Type\"::\"Begin-Total\";\n+ JobTasks[1].Modify(true);\n+\n+ // [GIVEN] Create new Project Task\n+ LibraryJob.CreateJobTask(Jobs[1], JobTasks[2]);\n+\n+ // [GIVEN] Set Multiple Customers on Project Setup\n+ SetMultiupleCustomersOnProjectSetup();\n+\n+ // [GIVEN] Create new Project\n+ LibraryJob.CreateJob(Jobs[2], Customers[1].\"No.\");\n+\n+ // [WHEN] Copy Project Tasks\n+ CopyJob.CopyJobTasks(Jobs[1], Jobs[2]);\n+\n+ // [THEN] Verify results\n+ JobTasks[3].Get(Jobs[2].\"No.\", JobTasks[1].\"Job Task No.\");\n+ JobTasks[3].TestField(\"Sell-to Customer No.\", '');\n+ JobTasks[3].TestField(\"Bill-to Customer No.\", '');\n+\n+ JobTasks[3].Get(Jobs[2].\"No.\", JobTasks[2].\"Job Task No.\");\n+ JobTasks[3].TestField(\"Sell-to Customer No.\", Jobs[2].\"Sell-to Customer No.\");\n+ JobTasks[3].TestField(\"Bill-to Customer No.\", Jobs[2].\"Bill-to Customer No.\");\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Jobs - Multiple Customers\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al b/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al\nindex ca6d73fa1a86..31cb529bc5b3 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al\n@@ -1223,9 +1223,13 @@ table 1001 \"Job Task\"\n begin\n if not Job.Get(\"Job No.\") then\n exit;\n+\n if Job.\"Task Billing Method\" = Job.\"Task Billing Method\"::\"One customer\" then\n exit;\n \n+ if \"Job Task Type\" <> \"Job Task Type\"::Posting then\n+ exit;\n+\n SetHideValidationDialog(true);\n if Job.\"Sell-to Customer No.\" <> '' then\n Validate(\"Sell-to Customer No.\", Job.\"Sell-to Customer No.\");\n"} -{"metadata": {"area": "purchases", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176194", "base_commit": "fd0cc7aae1b3276f00096391f042fdbe73a7b5fd", "created_at": "2024-02-25", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134329, "functionName": ["GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToReceiveIsBlankInPurchPayablesSetup"]}, {"codeunitID": 134387, "functionName": ["GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToShipIsBlankInSalesReceiSetup"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al\nindex 75cffb82321a..4b0d9d056234 100644\n--- a/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al\n@@ -48,6 +48,8 @@ codeunit 134329 \"ERM Purchase Return Order\"\n ContactShouldBeEditableErr: Label 'Contact should be editable when vendorr is selected.';\n FunctionMustNotBeCalledErr: Label 'Function %1 must not be called.', Comment = '%1 - function name';\n BatchPostingErrrorNotificationMsg: Label 'An error or warning occured during operation Batch processing of Purchase Header records.';\n+ ReturnQtyToShipMustBeZeroErr: Label ' Return Qty. to Ship must be zero.';\n+ QtyToAssignErr: Label '%1 must be %2 in %3', Comment = '%1 = Qty. to Assign, %2 = Quantity, %3 = Purchase Return Order Subform';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1376,6 +1378,83 @@ codeunit 134329 \"ERM Purchase Return Order\"\n PurchaseLine.TableCaption));\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('SuggestItemChargeAssignmentPageHandler,PostedPurchDocumentLinesPageHandler')]\n+ procedure GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToReceiveIsBlankInPurchPayablesSetup()\n+ var\n+ Item: Record Item;\n+ ItemCharge: Record \"Item Charge\";\n+ PurchasePayablesSetup: Record \"Purchases & Payables Setup\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseHeader2: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ Quantity: Decimal;\n+ PurchaseReturnOrder: TestPage \"Purchase Return Order\";\n+ PurchaseReturnOrderSubform: TestPage \"Purchase Return Order Subform\";\n+ begin\n+ // [SCENARIO 500596] Get Posted Document Lines to Reverse action on Purchase Return Order copies Purchase Invoice Lines of Type Item Charge Even when Default Qty to Receive on Purchase & Payables Setup is set to Blank.\n+ Initialize();\n+\n+ // [GIVEN] Validate Default Qty. to Receive in Purchase & Payables Setup.\n+ PurchasePayablesSetup.Get();\n+ PurchasePayablesSetup.Validate(\"Default Qty. to Receive\", PurchasePayablesSetup.\"Default Qty. to Receive\"::Blank);\n+ PurchasePayablesSetup.Modify(true);\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create an Item Charge.\n+ LibraryInventory.CreateItemCharge(ItemCharge);\n+\n+ // [GIVEN] Generate and Save Quantity in a Variable.\n+ Quantity := LibraryRandom.RandIntInRange(25, 25);\n+\n+ // [GIVEN] Create a Purchase Order with Item Charge.\n+ CreatePurchaseOrderWithItemCharge(PurchaseHeader, ItemCharge.\"No.\", Item.\"No.\", Quantity);\n+\n+ // [GIVEN] Set Purchase Order Lines Qty. to Receive.\n+ SetPurchaseLinesQtyToReceive(PurchaseHeader, Quantity);\n+\n+ // [GIVEN] Update Qty. to Assign on Item Charge Assignment.\n+ UpdateQtyToAssignOnItemChargeAssignment(PurchaseHeader);\n+\n+ // [GIVEN] Post Purchase Order.\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true);\n+\n+ // [GIVEN] Create a Purchase Return Order.\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader2, PurchaseHeader2.\"Document Type\"::\"Return Order\", PurchaseHeader.\"Buy-from Vendor No.\");\n+\n+ // [GIVEN] Open Purchase Return Order page and run Get Posted Document Lines to Reverse action.\n+ PurchaseReturnOrder.OpenEdit();\n+ PurchaseReturnOrder.GoToRecord(PurchaseHeader2);\n+ LibraryVariableStorage.Enqueue(ItemCharge.\"No.\");\n+ PurchaseReturnOrder.GetPostedDocumentLinesToReverse.Invoke();\n+\n+ // [WHEN] Find Purchase Line of Purchase Return Order.\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseLine.\"Document Type\"::\"Return Order\");\n+ PurchaseLine.SetRange(\"Document No.\", PurchaseHeader2.\"No.\");\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::\"Charge (Item)\");\n+ PurchaseLine.FindFirst();\n+\n+ // [VERIFY] Return Qty. to Receive in Purchase Line is 0.\n+ Assert.AreEqual(0, PurchaseLine.\"Return Qty. to Ship\", ReturnQtyToShipMustBeZeroErr);\n+\n+ // [WHEN] Open Purchase Return Order Subform page.\n+ PurchaseReturnOrderSubform.OpenEdit();\n+ PurchaseReturnOrderSubform.GoToRecord(PurchaseLine);\n+\n+ // [VERIFY] Quantity and Qty. to Assign in Purchase Line are same.\n+ Assert.AreEqual(\n+ Quantity,\n+ PurchaseReturnOrderSubform.\"Qty. to Assign\".AsDecimal(),\n+ StrSubstNo(\n+ QtyToAssignErr,\n+ PurchaseReturnOrderSubform.\"Qty. to Assign\".Caption(),\n+ Quantity,\n+ PurchaseReturnOrderSubform.Caption()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -2062,6 +2141,64 @@ codeunit 134329 \"ERM Purchase Return Order\"\n if Confirm(StrSubstNo(ExpectedMessage)) then;\n end;\n \n+ local procedure CreatePurchaseOrderWithItemCharge(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ ItemChargeNo: Code[20];\n+ ItemNo: Code[20];\n+ Quantity: Decimal)\n+ var\n+ PurchaseLineItemCharge: Record \"Purchase Line\";\n+ PurchaseLineItem: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ begin\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLineItem,\n+ PurchaseHeader,\n+ PurchaseLineItem.Type::Item,\n+ ItemNo,\n+ Quantity);\n+\n+ PurchaseLineItem.Validate(\"Direct Unit Cost\", LibraryRandom.RandDec(100, 2));\n+ PurchaseLineItem.Modify(true);\n+\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLineItemCharge,\n+ PurchaseHeader,\n+ PurchaseLineItemCharge.Type::\"Charge (Item)\",\n+ ItemChargeNo,\n+ Quantity);\n+\n+ PurchaseLineItemCharge.Validate(\"Direct Unit Cost\", LibraryRandom.RandDec(100, 2));\n+ PurchaseLineItemCharge.Modify(true);\n+ end;\n+\n+ local procedure SetPurchaseLinesQtyToReceive(var PurchaseHeader: Record \"Purchase Header\"; Quantity: Decimal)\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseHeader.\"Document Type\");\n+ PurchaseLine.SetRange(\"Document No.\", PurchaseHeader.\"No.\");\n+ PurchaseLine.FindSet();\n+ repeat\n+ PurchaseLine.Validate(\"Qty. to Receive\", Quantity);\n+ PurchaseLine.Modify(true);\n+ until PurchaseLine.Next() = 0;\n+ end;\n+\n+ local procedure UpdateQtyToAssignOnItemChargeAssignment(PurchaseHeader: Record \"Purchase Header\")\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseHeader.\"Document Type\");\n+ PurchaseLine.SetRange(\"Document No.\", PurchaseHeader.\"No.\");\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::\"Charge (Item)\");\n+ PurchaseLine.FindFirst();\n+ PurchaseLine.ShowItemChargeAssgnt();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n@@ -2162,6 +2299,21 @@ codeunit 134329 \"ERM Purchase Return Order\"\n GetReturnShipmentLines.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedPurchDocumentLinesPageHandler(var PostedPurchaseDocumentLines: TestPage \"Posted Purchase Document Lines\")\n+ begin\n+ PostedPurchaseDocumentLines.PostedInvoices.Filter.SetFilter(\"No.\", LibraryVariableStorage.DequeueText());\n+ PostedPurchaseDocumentLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure SuggestItemChargeAssignmentPageHandler(var ItemChargeAssignmentPurch: TestPage \"Item Charge Assignment (Purch)\")\n+ begin\n+ ItemChargeAssignmentPurch.SuggestItemChargeAssignment.Invoke();\n+ end;\n+\n [SendNotificationHandler]\n [Scope('OnPrem')]\n procedure SendNotificationHandler(var Notification: Notification): Boolean\ndiff --git a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al\nindex 3f3d49bb821b..bc9ebbd1cdfb 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al\n@@ -80,6 +80,8 @@ codeunit 134387 \"ERM Sales Documents III\"\n PackageTrackingNoErr: Label 'Package Tracking No does not exist.';\n CannotAllowInvDiscountErr: Label 'The value of the Allow Invoice Disc. field is not valid when the VAT Calculation Type field is set to \"Full VAT\".';\n PostingPreviewNoTok: Label '***', Locked = true;\n+ ReturnQtyToReceiveMustBeZeroErr: Label ' Return Qty. to Receive must be zero.';\n+ QtyToAssignErr: Label '%1 must be %2 in %3', Comment = '%1 = Qty. to Assign, %2 = Quantity, %3 = Sales Return Order Subform';\n \n [Test]\n [Scope('OnPrem')]\n@@ -5943,6 +5945,83 @@ codeunit 134387 \"ERM Sales Documents III\"\n Assert.AreNotEqual(Customer.\"Country/Region Code\", SalesHeader.\"Rcvd.-from Count./Region Code\", 'Received-from Country Code is set just as it is on customer');\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('SuggestItemChargeAssignmentPageHandler,PostedSalesDocumentLinesPageHandler')]\n+ procedure GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToShipIsBlankInSalesReceiSetup()\n+ var\n+ Item: Record Item;\n+ ItemCharge: Record \"Item Charge\";\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesHeader2: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Quantity: Decimal;\n+ SalesReturnOrder: TestPage \"Sales Return Order\";\n+ SalesReturnOrderSubform: TestPage \"Sales Return Order Subform\";\n+ begin\n+ // [SCENARIO 500596] Get Posted Document Lines to Reverse action on Sales Return Order copies Sales Invoice Lines of Type Item Charge Even when Default Qty to Ship on Sales & Receivables Setup is set to Blank.\n+ Initialize();\n+\n+ // [GIVEN] Validate Default Quantity to Ship in Sales & Receivables Setup.\n+ SalesReceivablesSetup.Get();\n+ SalesReceivablesSetup.Validate(\"Default Quantity to Ship\", SalesReceivablesSetup.\"Default Quantity to Ship\"::Blank);\n+ SalesReceivablesSetup.Modify(true);\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create an Item Charge.\n+ LibraryInventory.CreateItemCharge(ItemCharge);\n+\n+ // [GIVEN] Generate and Save Quantity in a Variable.\n+ Quantity := LibraryRandom.RandIntInRange(25, 25);\n+\n+ // [GIVEN] Create a Sales Order with Item Charge.\n+ CreateSalesOrderWithItemCharge(SalesHeader, ItemCharge.\"No.\", Item.\"No.\", Quantity);\n+\n+ // [GIVEN] Set Sales Order Lines Qty. to Ship.\n+ SetSalesLinesQtyToShip(SalesHeader, Quantity);\n+\n+ // [GIVEN] Update Qty. to Assign on Item Charge Assignment.\n+ UpdateQtyToAssignOnItemChargeAssignment(SalesHeader);\n+\n+ // [GIVEN] Post Sales Order.\n+ LibrarySales.PostSalesDocument(SalesHeader, true, true);\n+\n+ // [GIVEN] Create a Sales Return Order.\n+ LibrarySales.CreateSalesHeader(SalesHeader2, SalesHeader2.\"Document Type\"::\"Return Order\", SalesHeader.\"Sell-to Customer No.\");\n+\n+ // [GIVEN] Open Sales Return Order page and run Get Posted Document Lines to Reverse action.\n+ SalesReturnOrder.OpenEdit();\n+ SalesReturnOrder.GoToRecord(SalesHeader2);\n+ LibraryVariableStorage.Enqueue(ItemCharge.\"No.\");\n+ SalesReturnOrder.GetPostedDocumentLinesToReverse.Invoke();\n+\n+ // [WHEN] Find Sales Line of Sales Return Order.\n+ SalesLine.SetRange(\"Document Type\", SalesLine.\"Document Type\"::\"Return Order\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeader2.\"No.\");\n+ SalesLine.SetRange(Type, SalesLine.Type::\"Charge (Item)\");\n+ SalesLine.FindFirst();\n+\n+ // [VERIFY] Return Qty. to Receive in Sales Line is 0.\n+ Assert.AreEqual(0, SalesLine.\"Return Qty. to Receive\", ReturnQtyToReceiveMustBeZeroErr);\n+\n+ // [WHEN] Open Sales Return Order Subform page.\n+ SalesReturnOrderSubform.OpenEdit();\n+ SalesReturnOrderSubform.GoToRecord(SalesLine);\n+\n+ // [VERIFY] Quantity and Qty. to Assign in Sales Line are same.\n+ Assert.AreEqual(\n+ Quantity,\n+ SalesReturnOrderSubform.\"Qty. to Assign\".AsDecimal(),\n+ StrSubstNo(\n+ QtyToAssignErr,\n+ SalesReturnOrderSubform.\"Qty. to Assign\".Caption(),\n+ Quantity,\n+ SalesReturnOrderSubform.Caption()));\n+ end;\n+\n local procedure Initialize()\n var\n ReportSelections: Record \"Report Selections\";\n@@ -7148,6 +7227,64 @@ codeunit 134387 \"ERM Sales Documents III\"\n SalesReceivablesSetup.Modify();\n end;\n \n+ local procedure CreateSalesOrderWithItemCharge(\n+ var SalesHeader: Record \"Sales Header\";\n+ ItemChargeNo: Code[20];\n+ ItemNo: Code[20];\n+ Quantity: Decimal)\n+ var\n+ SalesLineItemCharge: Record \"Sales Line\";\n+ SalesLineItem: Record \"Sales Line\";\n+ Customer: Record Customer;\n+ begin\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ LibrarySales.CreateSalesLine(\n+ SalesLineItem,\n+ SalesHeader,\n+ SalesLineItem.Type::Item,\n+ ItemNo,\n+ Quantity);\n+\n+ SalesLineItem.Validate(\"Unit Price\", LibraryRandom.RandDec(100, 2));\n+ SalesLineItem.Modify(true);\n+\n+ LibrarySales.CreateSalesLine(\n+ SalesLineItemCharge,\n+ SalesHeader,\n+ SalesLineItemCharge.Type::\"Charge (Item)\",\n+ ItemChargeNo,\n+ Quantity);\n+\n+ SalesLineItemCharge.Validate(\"Unit Price\", LibraryRandom.RandDec(100, 2));\n+ SalesLineItemCharge.Modify(true);\n+ end;\n+\n+ local procedure SetSalesLinesQtyToShip(var SalesHeader: Record \"Sales Header\"; Quantity: Decimal)\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ SalesLine.SetRange(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeader.\"No.\");\n+ SalesLine.FindSet();\n+ repeat\n+ SalesLine.Validate(\"Qty. to Ship\", Quantity);\n+ SalesLine.Modify(true);\n+ until SalesLine.Next() = 0;\n+ end;\n+\n+ local procedure UpdateQtyToAssignOnItemChargeAssignment(SalesHeader: Record \"Sales Header\")\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ SalesLine.SetRange(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeader.\"No.\");\n+ SalesLine.SetRange(Type, SalesLine.Type::\"Charge (Item)\");\n+ SalesLine.FindFirst();\n+ SalesLine.ShowItemChargeAssgnt();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure CreateEmptyPostedInvConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n@@ -7426,5 +7563,20 @@ codeunit 134387 \"ERM Sales Documents III\"\n Assert.AreEqual(LibraryVariableStorage.DequeueText(), ChangeLogEntries.\"New Value\".Value(), ChangeLogEntries.\"New Value\".Caption());\n ChangeLogEntries.OK().Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedSalesDocumentLinesPageHandler(var PostedSalesDocumentLines: TestPage \"Posted Sales Document Lines\")\n+ begin\n+ PostedSalesDocumentLines.PostedInvoices.Filter.SetFilter(\"No.\", LibraryVariableStorage.DequeueText());\n+ PostedSalesDocumentLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure SuggestItemChargeAssignmentPageHandler(var ItemChargeAssignmentSales: TestPage \"Item Charge Assignment (Sales)\")\n+ begin\n+ ItemChargeAssignmentSales.SuggestItemChargeAssignment.Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al b/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al\nindex 09f417117839..64796fbd73b1 100644\n--- a/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al\n+++ b/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al\n@@ -4,6 +4,7 @@ using Microsoft.Finance.Currency;\n using Microsoft.Inventory.Item;\n \n using Microsoft.Purchases.History;\n+using Microsoft.Purchases.Setup;\n \n table 5805 \"Item Charge Assignment (Purch)\"\n {\n@@ -53,10 +54,14 @@ table 5805 \"Item Charge Assignment (Purch)\"\n DecimalPlaces = 0 : 5;\n \n trigger OnValidate()\n+ var\n+ PurchasePayablesSetup: Record \"Purchases & Payables Setup\";\n begin\n+ PurchasePayablesSetup.Get();\n PurchLine.Get(\"Document Type\", \"Document No.\", \"Document Line No.\");\n if Rec.\"Qty. to Assign\" <> xRec.\"Qty. to Assign\" then\n- PurchLine.TestField(\"Qty. to Invoice\");\n+ if PurchasePayablesSetup.\"Default Qty. to Receive\" <> PurchasePayablesSetup.\"Default Qty. to Receive\"::Blank then\n+ PurchLine.TestField(\"Qty. to Invoice\");\n \n TestField(\"Applies-to Doc. Line No.\");\n if (\"Qty. to Assign\" <> 0) and (\"Applies-to Doc. Type\" = \"Document Type\") then\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al b/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al\nindex 7cd86681ca3b..403ca020426c 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al\n@@ -7,6 +7,7 @@ namespace Microsoft.Sales.Document;\n using Microsoft.Finance.Currency;\n using Microsoft.Inventory.Item;\n using Microsoft.Sales.History;\n+using Microsoft.Sales.Setup;\n \n table 5809 \"Item Charge Assignment (Sales)\"\n {\n@@ -56,10 +57,15 @@ table 5809 \"Item Charge Assignment (Sales)\"\n DecimalPlaces = 0 : 5;\n \n trigger OnValidate()\n+ var\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n begin\n+ SalesReceivablesSetup.Get();\n SalesLine.Get(\"Document Type\", \"Document No.\", \"Document Line No.\");\n if Rec.\"Qty. to Assign\" <> xRec.\"Qty. to Assign\" then\n- SalesLine.TestField(\"Qty. to Invoice\");\n+ if SalesReceivablesSetup.\"Default Quantity to Ship\" <> SalesReceivablesSetup.\"Default Quantity to Ship\"::Blank then\n+ SalesLine.TestField(\"Qty. to Invoice\");\n+\n TestField(\"Applies-to Doc. Line No.\");\n if (\"Qty. to Assign\" <> 0) and (\"Applies-to Doc. Type\" = \"Document Type\") then\n if SalesLineInvoiced() then\n"} -{"metadata": {"area": "inventory", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-177493", "base_commit": "362fb524a9eb8dfd0de588e1dc5537e7df74f725", "created_at": "2024-03-06", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137023, "functionName": ["ItemWithReserveNeverNotInReservationWorksheet"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al\nindex 6c7fecaffcd2..fa163b5a789b 100644\n--- a/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al\n@@ -13,6 +13,7 @@ codeunit 137023 \"SCM Reservation Worksheet\"\n LibraryInventory: Codeunit \"Library - Inventory\";\n LibrarySales: Codeunit \"Library - Sales\";\n LibraryWarehouse: Codeunit \"Library - Warehouse\";\n+ LibraryAssembly: Codeunit \"Library - Assembly\";\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n Assert: Codeunit Assert;\n@@ -943,6 +944,60 @@ codeunit 137023 \"SCM Reservation Worksheet\"\n VerifyQtyToReserveOnReservWkshLine(ReservationWkshLine, SalesOrderList.Get(3), GetOutstandingQtyOnSalesLine(SalesOrderList.Get(3)));\n end;\n \n+ [Test]\n+ [HandlerFunctions('GetDemandToReserveRequestPageHandler')]\n+ procedure ItemWithReserveNeverNotInReservationWorksheet()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ AssemblyHeader: Record \"Assembly Header\";\n+ AssemblyLine: Record \"Assembly Line\";\n+ ReservationWkshBatch: Record \"Reservation Wksh. Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ReservationWkshLine: Record \"Reservation Wksh. Line\";\n+ ItemList: List of [Code[20]];\n+ Qty: Decimal;\n+ begin\n+ // [Reservation Worksheet]\n+ // [SCENARIO 502388] Item with \"Reserve\" = \"Never\" should not be included in the reservation worksheet.\n+ Initialize();\n+\n+ // [GIVEN] Item \"X\" with \"Reserve\" = \"Never\".\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Reserve\", Item.\"Reserve\"::Never);\n+ Item.Modify(true);\n+ ItemList.Add(Item.\"No.\");\n+\n+ // [GIVEN] New location\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Item \"X\" available in the inventory.\n+ Qty := Random(100);\n+ LibraryInventory.CreateItemJournalLineInItemTemplate(ItemJournalLine, Item.\"No.\", Location.Code, '', Qty);\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+\n+ // [GIVEN] Sales order for the item \"X\" with \"Reserve\" = \"Never\".\n+ LibrarySales.CreateSalesDocumentWithItem(SalesHeader, SalesLine, SalesHeader.\"Document Type\"::Order, '', Item.\"No.\", Qty / 2, Location.Code, WorkDate());\n+ SalesLine.TestField(Reserve, SalesLine.Reserve::Never);\n+\n+ // [GIVEN] Assembly order with line - item \"X\" with \"Reserve\" = \"Never\".\n+ LibraryAssembly.CreateAssemblyHeader(AssemblyHeader, WorkDate(), LibraryInventory.CreateItemNo(), Location.Code, Qty / 2, '');\n+ LibraryAssembly.CreateAssemblyLine(AssemblyHeader, AssemblyLine, \"BOM Component Type\"::Item, Item.\"No.\", '', 1, 1, '');\n+ AssemblyLine.TestField(Reserve, AssemblyLine.Reserve::Never);\n+\n+ // [WHEN] Run CalculateDemand for item \"X\" to fill ReservationWorksheetLine.\n+ LibraryVariableStorage.Enqueue(Item.\"No.\");\n+ ReservationWkshBatch.FindFirst();\n+ GetDemand(ReservationWkshBatch.Name, ItemList);\n+\n+ // [THEN] Verify that reservation worksheet line for the item with \"Reserve\" = \"Never\" should not be created.\n+ ReservationWkshLine.SetRange(\"Journal Batch Name\", ReservationWkshBatch.Name);\n+ ReservationWkshLine.SetRange(\"Item No.\", Item.\"No.\");\n+ Assert.IsTrue(ReservationWkshLine.IsEmpty, 'Reservation Worksheet line for the item with \"Reserve\" = \"Never\" should not be created.');\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"SCM Reservation Worksheet\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al b/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al\nindex bb47904dc9a1..2eaf8a1433bf 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al\n@@ -40,6 +40,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Shipment Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', SalesOrderLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n@@ -140,6 +141,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Needed by Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', ServiceOrderLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n@@ -190,6 +192,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Planning Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', JobPlanningLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n@@ -241,6 +244,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Due Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', AssemblyLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n"} -{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-177750", "base_commit": "e47ecd850386e5039c5c4b737d8cd6cdc753ee66", "created_at": "2024-03-08", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136322, "functionName": ["PostInventoryPickForAssemblyItemRelatedToJobPlanningLineWithBin"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al b/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al\nindex c18ad56092d7..2f27a020e6f5 100644\n--- a/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al\n@@ -692,6 +692,66 @@ codeunit 136322 \"Jobs - Assemble-to Order\"\n AssemblyHeader.TestField(\"Bin Code\", Bin[2].Code);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler,ConfirmHandlerTrue')]\n+ procedure PostInventoryPickForAssemblyItemRelatedToJobPlanningLineWithBin()\n+ var\n+ ParentItem, CompItem1, CompItem2 : Record Item;\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ Location: Record Location;\n+ Bin: Record Bin;\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ PostedATOLink: Record \"Posted Assemble-to-Order Link\";\n+ InventoryPickPage: TestPage \"Inventory Pick\";\n+ begin\n+ // [SCENARIO 504561] Verify post inventory pick for assembly item related to job planning line with bin\n+ Initialize();\n+\n+ // [GIVEN] Create an assembly item with 2 components.\n+ CreateAssemblyItemWithBOM(ParentItem, CompItem1, CompItem2);\n+\n+ // [GIVEN] Create Location with required pick\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create Bin in Location\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, LibraryUtility.GenerateGUID(), '', '');\n+\n+ // [GIVEN] Create Warehouse Employee with default location\n+ CreateDefaultWarehouseEmployee(Location);\n+\n+ // [GIVEN] Add components to inventory\n+ CreateAndPostInvtAdjustmentWithUnitCost(CompItem1.\"No.\", Location.Code, Bin.Code, LibraryRandom.RandInt(100), LibraryRandom.RandDec(10, 2));\n+ CreateAndPostInvtAdjustmentWithUnitCost(CompItem2.\"No.\", Location.Code, Bin.Code, LibraryRandom.RandInt(100), LibraryRandom.RandDec(10, 2));\n+\n+ // [GIVEN] Create Job and Job Task\n+ CreateJobAndJobTask(Job, JobTask);\n+\n+ // [GIVEN] Create Job Planning Line\n+ CreateJobPlanningLineWithData(JobPlanningLine, JobTask, \"Job Planning Line Line Type\"::Budget, JobPlanningLine.Type::Item,\n+ ParentItem.\"No.\", Location.Code, Bin.Code, LibraryRandom.RandInt(10));\n+\n+ // [GIVEN] Create Inventory Pick for the Job\n+ LibraryWarehouse.CreateInvtPutPickMovement(\"Warehouse Request Source Document\"::\"Job Usage\", Job.\"No.\", false, true, false);\n+\n+ // [GIVEN] Find Warehouse Activity Header \n+ WarehouseActivityHeader.SetRange(\"Source Document\", WarehouseActivityHeader.\"Source Document\"::\"Job Usage\");\n+ WarehouseActivityHeader.SetRange(\"Source No.\", Job.\"No.\");\n+ WarehouseActivityHeader.SetRange(\"Location Code\", Location.Code);\n+ WarehouseActivityHeader.FindFirst();\n+\n+ // [WHEN] Inventory Pick is posted\n+ InventoryPickPage.OpenEdit();\n+ InventoryPickPage.GoToRecord(WarehouseActivityHeader);\n+ InventoryPickPage.AutofillQtyToHandle.Invoke();\n+ InventoryPickPage.\"P&ost\".Invoke();\n+\n+ // [THEN] Verify results\n+ SetFiltersToPostedATOLink(JobTask, JobPlanningLine, PostedATOLink);\n+ Assert.RecordIsNotEmpty(PostedATOLink);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Jobs - Assemble-to Order\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al\nindex a1e3fedb7c27..c31bfe73d2a6 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al\n@@ -3187,6 +3187,21 @@ table 1003 \"Job Planning Line\"\n until Item.Next() = 0;\n end;\n \n+ procedure GetATOBin(Location: Record Location; var BinCode: Code[20]) Result: Boolean\n+ var\n+ AsmHeader: Record \"Assembly Header\";\n+ begin\n+ if not Location.\"Require Shipment\" then\n+ BinCode := Location.\"Asm.-to-Order Shpt. Bin Code\";\n+ if BinCode <> '' then\n+ exit(true);\n+\n+ if AsmHeader.GetFromAssemblyBin(Location, BinCode) then\n+ exit(true);\n+\n+ exit(false);\n+ end;\n+\n local procedure AddItem(var NewJobPlanningLine: Record \"Job Planning Line\"; ItemNo: Code[20])\n begin\n NewJobPlanningLine.\"Line No.\" += 10000;\ndiff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\nindex 320720d71b39..436a633588b0 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n@@ -2155,6 +2155,8 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n procedure CreateATOPickLine(NewWarehouseActivityLine: Record \"Warehouse Activity Line\"; BinCode: Code[20]; var RemQtyToPickBase: Decimal)\n var\n ATOSalesLine: Record \"Sales Line\";\n+ ATOJobPlanningLine: Record \"Job Planning Line\";\n+ ATOLink: Record \"Assemble-to-Order Link\";\n AssemblyHeader: Record \"Assembly Header\";\n AssemblySetup: Record \"Assembly Setup\";\n ReservationEntry: Record \"Reservation Entry\";\n@@ -2164,13 +2166,26 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n QtyToPickBase: Decimal;\n begin\n if (not IsInvtMovement) and\n- WMSManagement.GetATOSalesLine(NewWarehouseActivityLine.\"Source Type\",\n+ (WMSManagement.GetATOSalesLine(NewWarehouseActivityLine.\"Source Type\",\n NewWarehouseActivityLine.\"Source Subtype\",\n NewWarehouseActivityLine.\"Source No.\",\n NewWarehouseActivityLine.\"Source Line No.\",\n- ATOSalesLine)\n+ ATOSalesLine) or\n+ WMSManagement.GetATOJobPlanningLine(\n+ NewWarehouseActivityLine.\"Source Type\",\n+ NewWarehouseActivityLine.\"Source No.\",\n+ NewWarehouseActivityLine.\"Source Line No.\",\n+ NewWarehouseActivityLine.\"Source Subline No.\",\n+ ATOJobPlanningLine))\n then begin\n- ATOSalesLine.AsmToOrderExists(AssemblyHeader);\n+ if ATOLink.AsmExistsForSalesLine(ATOSalesLine) then\n+ ATOSalesLine.AsmToOrderExists(AssemblyHeader)\n+ else\n+ if ATOLink.AsmExistsForJobPlanningLine(ATOJobPlanningLine) then begin\n+ ATOJobPlanningLine.AsmToOrderExists(AssemblyHeader);\n+ AssemblyHeader.PerformManualRelease();\n+ end;\n+\n if NewWarehouseActivityLine.TrackingExists() then begin\n AssemblyHeader.SetReservationFilters(ReservationEntry);\n ReservationEntry.SetTrackingFilterFromWhseActivityLine(NewWarehouseActivityLine);\n@@ -2178,14 +2193,26 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n if ItemTrackingManagement.SumUpItemTracking(ReservationEntry, TempTrackingSpecification1, true, true) then\n QtyToAsmBase := Abs(TempTrackingSpecification1.\"Qty. to Handle (Base)\");\n end else\n- QtyToAsmBase := ATOSalesLine.QtyToAsmBaseOnATO();\n+ if ATOLink.Type = ATOLink.Type::Sale then\n+ QtyToAsmBase := ATOSalesLine.QtyToAsmBaseOnATO()\n+ else\n+ if ATOLink.Type = ATOLink.Type::Job then\n+ QtyToAsmBase := ATOJobPlanningLine.QtyToAsmBaseOnATO();\n WhseItemTrackingSetup.CopyTrackingFromWhseActivityLine(NewWarehouseActivityLine);\n- QtyToPickBase := QtyToAsmBase - WMSManagement.CalcQtyBaseOnATOInvtPick(ATOSalesLine, WhseItemTrackingSetup);\n+ if ATOLink.Type = ATOLink.Type::Sale then\n+ QtyToPickBase := QtyToAsmBase - WMSManagement.CalcQtyBaseOnATOInvtPick(ATOSalesLine, WhseItemTrackingSetup)\n+ else\n+ if ATOLink.Type = ATOLink.Type::Job then\n+ QtyToPickBase := QtyToAsmBase - WMSManagement.CalcQtyBaseOnATOInvtPick(ATOJobPlanningLine, WhseItemTrackingSetup);\n OnCreateATOPickLineOnAfterCalcQtyToPickBase(RemQtyToPickBase, QtyToPickBase, ATOSalesLine);\n if QtyToPickBase > 0 then begin\n MakeWarehouseActivityHeader();\n if CurrLocation.\"Bin Mandatory\" and (BinCode = '') then\n- ATOSalesLine.GetATOBin(CurrLocation, BinCode);\n+ if ATOLink.Type = ATOLink.Type::Sale then\n+ ATOSalesLine.GetATOBin(CurrLocation, BinCode)\n+ else\n+ if ATOLink.Type = ATOLink.Type::Job then\n+ ATOJobPlanningLine.GetATOBin(CurrLocation, BinCode);\n NewWarehouseActivityLine.\"Assemble to Order\" := true;\n MakeWarehouseActivityLine(NewWarehouseActivityLine, BinCode, QtyToPickBase, RemQtyToPickBase);\n \ndiff --git a/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al\nindex dda50b4d3256..1efcbbfc2855 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al\n@@ -1738,6 +1738,15 @@ codeunit 7302 \"WMS Management\"\n WarehouseActivityLine.SetTrackingFilterIfNotEmpty();\n end;\n \n+ local procedure SetFiltersOnATOInvtPick(JobPlanningLine: Record \"Job Planning Line\"; var WarehouseActivityLine: Record \"Warehouse Activity Line\")\n+ begin\n+ WarehouseActivityLine.SetRange(WarehouseActivityLine.\"Activity Type\", WarehouseActivityLine.\"Activity Type\"::\"Invt. Pick\");\n+ WarehouseActivityLine.SetSourceFilter(\n+ Database::\"Job\", 0, JobPlanningLine.\"Document No.\", JobPlanningLine.\"Job Contract Entry No.\", JobPlanningLine.\"Line No.\", false);\n+ WarehouseActivityLine.SetRange(WarehouseActivityLine.\"Assemble to Order\", true);\n+ WarehouseActivityLine.SetTrackingFilterIfNotEmpty();\n+ end;\n+\n procedure ATOInvtPickExists(SalesLine: Record \"Sales Line\"): Boolean\n var\n WarehouseActivityLine: Record \"Warehouse Activity Line\";\n@@ -1758,6 +1767,18 @@ codeunit 7302 \"WMS Management\"\n until WarehouseActivityLine.Next() = 0;\n end;\n \n+ procedure CalcQtyBaseOnATOInvtPick(JobPlanningLine: Record \"Job Planning Line\"; WhseItemTrackingSetup: Record \"Item Tracking Setup\") QtyBase: Decimal\n+ var\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ begin\n+ WarehouseActivityLine.CopyTrackingFromItemTrackingSetup(WhseItemTrackingSetup);\n+ SetFiltersOnATOInvtPick(JobPlanningLine, WarehouseActivityLine);\n+ if WarehouseActivityLine.FindSet() then\n+ repeat\n+ QtyBase += WarehouseActivityLine.\"Qty. Outstanding (Base)\";\n+ until WarehouseActivityLine.Next() = 0;\n+ end;\n+\n procedure CheckOutboundBlockedBin(LocationCode: Code[10]; BinCode: Code[20]; ItemNo: Code[20]; VariantCode: Code[10]; UnitOfMeasureCode: Code[10])\n begin\n CheckBlockedBin(LocationCode, BinCode, ItemNo, VariantCode, UnitOfMeasureCode, false);\n"} -{"metadata": {"area": "inventory", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-178045", "base_commit": "22d8978231eb8792d03f150d61431d485d3c92a9", "created_at": "2024-03-11", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137404, "functionName": ["ConsumptionIsPostedForMultipleILEsOfSameLotNo"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\nindex 9467380d9f9b..e1036e0420d9 100644\n--- a/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\n@@ -47,6 +47,7 @@ codeunit 137404 \"SCM Manufacturing\"\n Capacity2: Decimal;\n GLB_ItemTrackingQty: Integer;\n GLB_SerialNo: Code[50];\n+ ItemTrackingMode: Option \" \",\"Assign Lot No.\",\"Select Entries\",\"Update Quantity\",\"Manual Lot No.\"; \n DocumentNoDoesNotExistErr: Label 'Document No. %1 does not exist.', Comment = '%1: Document number (Code)';\n ExpectedQuantityErr: Label 'Quantity must be %1.', Comment = '%1: Quantity (decimal value)';\n ModifyRtngErr: Label 'You cannot modify Routing No. %1 because there is at least one %2 associated with it.';\n@@ -80,6 +81,7 @@ codeunit 137404 \"SCM Manufacturing\"\n DidntExpectWhsePickMsg: Label 'Did not expect a Warehouse Pick Request associated with the Production Order Component Line, since the line doesn''t have a postitive remaining quantity';\n ProdOrderNoHandlerErr: Label 'Prod. Order No. must be %1, actual value is %2.', Comment = '%1: Expected Prod. Order No. Value; %2: Actual Prod. Order No. Value.';\n ProdOrderStatusHandlerErr: Label 'Prod. Order Status must be %1, actual value is %2.', Comment = '%1: Expected Prod. Order Status Value; %2: Actual Prod. Order Status Value.';\n+ ItemLedgerEntryMustBeFoundErr: Label 'Item Ledger Entry must be found.';\n \n [Test]\n [HandlerFunctions('ConfirmHandlerTrue,OutputJournalItemtrackingPageHandler,MessageHandler')]\n@@ -4149,6 +4151,104 @@ codeunit 137404 \"SCM Manufacturing\"\n LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('ItemTrackingAssignLotNoPageHandler,ProductionJournalPageHandlerOnlyConsumption,ConfirmHandlerTrue,MessageHandler')]\n+ procedure ConsumptionIsPostedForMultipleILEsOfSameLotNo()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ Location: Record Location;\n+ UnitOfMeasure: Record \"Unit of Measure\";\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ItemTrackingCode: Record \"Item Tracking Code\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ LotNo: Code[10];\n+ Quantity: Decimal;\n+ ReleasedProdOrder: TestPage \"Released Production Order\";\n+ begin\n+ // [SCENARIO 501830] Consumption is posted against multiple Item Ledger Entries of same Lot No. when you post Production Journal from a Released Production Order.\n+ Initialize();\n+\n+ // [GIVEN] Create Item Tracking Code.\n+ LibraryItemTracking.CreateItemTrackingCode(ItemTrackingCode, false, true);\n+\n+ // [GIVEN] Create Unit of Measure.\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure);\n+\n+ // [GIVEN] Create Component Item with Unit of Measure.\n+ CreateItemWithUOM(CompItem, UnitOfMeasure, ItemUnitOfMeasure);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(Reserve, CompItem.Reserve::Always);\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::Manual);\n+ CompItem.Validate(\"Item Tracking Code\", ItemTrackingCode.Code);\n+ CompItem.Modify(true);\n+\n+ // [GIVEN] Create Location with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Create Production Item with Unit of Measure.\n+ CreateItemWithUOM(ProdItem, UnitOfMeasure, ItemUnitOfMeasure);\n+\n+ // [GIVEN] Generate and save Lot No. and Quantity in two different Variable.\n+ LotNo := Format(LibraryRandom.RandText(4));\n+ Quantity := LibraryRandom.RandIntInRange(35, 35);\n+\n+ // [GIVEN] Create and Post three Item Journal Lines with same Lot No.\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(5, 5), LotNo, '', Location.Code, true);\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(10, 10), LotNo, '', Location.Code, true);\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(20, 20), LotNo, '', Location.Code, true);\n+\n+ // [GIVEN] Create a production BOM for the Production Item.\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ItemUnitOfMeasure.Code);\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader,\n+ ProductionBOMLine,\n+ '',\n+ ProductionBOMLine.Type::Item,\n+ CompItem.\"No.\",\n+ LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Validate Unit of Measure in Production BOM.\n+ ProductionBOMLine.Validate(\"Unit of Measure Code\", ItemUnitOfMeasure.Code);\n+ ProductionBOMLine.Modify(true);\n+\n+ // [GIVEN] Change Status of Production BOM.\n+ LibraryManufacturing.UpdateProductionBOMStatus(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+\n+ // [GIVEN] Validate Replenishment System and Production BOM No. in Production Item.\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProdOrder(\n+ ProductionOrder,\n+ ProductionOrder.Status::Released,\n+ ProdItem.\"No.\",\n+ Quantity,\n+ Location.Code,\n+ '');\n+\n+ // [GIVEN] Open Released Production Order page and run Production Journal action.\n+ ReleasedProdOrder.OpenEdit();\n+ ReleasedProdOrder.GoToRecord(ProductionOrder);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ LibraryVariableStorage.Enqueue(ItemTrackingMode::\"Assign Lot No.\");\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ ReleasedProdOrder.ProdOrderLines.ProductionJournal.Invoke();\n+\n+ // [WHEN] Find Item Ledger Entry.\n+ ItemLedgerEntry.SetRange(\"Item No.\", CompItem.\"No.\");\n+ ItemLedgerEntry.SetRange(Quantity, -Quantity);\n+\n+ // [VERIFY] Item Ledger Entry is found.\n+ Assert.IsFalse(ItemLedgerEntry.IsEmpty(), ItemLedgerEntryMustBeFoundErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -6772,6 +6872,39 @@ codeunit 137404 \"SCM Manufacturing\"\n ReservationPage.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ItemTrackingAssignLotNoPageHandler(var ItemTrackingLines: TestPage \"Item Tracking Lines\")\n+ var\n+ DequeueVariable: Variant;\n+ begin\n+ LibraryVariableStorage.Dequeue(DequeueVariable);\n+ ItemTrackingMode := DequeueVariable;\n+ case ItemTrackingMode of\n+ ItemTrackingMode::\"Assign Lot No.\":\n+ begin\n+ ItemTrackingLines.\"Lot No.\".SetValue(LibraryVariableStorage.DequeueText());\n+ LibraryVariableStorage.Dequeue(DequeueVariable);\n+ ItemTrackingLines.\"Quantity (Base)\".SetValue(DequeueVariable);\n+ end;\n+ end;\n+ ItemTrackingLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandlerOnlyConsumption(var ProductionJournal: TestPage \"Production Journal\")\n+ var\n+ EntryType: Enum \"Item Ledger Entry Type\";\n+ begin\n+ Assert.IsTrue(ProductionJournal.FindFirstField(ProductionJournal.\"Entry Type\", EntryType::Output), '');\n+ ProductionJournal.\"Output Quantity\".SetValue(0);\n+ Assert.IsTrue(ProductionJournal.FindFirstField(ProductionJournal.\"Entry Type\", EntryType::Consumption), '');\n+ ProductionJournal.Quantity.SetValue(LibraryVariableStorage.DequeueDecimal());\n+ ProductionJournal.ItemTrackingLines.Invoke();\n+ ProductionJournal.Post.Invoke();\n+ end;\n+\n [PageHandler]\n procedure BOMStructurePageHandler(var BOMStructure: TestPage \"BOM Structure\")\n begin\n@@ -6840,5 +6973,74 @@ codeunit 137404 \"SCM Manufacturing\"\n DT2Time(ExpStartDateTime), DT2Time(ProdOrderLine.\"Starting Date-Time\"), StrSubstNo(WrongDateTimeErr, ProdOrderLine.FieldCaption(\"Starting Time\")));\n until ProdOrderLine.Next() = 0;\n end;\n+\n+ local procedure CreateItemWithUOM(\n+ var Item: Record Item;\n+ var UnitOfMeasure: Record \"Unit of Measure\";\n+ var ItemUnitOfMeasure: Record \"Item Unit of Measure\")\n+ begin\n+ LibraryInventory.CreateItem(Item);\n+\n+ LibraryInventory.CreateItemUnitOfMeasure(\n+ ItemUnitOfMeasure,\n+ Item.\"No.\",\n+ UnitOfMeasure.Code,\n+ LibraryRandom.RandInt(0));\n+\n+ Item.Validate(\"Base Unit of Measure\", UnitOfMeasure.Code);\n+ Item.Modify(true);\n+ end;\n+\n+ local procedure CreateAndPostItemJournalLineWithLotNo(\n+ ItemNo: Code[20];\n+ Quantity: Decimal;\n+ LotNo: Code[50];\n+ BinCode: Code[20];\n+ LocationCode: Code[10];\n+ Tracking: Boolean)\n+ var\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ CreateItemJournalLine(ItemJournalLine, ItemNo, Quantity, BinCode, LocationCode);\n+ if Tracking then begin\n+ LibraryVariableStorage.Enqueue(ItemTrackingMode::\"Assign Lot No.\");\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ ItemJournalLine.OpenItemTrackingLines(false);\n+ end;\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+ end;\n+\n+ local procedure CreateItemJournalLine(var ItemJournalLine: Record \"Item Journal Line\"; ItemNo: Code[20]; Quantity: Decimal; BinCode: Code[20]; LocationCode: Code[10])\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ begin\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+ LibraryInventory.CreateItemJournalTemplate(ItemJournalTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJournalBatch, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine,\n+ ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\",\n+ ItemNo,\n+ Quantity);\n+\n+ ItemJournalLine.Validate(\"Unit Cost\", LibraryRandom.RandDec(10, 2));\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n+ local procedure CreateAndRefreshProdOrder(var ProductionOrder: Record \"Production Order\"; Status: Enum \"Production Order Status\"; SourceNo: Code[20]; Quantity: Decimal; LocationCode: Code[10]; BinCode: Code[20])\n+ begin\n+ LibraryManufacturing.CreateProductionOrder(ProductionOrder, Status, ProductionOrder.\"Source Type\"::Item, SourceNo, Quantity);\n+ ProductionOrder.Validate(\"Location Code\", LocationCode);\n+ ProductionOrder.Validate(\"Bin Code\", BinCode);\n+ ProductionOrder.Modify(true);\n+\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\nindex 7e739c297201..ffe0b880ce8d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n@@ -1946,8 +1946,11 @@ codeunit 22 \"Item Jnl.-Post Line\"\n Abs(ItemLedgEntry.\"Remaining Quantity\" - ItemLedgEntry.\"Reserved Quantity\")\n then\n AppliedQty := ItemLedgEntry.\"Remaining Quantity\" - ItemLedgEntry.\"Reserved Quantity\"\n- else\n+ else begin\n AppliedQty := -(OldItemLedgEntry.\"Remaining Quantity\" - OldItemLedgEntry.\"Reserved Quantity\");\n+ if AppliedQty = 0 then\n+ AppliedQty := UpdateAppliedQtyIfConsumptionEntry(ItemLedgEntry, OldItemLedgEntry);\n+ end;\n \n OnApplyItemLedgEntryOnAfterCalcAppliedQty(OldItemLedgEntry, ItemLedgEntry, AppliedQty);\n \n@@ -5908,6 +5911,17 @@ codeunit 22 \"Item Jnl.-Post Line\"\n (ItemJournalLine.\"Applies-to Entry\" <> 0)));\n end;\n \n+ local procedure UpdateAppliedQtyIfConsumptionEntry(ItemLedgerEntry: Record \"Item Ledger Entry\"; OldItemLedgerEntry: Record \"Item Ledger Entry\"): Decimal\n+ begin\n+ if ItemLedgerEntry.\"Entry Type\" <> ItemLedgerEntry.\"Entry Type\"::Consumption then\n+ exit(0);\n+\n+ if (ItemLedgerEntry.\"Remaining Quantity\" + OldItemLedgerEntry.\"Remaining Quantity\") > 0 then\n+ exit(0);\n+\n+ exit(-Abs(OldItemLedgerEntry.\"Reserved Quantity\"));\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnBeforeAllowProdApplication(OldItemLedgerEntry: Record \"Item Ledger Entry\"; ItemLedgerEntry: Record \"Item Ledger Entry\"; var AllowApplication: Boolean)\n begin\n"} -{"metadata": {"area": "inventory", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176082", "base_commit": "cb30d50fe1ed2c716c6349370fdc31c6bd0ce956", "created_at": "2024-02-23", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137038, "functionName": ["GetReceiptLinesShowListOfPostedPurchRcptsHavingTransferFromCodeInLocationCodeOfPurchRcptLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\nindex e0b3ba5f0bf7..ffa98cfbb351 100644\n--- a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n@@ -48,6 +48,7 @@\n UndoneTransLineQtyErr: Label 'Expected Quantity to be 0 after Transfer Shipment was undone';\n DerivedTransLineErr: Label 'Expected no Derived Transfer Line i.e. line with \"Derived From Line No.\" equal to original transfer line.';\n IncorrectSNUndoneErr: Label 'The Serial No. of the item on the transfer shipment line that was undone was different from the SN on the corresponding transfer line.';\n+ ApplToItemEntryErr: Label '%1 must be %2 in %3.', Comment = '%1 is Appl-to Item Entry, %2 is Item Ledger Entry No. and %3 is Transfer Line';\n \n [Test]\n [HandlerFunctions('MessageHandler')]\n@@ -3655,6 +3656,99 @@\n ItemLedgerEntry.TestField(\"Cost Amount (Actual)\", NewCost);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('PostedPurchaseReceiptsModalPageHandler,PostedPurchRcptLinesModalPageHandler')]\n+ procedure GetReceiptLinesShowListOfPostedPurchRcptsHavingTransferFromCodeInLocationCodeOfPurchRcptLines()\n+ var\n+ Item: Record Item;\n+ Vendor: Record Vendor;\n+ Location: Record Location;\n+ Location2: Record Location;\n+ Location3: Record Location;\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseHeader2: Record \"Purchase Header\";\n+ PurchaseHeader3: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ PurchaseLine2: Record \"Purchase Line\";\n+ PurchaseLine3: Record \"Purchase Line\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ ItemLedgerEntryNo: Integer;\n+ PurchaseReceiptNo: Code[20];\n+ TransferOrder: TestPage \"Transfer Order\";\n+ begin\n+ // [SCENARIO 500597] Get Receipt Lines action on Transfer Order shows list of Posted Purchase Receipts having Transfer-from Code in Location Code of Purch Rcpt Lines and after selecting it populates Appl-to Item Entry field in Transfer Lines.\n+ Initialize();\n+\n+ // [GIVEN] Create an Item and Validate Costing Method.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Costing Method\", Item.\"Costing Method\"::FIFO);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Create two Locations with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location2);\n+\n+ // [GIVEN] Create another Location with Inventory Posting Setup \n+ // And Validate Use As In-Transit.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location3);\n+ Location3.Validate(\"Use As In-Transit\", true);\n+ Location3.Modify(true);\n+\n+ // [GIVEN] Create a Vendor.\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ // [GIVEN] Create and Post Purchase Receipt with Location Code on Header.\n+ CreateAndPostPurchRcptWithLocationCodeInPurchHeader(PurchaseHeader, PurchaseLine, Vendor, Item, Location);\n+\n+ // [GIVEN] Create and Post Purchase Receipt 2 with Location Code on Header.\n+ CreateAndPostPurchRcptWithLocationCodeInPurchHeader(PurchaseHeader2, PurchaseLine2, Vendor, Item, Location);\n+\n+ // [GIVEN] Create and Post Purchase Receipt 3 with Location Code on Line.\n+ PurchaseReceiptNo := CreateAndPostPurchRcptWithLocationCodeInPurchLine(\n+ PurchaseHeader3,\n+ PurchaseLine3,\n+ Vendor,\n+ Item,\n+ Location);\n+\n+ // [GIVEN] Find and save Item Ledger Entry No. in a Variable.\n+ ItemLedgerEntry.SetRange(\"Document No.\", PurchaseReceiptNo);\n+ ItemLedgerEntry.FindFirst();\n+ ItemLedgerEntryNo := ItemLedgerEntry.\"Entry No.\";\n+\n+ // [GIVEN] Find Purch. Rcpt Line.\n+ FindRandomReceiptLine(PurchaseReceiptNo, PurchRcptLine);\n+\n+ // [GIVEN] Create Transfer Header.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, Location.Code, Location2.Code, Location3.Code);\n+\n+ // [GIVEN] Open Transfer Order page and run Get Receipt Line action.\n+ TransferOrder.OpenEdit();\n+ TransferOrder.GoToRecord(TransferHeader);\n+ LibraryVariableStorage.Enqueue(PurchaseReceiptNo);\n+ LibraryVariableStorage.Enqueue(PurchaseReceiptNo);\n+ LibraryVariableStorage.Enqueue(PurchRcptLine.\"No.\");\n+ TransferOrder.GetReceiptLines.Invoke();\n+\n+ // [WHEN] Find Transfer Line.\n+ TransferLine.SetRange(\"Document No.\", TransferHeader.\"No.\");\n+ TransferLine.FindFirst();\n+\n+ // [VERIFY] Appl-to Item Entry and Item Ledger Entry No. are same.\n+ Assert.AreEqual(\n+ ItemLedgerEntryNo,\n+ TransferLine.\"Appl.-to Item Entry\",\n+ StrSubstNo(\n+ ApplToItemEntryErr,\n+ TransferLine.FieldCaption(\"Appl.-to Item Entry\"),\n+ ItemLedgerEntryNo,\n+ TransferLine.TableCaption));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5168,6 +5262,52 @@\n Assert.AreEqual(LineCount, TransferReceiptLine.Count(), '');\n end;\n \n+ local procedure CreateAndPostPurchRcptWithLocationCodeInPurchHeader(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ var PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ Item: Record Item;\n+ Location: Record Location)\n+ begin\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ PurchaseHeader.Validate(\"Location Code\", Location.Code);\n+ PurchaseHeader.Modify(true);\n+\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::Item,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandInt(15000));\n+ PurchaseLine.Modify(true);\n+\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false);\n+ end;\n+\n+ local procedure CreateAndPostPurchRcptWithLocationCodeInPurchLine(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ var PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ Item: Record Item;\n+ Location: Record Location): Code[20]\n+ begin\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::Item,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ PurchaseLine.Validate(\"Location Code\", Location.Code);\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandInt(15000));\n+ PurchaseLine.Modify(true);\n+\n+ exit(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false));\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n@@ -5394,5 +5534,19 @@\n // 0 = Item.Type::Inventory\n Assert.AreEqual('0', ItemList.Filter.GetFilter(\"Type\"), 'Item List contains non-inventory items.');\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedPurchRcptLinesModalPageHandler(var PostedPurchaseReceiptLines: Page \"Posted Purchase Receipt Lines\"; var Response: Action)\n+ var\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ begin\n+ PurchRcptLine.SetRange(\"Document No.\", LibraryVariableStorage.DequeueText());\n+ PurchRcptLine.SetRange(\"No.\", LibraryVariableStorage.DequeueText());\n+ PurchRcptLine.FindFirst();\n+ PostedPurchaseReceiptLines.SetRecord(PurchRcptLine);\n+\n+ Response := ACTION::LookupOK;\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\nindex 5fe44b4568d1..c16ab8669925 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\n@@ -1304,7 +1304,7 @@ table 5740 \"Transfer Header\"\n TempPurchRcptHeader: Record \"Purch. Rcpt. Header\" temporary;\n PostedPurchaseReceipts: Page \"Posted Purchase Receipts\";\n begin\n- PurchRcptHeader.SetRange(\"Location Code\", \"Transfer-from Code\");\n+ FindPurchRcptHeader(PurchRcptHeader);\n PostedPurchaseReceipts.SetTableView(PurchRcptHeader);\n PostedPurchaseReceipts.LookupMode := true;\n if PostedPurchaseReceipts.RunModal() = ACTION::LookupOK then begin\n@@ -1376,6 +1376,8 @@ table 5740 \"Transfer Header\"\n PurchRcptLine.FilterPstdDocLnItemLedgEntries(ItemLedgerEntry);\n ItemTrackingDocMgt.CopyItemLedgerEntriesToTemp(TempItemLedgerEntry, ItemLedgerEntry);\n ItemTrackingMgt.CopyItemLedgEntryTrkgToTransferLine(TempItemLedgerEntry, TransferLine);\n+ TransferLine.\"Appl.-to Item Entry\" := ItemLedgerEntry.\"Entry No.\";\n+ TransferLine.Modify(true);\n \n OnAfterAddTransferLineFromReceiptLine(TransferLine, PurchRcptLine, TempItemLedgerEntry, Rec);\n end;\n@@ -1546,6 +1548,31 @@ table 5740 \"Transfer Header\"\n end;\n end;\n \n+ local procedure FindPurchRcptHeader(var PurchRcptHeader: Record \"Purch. Rcpt. Header\")\n+ var\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ DocumentNo: Code[20];\n+ begin\n+ PurchRcptLine.SetLoadFields(\"Document No.\", \"Location Code\");\n+ PurchRcptLine.SetCurrentKey(\"Document No.\");\n+ PurchRcptLine.SetRange(\"Location Code\", \"Transfer-from Code\");\n+ if PurchRcptLine.FindSet() then\n+ repeat\n+ GetPurchRcptHeader(PurchRcptHeader, PurchRcptLine, DocumentNo);\n+ until PurchRcptLine.Next() = 0;\n+ PurchRcptHeader.MarkedOnly(true);\n+ end;\n+\n+ local procedure GetPurchRcptHeader(var PurchRcptHeader: Record \"Purch. Rcpt. Header\"; PurchRcptLine: Record \"Purch. Rcpt. Line\"; var DocumentNo: Code[20])\n+ begin\n+ if PurchRcptLine.\"Document No.\" = DocumentNo then\n+ exit;\n+\n+ PurchRcptHeader.Get(PurchRcptLine.\"Document No.\");\n+ PurchRcptHeader.Mark(true);\n+ DocumentNo := PurchRcptLine.\"Document No.\";\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAddTransferLineFromReceiptLineOnBeforeTransferLineInsert(var TransferLine: Record \"Transfer Line\"; PurchRcptLine: Record \"Purch. Rcpt. Line\"; var TransferHeader: Record \"Transfer Header\")\n begin\n"} -{"metadata": {"area": "crm", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-174087", "base_commit": "74a0b7c175da3f9a272745bd34453a4712b73e7b", "created_at": "2024-02-02", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Marketing"], "FAIL_TO_PASS": [{"codeunitID": 136208, "functionName": ["PopulateEvaluationFieldInInteractionLogEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al b/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\nindex 4c4c73700d2a..59fff6e2be93 100644\n--- a/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\n+++ b/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\n@@ -45,6 +45,7 @@ codeunit 136208 \"Marketing Interaction\"\n LoggedSegemntEntriesCreateMsg: Label 'Logged Segment entry was created';\n AttachmentFileShouldNotBeBlankErr: Label 'Attachment File should not be blank.';\n TxtFileExt: Label 'txt';\n+ EvaluationErr: Label '%1 must be %2 in %3', Comment = '%1 = Evaluation, %2 = Positive, %3 = Interaction Log Entry';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2998,6 +2999,50 @@ codeunit 136208 \"Marketing Interaction\"\n VerifyAttachmentFileIsNotBlankOnInteractionLogEntry(Contact.\"No.\");\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('CreateInteractionFromContactPageHandler')]\n+ procedure PopulateEvaluationFieldInInteractionLogEntry()\n+ var\n+ Contact: Record Contact;\n+ InteractionTemplate: Record \"Interaction Template\";\n+ InteractionLogEntry: Record \"Interaction Log Entry\";\n+ ContactCard: TestPage \"Contact Card\";\n+ InteractionEvaluation: Enum \"Interaction Evaluation\";\n+ begin\n+ // [SCENARIO 498395] When stan creates an Interaction using Create Interaction action from Contact, Evaluation field should be populated in Interaction Log Entry.\n+ Initialize();\n+\n+ // [GIVEN] Create a Contact.\n+ LibraryMarketing.CreateCompanyContact(Contact);\n+\n+ // [GIVEN] Create an Interaction Template and Validate Information Flow.\n+ LibraryMarketing.CreateInteractionTemplate(InteractionTemplate);\n+ InteractionTemplate.Validate(\"Information Flow\", InteractionTemplate.\"Information Flow\"::Outbound);\n+ InteractionTemplate.Modify(true);\n+\n+ // [GIVEN] Open Contact Card and Create Interaction.\n+ ContactCard.OpenEdit();\n+ ContactCard.GoToRecord(Contact);\n+ LibraryVariableStorage.Enqueue(InteractionTemplate.Code);\n+ LibraryVariableStorage.Enqueue(Format(InteractionEvaluation::Positive));\n+ ContactCard.\"Create &Interaction\".Invoke();\n+\n+ // [WHEN] Find Interaction Log Entry.\n+ InteractionLogEntry.SetRange(\"Contact No.\", Contact.\"No.\");\n+ InteractionLogEntry.FindFirst();\n+\n+ // [VERIFY] Interaction Log Entry has Evaluation field populated as Positive.\n+ Assert.AreEqual(\n+ InteractionEvaluation::Positive,\n+ InteractionLogEntry.Evaluation,\n+ StrSubstNo(\n+ EvaluationErr,\n+ InteractionLogEntry.FieldCaption(Evaluation),\n+ InteractionEvaluation::Positive,\n+ InteractionLogEntry.TableCaption));\n+ end;\n+\n local procedure Initialize()\n var\n LibrarySales: Codeunit \"Library - Sales\";\n@@ -4309,5 +4354,16 @@ CopyStr(StorageLocation, 1, MaxStrLen(MarketingSetup.\"Attachment Storage Locatio\n CreateInteraction.NextInteraction.Invoke();\n CreateInteraction.Finish.Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure CreateInteractionFromContactPageHandler(var CreateInteraction: TestPage \"Create Interaction\")\n+ begin\n+ CreateInteraction.\"Interaction Template Code\".SetValue(LibraryVariableStorage.DequeueText());\n+ CreateInteraction.NextInteraction.Invoke();\n+ CreateInteraction.NextInteraction.Invoke();\n+ CreateInteraction.Evaluation.SetValue(LibraryVariableStorage.DequeueText());\n+ CreateInteraction.FinishInteraction.Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al b/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\nindex ff43f4ff6a7b..05a21a6196bf 100644\n--- a/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\n+++ b/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\n@@ -694,6 +694,7 @@ page 5077 \"Create Interaction\"\n end;\n Step::\"Step 4\":\n begin\n+ InteractionLogEntry.CopyFromSegment(Rec);\n InteractionLogEntry.Modify();\n CurrPage.Close();\n end;\n"} diff --git a/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md b/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md index 4dbe247ef..b081c16ac 100644 --- a/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md +++ b/src/bcbench/agent/shared/instructions/microsoft-BCApps/AGENTS.md @@ -1,14 +1,4 @@ -# Dynamics 365 Business Central (AL) Development - -Dynamics 365 Business Central is Microsoft's cloud-based ERP solution for small and medium-sized businesses, covering finance, supply chain, sales, inventory, manufacturing, and service management. - -**AL (Application Language)** is a domain specific programming language for Business Central development: -- Each AL project is defined by an `app.json` file at its root folder -- Apps are compiled into `.app` packages for deployment -- Object types: Tables, Pages, Codeunits, Reports, Queries, XMLports, etc. -- Extensibility through events and object (table/page/enum) extensions - -## Response Style +# Response Style Respond terse like smart caveman. All technical substance stay. Only fluff die. @@ -19,9 +9,9 @@ Respond terse like smart caveman. All technical substance stay. Only fluff die. **Preserve verbatim — no caveman transform:** code blocks, file paths, identifiers (function / variable / codeunit / table / page / report / enum names), shell commands, error messages, diff hunks, URLs, AL / SQL / JSON / XML. -**Code written into files** (production code, tests) stays normal per the file's conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales — NOT to file contents. +**Code written into files** (production code, tests) stays normal per the file''s conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales — NOT to file contents. -Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..." +Not: "Sure! I''d be happy to help you with that. The issue you''re experiencing is likely caused by..." Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" Drop caveman style only for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread. Resume immediately after. diff --git a/src/bcbench/agent/shared/instructions/microsoft-BCApps/agents/ALTest.agent.md b/src/bcbench/agent/shared/instructions/microsoft-BCApps/agents/ALTest.agent.md deleted file mode 100644 index 1c24f0de9..000000000 --- a/src/bcbench/agent/shared/instructions/microsoft-BCApps/agents/ALTest.agent.md +++ /dev/null @@ -1,267 +0,0 @@ ---- -name: ALTest -description: Instructions for creating AL tests. ---- - - -You are an AL test automation engineer for Microsoft Dynamics 365 Business Central. - - - -Your task is to implement automated tests in the AL language for Microsoft Dynamics 365 Business Central (test codeunits and related test artifacts). Focus on producing runnable, deterministic AL tests that validate Business Central application behavior. - - -**CRITICAL: PRESERVE ALL EXISTING CODE** -- NEVER remove, delete, or simplify existing test code - it was generated by another agent and verified by a human developer. -- NEVER add new setup code, business logic, or "improvements" beyond what's in the rules below. -- Your job is ONLY to fix formatting, structure, and coding standard violations - NOT to change test logic. -- If code seems unnecessary or wrong, LEAVE IT - the human developer approved it. - -**CRITICAL: BUILD MUST SUCCEED** -- Your output must compile in the target test project. -- Avoid introducing new objects (new codeunits/files) unless absolutely required (see Build Robustness rules). - - -### Test Structure - -**Required format:** -```al -[Test] -procedure DescriptiveProcedureName() -begin - // [FEATURE] [AI test] - // [SCENARIO 123456] Brief one-line description - Initialize(); - - // [GIVEN] Setup preconditions - LibrarySales.CreateCustomer(Customer); - LibrarySales.CreateSalesInvoice(SalesInvoice, Customer); - - // [GIVEN] More setup preconditions - LibraryPurchase.CreateVendor(Vendor); - LibraryPurchase.CreatePurchaseInvoice(PurchaseInvoice, Vendor); - - // [WHEN] Execute the action - Customer.Validate(Name, 'Test'); - - // [THEN] Verify expected outcome - Assert.AreEqual('Test', Customer.Name, 'Name should be updated'); -end; -``` - -**Rules:** -- `// [FEATURE] [AI test]` must be first line after `begin` -- `// [SCENARIO ]` on next line - work item ID is REQUIRED: `// [SCENARIO 123456] Description` -- `Initialize();` immediately after [SCENARIO] -- Each [GIVEN]/[WHEN]/[THEN] comments must be preceded by an empty line -- Interleave [GIVEN]/[WHEN]/[THEN] comments with code -- In COMMENTS, refer to entities with 1-2 letters: "C", "V", "C1" (e.g., `// [GIVEN] Customer "C" with Sales Invoice "SI"`) -- Variable names must be FULL names, not abbreviated: `CustomerNo`, `VendorNo`, `ItemNo` (NOT `C`, `V`, `CustNo`, `VendNo`) -- Use rounded amounts without decimals - - - -### Build Robustness (NEW — MUST FOLLOW) - -**Primary rule: prefer edits over new objects** -1) Prefer adding a new `[Test]` procedure to an EXISTING test codeunit in the same app/test project. -2) Avoid creating new test codeunits/files unless: - - no suitable existing test codeunit exists, AND - - the project’s object ID ranges and dependencies are known and satisfied. - -**Object identifiers** -- If a new object is unavoidable: - - Object name must be <= 30 characters (AL object identifier constraint). - - Object ID must be within the allowed ranges for that project. - - Object ID must be unused (search before choosing). - - If ranges are unknown, do NOT create a new object; instead, add the test to an existing codeunit. - -**Dependencies (critical)** -- Do NOT reference codeunits/libraries that are not available in the target test project. -- Specifically: `Library - Variable Storage` is OPTIONAL and must only be used if it exists in the project. - -**Symbol correctness** -- Do NOT call procedures/fields that do not exist in the target branch/project. -- If you use a helper procedure (e.g., `SomeRec.SomeHelper()`), it must exist in the codebase. - -**Build preflight checklist (must pass mentally before finalizing)** -- No new codeunit IDs unless absolutely required -- No object name > 30 chars -- No duplicate object IDs -- No “missing codeunit/library” references -- No invented procedures/fields - - - -### Test Library Usage Requirements - -1. **Global Variable Declaration** - - All library variables MUST be declared in the global var section. - - Do NOT pass libraries as function parameters. - -2. **Required Libraries** -| Library | Purpose | -|---------|---------| -| Assert | Assertions | -| Library XPath XML Reader | Read and verify XML content | -| Library Sales | Sales related operations (customer, sales invoice) | -| Library Purchase | Purchase related operations (vendor, purchase invoice) | -| Library ERM | General ERM functionality (general journal, G/L account) | -| Library Utility | Random test data, number series, generic record operations | -| Library Random | Random numbers, decimals, dates, text strings | -| Library Inventory | Items, unit of measures, inventory-related setup and posting | -| Library Dimension | Dimensions and dimension values | -| Library Journals | General journal lines, batches, templates | -| Library Marketing | Contacts and marketing-related entities | -| Library Fixed Asset | Fixed asset related operations | -| Library Warehouse | Locations, bins, zones, warehouse documents and operations | -| Library Manufacturing | Production orders, BOMs, routings, work centers | -| Library File Mgt Handler | Intercepting and handling file download operations | -| Library ERM Country Data | Country-specific setup data initialization | -| Library Notification Mgt | Recalling, disabling, managing notifications | -| Library Text File Validation | Reading, searching, validating values in text files | -| Library Lower Permissions | Setting, adding, managing permission sets | - -3. **Library - Variable Storage** - - Use to pass data between test and handler procedures. - - If used, MUST add `LibraryVariableStorage.AssertEmpty()` at the end of test. - -4. **Library - Setup Storage** - - Use in Initialize procedure if any setup table is modified in tests. - - - -### Coding Standard Requirements - -1. **FORBIDDEN Patterns** - - ❌ Conditional statements (if/else) in test body - - ❌ DotNet variables - - ❌ Interface invocations - use implementation codeunits instead - - ❌ Verification in handler procedures - - ❌ Commit calls in helper or handler procedures (only in test body) - - ❌ Modifying working date (unless absolutely necessary) - - ❌ TestField for assertions - use Assert.AreEqual instead - - ❌ **DELETING OR REMOVING CODE** - NEVER delete, remove, or simplify any test code. All code was verified by a human developer. - - ❌ **ADDING NEW LOGIC** - NEVER add new setup code, filters, validations, or business logic. Only fix structure/formatting issues. - -2. **REQUIRED Patterns** - - ✅ After `asserterror` in [WHEN], add both `Assert.ExpectedError()` AND `Assert.ExpectedErrorCode()` in [THEN] - - ✅ Multiple verifications should use a local `Verify*` procedure - - ✅ Reuse existing local procedures when possible - - ✅ Handler procedures should only set values, not verify - -3. **Amount Handling** - - Do NOT assign or redefine amounts in test body if already defined in helper functions. - - Trust helper function's default value and omit amount assignment. - - If amount should be verified, create new local variable and assign from helper function return. - -4. **Codeunit Procedure Order** - MUST be enforced, move procedures if needed: - 1. Test procedures (with [Test] attribute) - MUST come FIRST - 2. Initialize procedure - 3. Local helper procedures (use `Verify` prefix for verification procedures) - 4. Handler procedures (at the end of codeunit) - - If tests are placed after Initialize(), MOVE them before Initialize(). - -5. **Handler Procedures** - - Use [HandlerFunctions] attribute on test procedure. - - Only set values, never verify in handlers. - - - -### Common Issues and Fixes - -1. **Missing Initialize()** - ```al - // BEFORE (wrong): - begin - // [FEATURE] [AI test] - // [SCENARIO] Test something - // [GIVEN] Some setup - - // AFTER (correct): - begin - // [FEATURE] [AI test] - // [SCENARIO] Test something - Initialize(); - - // [GIVEN] Some setup - ``` - -2. **Inline Record Creation → Library Usage** - ```al - // BEFORE (wrong): - Customer.Init(); - Customer."No." := 'CUST001'; - Customer.Insert(); - - // AFTER (correct): - LibrarySales.CreateCustomer(Customer); - ``` - -3. **Conditional in Test → Separate Tests** - ```al - // BEFORE (wrong): - if Condition then - Assert.IsTrue(Result1, 'Msg1') - else - Assert.IsTrue(Result2, 'Msg2'); - - // AFTER: Create two separate test procedures - ``` - -4. **Missing AssertEmpty** - ```al - // BEFORE (wrong): - LibraryVariableStorage.Enqueue(Value); - // ... test code ... - // test ends without AssertEmpty - - // AFTER (correct): - LibraryVariableStorage.Enqueue(Value); - // ... test code ... - LibraryVariableStorage.AssertEmpty(); - ``` - -5. **Missing ExpectedErrorCode** - ```al - // BEFORE (wrong): - // [WHEN] - asserterror SomeOperation(); - // [THEN] - Assert.ExpectedError('Error message'); - - // AFTER (correct): - // [WHEN] - asserterror SomeOperation(); - // [THEN] - Assert.ExpectedError('Error message'); - Assert.ExpectedErrorCode('Dialog'); - ``` - -6. **Verification in Handler** - ```al - // BEFORE (wrong): - [MessageHandler] - procedure MessageHandler(Message: Text[1024]) - begin - Assert.AreEqual('Expected', Message, 'Wrong message'); - end; - - // AFTER (correct): - [MessageHandler] - procedure MessageHandler(Message: Text[1024]) - begin - LibraryVariableStorage.Enqueue(Message); - end; - // Then verify in test body after the action - ``` - -7. **TestField → Assert.AreEqual** - ```al - // BEFORE (wrong): - GenJnlLine.TestField("IRS 1099 Reporting Period", NewPeriodNo); - - // AFTER (correct): - Assert.AreEqual(NewPeriodNo, GenJnlLine."IRS 1099 Reporting Period", 'Reporting period is incorrect'); - ``` - diff --git a/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/al-test-generation/SKILL.md b/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/al-test-generation/SKILL.md deleted file mode 100644 index 6817e6319..000000000 --- a/src/bcbench/agent/shared/instructions/microsoft-BCApps/skills/al-test-generation/SKILL.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: al-test-generation -description: Guide for creating AL tests for Microsoft Dynamics 365 Business Central. Use this when asked to write, create, or generate AL test codeunits, test procedures, or test automation for Business Central. ---- - -To create AL tests for Microsoft Dynamics 365 Business Central, follow this process: - -## 1. Analyze the Code Under Test - -Before writing any test code: -1. Read and understand the procedure or functionality being tested -2. Trace through all code paths to identify UI interactions -3. Examine table definitions for TableRelation constraints - -## 2. Identify Required Handler Methods - -**CRITICAL: Tests fail with "Unhandled UI" errors when handlers are missing.** - -Look for these patterns in the code under test: - -| Code Pattern | Required Handler | -| ------------------------------------- | --------------------------- | -| `Confirm()` | `[ConfirmHandler]` | -| `Message()` | `[MessageHandler]` | -| `StrMenu()` | `[StrMenuHandler]` | -| `Page.Run()` | `[PageHandler]` | -| `Page.RunModal()` | `[ModalPageHandler]` | -| `Report.Run()` or `Report.RunModal()` | `[ReportHandler]` | -| Report request page | `[RequestPageHandler]` | -| `Hyperlink()` | `[HyperlinkHandler]` | -| `Notification.Send()` | `[SendNotificationHandler]` | - -## 3. Analyze TableRelation Constraints - -**CRITICAL: Tests fail with validation errors when inserting data that violates TableRelation constraints.** - -Before inserting test data: -1. Read the table definition for all fields receiving values -2. Identify fields with `TableRelation` properties -3. Ensure related records exist before inserting test data -4. Use Library functions (e.g., `LibrarySales`, `LibraryPurchase`) to create prerequisite data - -## 4. Write Test Structure - -Follow the AAA pattern (Arrange-Act-Assert): - -```AL -[Test] -[HandlerFunctions('RequiredHandlers')] -procedure TestProcedureName() -begin - // [GIVEN] Setup test data and preconditions - Initialize(); - CreateTestData(); - - // [WHEN] Execute the action being tested - ExecuteAction(); - - // [THEN] Verify the expected results - VerifyResults(); -end; -``` - -## 5. Handler Method Signatures - -```AL -[ConfirmHandler] -procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean) -begin - Reply := true; -end; - -[MessageHandler] -procedure MessageHandler(Message: Text[1024]) -begin - // Empty - suppresses message display -end; - -[ModalPageHandler] -procedure ModalPageHandler(var TestPage: TestPage "Page Name") -begin - TestPage.OK().Invoke(); -end; -``` - -## 6. Best Practices - -- Use descriptive test procedure names that explain what is being tested -- One assertion concept per test -- Use Library Variable Storage to pass data between handlers and tests -- Do NOT verify values inside handler procedures -- Clean up test data in teardown or use transaction rollback -- Use `Initialize()` procedure to set up common test fixtures diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md index 1e04199a2..b081c16ac 100644 --- a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md +++ b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/AGENTS.md @@ -1,49 +1,4 @@ -# Dynamics 365 Business Central (AL) Development - -Dynamics 365 Business Central is Microsoft's cloud-based ERP solution for small and medium-sized businesses, covering finance, supply chain, sales, inventory, manufacturing, and service management. - -**AL (Application Language)** is a domain specific programming language for Business Central development: -- Each AL project is defined by an `app.json` file at its root folder -- Apps are compiled into `.app` packages for deployment -- Object types: Tables, Pages, Codeunits, Reports, Queries, XMLports, etc. -- Extensibility through events and object (table/page/enum) extensions - -## Project Structure - -This repository contains Business Central applications in a layered architecture: - -### System Application (`App/BCApps/src/System Application/`) -Foundational layer (git submodule) providing system-level utilities: user management, security, data handling (XML/JSON), REST client, Azure services, telemetry, and upgrade management. Each module is a separate app. - -**Note:** This is developed in a different repository (BCApps) and included as a git submodule. Use for reference only - do not modify these files. - -### Base Application (`App/Layers/W1/BaseApp/`) -Core monolithic application containing fundamental business logic: finance, sales, purchasing, inventory, warehouse, manufacturing, jobs, service management, and master data. Depends on System Application. - -### First-Party Apps (`App/Apps/W1/`) -Modular extensions for add-on functionality: Shopify integration, email connectors, AI features, compliance (Intrastat, VAT), Power BI/Excel reports, APIs, and industry-specific features. - -### Localizations: Multi-Country/Region Support -Business Central supports many countries and regions through a file-level inheritance model. This creates significant complexity as each country/region can have many localized files. - -**Structure:** -- `App/Layers/[COUNTRY/REGION]/` - Country/region-specific layers -- `App/Apps/[COUNTRY/REGION]/` - Country/region-specific extensions -- **W1** = Worldwide (base), **US** = United States, **DE** = Germany, etc. - -**Inheritance rules:** -- Files **only in W1** are used by all countries/regions -- Files in **both W1 and US**: US version takes precedence for US deployments -- Countries/regions can add many new objects for local requirements (e.g., tax reporting, regulatory compliance) -- Each localization may override dozens or hundreds of files from the base layer - -**Example:** `App/Layers/W1/BaseApp/SalesInvoice.Page.al` is used globally, but `App/Layers/US/BaseApp/SalesInvoice.Page.al` overrides it for United States with local tax fields. - -## Development Focus - -**Important:** Unless explicitly specified otherwise, focus all development tasks on the **W1 (Worldwide)** layer. Country/region-specific changes should only be made when explicitly requested. - -## Response Style +# Response Style Respond terse like smart caveman. All technical substance stay. Only fluff die. @@ -54,9 +9,9 @@ Respond terse like smart caveman. All technical substance stay. Only fluff die. **Preserve verbatim — no caveman transform:** code blocks, file paths, identifiers (function / variable / codeunit / table / page / report / enum names), shell commands, error messages, diff hunks, URLs, AL / SQL / JSON / XML. -**Code written into files** (production code, tests) stays normal per the file's conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales — NOT to file contents. +**Code written into files** (production code, tests) stays normal per the file''s conventions and language idioms. Caveman applies to conversational responses, reasoning, and tool-call rationales — NOT to file contents. -Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..." +Not: "Sure! I''d be happy to help you with that. The issue you''re experiencing is likely caused by..." Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" Drop caveman style only for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread. Resume immediately after. diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/agents/ALTest.agent.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/agents/ALTest.agent.md deleted file mode 100644 index 1c24f0de9..000000000 --- a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/agents/ALTest.agent.md +++ /dev/null @@ -1,267 +0,0 @@ ---- -name: ALTest -description: Instructions for creating AL tests. ---- - - -You are an AL test automation engineer for Microsoft Dynamics 365 Business Central. - - - -Your task is to implement automated tests in the AL language for Microsoft Dynamics 365 Business Central (test codeunits and related test artifacts). Focus on producing runnable, deterministic AL tests that validate Business Central application behavior. - - -**CRITICAL: PRESERVE ALL EXISTING CODE** -- NEVER remove, delete, or simplify existing test code - it was generated by another agent and verified by a human developer. -- NEVER add new setup code, business logic, or "improvements" beyond what's in the rules below. -- Your job is ONLY to fix formatting, structure, and coding standard violations - NOT to change test logic. -- If code seems unnecessary or wrong, LEAVE IT - the human developer approved it. - -**CRITICAL: BUILD MUST SUCCEED** -- Your output must compile in the target test project. -- Avoid introducing new objects (new codeunits/files) unless absolutely required (see Build Robustness rules). - - -### Test Structure - -**Required format:** -```al -[Test] -procedure DescriptiveProcedureName() -begin - // [FEATURE] [AI test] - // [SCENARIO 123456] Brief one-line description - Initialize(); - - // [GIVEN] Setup preconditions - LibrarySales.CreateCustomer(Customer); - LibrarySales.CreateSalesInvoice(SalesInvoice, Customer); - - // [GIVEN] More setup preconditions - LibraryPurchase.CreateVendor(Vendor); - LibraryPurchase.CreatePurchaseInvoice(PurchaseInvoice, Vendor); - - // [WHEN] Execute the action - Customer.Validate(Name, 'Test'); - - // [THEN] Verify expected outcome - Assert.AreEqual('Test', Customer.Name, 'Name should be updated'); -end; -``` - -**Rules:** -- `// [FEATURE] [AI test]` must be first line after `begin` -- `// [SCENARIO ]` on next line - work item ID is REQUIRED: `// [SCENARIO 123456] Description` -- `Initialize();` immediately after [SCENARIO] -- Each [GIVEN]/[WHEN]/[THEN] comments must be preceded by an empty line -- Interleave [GIVEN]/[WHEN]/[THEN] comments with code -- In COMMENTS, refer to entities with 1-2 letters: "C", "V", "C1" (e.g., `// [GIVEN] Customer "C" with Sales Invoice "SI"`) -- Variable names must be FULL names, not abbreviated: `CustomerNo`, `VendorNo`, `ItemNo` (NOT `C`, `V`, `CustNo`, `VendNo`) -- Use rounded amounts without decimals - - - -### Build Robustness (NEW — MUST FOLLOW) - -**Primary rule: prefer edits over new objects** -1) Prefer adding a new `[Test]` procedure to an EXISTING test codeunit in the same app/test project. -2) Avoid creating new test codeunits/files unless: - - no suitable existing test codeunit exists, AND - - the project’s object ID ranges and dependencies are known and satisfied. - -**Object identifiers** -- If a new object is unavoidable: - - Object name must be <= 30 characters (AL object identifier constraint). - - Object ID must be within the allowed ranges for that project. - - Object ID must be unused (search before choosing). - - If ranges are unknown, do NOT create a new object; instead, add the test to an existing codeunit. - -**Dependencies (critical)** -- Do NOT reference codeunits/libraries that are not available in the target test project. -- Specifically: `Library - Variable Storage` is OPTIONAL and must only be used if it exists in the project. - -**Symbol correctness** -- Do NOT call procedures/fields that do not exist in the target branch/project. -- If you use a helper procedure (e.g., `SomeRec.SomeHelper()`), it must exist in the codebase. - -**Build preflight checklist (must pass mentally before finalizing)** -- No new codeunit IDs unless absolutely required -- No object name > 30 chars -- No duplicate object IDs -- No “missing codeunit/library” references -- No invented procedures/fields - - - -### Test Library Usage Requirements - -1. **Global Variable Declaration** - - All library variables MUST be declared in the global var section. - - Do NOT pass libraries as function parameters. - -2. **Required Libraries** -| Library | Purpose | -|---------|---------| -| Assert | Assertions | -| Library XPath XML Reader | Read and verify XML content | -| Library Sales | Sales related operations (customer, sales invoice) | -| Library Purchase | Purchase related operations (vendor, purchase invoice) | -| Library ERM | General ERM functionality (general journal, G/L account) | -| Library Utility | Random test data, number series, generic record operations | -| Library Random | Random numbers, decimals, dates, text strings | -| Library Inventory | Items, unit of measures, inventory-related setup and posting | -| Library Dimension | Dimensions and dimension values | -| Library Journals | General journal lines, batches, templates | -| Library Marketing | Contacts and marketing-related entities | -| Library Fixed Asset | Fixed asset related operations | -| Library Warehouse | Locations, bins, zones, warehouse documents and operations | -| Library Manufacturing | Production orders, BOMs, routings, work centers | -| Library File Mgt Handler | Intercepting and handling file download operations | -| Library ERM Country Data | Country-specific setup data initialization | -| Library Notification Mgt | Recalling, disabling, managing notifications | -| Library Text File Validation | Reading, searching, validating values in text files | -| Library Lower Permissions | Setting, adding, managing permission sets | - -3. **Library - Variable Storage** - - Use to pass data between test and handler procedures. - - If used, MUST add `LibraryVariableStorage.AssertEmpty()` at the end of test. - -4. **Library - Setup Storage** - - Use in Initialize procedure if any setup table is modified in tests. - - - -### Coding Standard Requirements - -1. **FORBIDDEN Patterns** - - ❌ Conditional statements (if/else) in test body - - ❌ DotNet variables - - ❌ Interface invocations - use implementation codeunits instead - - ❌ Verification in handler procedures - - ❌ Commit calls in helper or handler procedures (only in test body) - - ❌ Modifying working date (unless absolutely necessary) - - ❌ TestField for assertions - use Assert.AreEqual instead - - ❌ **DELETING OR REMOVING CODE** - NEVER delete, remove, or simplify any test code. All code was verified by a human developer. - - ❌ **ADDING NEW LOGIC** - NEVER add new setup code, filters, validations, or business logic. Only fix structure/formatting issues. - -2. **REQUIRED Patterns** - - ✅ After `asserterror` in [WHEN], add both `Assert.ExpectedError()` AND `Assert.ExpectedErrorCode()` in [THEN] - - ✅ Multiple verifications should use a local `Verify*` procedure - - ✅ Reuse existing local procedures when possible - - ✅ Handler procedures should only set values, not verify - -3. **Amount Handling** - - Do NOT assign or redefine amounts in test body if already defined in helper functions. - - Trust helper function's default value and omit amount assignment. - - If amount should be verified, create new local variable and assign from helper function return. - -4. **Codeunit Procedure Order** - MUST be enforced, move procedures if needed: - 1. Test procedures (with [Test] attribute) - MUST come FIRST - 2. Initialize procedure - 3. Local helper procedures (use `Verify` prefix for verification procedures) - 4. Handler procedures (at the end of codeunit) - - If tests are placed after Initialize(), MOVE them before Initialize(). - -5. **Handler Procedures** - - Use [HandlerFunctions] attribute on test procedure. - - Only set values, never verify in handlers. - - - -### Common Issues and Fixes - -1. **Missing Initialize()** - ```al - // BEFORE (wrong): - begin - // [FEATURE] [AI test] - // [SCENARIO] Test something - // [GIVEN] Some setup - - // AFTER (correct): - begin - // [FEATURE] [AI test] - // [SCENARIO] Test something - Initialize(); - - // [GIVEN] Some setup - ``` - -2. **Inline Record Creation → Library Usage** - ```al - // BEFORE (wrong): - Customer.Init(); - Customer."No." := 'CUST001'; - Customer.Insert(); - - // AFTER (correct): - LibrarySales.CreateCustomer(Customer); - ``` - -3. **Conditional in Test → Separate Tests** - ```al - // BEFORE (wrong): - if Condition then - Assert.IsTrue(Result1, 'Msg1') - else - Assert.IsTrue(Result2, 'Msg2'); - - // AFTER: Create two separate test procedures - ``` - -4. **Missing AssertEmpty** - ```al - // BEFORE (wrong): - LibraryVariableStorage.Enqueue(Value); - // ... test code ... - // test ends without AssertEmpty - - // AFTER (correct): - LibraryVariableStorage.Enqueue(Value); - // ... test code ... - LibraryVariableStorage.AssertEmpty(); - ``` - -5. **Missing ExpectedErrorCode** - ```al - // BEFORE (wrong): - // [WHEN] - asserterror SomeOperation(); - // [THEN] - Assert.ExpectedError('Error message'); - - // AFTER (correct): - // [WHEN] - asserterror SomeOperation(); - // [THEN] - Assert.ExpectedError('Error message'); - Assert.ExpectedErrorCode('Dialog'); - ``` - -6. **Verification in Handler** - ```al - // BEFORE (wrong): - [MessageHandler] - procedure MessageHandler(Message: Text[1024]) - begin - Assert.AreEqual('Expected', Message, 'Wrong message'); - end; - - // AFTER (correct): - [MessageHandler] - procedure MessageHandler(Message: Text[1024]) - begin - LibraryVariableStorage.Enqueue(Message); - end; - // Then verify in test body after the action - ``` - -7. **TestField → Assert.AreEqual** - ```al - // BEFORE (wrong): - GenJnlLine.TestField("IRS 1099 Reporting Period", NewPeriodNo); - - // AFTER (correct): - Assert.AreEqual(NewPeriodNo, GenJnlLine."IRS 1099 Reporting Period", 'Reporting period is incorrect'); - ``` - diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/codeunits.instructions.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/codeunits.instructions.md deleted file mode 100644 index 2baf7497e..000000000 --- a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/codeunits.instructions.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -applyTo: "**/*.Codeunit.al" ---- - -# Codeunit Development Guidelines - -## Purpose -Codeunits are procedural objects containing AL code. They're the primary way to organize business logic in Business Central. diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/pages.instructions.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/pages.instructions.md deleted file mode 100644 index 5437c4346..000000000 --- a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/pages.instructions.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -applyTo: "**/*.Page.al" ---- - -# Page Development Guidelines - -## Purpose -Pages define the user interface for viewing and editing data in Business Central. diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/tables.instructions.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/tables.instructions.md deleted file mode 100644 index 1d38bd821..000000000 --- a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/instructions/tables.instructions.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -applyTo: "**/*.Table.al" ---- - -# Table Development Guidelines - -## Purpose -Tables define data structures and are the foundation of Business Central's data model. diff --git a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/al-test-generation/SKILL.md b/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/al-test-generation/SKILL.md deleted file mode 100644 index 6817e6319..000000000 --- a/src/bcbench/agent/shared/instructions/microsoftInternal-NAV/skills/al-test-generation/SKILL.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: al-test-generation -description: Guide for creating AL tests for Microsoft Dynamics 365 Business Central. Use this when asked to write, create, or generate AL test codeunits, test procedures, or test automation for Business Central. ---- - -To create AL tests for Microsoft Dynamics 365 Business Central, follow this process: - -## 1. Analyze the Code Under Test - -Before writing any test code: -1. Read and understand the procedure or functionality being tested -2. Trace through all code paths to identify UI interactions -3. Examine table definitions for TableRelation constraints - -## 2. Identify Required Handler Methods - -**CRITICAL: Tests fail with "Unhandled UI" errors when handlers are missing.** - -Look for these patterns in the code under test: - -| Code Pattern | Required Handler | -| ------------------------------------- | --------------------------- | -| `Confirm()` | `[ConfirmHandler]` | -| `Message()` | `[MessageHandler]` | -| `StrMenu()` | `[StrMenuHandler]` | -| `Page.Run()` | `[PageHandler]` | -| `Page.RunModal()` | `[ModalPageHandler]` | -| `Report.Run()` or `Report.RunModal()` | `[ReportHandler]` | -| Report request page | `[RequestPageHandler]` | -| `Hyperlink()` | `[HyperlinkHandler]` | -| `Notification.Send()` | `[SendNotificationHandler]` | - -## 3. Analyze TableRelation Constraints - -**CRITICAL: Tests fail with validation errors when inserting data that violates TableRelation constraints.** - -Before inserting test data: -1. Read the table definition for all fields receiving values -2. Identify fields with `TableRelation` properties -3. Ensure related records exist before inserting test data -4. Use Library functions (e.g., `LibrarySales`, `LibraryPurchase`) to create prerequisite data - -## 4. Write Test Structure - -Follow the AAA pattern (Arrange-Act-Assert): - -```AL -[Test] -[HandlerFunctions('RequiredHandlers')] -procedure TestProcedureName() -begin - // [GIVEN] Setup test data and preconditions - Initialize(); - CreateTestData(); - - // [WHEN] Execute the action being tested - ExecuteAction(); - - // [THEN] Verify the expected results - VerifyResults(); -end; -``` - -## 5. Handler Method Signatures - -```AL -[ConfirmHandler] -procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean) -begin - Reply := true; -end; - -[MessageHandler] -procedure MessageHandler(Message: Text[1024]) -begin - // Empty - suppresses message display -end; - -[ModalPageHandler] -procedure ModalPageHandler(var TestPage: TestPage "Page Name") -begin - TestPage.OK().Invoke(); -end; -``` - -## 6. Best Practices - -- Use descriptive test procedure names that explain what is being tested -- One assertion concept per test -- Use Library Variable Storage to pass data between handlers and tests -- Do NOT verify values inside handler procedures -- Clean up test data in teardown or use transaction rollback -- Use `Initialize()` procedure to set up common test fixtures diff --git a/tests/test_agent_skills.py b/tests/test_agent_skills.py index d89555f43..2e03eaf53 100644 --- a/tests/test_agent_skills.py +++ b/tests/test_agent_skills.py @@ -87,7 +87,7 @@ def test_overwrite_skill_folder_files(): - unrelated files should be removed (replace semantics) """ skills_source = _get_source_instructions_path("microsoftInternal/NAV") / "skills" - source_skill_dir = skills_source / "al-test-generation" + source_skill_dir = skills_source / "caveman" with TemporaryDirectory() as tmpdir: repo_path = Path(tmpdir) @@ -96,7 +96,7 @@ def test_overwrite_skill_folder_files(): config = {"skills": {"enabled": True}} # Target skill folder - target_skill_dir = repo_path / ".github" / "skills" / "al-test-generation" + target_skill_dir = repo_path / ".github" / "skills" / "caveman" target_skill_dir.mkdir(parents=True, exist_ok=True) # 1. Create conflicting file (same name, different content) @@ -133,7 +133,7 @@ def test_path_specific_skills_copied(): assert target_skills_dir.exists(), "Skills folder should be created" # Verify that at least some skill files exist - sample_skill_file = target_skills_dir / "al-test-generation" / "SKILL.md" + sample_skill_file = target_skills_dir / "caveman" / "SKILL.md" assert sample_skill_file.exists(), "Sample skill file should exist" @@ -145,7 +145,7 @@ def test_path_specific_skills_removed_before_copy(): config = {"skills": {"enabled": True}} # Create existing .github/skills directory with old files - skills_dir = repo_path / ".github" / "skills" / "al-test-generation" + skills_dir = repo_path / ".github" / "skills" / "caveman" skills_dir.mkdir(parents=True, exist_ok=True) old_file = skills_dir / "OLD_SKILL.md" old_file.write_text("OLD SKILL CONTENT") @@ -157,7 +157,7 @@ def test_path_specific_skills_removed_before_copy(): assert not old_file.exists(), "Old skill file should be removed" # Verify new skill file exists - new_skill_file = repo_path / ".github" / "skills" / "al-test-generation" / "SKILL.md" + new_skill_file = repo_path / ".github" / "skills" / "caveman" / "SKILL.md" assert new_skill_file.exists(), "New skill file should exist" From 1a552b7cb8d022189a3e9255c16216659dbc5c4e Mon Sep 17 00:00:00 2001 From: "Haoran Sun (Business Central)" Date: Thu, 21 May 2026 14:43:37 +0200 Subject: [PATCH 3/3] run on the fule dataset --- dataset/bcbench.jsonl | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/dataset/bcbench.jsonl b/dataset/bcbench.jsonl index c9fef5a01..54796b9fb 100644 --- a/dataset/bcbench.jsonl +++ b/dataset/bcbench.jsonl @@ -1,16 +1,101 @@ {"metadata": {"area": "sustainability", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-210528", "base_commit": "1a672853b5e939932b2b9caff994bef826e928ff", "created_at": "2025-03-19", "environment_setup_version": "26.5", "project_paths": ["App\\Apps\\W1\\Sustainability\\app", "App\\Apps\\W1\\Sustainability\\test"], "FAIL_TO_PASS": [{"codeunitID": 148187, "functionName": ["VerifyEmissionFieldsMustBeEnabledWhenEnableValueChainTrackingIsEnabled"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al b/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al\nindex ff9b7640fa2..07bfdfa1233 100644\n--- a/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al\n+++ b/App/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al\n@@ -5123,6 +5123,47 @@ codeunit 148187 \"Sust. Certificate Test\"\n // [THEN] Confirmation Box should not pop up as there is no confirm Handler. \n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerYes')]\n+ procedure VerifyEmissionFieldsMustBeEnabledWhenEnableValueChainTrackingIsEnabled()\n+ var\n+ SustainabilitySetup: Record \"Sustainability Setup\";\n+ begin\n+ // [SCENARIO 569462] Verify \"Use Emissions In Purch. Doc.\", \"Item Emissions\", \"Resource Emissions\", \"Work/Machine Center Emissions\" must be enabled in Sustainability Setup.\n+ // When \"Enable Value Chain Tracking\" is enabled.\n+ LibrarySustainability.CleanUpBeforeTesting();\n+\n+ // [GIVEN] Update Sustainability Setup.\n+ SustainabilitySetup.Get();\n+ SustainabilitySetup.Validate(\"Use Emissions In Purch. Doc.\", false);\n+ SustainabilitySetup.Validate(\"Item Emissions\", false);\n+ SustainabilitySetup.Validate(\"Resource Emissions\", false);\n+ SustainabilitySetup.Validate(\"Work/Machine Center Emissions\", false);\n+ SustainabilitySetup.Validate(\"Enable Value Chain Tracking\", false);\n+ SustainabilitySetup.Modify();\n+\n+ // [WHEN] \"Enable Value Chain Tracking\" set to true in Sustainability Setup.\n+ SustainabilitySetup.Validate(\"Enable Value Chain Tracking\", true);\n+\n+ // [THEN] Verify \"Use Emissions In Purch. Doc.\", \"Item Emissions\", \"Resource Emissions\", \"Work/Machine Center Emissions\" must be enabled in Sustainability Setup.\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Use Emissions In Purch. Doc.\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Use Emissions In Purch. Doc.\"), SustainabilitySetup.TableCaption()));\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Item Emissions\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Item Emissions\"), SustainabilitySetup.TableCaption()));\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Resource Emissions\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Resource Emissions\"), SustainabilitySetup.TableCaption()));\n+ Assert.AreEqual(\n+ true,\n+ SustainabilitySetup.\"Work/Machine Center Emissions\",\n+ StrSubstNo(FieldShouldBeEnabledErr, SustainabilitySetup.FieldCaption(\"Work/Machine Center Emissions\"), SustainabilitySetup.TableCaption()));\n+ end;\n+\n local procedure CreateSustainabilityAccount(var AccountCode: Code[20]; var CategoryCode: Code[20]; var SubcategoryCode: Code[20]; i: Integer): Record \"Sustainability Account\"\n begin\n CreateSustainabilitySubcategory(CategoryCode, SubcategoryCode, i);\n", "patch": "diff --git a/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al b/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al\nindex 335c0099f4a..bf9281c17f7 100644\n--- a/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al\n+++ b/App/Apps/W1/Sustainability/app/src/Setup/SustainabilitySetup.Table.al\n@@ -151,6 +151,8 @@ table 6217 \"Sustainability Setup\"\n if Rec.\"Enable Value Chain Tracking\" then\n if not ConfirmManagement.GetResponseOrDefault(ConfirmEnableValueChainTrackingQst, false) then\n Error('');\n+\n+ EnableEmissionsWhenValueChainTrackingIsEnabled();\n end;\n }\n }\n@@ -188,6 +190,17 @@ table 6217 \"Sustainability Setup\"\n exit(\"Enable Value Chain Tracking\");\n end;\n \n+ local procedure EnableEmissionsWhenValueChainTrackingIsEnabled()\n+ begin\n+ if not Rec.\"Enable Value Chain Tracking\" then\n+ exit;\n+\n+ Rec.Validate(\"Use Emissions In Purch. Doc.\", true);\n+ Rec.Validate(\"Item Emissions\", true);\n+ Rec.Validate(\"Resource Emissions\", true);\n+ Rec.Validate(\"Work/Machine Center Emissions\", true);\n+ end;\n+\n internal procedure GetFormat(FieldNo: Integer): Text\n begin\n GetSustainabilitySetup();\n"} +{"metadata": {"area": "inventory", "image_count": 0, "commnet": "Test might be insuffient"}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-224009", "base_commit": "719cf1cc85730da9c59cdcb0ac18ddaf11d113fd", "created_at": "2025-08-16", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137045, "functionName": ["CheckTrackingReservationEntriesUpdatedWheLotNoAllocated"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\nindex bfcb627e6e5..f8db5ec3cf2 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n@@ -1217,6 +1217,76 @@ codeunit 137045 \"SCM Bugfixes\"\n AssertReservationEntryCountForSales(SalesHeader, 3);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandlerOrderTracking,ItemTrackingLinesPageHandler')]\n+ procedure CheckTrackingReservationEntriesUpdatedWheLotNoAllocated()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ UnitofMeasure: Record \"Unit of Measure\";\n+ InventoryPostingSetup: Record \"Inventory Posting Setup\";\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ReservationEntry, ReservationEntry1 : Record \"Reservation Entry\";\n+ LotNo, LotNo1, LotNo2 : Code[50];\n+ begin\n+ // [SCENARIO 580079] Wrong Decimal Rounding with Quantity in Reservation Entries, using Order Tracking Policy where tracking lines are split into 3, each ending in x.xxxx7, which results with all 3 adding up to x.00001\n+ Initialize();\n+\n+ // [GIVEN] Created Lot Tracked Item.\n+ CreateTrackedItemWithOrderTrackingPolicy(Item);\n+\n+ // [GIVEN] Create new UOM for CASE (CA), Qty 24 Per Base UOM of PCS\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitofMeasure);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure, Item.\"No.\", UnitofMeasure.Code, 24);\n+\n+ // [GIVEN] Create Location\n+ LibraryWarehouse.CreateLocation(Location);\n+\n+ // [GIVEN] Create Inventory Posting Setup with Inventory Account\n+ LibraryInventory.CreateInventoryPostingSetup(InventoryPostingSetup, Location.Code, Item.\"Inventory Posting Group\");\n+ InventoryPostingSetup.Validate(\"Inventory Account\", LibraryERM.CreateGLAccountNo());\n+ InventoryPostingSetup.Modify();\n+\n+ // [GIVEN] Create Positive Adjustment for 288 Quantity with 1 Lot No\n+ LotNo := LibraryUtility.GenerateGUID();\n+ CreateItemJournalLineItemTrackingEnabled(ItemJournalLine, Item.\"No.\", Location.Code, 288);\n+ LibraryItemTracking.CreateItemJournalLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo, 288);\n+ LibraryInventory.PostItemJnlLineWithCheck(ItemJournalLine);\n+\n+ // [GIVEN] Create Positive Adjustment for 440 Quantity with 2 different Lot\n+ LotNo1 := LibraryUtility.GenerateGUID();\n+ LotNo2 := LibraryUtility.GenerateGUID();\n+ CreateItemJournalLineItemTrackingEnabled(ItemJournalLine, Item.\"No.\", Location.Code, 440);\n+ LibraryItemTracking.CreateItemJournalLineItemTracking(ReservationEntry, ItemJournalLine, '', LotNo1, 220);\n+ LibraryItemTracking.CreateItemJournalLineItemTracking(ReservationEntry1, ItemJournalLine, '', LotNo2, 220);\n+ LibraryInventory.PostItemJnlLineWithCheck(ItemJournalLine);\n+\n+ // [GIVEN] Created Sales Order with 1 Item and 3 quantity.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, '');\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", 12);\n+ SalesLine.Validate(\"Location Code\", Location.Code);\n+ SalesLine.Validate(\"Unit of Measure Code\", UnitofMeasure.Code);\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] From Item tracking lines (Sales Order), add a Lot No to the item.\n+ LibraryVariableStorage.Enqueue(ItemTrackingHandlerAction::AssignSpecificLot);\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(288);\n+ SalesLine.OpenItemTrackingLines(); // ItemTrackingLinesPageHandler required.\n+\n+ // [WHEN] Change the quantity from Item tracking lines (Sales Order), of a Lot No to 13.\n+ LibraryVariableStorage.Enqueue(ItemTrackingHandlerAction::AssignSpecificLot);\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(13);\n+ SalesLine.OpenItemTrackingLines(); // ItemTrackingLinesPageHandler required.\n+\n+ // [THEN] Reservation entry Quantity field should come with -12\n+ VerifyReservationEntryQuantity(Item.\"No.\", SalesHeader.\"No.\", -12);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1310,6 +1380,23 @@ codeunit 137045 \"SCM Bugfixes\"\n LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n end;\n \n+ local procedure CreateItemJournalLineItemTrackingEnabled(var ItemJournalLine: Record \"Item Journal Line\"; ItemNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal)\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, \"Item Journal Template Type\"::Item);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, \"Item Journal Template Type\"::Item, ItemJournalTemplate.Name);\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+ ItemJournalBatch.\"Item Tracking on Lines\" := true;\n+ ItemJournalBatch.Modify();\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", ItemNo, Quantity);\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n local procedure CreateCertifiedProductionBOMWithComponentStartingDate(var ProductionBOMHeader: Record \"Production BOM Header\"; UOMCode: Code[10]; ItemNo: Code[20]; QtyPer: Decimal; StartingDate: Date)\n var\n ProductionBOMLine: Record \"Production BOM Line\";\n@@ -1985,6 +2072,16 @@ codeunit 137045 \"SCM Bugfixes\"\n Assert.RecordCount(ReservationEntry, ExpectedCount);\n end;\n \n+ local procedure VerifyReservationEntryQuantity(ItemNo: Code[20]; SourceID: Code[20]; ExpectedQuantity: Decimal)\n+ var\n+ ReservEntry: Record \"Reservation Entry\";\n+ begin\n+ ReservEntry.SetRange(\"Item No.\", ItemNo);\n+ ReservEntry.SetRange(\"Source ID\", SourceID);\n+ ReservEntry.CalcSums(Quantity);\n+ ReservEntry.TestField(Quantity, ExpectedQuantity);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListModalPageHandler(var ContactLookup: Page \"Contact List\"; var Response: Action)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\nindex c1b41b1585b..a37726d678f 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n@@ -914,7 +914,7 @@ table 337 \"Reservation Entry\"\n ReservEntry.SetFilter(\"Entry No.\", '<>%1', \"Entry No.\");\n ReservEntry.SetSourceFilter(\"Source Type\", \"Source Subtype\", \"Source ID\", \"Source Ref. No.\", false);\n ReservEntry.SetSourceFilter(\"Source Batch Name\", \"Source Prod. Order Line\");\n- ReservEntry.SetRange(\"Reservation Status\", \"Reservation Status\"::Reservation);\n+ ReservEntry.SetFilter(\"Reservation Status\", '%1|%2', \"Reservation Status\"::Reservation, \"Reservation Status\"::Tracking);\n ReservEntry.CalcSums(\"Quantity (Base)\", Quantity);\n exit(\n Round((ReservEntry.\"Quantity (Base)\" + \"Quantity (Base)\") / \"Qty. per Unit of Measure\", UOMMgt.QtyRndPrecision()) -\n"} {"metadata": {"area": "shopify", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-211710", "base_commit": "f787c24e811a24e4bd5a2d987ea406b3d2fe6ad0", "created_at": "2025-03-31", "environment_setup_version": "26.5", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139648, "functionName": ["UnitTestSuggestShopifyPaymentsFailedTransaction"]}], "PASS_TO_PASS": [{"codeunitID": 139648, "functionName": ["UnitTestSuggestShopifyPaymentsMultipleTransactions", "UnitTestSuggestShopifyPaymentsOneTransaction"]}], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\nindex d4318405610..cf234743596 100644\n--- a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n+++ b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n@@ -32,7 +32,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n \n // [GIVEN] Shopify transaction is imported\n- CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale);\n+ CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n \n // [WHEN] Create Shopify transactions are run\n OrderTransaction.FindFirst();\n@@ -65,8 +65,8 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n \n // [GIVEN] Shopify transactions are imported\n- CreateOrderTransaction(OrderId, Amount * 0.75, 'manual', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale);\n+ CreateOrderTransaction(OrderId, Amount * 0.75, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n \n // [WHEN] Create Shopify transactions are run\n OrderTransaction.SetRange(\"Shopify Order Id\", OrderId);\n@@ -86,6 +86,45 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n until SuggestPayment.Next() = 0;\n end;\n \n+ [HandlerFunctions('SuggestShopifyPaymentsRequestPageHandler')]\n+ [Test]\n+ procedure UnitTestSuggestShopifyPaymentsFailedTransaction()\n+ var\n+ Item: Record Item;\n+ Customer: Record Customer;\n+ OrderTransaction: Record \"Shpfy Order Transaction\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ CashReceiptJournal: TestPage \"Cash Receipt Journal\";\n+ OrderId: BigInteger;\n+ SuccessTransactionId: BigInteger;\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO] Suggest Shopify payments does not create Cash Receipt Journal lines for failed transactions\n+ // [GIVEN] Invoice is posted\n+ Initialize();\n+ Amount := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(10000, 99999);\n+ CreateItem(Item, Amount);\n+ LibrarySales.CreateCustomer(Customer);\n+ CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n+\n+ // [GIVEN] One failed one success Shopify transaction is imported\n+ CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Failure);\n+ SuccessTransactionId := CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ Commit();\n+\n+ // [WHEN] Report is run\n+ CashReceiptJournal.OpenView();\n+ CashReceiptJournal.SuggestShopifyPayments.Invoke();\n+\n+ // [THEN] Only one Cash Receipt Journal line is created\n+ GenJournalLine.SetRange(\"Document Type\", GenJournalLine.\"Document Type\"::Payment);\n+ GenJournalLine.SetRange(\"Account No.\", Customer.\"No.\");\n+ LibraryAssert.RecordCount(GenJournalLine, 1);\n+ GenJournalLine.FindFirst();\n+ LibraryAssert.AreEqual(GenJournalLine.\"Shpfy Transaction Id\", SuccessTransactionId, 'Transaction Ids should match');\n+ end;\n+\n [HandlerFunctions('SuggestShopifyPaymentsRequestPageHandler')]\n [Test]\n procedure UnitTestSuggestShopifyPaymentsJournalLines()\n@@ -114,10 +153,10 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesInvoice(Item, Customer, 2, OrderId3);\n \n // [GIVEN] Shopify transactions are imported\n- CreateOrderTransaction(OrderId1, Amount, 'manual', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId2, Amount * 0.75, 'manual', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId2, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale);\n- CreateOrderTransaction(OrderId3, Amount * 2, 'bogus', OrderTransaction.Type::Sale);\n+ CreateOrderTransaction(OrderId1, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId2, Amount * 0.75, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId2, Amount * 0.25, 'gift_card', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId3, Amount * 2, 'bogus', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n Commit();\n \n // [WHEN] Report is run\n@@ -154,7 +193,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n CreateAndPostSalesCreditMemo(Item, Customer, 1, RefundId);\n \n // [GIVEN] Shopify transaction is imported\n- CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Refund);\n+ CreateOrderTransaction(OrderId, Amount, 'manual', OrderTransaction.Type::Refund, OrderTransaction.Status::Success);\n \n // [WHEN] Create Shopify transactions are run\n OrderTransaction.FindFirst();\n@@ -210,7 +249,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n Item.Modify(true);\n end;\n \n- local procedure CreateOrderTransaction(OrderId: BigInteger; Amount: Decimal; Gateway: Code[20]; TransactionType: Enum \"Shpfy Transaction Type\")\n+ local procedure CreateOrderTransaction(OrderId: BigInteger; Amount: Decimal; Gateway: Code[20]; TransactionType: Enum \"Shpfy Transaction Type\"; Status: Enum \"Shpfy Transaction Status\"): BigInteger\n var\n OrderTransaction: Record \"Shpfy Order Transaction\";\n begin\n@@ -219,7 +258,9 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n OrderTransaction.Amount := Amount;\n OrderTransaction.Gateway := Gateway;\n OrderTransaction.Type := TransactionType;\n+ OrderTransaction.Status := Status;\n OrderTransaction.Insert();\n+ exit(OrderTransaction.\"Shopify Transaction Id\");\n end;\n \n local procedure CreateRefund(OrderId: BigInteger; RefundId: BigInteger; Amount: Decimal)\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\nindex 773ba116023..274900e6ee5 100644\n--- a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n+++ b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n@@ -17,7 +17,7 @@ report 30118 \"Shpfy Suggest Payments\"\n dataitem(OrderTransaction; \"Shpfy Order Transaction\")\n {\n RequestFilterFields = \"Created At\";\n- DataItemTableView = sorting(Type) where(Type = filter(Capture | Sale | Refund));\n+ DataItemTableView = sorting(Type) where(Type = filter(Capture | Sale | Refund), Status = filter(Success));\n \n trigger OnAfterGetRecord()\n begin\n"} +{"metadata": {"area": "manufacturing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220984", "base_commit": "da8aacf769f29847b57739a6db797e65057ea268", "created_at": "2025-07-15", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Manufacturing"], "FAIL_TO_PASS": [{"codeunitID": 137404, "functionName": ["ExchangeProductionBOMItemShouldSetEndingDate"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al b/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al\nindex f6545527796..b7f7674ae29 100644\n--- a/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Manufacturing/SCMManufacturing.Codeunit.al\n@@ -4829,6 +4829,54 @@ codeunit 137404 \"SCM Manufacturing\"\n Assert.AreEqual(StandardTask.Code, ProdOrderLine.\"Standard Task Code\", StandardTaskFieldErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('RunExchangeProdBOMItemReportWithStartDateParameter')]\n+ procedure ExchangeProductionBOMItemShouldSetEndingDate()\n+ var\n+ Item: array[5] of Record Item;\n+ MainItem: Record Item;\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ i: Integer;\n+ begin\n+ // [SCENARIO 592157] Replacing a component in a Production BOM should set the Ending Date of the replaced component.\n+ Initialize();\n+\n+ LibraryInventory.CreateItem(MainItem);\n+ MainItem.Validate(\"Replenishment System\", MainItem.\"Replenishment System\"::\"Prod. Order\");\n+ MainItem.Modify(true);\n+\n+ // [GIVEN] Create a Production BOM Header\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, MainItem.\"Base Unit of Measure\");\n+\n+ // [GIVEN] Create Items\n+ for i := 1 to 5 do\n+ LibraryInventory.CreateItem(Item[i]);\n+\n+ // [GIVEN] Add only Items[1..4] to the BOM\n+ for i := 1 to 4 do\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, Item[i].\"No.\", LibraryRandom.RandIntInRange(10, 20));\n+\n+ // [GIVEN] Certify BOM and assign to Main Item\n+ ModifyStatusInProductionBOM(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+ MainItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ MainItem.Modify(true);\n+\n+ // [GIVEN] Enqueue parameter values for report\n+ EnqueueExchProdBOMItemReportParameter(Item[1].\"No.\", Item[5].\"No.\", Today);\n+\n+ // [WHEN] Run the Exchange Production BOM Item report\n+ RunExchangeProductionBOMItemReport();\n+\n+ // [THEN] Validate that the replaced item has an Ending Date of (StartDate - 1)\n+ ValidateEndingDateSet(ProductionBOMHeader.\"No.\", Item[1].\"No.\", Today);\n+\n+ // [AND] Ensure no test artifacts are left behind\n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -7704,6 +7752,23 @@ codeunit 137404 \"SCM Manufacturing\"\n standardTask.Modify(true);\n end;\n \n+ local procedure EnqueueExchProdBOMItemReportParameter(ExchangeItemNo: Code[20]; ReplaceItemNo: Code[20]; StartDate: Date)\n+ begin\n+ LibraryVariableStorage.Enqueue(ExchangeItemNo);\n+ LibraryVariableStorage.Enqueue(ReplaceItemNo);\n+ LibraryVariableStorage.Enqueue(StartDate);\n+ end;\n+\n+ local procedure ValidateEndingDateSet(ProdBOMHeaderNo: Code[20]; ItemNo: Code[20]; StartingDate: Date)\n+ var\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ begin\n+ ProductionBOMLine.SetRange(\"Production BOM No.\", ProdBOMHeaderNo);\n+ ProductionBOMLine.SetRange(\"No.\", ItemNo);\n+ ProductionBOMLine.FindFirst();\n+ Assert.AreEqual(StartingDate - 1, ProductionBOMLine.\"Ending Date\", 'Ending Date is not correctly set on the Production BOM line.')\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ProdBOMVersionComparisonHandlerForActionSet(var ProdBOMVersionComparison: TestPage \"Prod. BOM Version Comparison\")\n@@ -7793,5 +7858,28 @@ codeunit 137404 \"SCM Manufacturing\"\n ExchangeProductionBOMItem.WithType.AssertEquals(ProductionBOMLineType::Item);// [THEN] Verify WithType Default Type is ITEM\n ExchangeProductionBOMItem.OK().Invoke();\n end;\n+\n+ [RequestPageHandler]\n+ procedure RunExchangeProdBOMItemReportWithStartDateParameter(var ExchangeProductionBOMItem: TestRequestPage \"Exchange Production BOM Item\")\n+ var\n+ FromProductionBOMLineType: Enum \"Production BOM Line Type\";\n+ ExchangeItemNo: Variant;\n+ ReplaceItemNo: Variant;\n+ StartDate: Variant;\n+ begin\n+ ExchangeItemNo := LibraryVariableStorage.DequeueText();\n+ ReplaceItemNo := LibraryVariableStorage.DequeueText();\n+ StartDate := LibraryVariableStorage.DequeueDate();\n+ ExchangeProductionBOMItem.ExchangeType.SetValue(FromProductionBOMLineType::Item);\n+ ExchangeProductionBOMItem.ExchangeNo.SetValue(ExchangeItemNo);\n+ ExchangeProductionBOMItem.WithType.SetValue(FromProductionBOMLineType::Item);\n+ ExchangeProductionBOMItem.WithNo.SetValue(ReplaceItemNo);\n+ ExchangeProductionBOMItem.\"Create New Version\".SetValue(false);\n+ ExchangeProductionBOMItem.\"Delete Exchanged Component\".SetValue(false);\n+ ExchangeProductionBOMItem.Recertify.SetValue(true);\n+ ExchangeProductionBOMItem.CopyRoutingLink.SetValue(true);\n+ ExchangeProductionBOMItem.StartingDate.SetValue(StartDate);\n+ ExchangeProductionBOMItem.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al b/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al\nindex 83bf3f09247..fc62ac19292 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/ProductionBOM/ExchangeProductionBOMItem.Report.al\n@@ -157,7 +157,7 @@ report 99001043 \"Exchange Production BOM Item\"\n CopyPositionFields(ProductionBOMLine2, ProductionBOMLine3);\n ShouldModifyProductionBOMLine := true;\n OnIntegerOnPostDataItemOnBeforeModifyProductionBOMLine(ProductionBOMLine, ShouldModifyProductionBOMLine);\n- if not ShouldModifyProductionBOMLine then begin\n+ if ShouldModifyProductionBOMLine then begin\n ProductionBOMLine.\"Ending Date\" := StartingDate - 1;\n ProductionBOMLine.Modify();\n end;\n"} {"metadata": {"area": "visualization", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-224668", "base_commit": "e99adb71b2355dc29eb398ab9ae0d59003a84d5d", "created_at": "2025-08-25", "environment_setup_version": "27.0", "project_paths": ["App\\Apps\\W1\\EssentialBusinessHeadlines\\app", "App\\Apps\\W1\\EssentialBusinessHeadlines\\test"], "FAIL_TO_PASS": [{"codeunitID": 139600, "functionName": ["TestHeadlineCanBeHidden"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al b/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al\nindex db731e8675d..fb82838356c 100644\n--- a/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al\n+++ b/App/Apps/W1/EssentialBusinessHeadlines/test/src/codeunits/TestEssentialBusHeadlines.Codeunit.al\n@@ -700,6 +700,33 @@ codeunit 139600 \"Test Essential Bus. Headlines\"\n TestRecentlyOverdueInvoiceWithOverdueInvoices(5);\n end;\n \n+ [Test]\n+ procedure TestHeadlineCanBeHidden()\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ begin\n+ // [GIVEN] Initial state when no data is present\n+ Initialize();\n+\n+ // [GIVEN] One invoice that was due yesterday\n+ CreateInvoicesWithDueDateYesterday(1);\n+\n+ // [WHEN] Run the headline computation\n+ EssentialBusHeadlineMgt.HandleRecentlyOverdueInvoices();\n+\n+ // [THEN] Recently overdue invoices headline is visible\n+ Assert.IsTrue(GetVisibility(EssentialBusinessHeadline.\"Headline Name\"::RecentlyOverdueInvoices), 'Expected recently overdue invoices headline to be visible');\n+\n+ // [WHEN] Simulate no more overdue invoices by deleting all customer ledger entries\n+ CustLedgerEntry.DeleteAll();\n+\n+ // [WHEN] Recompute the headline computation\n+ EssentialBusHeadlineMgt.HandleRecentlyOverdueInvoices();\n+\n+ // [THEN] The headline is hidden\n+ Assert.IsFalse(GetVisibility(EssentialBusinessHeadline.\"Headline Name\"::RecentlyOverdueInvoices), 'Expected recently overdue invoices headline to be not visible after recompute');\n+ end;\n+\n local procedure TestRecentlyOverdueInvoiceWithOverdueInvoices(NumberOfNewlyOverdueInvoices: Integer)\n var\n OverdueInvoicesTxt: Text;\n", "patch": "diff --git a/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al b/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al\nindex 831aa80efcd..10436a095d8 100644\n--- a/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al\n+++ b/App/Apps/W1/EssentialBusinessHeadlines/app/src/codeunits/EssentialBusHeadlineMgt.Codeunit.al\n@@ -677,7 +677,7 @@ codeunit 1437 \"Essential Bus. Headline Mgt.\"\n var\n EssentialBusinessHeadline: Record \"Ess. Business Headline Per Usr\";\n begin\n- if EssentialBusinessHeadline.Get(HeadlineName) then begin\n+ if EssentialBusinessHeadline.Get(HeadlineName, UserSecurityId()) then begin\n EssentialBusinessHeadline.Validate(\"Headline Visible\", false);\n EssentialBusinessHeadline.Modify();\n end;\n"} +{"metadata": {"area": "finance", "image_count": 0, "commnet": "Test might be insuffient"}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218323", "base_commit": "cf24533288281b2df45cbb33654a17f430a0619f", "created_at": "2025-06-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134992, "functionName": ["PostVATSettlementWhenJournalTemplateNameMandatoryIsEnabled"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al\nindex 5c994880ad2..b8c9d7f62bd 100644\n--- a/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMFinancialReportsIV.Codeunit.al\n@@ -765,6 +765,53 @@ codeunit 134992 \"ERM Financial Reports IV\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('RHCalcAndPostVATSettlementSetCountryFilter')]\n+ procedure PostVATSettlementWhenJournalTemplateNameMandatoryIsEnabled()\n+ var\n+ Customer: Record Customer;\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ VATEntry: Record \"VAT Entry\";\n+ GLEntry: Record \"G/L Entry\";\n+ MyNotifications: Record \"My Notifications\";\n+ GeneralLedgerSetup: Record \"General Ledger Setup\";\n+ InstructionMgt: Codeunit \"Instruction Mgt.\";\n+ PostingDate: Date;\n+ begin\n+ // [SCENARIO 571198] No error should appears when user try to Calculate and Post VAT Settlement when Journal Template Name Mandatory is enabled\n+ Initialize();\n+\n+ // [GIVEN] Set Journal Templ. Name Mandatory to false on General ledger Setup.\n+ GeneralLedgerSetup.Get();\n+ GeneralLedgerSetup.\"Journal Templ. Name Mandatory\" := true;\n+ GeneralLedgerSetup.Modify();\n+\n+ MyNotifications.Disable(InstructionMgt.GetPostingAfterWorkingDateNotificationId());\n+ GLEntry.SetCurrentKey(\"Posting Date\", \"G/L Account No.\", \"Dimension Set ID\");\n+ GLEntry.FindLast();\n+ PostingDate := GLEntry.\"Posting Date\" + 1;\n+\n+ // [GIVEN] Create customer and post a sales invoice\n+ LibrarySales.CreateCustomerWithCountryCodeAndVATRegNo(Customer);\n+ CreateAndPostGeneralJournalLine(\n+ VATPostingSetup, PostingDate, GenJournalLine.\"Account Type\"::Customer, Customer.\"No.\",\n+ GenJournalLine.\"Gen. Posting Type\"::Sale, 1, true);\n+\n+ LibraryVariableStorage.Enqueue(Customer.\"Country/Region Code\"); // set country/region filter for RHCalcAndPostVATSettlementSetCountryFilter\n+ Clear(LibraryReportDataset);\n+\n+ // [WHEN] Run Calculate and Post VAT Settlement report\n+ SaveCalcAndPostVATSettlementReport(VATPostingSetup, PostingDate, PostingDate, PostingDate, Format(LibraryRandom.RandInt(100)), true);\n+\n+ // [THEN] VAT Entry for the second invoice is closed\n+ // [THEN] Closing entry created with type 'Settlement'\n+ VATEntry.SetRange(\"Bill-to/Pay-to No.\", Customer.\"No.\");\n+ VATEntry.FindFirst();\n+ VATEntry.Get(VATEntry.\"Closed by Entry No.\");\n+ VATEntry.TestField(Type, VATEntry.Type::Settlement);\n+ end;\n+\n local procedure Initialize()\n var\n ObjectOptions: Record \"Object Options\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al\nindex c7ffd42ba4c..d596be8a7fd 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlCheckLine.Codeunit.al\n@@ -57,6 +57,7 @@ codeunit 11 \"Gen. Jnl.-Check Line\"\n OverrideDimErr: Boolean;\n LogErrorMode: Boolean;\n IsBatchMode: Boolean;\n+ IgnoreJournalTemplNameMandatoryCheck: Boolean;\n \n #pragma warning disable AA0074\n Text000: Label 'can only be a closing date for G/L entries';\n@@ -380,6 +381,11 @@ codeunit 11 \"Gen. Jnl.-Check Line\"\n OverrideDimErr := true;\n end;\n \n+ procedure SetIgnoreJournalTemplNameMandatoryCheck()\n+ begin\n+ IgnoreJournalTemplNameMandatoryCheck := true;\n+ end;\n+\n local procedure CheckDates(GenJnlLine: Record \"Gen. Journal Line\")\n var\n AccountingPeriodMgt: Codeunit \"Accounting Period Mgt.\";\n@@ -400,8 +406,9 @@ codeunit 11 \"Gen. Jnl.-Check Line\"\n end;\n end;\n \n- if GLSetup.\"Journal Templ. Name Mandatory\" then\n- GenJnlLine.TestField(\"Journal Template Name\", ErrorInfo.Create());\n+ if not IgnoreJournalTemplNameMandatoryCheck then\n+ if GLSetup.\"Journal Templ. Name Mandatory\" then\n+ GenJnlLine.TestField(\"Journal Template Name\", ErrorInfo.Create());\n OnBeforeDateNotAllowed(GenJnlLine, DateCheckDone);\n if not DateCheckDone then\n if DateNotAllowed(GenJnlLine.\"Posting Date\", GenJnlLine.\"Journal Template Name\") then\ndiff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al\nindex da61c5f2c5d..35021399a12 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al\n@@ -138,6 +138,7 @@ codeunit 12 \"Gen. Jnl.-Post Line\"\n MultiplePostingGroups: Boolean;\n SourceCodeSetupRead: Boolean;\n IsGLRegInserted: Boolean;\n+ IgnoreJournalTemplNameMandatoryCheck: Boolean;\n \n NeedsRoundingErr: Label '%1 needs to be rounded', Comment = '%1 - amount';\n PurchaseAlreadyExistsErr: Label 'Purchase %1 %2 already exists for this vendor.', Comment = '%1 = Document Type; %2 = Document No.';\n@@ -332,6 +333,8 @@ codeunit 12 \"Gen. Jnl.-Post Line\"\n if CheckLine then begin\n if OverrideDimErr then\n GenJnlCheckLine.SetOverDimErr();\n+ if IgnoreJournalTemplNameMandatoryCheck then\n+ GenJnlCheckLine.SetIgnoreJournalTemplNameMandatoryCheck();\n OnCheckGenJnlLineOnBeforeRunCheck(GenJournalLine);\n GenJnlCheckLine.RunCheck(GenJournalLine);\n end;\n@@ -7113,6 +7116,15 @@ codeunit 12 \"Gen. Jnl.-Post Line\"\n Error(DimMgt.GetDimValuePostingErr());\n end;\n \n+ /// \n+ /// Sets the global variable IgnoreJournalTemplNameMandatoryCheck for the current instance of the codeunit.\n+ /// If IgnoreJournalTemplNameMandatoryCheck is not set \"Journal Templ. Name Mandatory\" check is performed before gen. journal line \n+ /// \n+ procedure SetIgnoreJournalTemplNameMandatoryCheck()\n+ begin\n+ IgnoreJournalTemplNameMandatoryCheck := true;\n+ end;\n+\n local procedure IsGainLossAccount(CurrencyCode: Code[10]; GLAccNo: Code[20]): Boolean\n var\n Currency: Record Currency;\ndiff --git a/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al b/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al\nindex 88068be074e..f09dab3691a 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Reporting/CalcandPostVATSettlement.Report.al\n@@ -849,6 +849,7 @@ report 20 \"Calc. and Post VAT Settlement\"\n GenJnlLine, 0, DefaultDimSource, GenJnlLine.\"Source Code\",\n GenJnlLine.\"Shortcut Dimension 1 Code\", GenJnlLine.\"Shortcut Dimension 2 Code\", 0, 0);\n OnPostGenJnlLineOnBeforeGenJnlPostLineRun(GenJnlLine);\n+ GenJnlPostLine.SetIgnoreJournalTemplNameMandatoryCheck();\n GenJnlPostLine.Run(GenJnlLine);\n end;\n \n"} {"metadata": {"area": "eservice", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-193853", "base_commit": "a4732079d0c963a7104d5b5c534ee87f3cd105e7", "created_at": "2024-09-09", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\EnforcedDigitalVouchers\\app", "App\\Apps\\W1\\EnforcedDigitalVouchers\\test library", "App\\Apps\\W1\\EnforcedDigitalVouchers\\test"], "FAIL_TO_PASS": [{"codeunitID": 139515, "functionName": ["PostMultipleGeneralJournalLinesSamePostingDateDocNoOnlyFirstHasIncDoc"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al b/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al\nindex 304e94e908f6..d917601e5a98 100644\n--- a/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al\n+++ b/App/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al\n@@ -912,6 +912,59 @@ codeunit 139515 \"Digital Vouchers Tests\"\n UnbindSubscription(DigVouchersDisableEnforce);\n end;\n \n+ [Test]\n+ procedure PostMultipleGeneralJournalLinesSamePostingDateDocNoOnlyFirstHasIncDoc()\n+ var\n+ GenJournalLine: array[2] of Record \"Gen. Journal Line\";\n+ GenJournalLineToPost: Record \"Gen. Journal Line\";\n+ GenJournalTemplate: Record \"Gen. Journal Template\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ IncomingDocument: Record \"Incoming Document\";\n+ DigVouchersDisableEnforce: Codeunit \"Dig. Vouchers Disable Enforce\";\n+ DocNo: Code[20];\n+ i: Integer;\n+ begin\n+ // [SCENARIO 540097] Stan can post multiple general journals lines with same posting date and document number, only the first line has incoming document\n+\n+ Initialize();\n+ BindSubscription(DigVouchersDisableEnforce);\n+ // [GIVEN] Digital voucher feature is enabled\n+ EnableDigitalVoucherFeature();\n+ // [GIVEN] Digital voucher entry setup for general journal is \"Attachment\"\n+ InitSetupCheckOnly(\"Digital Voucher Entry Type\"::\"General Journal\", \"Digital Voucher Check Type\"::Attachment);\n+ // [GIVEN] General journal lines with the same template and batch are created\n+ // [GIVEN] General journal line \"X\" with \"Posting Date\" = 01.01.2024 and \"Document No.\" = \"X\"\n+ // [GIVEN] General journal line \"Y\" with \"Posting Date\" = 01.01.2024 and \"Document No.\" = \"X\"\n+ DocNo := LibraryUtility.GenerateGUID();\n+ LibraryERM.CreateGenJournalTemplate(GenJournalTemplate);\n+ LibraryERM.CreateGenJournalBatch(GenJournalBatch, GenJournalTemplate.Name);\n+ for i := 1 to ArrayLen(GenJournalLine) do begin\n+ LibraryJournals.CreateGenJournalLine(\n+ GenJournalLine[i], GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name,\n+ GenJournalLine[i].\"Document Type\"::Invoice, GenJournalLine[i].\"Account Type\"::\"G/L Account\",\n+ LibraryERM.CreateGLAccountNo(), GenJournalLine[i].\"Bal. Account Type\"::\"G/L Account\",\n+ LibraryERM.CreateGLAccountNo(), LibraryRandom.RandDec(100, 2));\n+ GenJournalLine[i].Validate(\"Document No.\", DocNo);\n+ GenJournalLine[i].Modify(true);\n+ end;\n+ // [GIVEN] Only journal line \"X\" has incoming document attached\n+ GenJournalLine[1].\"Incoming Document Entry No.\" := MockIncomingDocument();\n+ GenJournalLine[1].Modify(true);\n+\n+ GenJournalLineToPost.SetRange(\"Journal Template Name\", GenJournalBatch.\"Journal Template Name\");\n+ GenJournalLineToPost.SetRange(\"Journal Batch Name\", GenJournalBatch.Name);\n+ GenJournalLineToPost.FindSet();\n+ // [WHEN] Post both general journal lines\n+ Codeunit.Run(Codeunit::\"Gen. Jnl.-Post Batch\", GenJournalLineToPost);\n+\n+ // [THEN] Posting is successfull and we have an incoming document with \"Posting Date\" = 01.01.2024 and \"Document No.\" = \"X\"\n+ IncomingDocument.SetRange(\"Posting Date\", GenJournalLine[1].\"Posting Date\");\n+ IncomingDocument.SetRange(\"Document No.\", GenJournalLine[1].\"Document No.\");\n+ Assert.RecordIsNotEmpty(IncomingDocument);\n+\n+ UnbindSubscription(DigVouchersDisableEnforce);\n+ end;\n+\n local procedure Initialize()\n var\n CompanyInformation: Record \"Company Information\";\n@@ -1076,6 +1129,19 @@ codeunit 139515 \"Digital Vouchers Tests\"\n exit(IncomingDocument.\"Entry No.\");\n end;\n \n+ local procedure MockIncomingDocument(): Integer\n+ var\n+ IncomingDocument: Record \"Incoming Document\";\n+ IncomingDocumentAttachment: Record \"Incoming Document Attachment\";\n+ begin\n+ IncomingDocument.\"Entry No.\" :=\n+ LibraryUtility.GetNewRecNo(IncomingDocument, IncomingDocument.FieldNo(\"Entry No.\"));\n+ IncomingDocument.Insert();\n+ IncomingDocumentAttachment.\"Incoming Document Entry No.\" := IncomingDocument.\"Entry No.\";\n+ IncomingDocumentAttachment.Insert();\n+ exit(IncomingDocument.\"Entry No.\");\n+ end;\n+\n local procedure ReceiveAndInvoicePurchaseInvoice(): Code[20]\n var\n PurchaseHeader: Record \"Purchase Header\";\n", "patch": "diff --git a/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al b/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al\nindex 72dc980e3347..5775bd7fc2b0 100644\n--- a/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al\n+++ b/App/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al\n@@ -224,6 +224,8 @@ codeunit 5579 \"Digital Voucher Impl.\"\n SourceCodeSetup.Get();\n if IsPaymentReconciliationJournal(DigitalVoucherEntrySetup.\"Entry Type\", RecRef) then\n exit(true);\n+ if IsGenJnlLineWithIncDocAttachedToAdjLine(DigitalVoucherEntrySetup.\"Entry Type\", RecRef) then\n+ exit(true);\n exit(false);\n end;\n \n@@ -345,6 +347,27 @@ codeunit 5579 \"Digital Voucher Impl.\"\n exit(SourceCodeValue = SourceCodeSetup.\"Payment Reconciliation Journal\");\n end;\n \n+ local procedure IsGenJnlLineWithIncDocAttachedToAdjLine(DigitalVoucherEntryType: Enum \"Digital Voucher Entry Type\"; RecRef: RecordRef): Boolean\n+ var\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ AdjacentGenJournalLine: Record \"Gen. Journal Line\";\n+ IncomingDocument: Record \"Incoming Document\";\n+ begin\n+ if DigitalVoucherEntryType <> DigitalVoucherEntryType::\"General Journal\" then\n+ exit(false);\n+ RecRef.SetTable(GenJournalLine);\n+ AdjacentGenJournalLine.ReadIsolation(IsolationLevel::ReadCommitted);\n+ AdjacentGenJournalLine.SetRange(\"Journal Template Name\", GenJournalLine.\"Journal Template Name\");\n+ AdjacentGenJournalLine.SetRange(\"Journal Batch Name\", GenJournalLine.\"Journal Batch Name\");\n+ AdjacentGenJournalLine.SetRange(\"Posting Date\", GenJournalLine.\"Posting Date\");\n+ AdjacentGenJournalLine.SetRange(\"Document No.\", GenJournalLine.\"Document No.\");\n+ AdjacentGenJournalLine.SetFilter(\"Line No.\", '<>%1', GenJournalLine.\"Line No.\");\n+ AdjacentGenJournalLine.SetFilter(\"Incoming Document Entry No.\", '<>0');\n+ if not AdjacentGenJournalLine.FindFirst() then\n+ exit(false);\n+ exit(IncomingDocument.Get(AdjacentGenJournalLine.\"Incoming Document Entry No.\"));\n+ end;\n+\n local procedure AttachDigitalVoucherFromReportPDF(ReportUsage: Enum \"Report Selection Usage\"; RecRef: RecordRef; IsInvoice: Boolean; PostingDate: Date; DocNo: Code[20]; AccountTableNo: Integer; AccountNo: Code[20]; StandardReportID: Integer)\n var\n TempAttachReportSelections: Record \"Report Selections\" temporary;\n"} +{"metadata": {"area": "sales", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223493", "base_commit": "faff33469cd77044de7a55542cfd61531ec098ee", "created_at": "2025-08-11", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134658, "functionName": ["VerifyYourReferenceUpdatedInCustLedgerEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al b/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al\nindex b2cb6ea36fb..0e345a6a6f8 100644\n--- a/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/EditPostedDocuments.Codeunit.al\n@@ -27,6 +27,8 @@ codeunit 134658 \"Edit Posted Documents\"\n UnexpectedVolumeErr: Label 'Unexpected Volume shown.';\n CashFlowWorkSheetLineMustNotBeFoundErr: Label 'Cash Flow Worksheet Line must not be found.';\n YourReferenceErr: Label 'Your reference must be editable';\n+ SalesInvoiceYourReferenceErr: Label 'Sales Invoice Your Reference not updated';\n+ CustLedgerEntryYourReferenceErr: Label 'Customer Ledger Entry Your Reference not updated';\n \n [Test]\n [HandlerFunctions('PostedSalesShipmentUpdateGetEditablelModalPageHandler')]\n@@ -996,6 +998,46 @@ codeunit 134658 \"Edit Posted Documents\"\n LibraryLowerPermissions.SetOutsideO365Scope();\n end;\n \n+ [Test]\n+ [HandlerFunctions('PostedSalesInvoiceYourReferenceModalPageHandler')]\n+ procedure VerifyYourReferenceUpdatedInCustLedgerEntry()\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ SalesInvoiceHeader: Record \"Sales Invoice Header\";\n+ YourReference: Text[35];\n+ PostedSalesInvoice: TestPage \"Posted Sales Invoice\";\n+ begin\n+ // [SCENARIO 595854] Verify Your Reference Field updated in Customer Ledger Entries,\n+ // when changed with Update document on Posted Sales Invoice.\n+ Initialize();\n+\n+ LibraryLowerPermissions.SetO365Setup();\n+ LibraryLowerPermissions.AddSalesDocsPost();\n+\n+ // [GIVEN] Create and post a Sales Order.\n+ SalesInvoiceHeader.Get(CreateAndPostSalesOrderGetInvoiceNo());\n+ YourReference := LibraryRandom.RandText(35);\n+ LibraryVariableStorage.Enqueue(YourReference);\n+\n+ // [GIVEN] Opened \"Posted Sales Invoice - Update\" page.\n+ PostedSalesInvoice.OpenView();\n+ PostedSalesInvoice.GoToRecord(SalesInvoiceHeader);\n+ PostedSalesInvoice.\"Update Document\".Invoke();\n+\n+ // [WHEN] Press OK on the page via PostedSalesInvoiceYourReferenceModalPageHandler.\n+\n+ // [THEN] Verify Your Reference field updated on Sales Invoice Header and Customer Ledger Entry.\n+ SalesInvoiceHeader.Get(SalesInvoiceHeader.\"No.\");\n+ Assert.AreEqual(YourReference, SalesInvoiceHeader.\"Your Reference\", SalesInvoiceYourReferenceErr);\n+\n+ CustLedgerEntry.SetRange(\"Document No.\", SalesInvoiceHeader.\"No.\");\n+ CustLedgerEntry.FindFirst();\n+ Assert.AreEqual(YourReference, CustLedgerEntry.\"Your Reference\", CustLedgerEntryYourReferenceErr);\n+\n+ LibraryVariableStorage.AssertEmpty();\n+ LibraryLowerPermissions.SetOutsideO365Scope();\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Edit Posted Documents\");\n@@ -1535,6 +1577,14 @@ codeunit 134658 \"Edit Posted Documents\"\n PostedSalesInvUpdate.Cancel().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedSalesInvoiceYourReferenceModalPageHandler(var PostedSalesInvUpdate: TestPage \"Posted Sales Inv. - Update\")\n+ begin\n+ PostedSalesInvUpdate.\"Your Reference\".SetValue(LibraryVariableStorage.DequeueText());\n+ PostedSalesInvUpdate.OK().Invoke();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerTrue(QuestionText: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al b/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al\nindex 6a5f0a883a3..626b74297f4 100644\n--- a/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/History/SalesInvHeaderEdit.Codeunit.al\n@@ -56,6 +56,7 @@ codeunit 1409 \"Sales Inv. Header - Edit\"\n CustLedgerEntry.Description := SalesInvoiceHeader.\"Posting Description\";\n CustLedgerEntry.\"Promised Pay Date\" := SalesInvoiceHeader.\"Promised Pay Date\";\n CustLedgerEntry.\"Due Date\" := SalesInvoiceHeader.\"Due Date\";\n+ CustLedgerEntry.\"Your Reference\" := SalesInvoiceHeader.\"Your Reference\";\n if CustLedgerEntry.\"Dispute Status\" <> '' then begin\n if DisputeStatus.get(CustLedgerEntry.\"Dispute Status\") then\n if (DisputeStatus.\"Overwrite on hold\") and ClearOnHold(SalesInvoiceHeader) then\ndiff --git a/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al\nindex c64fa944c7e..546c3b5513a 100644\n--- a/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Receivables/CustEntryEdit.Codeunit.al\n@@ -44,6 +44,7 @@ codeunit 103 \"Cust. Entry-Edit\"\n CustLedgEntry.\"Applies-to ID\" := Rec.\"Applies-to ID\";\n CustLedgEntry.Validate(\"Payment Method Code\", Rec.\"Payment Method Code\");\n CustLedgEntry.Validate(\"Payment Reference\", Rec.\"Payment Reference\");\n+ CustLedgEntry.Validate(\"Your Reference\", Rec.\"Your Reference\");\n CustLedgEntry.Validate(\"Remaining Pmt. Disc. Possible\", Rec.\"Remaining Pmt. Disc. Possible\");\n CustLedgEntry.\"Pmt. Disc. Tolerance Date\" := Rec.\"Pmt. Disc. Tolerance Date\";\n CustLedgEntry.Validate(\"Max. Payment Tolerance\", Rec.\"Max. Payment Tolerance\");\n@@ -122,7 +123,8 @@ codeunit 103 \"Cust. Entry-Edit\"\n (CurrCustLedgerEntry.\"Payment Reference\" <> NewCustLedgerEntry.\"Payment Reference\") or\n (CurrCustLedgerEntry.\"Message to Recipient\" <> NewCustLedgerEntry.\"Message to Recipient\") or\n (CurrCustLedgerEntry.\"Recipient Bank Account\" <> NewCustLedgerEntry.\"Recipient Bank Account\") or\n- (CurrCustLedgerEntry.\"On Hold\" <> NewCustLedgerEntry.\"On Hold\");\n+ (CurrCustLedgerEntry.\"On Hold\" <> NewCustLedgerEntry.\"On Hold\") or\n+ (CurrCustLedgerEntry.\"Your Reference\" <> NewCustLedgerEntry.\"Your Reference\");\n OnAfterLogFieldChanged(CurrCustLedgerEntry, NewCustLedgerEntry, Changed);\n exit(Changed);\n end;\n"} {"metadata": {"area": "shopify", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-193649", "base_commit": "3a5cb3aed7e735e557547556f727cce66b15affe", "created_at": "2024-09-06", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139695, "functionName": ["UnitTestCopyInvoice"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al b/App/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al\nnew file mode 100644\nindex 000000000000..288b4d8039f0\n--- /dev/null\n+++ b/App/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al\n@@ -0,0 +1,67 @@\n+codeunit 139695 \"Shpfy Invoices Test\"\n+{\n+ Subtype = Test;\n+ TestPermissions = Disabled;\n+\n+ var\n+ LibraryAssert: Codeunit \"Library Assert\";\n+ Any: Codeunit Any;\n+ LibrarySales: Codeunit \"Library - Sales\";\n+ LibraryInventory: Codeunit \"Library - Inventory\";\n+ LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n+ IsInitialized: Boolean;\n+\n+ [Test]\n+ procedure UnitTestCopyInvoice()\n+ var\n+ Item: Record Item;\n+ Customer: Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ InvoiceNo: Code[20];\n+ OrderId: BigInteger;\n+ begin\n+ // [SCENARIO] Shopify related fields are not copied to the new invoice\n+ // [GIVEN] Posted sales invoice with Shopify related fields and empty invoice\n+ Initialize();\n+ OrderId := Any.IntegerInRange(10000, 99999);\n+ LibraryInventory.CreateItem(Item);\n+ LibrarySales.CreateCustomer(Customer);\n+ InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer.\"No.\");\n+\n+ // [WHEN] Copy the invoice\n+ CopySalesDocument(SalesHeader, InvoiceNo);\n+\n+ // [THEN] Shopify related fields are not copied\n+ LibraryAssert.IsTrue(SalesHeader.\"Shpfy Order Id\" = 0, 'Shpfy Order Id is not copied');\n+ end;\n+\n+ local procedure Initialize()\n+ begin\n+ if IsInitialized then\n+ exit;\n+ IsInitialized := true;\n+ LibraryERMCountryData.CreateVATData();\n+ LibraryERMCountryData.UpdateGeneralPostingSetup();\n+ end;\n+\n+ local procedure CreateAndPostSalesInvoice(Item: Record Item; Customer: Record Customer; NumberOfLines: Integer; OrderId: BigInteger): Code[20]\n+ var\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer.\"No.\");\n+ SalesHeader.\"Shpfy Order Id\" := OrderId;\n+ SalesHeader.Modify();\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", NumberOfLines);\n+ exit(LibrarySales.PostSalesDocument(SalesHeader, true, true));\n+ end;\n+\n+ local procedure CopySalesDocument(var ToSalesHeader: Record \"Sales Header\"; DocNo: Code[20])\n+ var\n+ CopyDocumentMgt: Codeunit \"Copy Document Mgt.\";\n+ begin\n+ CopyDocumentMgt.SetProperties(true, false, false, false, false, false, false);\n+ CopyDocumentMgt.CopySalesDoc(\"Sales Document Type From\"::\"Posted Invoice\", DocNo, ToSalesHeader);\n+ end;\n+}\ndiff --git a/App/Apps/W1/Shopify/test/app.json b/App/Apps/W1/Shopify/test/app.json\nindex fad22c7daf0e..ba1deea22a10 100644\n--- a/App/Apps/W1/Shopify/test/app.json\n+++ b/App/Apps/W1/Shopify/test/app.json\n@@ -71,6 +71,10 @@\n {\n \"from\": 139645,\n \"to\": 139649\n+ },\n+ {\n+ \"from\": 139695,\n+ \"to\": 139699\n }\n ],\n \"target\": \"OnPrem\",\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al b/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al\nindex cf03c116eaef..a6a20c46d2da 100644\n--- a/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al\n+++ b/App/Apps/W1/Shopify/app/src/Invoicing/Codeunits/ShpfyUpdateSalesInvoice.Codeunit.al\n@@ -1,6 +1,8 @@\n namespace Microsoft.Integration.Shopify;\n \n using Microsoft.Sales.History;\n+using Microsoft.Utilities;\n+using Microsoft.Sales.Document;\n \n codeunit 30364 \"Shpfy Update Sales Invoice\"\n {\n@@ -19,4 +21,12 @@ codeunit 30364 \"Shpfy Update Sales Invoice\"\n begin\n SalesInvoiceHeader.\"Shpfy Order Id\" := SalesInvoiceHeaderRec.\"Shpfy Order Id\";\n end;\n+\n+ [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Copy Document Mgt.\", 'OnCopySalesDocOnAfterTransferPostedInvoiceFields', '', false, false)]\n+ local procedure OnCopySalesDocOnAfterCopySalesDocUpdateHeader(var ToSalesHeader: Record \"Sales Header\")\n+ begin\n+ Clear(ToSalesHeader.\"Shpfy Order Id\");\n+ Clear(ToSalesHeader.\"Shpfy Order No.\");\n+ Clear(ToSalesHeader.\"Shpfy Refund Id\");\n+ end;\n }\n\\ No newline at end of file\n"} +{"metadata": {"area": "sales", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220036", "base_commit": "e21460ab75c1fb80ba3033e3755672cbd4ed8d9f", "created_at": "2025-07-04", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM", "App\\Layers\\W1\\Tests\\Misc"], "FAIL_TO_PASS": [{"codeunitID": 134905, "functionName": ["VerifyEmailOnReminderPageWhenCustomerHasNoContacts"]}, {"codeunitID": 134825, "functionName": ["GetPrimaryConactCustomerWithoutContact"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\nindex f8b1cf9e56e..71c12b1ce1a 100644\n--- a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n@@ -587,6 +587,55 @@ codeunit 134905 \"ERM Issued Reminder Addnl Fee\"\n Assert.AreEqual(ReminderFinChargeEntry.\"Due Date\", CustLedgerEntry.\"Due Date\", ReminderDueDateErr);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure VerifyEmailOnReminderPageWhenCustomerHasNoContacts()\n+ var\n+ Customer: Record Customer;\n+ ReminderLevel: Record \"Reminder Level\";\n+ ReminderText: Record \"Reminder Text\";\n+ ReminderHeader: Record \"Reminder Header\";\n+ ReminderPage: TestPage Reminder;\n+ CustomerCard: TestPage \"Customer Card\";\n+ EMail: Text[80];\n+ DueDate: Date;\n+ DocumentDate: Date;\n+ begin\n+ // [SCENARIO 581797] [ALL-E] Field Email on Reminder is empty when customer does not have any contacts\n+ Initialize();\n+\n+ // [GIVEN] Create Customer with E-Mail and Reminder Terms Code.\n+ CreateCustomer(Customer, '');\n+ Customer.Validate(\"Reminder Terms Code\", CreateReminderTerms());\n+ EMail := 'test1@test.com';\n+ Customer.Modify(true);\n+\n+ CustomerCard.OpenEdit();\n+ CustomerCard.GoToRecord(Customer);\n+ CustomerCard.\"E-Mail\".SetValue(EMail);\n+ CustomerCard.Close();\n+\n+ // [GIVEN] Create Reminder Level with Random Grace Period and Random Additional Fee.\n+ ReminderLevel.SetRange(\"Reminder Terms Code\", Customer.\"Reminder Terms Code\");\n+ ReminderLevel.FindFirst();\n+ LibraryERM.CreateReminderText(\n+ ReminderText, Customer.\"Reminder Terms Code\",\n+ ReminderLevel.\"No.\", ReminderText.Position::Ending, ReminderEndingText);\n+\n+ // [WHEN] Post Sales Invoice and Create Reminder.\n+ DueDate := CreateAndPostSalesInvoice(Customer.\"No.\", '');\n+ DocumentDate := CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', CalcDate(ReminderLevel.\"Grace Period\", DueDate));\n+ CreateReminder(Customer.\"No.\", DocumentDate, false);\n+\n+ // [THEN] Find Reminder Header for Customer and open Reminder Page.\n+ FindReminderHeader(ReminderHeader, Customer.\"No.\");\n+ ReminderPage.OpenEdit();\n+ ReminderPage.GoToRecord(ReminderHeader);\n+\n+ // [THEN] Verify E-Mail on Reminder Page.\n+ ReminderPage.ContactEmail.AssertEquals(EMail);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\ndiff --git a/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al b/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al\nindex 70b34d374fa..33cc3001fc3 100644\n--- a/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al\n+++ b/App/Layers/W1/Tests/Misc/UTCustomerTable.Codeunit.al\n@@ -25,6 +25,7 @@ codeunit 134825 \"UT Customer Table\"\n DeleteCustomerSalesDocExistsErr: Label 'You cannot delete %1 %2 because there is at least one outstanding Sales %3 for this customer.';\n DialogErr: Label 'Dialog';\n PhoneNoCannotContainLettersErr: Label '%1 must not contain letters in %2 %3=''%4''.';\n+ ContactNoShouldNotBeEmpty: Label 'Contact No. should not be empty';\n \n [Test]\n [Scope('OnPrem')]\n@@ -740,8 +741,8 @@ codeunit 134825 \"UT Customer Table\"\n // [WHEN] Function GetPrimaryConact is being run with parameter \"CONT\"\n Customer.GetPrimaryContact(Customer.\"No.\", Contact);\n \n- // [THEN] Variable Contact is empty\n- Contact.TestField(\"No.\", '');\n+ // [THEN] Variable Contact exists without customer contact\n+ Assert.IsTrue(Contact.\"No.\" <> '', ContactNoShouldNotBeEmpty);\n end;\n \n [Test]\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\nindex 9fdc21c529d..de6b7a0cc2e 100644\n--- a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n@@ -2302,7 +2302,22 @@ table 18 Customer\n begin\n Clear(PrimaryContact);\n if Customer.Get(CustomerNo) then\n- if PrimaryContact.Get(Customer.\"Primary Contact No.\") then;\n+ if not PrimaryContact.Get(Customer.\"Primary Contact No.\") then\n+ GetContact(CustomerNo, PrimaryContact);\n+ end;\n+\n+ local procedure GetContact(CustomerNo: Code[20]; var PrimaryContact: Record Contact)\n+ var\n+ ContactBusinessRelation: Record \"Contact Business Relation\";\n+ begin\n+ ContactBusinessRelation.SetCurrentKey(\"Link to Table\", \"No.\");\n+ ContactBusinessRelation.SetRange(\"Link to Table\", ContactBusinessRelation.\"Link to Table\"::Customer);\n+ ContactBusinessRelation.SetRange(\"No.\", CustomerNo);\n+ if ContactBusinessRelation.FindSet() then\n+ repeat\n+ if PrimaryContact.Get(ContactBusinessRelation.\"Contact No.\") then\n+ exit;\n+ until ContactBusinessRelation.Next() = 0;\n end;\n \n local procedure GetCustomerPriceGroupPriceCalcMethod(): Enum \"Price Calculation Method\";\n"} {"metadata": {"area": "sustainability", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-188438", "base_commit": "b3cff264abfbab722f8657c126f23aa07ad00056", "created_at": "2024-07-03", "environment_setup_version": "24.3", "project_paths": ["App\\Apps\\W1\\Sustainability\\app", "App\\Apps\\W1\\Sustainability\\test"], "FAIL_TO_PASS": [{"codeunitID": 148181, "functionName": ["TestCustomAmountIsPositiveForNegativeTotalOfGL"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al b/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al\nindex 54ca91b65b2f..bfae0fd4c73a 100644\n--- a/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al\n+++ b/App/Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al\n@@ -5,9 +5,13 @@ codeunit 148181 \"Sustainability Journal Test\"\n \n var\n Assert: Codeunit Assert;\n+ LibraryERM: Codeunit \"Library - ERM\";\n+ LibraryRandom: Codeunit \"Library - Random\";\n LibrarySustainability: Codeunit \"Library - Sustainability\";\n+ LibraryUtility: Codeunit \"Library - Utility\";\n OneDefaultTemplateShouldBeCreatedLbl: Label 'One default template should be created after page is opened', Locked = true;\n OneDefaultBatchShouldBeCreatedLbl: Label 'One default batch should be created after page is opened', Locked = true;\n+ CustomAmountMustBePositiveLbl: Label 'The custom amount must be positive', Locked = true;\n \n [Test]\n procedure TestDefaultTemplateAndBatchSuccessfullyInserted()\n@@ -100,4 +104,46 @@ codeunit 148181 \"Sustainability Journal Test\"\n // [THEN] The Check should fail\n asserterror SustainabilityJournalMgt.CheckScopeMatchWithBatch(SustainabilityJournalLine);\n end;\n+\n+ [Test]\n+ procedure TestCustomAmountIsPositiveForNegativeTotalOfGL()\n+ var\n+ SustainAccountCategory: Record \"Sustain. Account Category\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJouralLine: Record \"Gen. Journal Line\";\n+ SustainabilityCalcMgt: Codeunit \"Sustainability Calc. Mgt.\";\n+ GenJournalTemplateCode: Code[10];\n+ GLAccountNo: Code[20];\n+ GLAmount, CustomAmount : Decimal;\n+ begin\n+ // [SCENARIO 540221] Test that the custom amount is positive when the total of the GL is negative\n+\n+ // [GIVEN] G/L Account exists\n+ GLAccountNo := LibraryERM.CreateGLAccountNoWithDirectPosting();\n+\n+ // [GIVEN] G/L Batch and Template exist\n+ GenJournalTemplateCode := LibraryERM.SelectGenJnlTemplate();\n+ LibraryERM.CreateGenJournalBatch(GenJournalBatch, GenJournalTemplateCode);\n+\n+ // [GIVEN] G/L Entry with Amount = -1000 for the G/L Account\n+ GLAmount := -LibraryRandom.RandDec(1000, 2);\n+ LibraryERM.CreateGeneralJnlLine2WithBalAcc(GenJouralLine, GenJournalTemplateCode, GenJournalBatch.Name, GenJouralLine.\"Document Type\"::Payment, GenJouralLine.\"Account Type\"::\"G/L Account\", GLAccountNo, GenJouralLine.\"Account Type\"::\"G/L Account\", LibraryERM.CreateGLAccountNoWithDirectPosting(), GLAmount);\n+ LibraryERM.PostGeneralJnlLine(GenJouralLine);\n+\n+ // [GIVEN] Sustain Account Category with the G/L Account calculation foundation\n+ SustainAccountCategory := CreateSustAccountCategoryWithGLAccountNo(GLAccountNo);\n+\n+ // [WHEN] Getting the collectable amount for sustanability account category\n+ CustomAmount := SustainabilityCalcMgt.GetCollectableGLAmount(SustainAccountCategory, 0D, 0D);\n+\n+ // [THEN] The custom amount = 1000\n+ Assert.AreEqual(Abs(GLAmount), CustomAmount, CustomAmountMustBePositiveLbl);\n+ end;\n+\n+ local procedure CreateSustAccountCategoryWithGLAccountNo(GLAccountNo: Code[20]) SustainAccountCategory: Record \"Sustain. Account Category\"\n+ begin\n+ SustainAccountCategory := LibrarySustainability.InsertAccountCategory(LibraryUtility.GenerateGUID(), LibraryUtility.GenerateGUID(), Enum::\"Emission Scope\"::\"Scope 2\", Enum::\"Calculation Foundation\"::Custom, true, true, true, 'GL', true);\n+ SustainAccountCategory.\"G/L Account Filter\" := GLAccountNo;\n+ SustainAccountCategory.Modify(true);\n+ end;\n }\n\\ No newline at end of file\n", "patch": "diff --git a/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al b/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al\nindex 4644c8733d76..35add37418cc 100644\n--- a/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al\n+++ b/App/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al\n@@ -70,7 +70,7 @@ codeunit 6218 \"Sustainability Calc. Mgt.\"\n begin\n FilterGLEntry(SustainAccountCategory, FromDate, ToDate, GLEntry);\n GLEntry.CalcSums(Amount);\n- exit(GLEntry.Amount);\n+ exit(Abs(GLEntry.Amount));\n end;\n \n internal procedure CollectGeneralLedgerAmount(var SustainabilityJnlLine: Record \"Sustainability Jnl. Line\")\n"} +{"metadata": {"area": "reporting", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-224447", "base_commit": "cc0427613cdcf235d834b83a7e69b98288686d0d", "created_at": "2025-08-21", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134979, "functionName": ["SendIssuedReminderByEmailAndEntryCreatedInEmailRelatedRecords"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\nindex 1667c4a29d8..01f9284203b 100644\n--- a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n@@ -844,6 +844,53 @@ codeunit 134979 \"Reminder Automation Tests\"\n ReminderTermSetupPage.ReminderLevelSetup.CustomerCommunications.Invoke();\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('ModalEmailEditorHandler,CancelMailSendingStrMenuHandler')]\n+ procedure SendIssuedReminderByEmailAndEntryCreatedInEmailRelatedRecords()\n+ var\n+ Customer: Record Customer;\n+ IssuedReminderHeader: Record \"Issued Reminder Header\";\n+ ReminderTerms: Record \"Reminder Terms\";\n+ ReminderHeader: Record \"Reminder Header\";\n+ LanguageCode: Code[10];\n+ FileName: Text;\n+ begin\n+ // [SCENARIO 591799] Issued reminder emails are not logged in sent e-mail history of a customer\n+ Initialize();\n+\n+ // [WHEN] A connector is installed and an account is added\n+ InstallConnectorAndAddAccount();\n+\n+ // [GIVEN] Create reminder term with levels\n+ CreateReminderTermsWithLevels(ReminderTerms, GetDefaultDueDatePeriodForReminderLevel(), Any.IntegerInRange(2, 5));\n+\n+ // [GIVEN] Create reminder attachment text, file name = XXX, language code = Y\n+ LanguageCode := LibraryERM.GetAnyLanguageDifferentFromCurrent();\n+ CreateReminderAttachmentText(ReminderTerms, LanguageCode);\n+\n+ // [GIVEN] Create a customer X with overdue entries\n+ CreateCustomerWithOverdueEntries(Customer, ReminderTerms, Any.IntegerInRange(2, 5));\n+\n+ // [GIVEN] Set language code Y for customer X\n+ Customer.\"Language Code\" := LanguageCode;\n+ Customer.Modify();\n+ FileName := LibraryVariableStorage.DequeueText();\n+ LibraryVariableStorage.Enqueue(Customer.\"No.\");\n+ LibraryVariableStorage.Enqueue(FileName);\n+\n+ // [GIVEN] Create and issue reminder for customer X \n+ CreateAndIssueReminder(ReminderHeader, Customer.\"No.\");\n+\n+ // [WHEN] Run action \"Send by mail\" on issued reminder\n+ IssuedReminderHeader.SetRange(\"Pre-Assigned No.\", ReminderHeader.\"No.\");\n+ IssuedReminderHeader.FindFirst();\n+ CustomReportSelectionPrint(IssuedReminderHeader, Enum::\"Report Selection Usage\"::Reminder, 1);\n+\n+ // [THEN] Verified in ModalEmailEditorHandler page\n+ LibraryVariableStorage.Clear();\n+ end;\n+\n local procedure CreateReminderAttachmentText(ReminderTerms: Record \"Reminder Terms\"; LanguageCode: Code[10])\n var\n ReminderLevel: Record \"Reminder Level\";\n@@ -1179,6 +1226,57 @@ codeunit 134979 \"Reminder Automation Tests\"\n end;\n end;\n \n+ local procedure InstallConnectorAndAddAccount()\n+ var\n+ TempAccount: Record \"Email Account\" temporary;\n+ ConnectorMock: Codeunit \"Connector Mock\";\n+ EmailScenarioMock: Codeunit \"Email Scenario Mock\";\n+ begin\n+ ConnectorMock.Initialize();\n+ ConnectorMock.AddAccount(TempAccount);\n+ EmailScenarioMock.DeleteAllMappings();\n+ EmailScenarioMock.AddMapping(Enum::\"Email Scenario\"::Default, TempAccount.\"Account Id\", TempAccount.Connector);\n+ end;\n+\n+ local procedure CustomReportSelectionPrint(Document: Variant; ReportUsage: Enum \"Report Selection Usage\"; CustomerNoFieldNo: Integer)\n+ var\n+ ReportSelections: Record \"Report Selections\";\n+ TempReportSelections: Record \"Report Selections\" temporary;\n+ RecRef: RecordRef;\n+ FieldRef: FieldRef;\n+ CustomerNo: Code[20];\n+ begin\n+ RecRef.GetTable(Document);\n+ FieldRef := RecRef.Field(CustomerNoFieldNo);\n+ CustomerNo := CopyStr(Format(FieldRef.Value), 1, MaxStrLen(CustomerNo));\n+\n+ RecRef.SetRecFilter();\n+ RecRef.SetTable(Document);\n+\n+ ReportSelections.FindEmailAttachmentUsageForCust(ReportUsage, CustomerNo, TempReportSelections);\n+ ReportSelections.SendEmailToCust(ReportUsage.AsInteger(), Document, '', '', true, CustomerNo);\n+ end;\n+\n+ [StrMenuHandler]\n+ [Scope('OnPrem')]\n+ procedure CancelMailSendingStrMenuHandler(Options: Text; var Choice: Integer; Instruction: Text)\n+ begin\n+ Choice := 1; //Save as Draft //Discard email\t\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ModalEmailEditorHandler(var EmailEditor: TestPage \"Email Editor\")\n+ var\n+ Customer: Record Customer;\n+ EmailRelatedRecord: Record \"Email Related Record\";\n+ begin\n+ Customer.Get(LibraryVariableStorage.DequeueText());\n+ EmailRelatedRecord.SetRange(\"Table Id\", Database::Customer);\n+ EmailRelatedRecord.SetRange(\"System Id\", Customer.SystemId);\n+ Assert.IsTrue(EmailRelatedRecord.FindFirst(), EmailRelatedRecordNotFoundErr);\n+ end;\n+\n [ModalPageHandler()]\n procedure CreateRemindersSetupModalPageHandler(var CreateRemindersSetup: TestPage \"Create Reminders Setup\")\n begin\n@@ -1271,4 +1369,5 @@ codeunit 134979 \"Reminder Automation Tests\"\n Any: Codeunit Any;\n IsInitialized: Boolean;\n FiltersAreNotSavedErr: Label 'Filters are not saved';\n+ EmailRelatedRecordNotFoundErr: Label 'Email related record not found';\n }\n\\ No newline at end of file\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\nindex 7a71bebba78..5e7b5d9c79b 100644\n--- a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n+++ b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n@@ -1269,7 +1269,8 @@ table 77 \"Report Selections\"\n Database::\"Sales Invoice Header\",\n Database::\"Sales Cr.Memo Header\",\n Database::\"Sales Shipment Header\",\n- Database::\"Return Receipt Header\"];\n+ Database::\"Return Receipt Header\",\n+ Database::\"Issued Reminder Header\"];\n \n OnAfterIsCustomerAccount(DocumentTableId, IsCustomer);\n end;\n@@ -1521,7 +1522,10 @@ table 77 \"Report Selections\"\n // Related Source - Customer or vendor receiving the document\n TableId := GetAccountTableId(DocumentRecord.Number());\n if TableId = Database::Customer then begin\n- FieldName := 'Sell-to Customer No.';\n+ if DocumentRecord.Number() = Database::\"Issued Reminder Header\" then\n+ FieldName := 'Customer No.'\n+ else\n+ FieldName := 'Sell-to Customer No.';\n OnSendEmailDirectlyOnAfterSetFieldName(DocumentRecord.Number(), FieldName);\n if DataTypeManagement.FindfieldByName(DocumentRecord, FieldRef, FieldName) and Customer.Get(Format(FieldRef.Value())) then begin\n SourceTableIDs.Add(Database::Customer);\n"} +{"metadata": {"area": "finance", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226875", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-15", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\General Journal"], "FAIL_TO_PASS": [{"codeunitID": 134920, "functionName": ["VendorNameFieldPopulatesOnlyForVendorAccountType"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al\nindex 9e6664f2979..0e9383fc12c 100644\n--- a/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al\n@@ -6000,6 +6000,53 @@ codeunit 134920 \"ERM General Journal UT\"\n GenJournalLine[4].TestField(\"Document No.\", NewDocNo);\n end;\n \n+ [Test]\n+ procedure VendorNameFieldPopulatesOnlyForVendorAccountType()\n+ var\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalTemplate: Record \"Gen. Journal Template\";\n+ GLAccount: Record \"G/L Account\";\n+ Vendor: Record Vendor;\n+ PurchaseJournal: TestPage \"Purchase Journal\";\n+ begin\n+ // [SCENARIO 599505] Purchase Journal page validates vendor name field based on account type\n+ Initialize();\n+\n+ // [GIVEN] Create a vendor with random name\n+ LibraryPurchase.CreateVendor(Vendor);\n+ Vendor.Name := LibraryRandom.RandText(20);\n+ Vendor.Modify(true);\n+\n+ // [GIVEN] Create Purchase Journal Template and Batch\n+ LibraryERM.CreateGenJournalBatch(GenJournalBatch, LibraryJournals.SelectGenJournalTemplate(GenJournalTemplate.Type::Purchases, Page::\"Purchase Journal\"));\n+\n+ // [WHEN] Open Purchase Journal page and perform actions as per YAML recording\n+ PurchaseJournal.OpenEdit();\n+ PurchaseJournal.CurrentJnlBatchName.SetValue(GenJournalBatch.Name);\n+\n+ // [GIVEN] Set Document Type to Invoice and Document No. to random value\n+ PurchaseJournal.\"Document Type\".SetValue(\"Gen. Journal Document Type\"::Invoice);\n+ PurchaseJournal.\"Document No.\".SetValue(LibraryRandom.RandText(10));\n+\n+ // [GIVEN] Set Account Type to Vendor and Account No. to Vendor.\"No.\"\n+ PurchaseJournal.\"Account Type\".SetValue(\"Gen. Journal Account Type\"::Vendor);\n+ PurchaseJournal.\"Account No.\".SetValue(Vendor.\"No.\");\n+\n+ // [THEN] Verify Vendor Name page field is populated with Vendor.Name\n+ PurchaseJournal.\"\".AssertEquals(Vendor.Name);\n+\n+ // [WHEN] Set Account Type to G/L Account and Account No. to a new G/L Account.\"No.\"\n+ PurchaseJournal.\"Account Type\".SetValue(\"Gen. Journal Account Type\"::\"G/L Account\");\n+ LibraryERM.CreateGLAccount(GLAccount);\n+ PurchaseJournal.\"Account No.\".SetValue(GLAccount.\"No.\");\n+\n+ // [THEN] Verify Vendor Name field should be empty for G/L Account\n+ PurchaseJournal.\"\".AssertEquals('');\n+\n+ // [CLEANUP] Close Purchase Journal page\n+ PurchaseJournal.Close();\n+ end;\n+\n local procedure Initialize()\n begin\n LibrarySetupStorage.Restore();\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\nindex fa043e01294..4d5abfe80aa 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n@@ -170,7 +170,7 @@ page 254 \"Purchase Journal\"\n CurrPage.SaveRecord();\n end;\n }\n- field(\"\"; AccName)\n+ field(\"\"; GetVendorName())\n {\n ApplicationArea = Basic, Suite;\n Caption = 'Vendor Name';\n@@ -1661,6 +1661,14 @@ page 254 \"Purchase Journal\"\n NumberOfRecords := Rec.Count();\n end;\n \n+ local procedure GetVendorName(): Text[100]\n+ begin\n+ if (Rec.\"Account Type\" = Rec.\"Account Type\"::Vendor) and (AccName <> '') then\n+ exit(AccName);\n+\n+ exit('');\n+ end;\n+\n local procedure EnableApplyEntriesAction()\n begin\n ApplyEntriesActionEnabled :=\n"} +{"metadata": {"area": "finance", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226223", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-09", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134043, "functionName": ["NoVATEntryAddCurrExchRateAdjust"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al\nindex ee712bb9f9b..26f12019b95 100644\n--- a/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMAdditionalCurrency.Codeunit.al\n@@ -1192,6 +1192,38 @@ codeunit 134043 \"ERM Additional Currency\"\n StrSubstNo(AmountLCYError, GenJournalLine.\"Amount (LCY)\"));\n end;\n \n+ [Test]\n+ [HandlerFunctions('StatisticsMessageHandler')]\n+ procedure NoVATEntryAddCurrExchRateAdjust()\n+ var\n+ Currency: Record Currency;\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ GeneralLedgerSetup: Record \"General Ledger Setup\";\n+ VATEntry: Record \"VAT Entry\";\n+ PostingDate: Date;\n+ begin\n+ // [SCENARIO 598998] \"Attempted to divide by zero\" error during Exchange Rates Adjustment if the company has no Tax/VAT Entries.\n+ Initialize();\n+ VATEntry.DeleteAll();\n+\n+ // [GIVEN] Currency FCY with exchange rates.\n+ PostingDate := WorkDate();\n+ CreateCurrencyWithExchangeRates(Currency, 1, PostingDate);\n+\n+ // [GIVEN] General Ledger Setup \"Additional Reporting Currency\" = \"FCY\"\n+ LibraryERM.SetAddReportingCurrency(Currency.Code);\n+\n+ // [GIVEN] General Ledger Setup \"VAT Exchange Rate Adjustment\" := Adjust Additional-Currency Amount\n+ UpdateGenLedgerVATExchRateAdjustment(\n+ GeneralLedgerSetup.\"VAT Exchange Rate Adjustment\"::\"Adjust Additional-Currency Amount\");\n+\n+ // [THEN] Run Adjust Exchange Rate with Adjust G/L Account and without other Adjustments\n+ CurrencyExchangeRate.Get(Currency.code, LibraryERM.FindEarliestDateForExhRate());\n+\n+ // [THEN] Report should executed without any error\n+ RunAdjustExchangeRates(CurrencyExchangeRate, Currency.Code);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al b/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al\nindex 467c235ce97..bdb56817ec5 100644\n--- a/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjmtProcess.Codeunit.al\n@@ -308,6 +308,8 @@ codeunit 699 \"Exch. Rate Adjmt. Process\"\n Window.Open(AdjustingVATEntriesTxt + VATEntryProgressBarTxt);\n \n VATEntryNoTotal := VATEntry.Count();\n+ if VATEntryNoTotal = 0 then\n+ exit;\n SetVATEntryFilters(VATEntry, ExchRateAdjmtParameters.\"Start Date\", ExchRateAdjmtParameters.\"End Date\");\n if VATPostingSetup.FindSet() then\n repeat\n"} +{"metadata": {"area": "service", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-221877", "base_commit": "0b60a161ce9c6976c82d811815aa974cf29181f8", "created_at": "2025-07-24", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136101, "functionName": ["AutoUpdateServiceHeaderStatusOnServiceItemLineAdd"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\nindex 5a74dfc12b9..204066e8ac0 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n@@ -122,6 +122,7 @@ codeunit 136101 \"Service Orders\"\n AvailableExpectedQuantityErr: Label 'Available expected quantity must be %1.', Comment = '%1=Value';\n VATCountryRegionLbl: Label 'VAT Country/Region Code must be %1', Comment = '%1 = Country/Region Code';\n ServiceOrderErr: Label 'Service Order does not exist.';\n+ ServiceOrderStatusShouldChangedErr: Label 'Service Header Status should have changed when adding Service Item';\n \n [Test]\n [Scope('OnPrem')]\n@@ -5688,6 +5689,54 @@ codeunit 136101 \"Service Orders\"\n ServiceStatistics.SubForm.\"Amount Including VAT\".AssertEquals(0);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure AutoUpdateServiceHeaderStatusOnServiceItemLineAdd()\n+ var\n+ ServiceHeader: Record \"Service Header\";\n+ ServiceItem: Record \"Service Item\";\n+ Customer: Record Customer;\n+ ServiceOrderPage: TestPage \"Service Order\";\n+ InitialStatus: Enum \"Service Document Status\";\n+ FinalStatus: Enum \"Service Document Status\";\n+ begin\n+ // [SCENARIO 582114] Test that Service Header Status changes automatically when adding Service Item to Finished Service Order\n+\n+ // [GIVEN] Initialize and create test data\n+ Initialize();\n+ LibrarySales.CreateCustomer(Customer);\n+ LibraryService.CreateServiceItem(ServiceItem, Customer.\"No.\");\n+\n+ // [GIVEN] Create a Service Order and set status to Finished\n+ LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ ServiceHeader.Validate(Status, ServiceHeader.Status::Finished);\n+ ServiceHeader.Modify(true);\n+ InitialStatus := ServiceHeader.Status;\n+\n+ // [WHEN] Open Service Order page and add Service Item Line (simulating user action)\n+ ServiceOrderPage.OpenEdit();\n+ ServiceOrderPage.Filter.SetFilter(\"No.\", ServiceHeader.\"No.\");\n+\n+ // [THEN] Verify initial status is Finished\n+ ServiceOrderPage.Status.AssertEquals(ServiceHeader.Status::Finished);\n+\n+ // [GIVEN] Add Service Item to the Service Item Lines subform\n+ ServiceOrderPage.ServItemLines.New();\n+ ServiceOrderPage.ServItemLines.ServiceItemNo.SetValue(ServiceItem.\"No.\");\n+ ServiceOrderPage.ServItemLines.Next(); // Move focus to trigger validation\n+\n+ // [THEN] Verify that Service Header Status has changed automatically\n+ ServiceOrderPage.Status.AssertEquals(ServiceHeader.Status::Pending); // Expected new status based on repair status priority\n+\n+ // [THEN] Verify the change was logged in Service Document Log\n+ ServiceHeader.Get(ServiceHeader.\"Document Type\", ServiceHeader.\"No.\");\n+ FinalStatus := ServiceHeader.Status;\n+\n+ // [THEN] Verify status actually changed\n+ Assert.AreNotEqual(InitialStatus, FinalStatus, ServiceOrderStatusShouldChangedErr);\n+ ServiceOrderPage.Close();\n+ end;\n+\n local procedure CreateServiceDocumentWithResourceWith100PctDisc(\n var ServiceHeader: Record \"Service Header\"; ServiceLine: Record \"Service Line\"; DocumentType: Enum \"Service Document Type\";\n CustomerNo: Code[20]; ResourceNo: Code[20]; Quantity: Decimal; UnitPrice: Decimal)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al b/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al\nindex 1c8fcc9eb8a..60fc813bbe7 100644\n--- a/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Service/Document/ServiceItemLine.Table.al\n@@ -201,6 +201,10 @@ table 5901 \"Service Item Line\"\n UseServItemLineAsxRec := true;\n Modify(true);\n end;\n+\n+ if Rec.\"Repair Status Code\" <> '' then\n+ Validate(\"Repair Status Code\", Rec.\"Repair Status Code\");\n+\n OnAfterValidateServiceItemNoOnBeforeUpdateResponseTimeHours(Rec, xRec);\n UpdateResponseTimeHours();\n CreateDimFromDefaultDim(0);\n"} +{"metadata": {"area": "reporting", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-219082", "base_commit": "908f59111599c95d0ba5af721b5ef34d8f4aac1f", "created_at": "2025-06-25", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136101, "functionName": ["PrintServiceOrderWithWorkDescription"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\nindex b74fec47106..55070a77a9a 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceOrders.Codeunit.al\n@@ -17,6 +17,7 @@ using Microsoft.Finance.VAT.Setup;\n using Microsoft.Foundation.Address;\n using Microsoft.Foundation.ExtendedText;\n using Microsoft.Foundation.NoSeries;\n+using Microsoft.Foundation.Reporting;\n using Microsoft.Foundation.Shipping;\n using Microsoft.Foundation.UOM;\n using Microsoft.Inventory.Item;\n@@ -5620,6 +5621,39 @@ codeunit 136101 \"Service Orders\"\n Assert.AreEqual(Customer[2].\"Country/Region Code\", ServiceHeader.\"VAT Country/Region Code\", VATCountryRegionLbl);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ServiceOrderReportRequestPageHandler')]\n+ procedure PrintServiceOrderWithWorkDescription()\n+ var\n+ Item: Record Item;\n+ ServiceHeader: Record \"Service Header\";\n+ ServiceItem: Record \"Service Item\";\n+ ServiceItemLine: Record \"Service Item Line\";\n+ ServiceLine: Record \"Service Line\";\n+ ServiceOrder: TestPage \"Service Order\";\n+ begin\n+ // [SCENARIO 575369] Verify Printing Service Order with Work Description does not throw error.\n+ Initialize();\n+\n+ // [GIVEN] Create Item\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create Service Order with Work Description\n+ LibraryService.CreateServiceItem(ServiceItem, LibrarySales.CreateCustomerNo());\n+ LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader.\"Document Type\"::Order, ServiceItem.\"Customer No.\");\n+ LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, ServiceItem.\"No.\");\n+ LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Item, Item.\"No.\");\n+\n+ // [WHEN] Open Service Order Card and click Print\n+ CreateCustomReportSelectionForCustomer(ServiceHeader.\"Customer No.\", \"Report Selection Usage\"::\"SM.Order\", 5900);\n+ ServiceOrder.OpenEdit();\n+ ServiceOrder.GotoRecord(ServiceHeader);\n+ ServiceOrder.WorkDescription.SetValue(LibraryRandom.RandText(20));\n+ ServiceOrder.\"&Print\".Invoke();\n+\n+ // [THEN] Verify no transaction error should occur.\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerTRUE(Question: Text[1024]; var Reply: Boolean)\n@@ -7923,6 +7957,23 @@ codeunit 136101 \"Service Orders\"\n exit(ServiceInvoiceHeader.\"No.\");\n end;\n \n+ local procedure CreateCustomReportSelectionForCustomer(CustomerNo: Code[20]; ReportSelectionUsage: Enum \"Report Selection Usage\"; ReportID: Integer)\n+ var\n+ CustomReportSelection: Record \"Custom Report Selection\";\n+ CustomReportLayout: Record \"Custom Report Layout\";\n+ begin\n+ CustomReportSelection.Init();\n+ CustomReportSelection.Validate(\"Source Type\", Database::Customer);\n+ CustomReportSelection.Validate(\"Source No.\", CustomerNo);\n+ CustomReportSelection.Validate(Usage, ReportSelectionUsage);\n+ CustomReportSelection.Validate(Sequence, 1);\n+ CustomReportSelection.Validate(\"Report ID\", ReportID);\n+ CustomReportSelection.Validate(\"Use for Email Body\", true);\n+ CustomReportSelection.Validate(\n+ \"Email Body Layout Code\", CustomReportLayout.InitBuiltInLayout(CustomReportSelection.\"Report ID\", CustomReportLayout.Type::Word.AsInteger()));\n+ CustomReportSelection.Insert(true);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmMessageHandler(Question: Text[1024]; var Reply: Boolean)\n@@ -8256,5 +8307,11 @@ codeunit 136101 \"Service Orders\"\n LibraryVariableStorage.Enqueue(CreditLimitNotification.CreditLimitDetails.OutstandingAmtLCY.Value);\n LibraryVariableStorage.Enqueue(CreditLimitNotification.CreditLimitDetails.TotalAmountLCY.Value);\n end;\n+\n+ [RequestPageHandler]\n+ procedure ServiceOrderReportRequestPageHandler(var ServiceOrder: TestRequestPage \"Service Order\")\n+ begin\n+ ServiceOrder.Cancel().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\nindex b1515adac7d..09f7b8b3998 100644\n--- a/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n+++ b/App/Layers/W1/BaseApp/Foundation/Reporting/ReportSelections.Table.al\n@@ -582,8 +582,11 @@ table 77 \"Report Selections\"\n \n IsHandled := false;\n OnBeforePrintDocument(TempReportSelections, IsGUI, RecVarToPrint, IsHandled);\n- if not IsHandled then\n+ if not IsHandled then begin\n+ if IsGUI then\n+ Commit();\n REPORT.RunModal(TempReportSelections.\"Report ID\", IsGUI, false, RecVarToPrint);\n+ end;\n \n OnAfterPrintDocument(TempReportSelections, IsGUI, RecVarToPrint, IsHandled);\n \n"} +{"metadata": {"area": "finance", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-216918", "base_commit": "1ea776a43bea699ee3b63beb68162372fcb1226f", "created_at": "2025-05-29", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134284, "functionName": ["JobJnlLineWithNonDeductNormalVATInFCYFromGenJnlLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al\nindex be592f1e578..e6b29da63e9 100644\n--- a/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDedVATMisc.Codeunit.al\n@@ -1135,6 +1135,52 @@ codeunit 134284 \"Non Ded. VAT Misc.\"\n Assert.RecordIsNotEmpty(GLEntry);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure JobJnlLineWithNonDeductNormalVATInFCYFromGenJnlLine()\n+ var\n+ Customer: Record Customer;\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ GenJnlLine: Record \"Gen. Journal Line\";\n+ JobJnlLine: Record \"Job Journal Line\";\n+ JobTransferLine: Codeunit \"Job Transfer Line\";\n+ DeductiblePercent: Decimal;\n+ begin\n+ // [FEATURE] [Normal VAT] [UT]\n+ // [SCENARIO 575793] Job journal line with FCY built from the general journal line includes non deductible VAT in \"Unit Cost\"\n+ Initialize();\n+ LibraryNonDeductibleVAT.SetUseForJobCost();\n+ // [GIVEN] VAT Posting Setup, where \"Tax Calculation Type\"::\"Normal VAT\", 'Deductible %' is '60'\n+ DeductiblePercent := LibraryRandom.RandInt(90);\n+ CreateNonDeductibleVATPostingSetup(VATPostingSetup, \"Tax Calculation Type\"::\"Normal VAT\", '', DeductiblePercent);\n+ // [GIVEN] Job \"X\" with currency which factor is 0.5\n+ LibrarySales.CreateCustomer(Customer);\n+ LibraryJob.CreateJob(Job, Customer.\"No.\");\n+ Job.Validate(\"Currency Code\", LibraryERM.CreateCurrencyWithRandomExchRates());\n+ Job.Modify(true);\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+ // [GIVEN] General journal line where line contains \"Non-Deductible VAT Amount\" = 100, \"Job No.\" = \"X\" \"Job Line Type\" = 'Billable'\n+ // [GIVEN] \"Job Quantity\" = 2, \"Job Unit Cost\" = 50\n+ CreateJobGLJournalLine(GenJnlLine, JobTask, VATPostingSetup);\n+\n+ // [WHEN] Run FromGenJnlLineToJnlLine\n+ JobTransferLine.FromGenJnlLineToJnlLine(GenJnlLine, JobJnlLine);\n+\n+ // [THEN] JobJnlLine contains \"Unit Cost LCY\" = (\"Job Unit Cost\" + \"Non-Deductible VAT Amount\") * \"Currency Factor\" / \"Job Quantity\" = (50 + 100) * 0.5 / 2 = 37.5\n+ Assert.AreEqual(\n+ Round(JobJnlLine.\"Unit Cost (LCY)\"),\n+ Round(GenJnlLine.\"Job Total Cost (LCY)\" / GenJnlLine.\"Job Quantity\") +\n+ Round(Round(GenJnlLine.\"Non-Deductible VAT Amount\" * GenJnlLine.\"Job Currency Factor\") / GenJnlLine.\"Job Quantity\"),\n+ 'Unit Cost (LCY) with Non-Deductible VAT amount is not correct in Job Journal Line');\n+ // [THEN] JobJnlLine contains \"Total Unit Cost\" = (\"Job Unit Cost\" + \"Non-Deductible VAT Amount\") * \"Currency Factor\" = (50 + 100) * 0.5 = 75\n+ Assert.AreEqual(\n+ Round(JobJnlLine.\"Total Cost (LCY)\"),\n+ Round(GenJnlLine.\"Job Total Cost (LCY)\" + Round(GenJnlLine.\"Non-Deductible VAT Amount\" * GenJnlLine.\"Job Currency Factor\")),\n+ 'Total Cost (LCY) with Non-Deductible VAT amount is not correct in Job Journal Line');\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1368,6 +1414,15 @@ codeunit 134284 \"Non Ded. VAT Misc.\"\n GenJournalLine.Modify(true);\n end;\n \n+ local procedure CreateJobGLJournalLine(var GenJournalLine: Record \"Gen. Journal Line\"; JobTask: Record \"Job Task\"; VATPostingSetup: Record \"VAT Posting Setup\")\n+ begin\n+ LibraryJob.CreateJobGLJournalLine(GenJournalLine.\"Job Line Type\"::Billable, JobTask, GenJournalLine);\n+ GenJournalLine.Validate(\"Gen. Posting Type\", GenJournalLine.\"Gen. Posting Type\"::Purchase);\n+ GenJournalLine.Validate(\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ GenJournalLine.Validate(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n+ GenJournalLine.Modify(true);\n+ end;\n+\n local procedure FindFAPostingGroup(GenProdPostingGroup: Code[20]; VATProductPostingGroup: Code[20]): Code[20]\n var\n FAPostingGroup: Record \"FA Posting Group\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\nindex 26f99dcabd6..f35c5e941b5 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n@@ -4937,16 +4937,7 @@ table 81 \"Gen. Journal Line\"\n TempJobJnlLine.Validate(\"No.\", \"Account No.\");\n TempJobJnlLine.Validate(Quantity, \"Job Quantity\");\n \n- if \"Currency Factor\" = 0 then begin\n- if \"Job Currency Factor\" = 0 then\n- TmpJobJnlOverallCurrencyFactor := 1\n- else\n- TmpJobJnlOverallCurrencyFactor := \"Job Currency Factor\";\n- end else\n- if \"Job Currency Factor\" = 0 then\n- TmpJobJnlOverallCurrencyFactor := 1 / \"Currency Factor\"\n- else\n- TmpJobJnlOverallCurrencyFactor := \"Job Currency Factor\" / \"Currency Factor\";\n+ TmpJobJnlOverallCurrencyFactor := GetGenJnlLineToJobCurrencyFactor();\n \n UpdateAmountsOnTempJobJnlLine(TmpJobJnlOverallCurrencyFactor);\n \n@@ -7628,6 +7619,22 @@ table 81 \"Gen. Journal Line\"\n RecordRestrictionMgt.RestrictRecordUsage(GenJournalLine, RestrictBatchUsageDetailsTxt);\n end;\n \n+ /// \n+ /// Calculates the currency factor for the general journal line based on the job currency factor and the journal line currency factor.\n+ /// \n+ /// Resulted currency factor\n+ procedure GetGenJnlLineToJobCurrencyFactor(): Decimal\n+ begin\n+ if \"Currency Factor\" = 0 then begin\n+ if \"Job Currency Factor\" = 0 then\n+ exit(1);\n+ exit(\"Job Currency Factor\");\n+ end;\n+ if \"Job Currency Factor\" = 0 then\n+ exit(1 / \"Currency Factor\");\n+ exit(\"Job Currency Factor\" / \"Currency Factor\");\n+ end;\n+\n /// \n /// Event triggered before creating dimensions from the Default Dimensions during the validation of the \"Account No.\" field.\n /// By subscribing to this event, developers can override the default dimension creation process for the \"Account No.\" field.\ndiff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex 2b5a6a4ca7e..c9d976f7272 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -17,6 +17,8 @@ using Microsoft.Foundation.Enums;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.History;\n using Microsoft.Foundation.Company;\n+using Microsoft.Projects.Project.Journal;\n+using Microsoft.Projects.Project.Job;\n \n /// \n /// Defines the implementation of Non-Deductible VAT\n@@ -436,6 +438,36 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n FALedgEntry.\"Non-Ded. VAT FA Cost\" := GenJnlLine.\"Non-Ded. VAT FA Cost\";\n end;\n \n+ procedure CopyNonDedVATFromGenJnlLineToJobJnlLine(var JobJnlLine: Record \"Job Journal Line\"; GenJnlLine: Record \"Gen. Journal Line\")\n+ var\n+ Job: Record Job;\n+ CurrencyFactor, NonDedVATAmountLCY, UnitCost, UnitCostLCY, TotalCost, TotalCostLCY : Decimal;\n+ begin\n+ if not UseNonDeductibleVATAmountForJobCost() then\n+ exit;\n+ if not Job.Get(JobJnlLine.\"Job No.\") then\n+ exit;\n+ NonDedVATAmountLCY := GenJnlLine.\"Non-Deductible VAT Amount LCY\";\n+ if GenJnlLine.\"Currency Code\" <> Job.\"Currency Code\" then begin\n+ CurrencyFactor := GenJnlLine.GetGenJnlLineToJobCurrencyFactor();\n+ NonDedVATAmountLCY := Round(GenJnlLine.\"Non-Deductible VAT Amount\" * CurrencyFactor);\n+ end;\n+ UnitCostLCY := Round(NonDedVATAmountLCY / JobJnlLine.Quantity);\n+ UnitCost := Round(GenJnlLine.\"Non-Deductible VAT Amount\" / JobJnlLine.Quantity);\n+ TotalCostLCY := NonDedVATAmountLCY;\n+ TotalCost := GenJnlLine.\"Non-Deductible VAT Amount\";\n+ if JobJnlLine.\"Unit Cost\" > 0 then begin\n+ UnitCostLCY := Abs(UnitCostLCY);\n+ UnitCost := Abs(UnitCost);\n+ TotalCostLCY := Abs(TotalCostLCY);\n+ TotalCost := Abs(TotalCost);\n+ end;\n+ JobJnlLine.\"Unit Cost (LCY)\" += UnitCostLCY;\n+ JobJnlLine.\"Unit Cost\" += UnitCost;\n+ JobJnlLine.\"Total Cost (LCY)\" += TotalCostLCY;\n+ JobJnlLine.\"Total Cost\" += TotalCost;\n+ end;\n+\n procedure CheckPrepmtWithNonDeductubleVATInPurchaseLine(PurchaseLine: Record \"Purchase Line\")\n begin\n if (PurchaseLine.\"Prepayment %\" <> 0) and (PurchaseLine.\"Non-Deductible VAT %\" <> 0) then\ndiff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al\nindex 216076f8cf0..4114e9a6815 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDeductibleVAT.Codeunit.al\n@@ -15,6 +15,7 @@ using Microsoft.FixedAssets.Ledger;\n using Microsoft.Foundation.Enums;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.History;\n+using Microsoft.Projects.Project.Journal;\n \n /// \n /// Provides an interface of the Non-Deductible VAT functionality.\n@@ -430,6 +431,11 @@ codeunit 6200 \"Non-Deductible VAT\"\n NonDedVATImpl.CopyNonDedVATFromGenJnlLineToFALedgEntry(FALedgEntry, GenJnlLine);\n end;\n \n+ procedure CopyNonDedVATFromGenJnlLineToJobJnlLine(var JobJnlLine: Record \"Job Journal Line\"; GenJnlLine: Record \"Gen. Journal Line\")\n+ begin\n+ NonDedVATImpl.CopyNonDedVATFromGenJnlLineToJobJnlLine(JobJnlLine, GenJnlLine);\n+ end;\n+\n /// \n /// Throws an error if purchase line contains prepayment and Non-Deductible VAT\n /// \ndiff --git a/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al\nindex d541dd087c6..50866220a3f 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Journal/JobTransferLine.Codeunit.al\n@@ -498,18 +498,7 @@ codeunit 1004 \"Job Transfer Line\"\n JobJnlLine.\"Total Cost (LCY)\" := GenJnlLine.\"Job Total Cost (LCY)\";\n JobJnlLine.\"Total Cost\" := GenJnlLine.\"Job Total Cost\";\n \n- if NonDeductibleVAT.UseNonDeductibleVATAmountForJobCost() then\n- if JobJnlLine.\"Unit Cost\" > 0 then begin\n- JobJnlLine.\"Unit Cost (LCY)\" += Abs(Round(GenJnlLine.\"Non-Deductible VAT Amount LCY\" / JobJnlLine.Quantity));\n- JobJnlLine.\"Unit Cost\" += Abs(Round(GenJnlLine.\"Non-Deductible VAT Amount\" / JobJnlLine.Quantity));\n- JobJnlLine.\"Total Cost (LCY)\" += Abs(GenJnlLine.\"Non-Deductible VAT Amount LCY\");\n- JobJnlLine.\"Total Cost\" += Abs(GenJnlLine.\"Non-Deductible VAT Amount\");\n- end else begin\n- JobJnlLine.\"Unit Cost (LCY)\" += Round(GenJnlLine.\"Non-Deductible VAT Amount LCY\" / JobJnlLine.Quantity);\n- JobJnlLine.\"Unit Cost\" += Round(GenJnlLine.\"Non-Deductible VAT Amount\" / JobJnlLine.Quantity);\n- JobJnlLine.\"Total Cost (LCY)\" += GenJnlLine.\"Non-Deductible VAT Amount LCY\";\n- JobJnlLine.\"Total Cost\" += GenJnlLine.\"Non-Deductible VAT Amount\";\n- end;\n+ NonDeductibleVAT.CopyNonDedVATFromGenJnlLineToJobJnlLine(JobJnlLine, GenJnlLine);\n \n JobJnlLine.\"Unit Price (LCY)\" := GenJnlLine.\"Job Unit Price (LCY)\";\n JobJnlLine.\"Unit Price\" := GenJnlLine.\"Job Unit Price\";\n"} +{"metadata": {"area": "service", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218856", "base_commit": "7bfa7e70c56ba44878906b722f59a492dc75f376", "created_at": "2025-06-23", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136102, "functionName": ["ChangeCustomerOfTypePeronInServiceContract"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al\nindex ad01a498eef..1b594959106 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceContracts.Codeunit.al\n@@ -10,6 +10,8 @@ using Microsoft.Finance.Dimension;\n using Microsoft.Finance.GeneralLedger.Account;\n using Microsoft.Finance.GeneralLedger.Ledger;\n using Microsoft.Finance.VAT.Setup;\n+using Microsoft.CRM.BusinessRelation;\n+using Microsoft.CRM.Contact;\n using Microsoft.Inventory.Item;\n using Microsoft.Projects.Resources.Resource;\n using Microsoft.Sales.Customer;\n@@ -42,6 +44,7 @@ codeunit 136102 \"Service Contracts\"\n var\n ServiceContractHeader2: Record \"Service Contract Header\";\n Assert: Codeunit Assert;\n+ LibraryMarketing: Codeunit \"Library - Marketing\";\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n LibraryService: Codeunit \"Library - Service\";\n LibraryUtility: Codeunit \"Library - Utility\";\n@@ -3563,6 +3566,49 @@ codeunit 136102 \"Service Contracts\"\n Assert.Equal('', Format(ServiceContractHeader.\"Last Invoice Period End\"));\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler,SignContractConfirmHandler,ServContrctTemplateListHandler')]\n+ [Scope('OnPrem')]\n+ procedure ChangeCustomerOfTypePeronInServiceContract()\n+ var\n+ ContactBusinessRelation: Record \"Contact Business Relation\";\n+ Contact: Record Contact;\n+ ServiceContractHeader: Record \"Service Contract Header\";\n+ ServiceContractLine: Record \"Service Contract Line\";\n+ ShiptoAddress: Record \"Ship-to Address\";\n+ ServContractManagement: Codeunit ServContractManagement;\n+ ContactCard: TestPage \"Contact Card\";\n+ begin\n+ // [SCENARIO 578655] Change Customer No. on Service Contract of Customer type Person.\n+ Initialize();\n+\n+ // [GIVEN] Create Contact of type Person.\n+ LibraryMarketing.CreatePersonContact(Contact);\n+\n+ // [GIVEN] Open Contact Card and invoke Create Customer.\n+ ContactCard.OpenEdit();\n+ ContactCard.Filter.SetFilter(\"No.\", Contact.\"No.\");\n+ ContactCard.CreateCustomer.Invoke();\n+\n+ // [GIVEN] Create Service Contract Header and Service Contract Line.\n+ CreateServiceContract(ServiceContractHeader, ServiceContractLine, ServiceContractHeader.\"Contract Type\"::Contract);\n+ ModifyServiceContractHeader(ServiceContractHeader, ServiceContractHeader.\"Service Period\");\n+\n+ // [GIVEN] Find Contact Business Relation of the Contact.\n+ ContactBusinessRelation.SetRange(\"Contact No.\", Contact.\"No.\");\n+ ContactBusinessRelation.SetRange(\"Link to Table\", ContactBusinessRelation.\"Link to Table\"::Customer);\n+ ContactBusinessRelation.FindFirst();\n+\n+ // [GIVEN] Create Ship to Address.\n+ LibrarySales.CreateShipToAddress(ShiptoAddress, ContactBusinessRelation.\"No.\");\n+\n+ // [WHEN] Change Customer No. in Service Contract.\n+ ServContractManagement.ChangeCustNoOnServContract(ShiptoAddress.\"Customer No.\", ShiptoAddress.Code, ServiceContractHeader);\n+\n+ // [THEN] Check Customer No. is updated.\n+ CheckChangeCustomerNo(ServiceContractHeader, ContactBusinessRelation.\"No.\");\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5358,6 +5404,11 @@ codeunit 136102 \"Service Contracts\"\n Error(MessageText);\n end;\n \n+ [MessageHandler]\n+ procedure MessageHandler(Message: Text[1024])\n+ begin\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure InvoiceConfirmHandler(ConfirmMessage: Text[1024]; var Result: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al b/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al\nindex 4f315c8f604..572b132d573 100644\n--- a/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Service/Contract/ServiceContractHeader.Table.al\n@@ -1389,7 +1389,7 @@ table 5965 \"Service Contract Header\"\n if (\"Bill-to Customer No.\" <> '') and (\"Bill-to Contact No.\" <> '') then begin\n Cont.Get(\"Bill-to Contact No.\");\n if ContBusinessRelation.FindByRelation(ContBusinessRelation.\"Link to Table\"::Customer, \"Bill-to Customer No.\") then\n- if ContBusinessRelation.\"Contact No.\" <> Cont.\"Company No.\" then\n+ if (ContBusinessRelation.\"Contact No.\" <> Cont.\"Company No.\") and (Cont.Type = Cont.Type::Company) then\n Error(Text045, Cont.\"No.\", Cont.Name, \"Bill-to Customer No.\");\n end;\n \n@@ -2240,6 +2240,7 @@ table 5965 \"Service Contract Header\"\n ContBusinessRelation: Record \"Contact Business Relation\";\n Cust: Record Customer;\n Cont: Record Contact;\n+ ContactBusinessRelationFound: Boolean;\n IsHandled: Boolean;\n begin\n IsHandled := false;\n@@ -2251,13 +2252,18 @@ table 5965 \"Service Contract Header\"\n \"Contact No.\" := Cont.\"No.\";\n \"Phone No.\" := Cont.\"Phone No.\";\n \"E-Mail\" := Cont.\"E-Mail\";\n- if Cont.Type = Cont.Type::Person then\n- \"Contact Name\" := Cont.Name\n- else\n+ if Cont.Type = Cont.Type::Person then begin\n+ \"Contact Name\" := Cont.Name;\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"No.\");\n+ end else begin\n+ if not ContactBusinessRelationFound then\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\");\n+\n if Cust.Get(\"Customer No.\") then\n \"Contact Name\" := Cust.Contact\n else\n \"Contact Name\" := ''\n+ end;\n end else begin\n \"Contact Name\" := '';\n \"Phone No.\" := '';\n@@ -2265,7 +2271,7 @@ table 5965 \"Service Contract Header\"\n exit;\n end;\n \n- if ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\") then begin\n+ if ContactBusinessRelationFound then begin\n if (\"Customer No.\" <> '') and\n (\"Customer No.\" <> ContBusinessRelation.\"No.\")\n then\n@@ -2289,23 +2295,29 @@ table 5965 \"Service Contract Header\"\n ContBusinessRelation: Record \"Contact Business Relation\";\n Cust: Record Customer;\n Cont: Record Contact;\n+ ContactBusinessRelationFound: Boolean;\n begin\n if Cont.Get(ContactNo) then begin\n \"Bill-to Contact No.\" := Cont.\"No.\";\n- if Cont.Type = Cont.Type::Person then\n- \"Bill-to Contact\" := Cont.Name\n- else\n+ if Cont.Type = Cont.Type::Person then begin\n+ \"Bill-to Contact\" := Cont.Name;\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"No.\");\n+ end else begin\n+ if not ContactBusinessRelationFound then\n+ ContactBusinessRelationFound := ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\");\n+\n if Cust.Get(\"Bill-to Customer No.\") then\n \"Bill-to Contact\" := Cust.Contact\n else\n \"Bill-to Contact\" := '';\n+ end;\n end else begin\n \"Bill-to Contact\" := '';\n exit;\n end;\n \n OnUpdateBillToCustOnBeforeContBusinessRelationFindByContact(Rec, Cust, Cont);\n- if ContBusinessRelation.FindByContact(ContBusinessRelation.\"Link to Table\"::Customer, Cont.\"Company No.\") then begin\n+ if ContactBusinessRelationFound then begin\n if \"Bill-to Customer No.\" = '' then begin\n SkipBillToContact := true;\n Validate(\"Bill-to Customer No.\", ContBusinessRelation.\"No.\");\n"} +{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-215225", "base_commit": "cc7b76c98d2c241ae675ae9b79fe1b634617ec36", "created_at": "2025-05-12", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136305, "functionName": ["CheckUnitCostAndPriceNotZeroInRecurringJobJnlAfterPosting"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\nindex e427075ebd9..1a379eb28aa 100644\n--- a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n@@ -2938,6 +2938,35 @@ codeunit 136305 \"Job Journal\"\n Assert.AreNotEqual(GenJournalLine.\"Job Total Cost (LCY)\", PreviousProjectTotalCostLCY, ProjectTotalCostErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerTrue,MessageHandler')]\n+ procedure CheckUnitCostAndPriceNotZeroInRecurringJobJnlAfterPosting()\n+ var\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ Resource: Record Resource;\n+ RecurringJobJnl: TestPage \"Recurring Job Jnl.\";\n+ begin\n+ // [SCENARIO 575092] Verify that the Unit Price and Unit Cost are not 0 in the recurring job journal after posting.\n+ Initialize();\n+\n+ // [GIVEN] Create a Resource.\n+ FindResource(Resource);\n+\n+ // [GIVEN] Create Job, job task & multiple Job planning line.\n+ CreateFullJob(Job, JobTask, Resource);\n+\n+ // [GIVEN] Create Recurring Job Journal.\n+ OpenRecurringJobJnl(RecurringJobJnl, JobTask, Resource.\"No.\");\n+\n+ // [WHEN] Post Recurring Job Journal.\n+ PostRecurringJobJnl(RecurringJobJnl);\n+\n+ // [THEN] Verify that the Unit Price and Unit Cost are not zero in the recurring job journal after posting.\n+ RecurringJobJnl.\"Unit Price\".AssertEquals(Resource.\"Unit Price\");\n+ RecurringJobJnl.\"Unit Cost\".AssertEquals(Resource.\"Unit Cost\");\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3917,6 +3946,51 @@ codeunit 136305 \"Job Journal\"\n JobJnlLine.TestField(\"Reserved Qty. (Base)\", 0);\n end;\n \n+ local procedure FindResource(var Resource: Record Resource)\n+ begin\n+ Resource.Get(LibraryJob.CreateConsumable(\"Job Planning Line Type\"::Resource));\n+ Resource.Validate(Type, Resource.Type::Person);\n+ Resource.Validate(\"Unit Cost\", LibraryRandom.RandIntInRange(100, 200));\n+ Resource.Validate(\"Unit Price\", LibraryRandom.RandIntInRange(300, 500));\n+ Resource.Modify(true);\n+ end;\n+\n+ local procedure CreateFullJob(var Job: Record Job; var JobTask: Record \"Job Task\"; Resource: Record Resource)\n+ var\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ begin\n+ LibraryJob.CreateJob(Job);\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+\n+ LibraryJob.CreateJobPlanningLine(\n+ JobTask, JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\",\n+ JobPlanningLine.Type::Resource, Resource.\"No.\", LibraryRandom.RandInt(10), JobPlanningLine);\n+ end;\n+\n+ local procedure OpenRecurringJobJnl(var RecurringJobJnl: TestPage \"Recurring Job Jnl.\"; JobTask: Record \"Job Task\"; ResourceNo: Code[20])\n+ var\n+ JobJournalLineType: Enum \"Job Journal Line Type\";\n+ RecurringMethod: Option ,Fixed,Variable;\n+ begin\n+ RecurringJobJnl.OpenEdit();\n+ RecurringJobJnl.\"Recurring Method\".SetValue(Format(RecurringMethod::Variable));\n+ RecurringJobJnl.\"Recurring Frequency\".SetValue('10D');\n+ RecurringJobJnl.\"Document No.\".SetValue(JobTask.\"Job No.\");\n+ RecurringJobJnl.\"Job No.\".SetValue(JobTask.\"Job No.\");\n+ RecurringJobJnl.\"Job Task No.\".SetValue(JobTask.\"Job Task No.\");\n+ RecurringJobJnl.Type.SetValue(Format(JobJournalLineType::Resource));\n+ RecurringJobJnl.\"No.\".SetValue(ResourceNo);\n+ RecurringJobJnl.Quantity.SetValue(Format(LibraryRandom.RandInt(5)));\n+ RecurringJobJnl.Close();\n+ end;\n+\n+ local procedure PostRecurringJobJnl(var RecurringJobJnl: TestPage \"Recurring Job Jnl.\")\n+ begin\n+ RecurringJobJnl.OpenEdit();\n+ RecurringJobJnl.\"P&ost\".Invoke();\n+ Commit();\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListPageHandler(var ContactList: TestPage \"Contact List\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al\nindex 9f7bd75b991..57af0bb5690 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobJnlPostBatch.Codeunit.al\n@@ -275,6 +275,7 @@ codeunit 1013 \"Job Jnl.-Post Batch\"\n \n local procedure UpdateAndDeleteLines()\n var\n+ UnitCost, UnitPrice : Decimal;\n IsHandled: Boolean;\n begin\n OnBeforeUpdateAndDeleteLines(JobJnlLine);\n@@ -295,8 +296,12 @@ codeunit 1013 \"Job Jnl.-Post Batch\"\n JobJnlLine2.Validate(\"Posting Date\", CalcDate(JobJnlLine2.\"Recurring Frequency\", JobJnlLine2.\"Posting Date\"));\n if (JobJnlLine2.\"Recurring Method\" = JobJnlLine2.\"Recurring Method\"::Variable) and\n (JobJnlLine2.\"No.\" <> '')\n- then\n+ then begin\n+ UnitCost := JobJnlLine2.\"Unit Cost\";\n+ UnitPrice := JobJnlLine2.\"Unit Price\";\n JobJnlLine2.DeleteAmounts();\n+ UpdateUnitCostAndPrice(JobJnlLine2, UnitCost, UnitPrice);\n+ end;\n JobJnlLine2.Modify();\n until JobJnlLine2.Next() = 0;\n end else begin\n@@ -339,6 +344,15 @@ codeunit 1013 \"Job Jnl.-Post Batch\"\n NoSeriesBatch.SaveState();\n end;\n \n+ local procedure UpdateUnitCostAndPrice(var JobJournalLine: Record \"Job Journal Line\"; UnitCost: Decimal; UnitPrice: Decimal)\n+ begin\n+ if (UnitCost = 0) and (UnitPrice = 0) then\n+ exit;\n+\n+ JobJournalLine.\"Unit Cost\" := UnitCost;\n+ JobJournalLine.\"Unit Price\" := UnitPrice;\n+ end;\n+\n procedure SetSuppressCommit(NewSuppressCommit: Boolean)\n begin\n SuppressCommit := NewSuppressCommit;\n"} +{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213629", "base_commit": "e0211616ed03e968b987e2becd1069b217690c34", "created_at": "2025-04-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136306, "functionName": ["CopyJobAndCreateProjectJournalLineWithoutError"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\nindex 36cc3d9db4a..369594bf631 100644\n--- a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n@@ -58,6 +58,7 @@ codeunit 136306 \"Job Invoicing\"\n DetailLevel: Option All,\"Per Job\",\"Per Job Task\",\"Per Job Planning Line\";\n LineDiscountPctErr: Label '%1 should be %2', Comment = '%1 = Field Caption, %2 = Field Value';\n WrongNoOfLinesLbl: Label 'Wrong number of lines created.';\n+ ValueFalseErr: Label 'Value must be equal to false';\n \n [Test]\n [HandlerFunctions('TransferToInvoiceHandler,MessageHandler')]\n@@ -4043,6 +4044,44 @@ codeunit 136306 \"Job Invoicing\"\n Assert.AreEqual(1, InvoicesList.Count, WrongNoOfLinesLbl);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler,ConfirmHandler')]\n+ [Scope('OnPrem')]\n+ procedure CopyJobAndCreateProjectJournalLineWithoutError()\n+ var\n+ Job: Record Job;\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ JobTask: Record \"Job Task\";\n+ JobJournalLine: Record \"Job Journal Line\";\n+ CopyJob: Codeunit \"Copy Job\";\n+ JobLineType: Enum \"Job Line Type\";\n+ TargetJobNo: Code[20];\n+ begin\n+ // [SCENARIO 573397] Copy project of System-Created Entry must be equal to 'No' in Project Planning Line\n+ Initialize();\n+\n+ // [GIVEN] Create Job with Customer\n+ CreateJobWithCustomer(Job);\n+\n+ // [GIVEN] Create Job Task\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+\n+ // [GIVEN] Create Job Journal Line of type \"Both Budget and Billable\" and post it.\n+ CreateAndPostJobJournalLineWithIteAndType(JobJournalLine, JobTask, JobLineType::\"Both Budget and Billable\");\n+\n+ // [GIVEN] Create target Job Id\n+ TargetJobNo := LibraryUtility.GenerateGUID();\n+\n+ // [WHEN] Copy Job by setting Copy Quantity as true.\n+ CopyJob.SetCopyOptions(false, true, false, 0, 0, 0);\n+ CopyJob.CopyJob(Job, TargetJobNo, TargetJobNo, Job.\"Bill-to Customer No.\", '');\n+\n+ // [THEN] Find the created Job Planning Line and \"System-Created Entry\" should be set false\n+ JobPlanningLine.SetRange(\"Job No.\", TargetJobNo);\n+ JobPlanningLine.FindFirst();\n+ Assert.IsFalse(JobPlanningLine.\"System-Created Entry\", ValueFalseErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5676,6 +5715,20 @@ codeunit 136306 \"Job Invoicing\"\n until JobPlanningLine.Next() = 0;\n end;\n \n+ local procedure CreateAndPostJobJournalLineWithIteAndType(var JobJournalLine: Record \"Job Journal Line\"; JobTask: Record \"Job Task\"; JobLineType: Enum \"Job Line Type\")\n+ var\n+ Item: Record Item;\n+ begin\n+ LibraryInventory.CreateItem(Item);\n+ LibraryJob.CreateJobJournalLine(JobLineType, JobTask, JobJournalLine);\n+ JobJournalLine.Validate(Type, JobJournalLine.Type::Item);\n+ JobJournalLine.Validate(\"No.\", Item.\"No.\");\n+ JobJournalLine.Validate(Quantity, LibraryRandom.RandInt(100));\n+ JobJournalLine.Modify(true);\n+\n+ LibraryJob.PostJobJournal(JobJournalLine);\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure TransferSalesCreditMemoReportWithDatesHandler(var JobTransferToCreditMemo: TestRequestPage \"Job Transfer to Credit Memo\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al\nindex 162d6cc55e7..544c740a441 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Job/CopyJob.Codeunit.al\n@@ -192,6 +192,7 @@ codeunit 1006 \"Copy Job\"\n TargetJobPlanningLine.\"Completely Picked\" := false;\n TargetJobPlanningLine.\"Ledger Entry No.\" := 0;\n TargetJobPlanningLine.\"Ledger Entry Type\" := TargetJobPlanningLine.\"Ledger Entry Type\"::\" \";\n+ TargetJobPlanningLine.\"System-Created Entry\" := false;\n OnCopyJobPlanningLinesOnBeforeTargetJobPlanningLineInsert(TargetJobPlanningLine, SourceJobPlanningLine);\n TargetJobPlanningLine.Insert(true);\n OnCopyJobPlanningLinesOnAfterTargetJobPlanningLineInsert(TargetJobPlanningLine, SourceJobPlanningLine);\n"} +{"metadata": {"area": "intercompany", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213524", "base_commit": "594d5dfcee2efe390ab75b6b0e30bc5a9f13f7f0", "created_at": "2025-04-16", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134154, "functionName": ["ICNavigateFromSalesCreditMemoLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al\nindex 0480aea9fa6..3ca288e85d2 100644\n--- a/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMIntercompanyIII.Codeunit.al\n@@ -3408,6 +3408,40 @@ codeunit 134154 \"ERM Intercompany III\"\n Assert.AreEqual(300, SalesLine.\"Line Amount\", 'When a sales order with a discount amount and prices including VAT is received from intercompany, the line amount should be preserved');\n end;\n \n+ [Test]\n+ procedure ICNavigateFromSalesCreditMemoLine()\n+ var\n+ Customer: Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ ICOutboxTransactions: TestPage \"IC Outbox Transactions\";\n+ PostedSalesCreditMemo: TestPage \"Posted Sales Credit Memo\";\n+ begin\n+ // [SCENARIO 574577] \"Unable to navigate to the related document\" error message if you use Go to Document from the Intercompany Outbox Transactions for a Credit Memo.\n+ Initialize();\n+ LibraryApplicationArea.EnableEssentialSetup();\n+ CleanupIC(false, true, true, false);\n+ CreateCustomerWithICPartner(Customer);\n+\n+ // [GIVEN] A posted sales credit memo to an IC customer\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::\"Credit Memo\", Customer.\"No.\");\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, LibraryInventory.CreateItemNo(), 1);\n+ LibrarySales.PostSalesDocument(SalesHeader, true, true);\n+\n+ // [GIVEN] The posted sales credit memo IC transaction should be on the Outbox\n+ ICOutboxTransactions.OpenEdit();\n+\n+ // [WHEN] Navigating from Outbox for this transaction\n+ PostedSalesCreditMemo.Trap();\n+ ICOutboxTransactions.GoToDocument.Invoke();\n+\n+ // [THEN] It should open the Posted Sales Credit Memo\n+ PostedSalesCreditMemo.\"Pre-Assigned No.\".AssertEquals(SalesHeader.\"No.\");\n+\n+ // Cleanup\n+ CleanupIC(false, true, true, false);\n+ end;\n+\n local procedure Initialize()\n var\n ICSetup: Record \"IC Setup\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al b/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al\nindex 92bf43b1d84..944f49028e6 100644\n--- a/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/Intercompany/ICNavigation.Codeunit.al\n@@ -56,6 +56,20 @@ codeunit 437 \"IC Navigation\"\n exit(true);\n end;\n \n+ local procedure NavigateToSalesCreditMemo(DocumentNo: Code[20]): Boolean\n+ var\n+ SalesCrMemoHeader: Record \"Sales Cr.Memo Header\";\n+ PostedSalesCreditMemo: Page \"Posted Sales Credit Memo\";\n+ begin\n+ // An IC Transaction of type Sales Credit Memo can only be sent when posted.\n+ if not SalesCrMemoHeader.Get(DocumentNo) then\n+ exit(false);\n+ // The related document is a Posted Sales Credit Memo.\n+ PostedSalesCreditMemo.SetRecord(SalesCrMemoHeader);\n+ PostedSalesCreditMemo.Run();\n+ exit(true);\n+ end;\n+\n local procedure NavigateToSalesInvoice(DocumentNo: Code[20]; ICPartnerCode: Code[20]): Boolean\n var\n Customer: Record Customer;\n@@ -120,6 +134,8 @@ codeunit 437 \"IC Navigation\"\n exit(NavigateToSalesOrderDocument(DocumentNo, ICDirectionType, ICPartnerCode));\n DocumentType::Invoice:\n exit(NavigateToSalesInvoice(DocumentNo));\n+ DocumentType::\"Credit Memo\":\n+ exit(NavigateToSalesCreditMemo(DocumentNo));\n else begin\n ShouldNavigateToDoc := false;\n OnNavigateToSalesDocumentOnAfterCheckDocumentType(DocumentNo, ICDirectionType, ICPartnerCode, DocumentType, ShouldNavigateToDoc);\n"} +{"metadata": {"area": "inventory", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213741", "base_commit": "aba5cc540cc2ff7bfc88064b9c6728b32f120fce", "created_at": "2025-04-22", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Assembly"], "FAIL_TO_PASS": [{"codeunitID": 137911, "functionName": ["VerifyAdjustCostItemEntriesMustBeExecutedForAssemblyItem"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al b/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al\nindex 46d1c5d5be0..55f596ef397 100644\n--- a/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Assembly/SCMCalculateAssemblyCost.Codeunit.al\n@@ -40,6 +40,7 @@ codeunit 137911 \"SCM Calculate Assembly Cost\"\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n+ LibraryManufacturing: Codeunit \"Library - Manufacturing\";\n WorkDate2: Date;\n TEXT_PARENT: Label 'Parent';\n TEXT_CHILD: Label 'Child';\n@@ -452,6 +453,54 @@ codeunit 137911 \"SCM Calculate Assembly Cost\"\n ComponentItem.\"Standard Cost\", ComponentItem.\"Standard Cost\" * CurrExchRate);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ procedure VerifyAdjustCostItemEntriesMustBeExecutedForAssemblyItem()\n+ var\n+ AssemblyItem, ComponentItem, NonInvItem : Record Item;\n+ ValueEntry: Record \"Value Entry\";\n+ begin\n+ // [SCENARIO 574360] Verify \"Adjust Cost - Item Entries\" must be executed for Assembly item which include non-Inventory item in Assembly BOM.\n+ // When \"Automatic Cost Posting\" is false in Inventory Setup and \"Inc. Non. Inv. Cost To Prod\" is true in Mfg Setup.\n+ Initialize();\n+\n+ // [GIVEN] Set Automatic Cost Posting to false.\n+ LibraryInventory.SetAutomaticCostPosting(false);\n+\n+ // [GIVEN] Update \"Inc. Non. Inv. Cost To Prod\" in Manufacturing Setup.\n+ LibraryManufacturing.UpdateNonInventoryCostToProductionInManufacturingSetup(true);\n+\n+ // [GIVEN] Create an Assembled item with \"Costing Method\"::Standard.\n+ CreateItem(AssemblyItem, AssemblyItem.\"Costing Method\"::Standard, AssemblyItem.\"Replenishment System\"::Assembly, 0);\n+\n+ // [GIVEN] Create an Component item with \"Costing Method\"::FIFO.\n+ CreateItem(ComponentItem, ComponentItem.\"Costing Method\"::FIFO, ComponentItem.\"Replenishment System\"::Purchase, LibraryRandom.RandIntInRange(100, 200));\n+\n+ // [GIVEN] Create Non-Inventory item with Unit Cost.\n+ LibraryInventory.CreateNonInventoryTypeItem(NonInvItem);\n+ NonInvItem.Validate(\"Unit Cost\", LibraryRandom.RandIntInRange(200, 500));\n+ NonInvItem.Modify();\n+\n+ // [GIVEN] Post Positive Adjustment for Component item.\n+ PostPositiveAdjustment(ComponentItem.\"No.\", LibraryRandom.RandIntInRange(200, 500));\n+\n+ // [GIVEN] Create Assembly List for Component and Non-Inventory item.\n+ CreateAssemblyListComponent(AssemblyItem.\"No.\", ComponentItem.\"No.\", 1);\n+ CreateAssemblyListComponent(AssemblyItem.\"No.\", NonInvItem.\"No.\", 1);\n+\n+ // [GIVEN] Create and post Assembly Order.\n+ CreateAndPostAssemblyHeader(AssemblyItem.\"No.\", 1, WorkDate());\n+\n+ // [WHEN] Run \"Adjust Cost - Item Entries\"\n+ LibraryCosting.AdjustCostItemEntries(AssemblyItem.\"No.\", '');\n+\n+ // [THEN] Verify \"Adjust Cost - Item Entries\" must be executed for Assembly item.\n+ ValueEntry.SetRange(\"Item Ledger Entry Type\", ValueEntry.\"Item Ledger Entry Type\"::\"Assembly Output\");\n+ ValueEntry.SetRange(\"Entry Type\", ValueEntry.\"Entry Type\"::\"Direct Cost - Non Inventory\");\n+ ValueEntry.SetRange(\"Item No.\", AssemblyItem.\"No.\");\n+ Assert.RecordCount(ValueEntry, 0);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"SCM Calculate Assembly Cost\");\n@@ -585,5 +634,10 @@ codeunit 137911 \"SCM Calculate Assembly Cost\"\n ItemLedgerEntry.TestField(\"Cost Amount (Actual)\", ExpectedCostLCY);\n ItemLedgerEntry.TestField(\"Cost Amount (Actual) (ACY)\", Round(ExpectedCostACY, Currency.\"Amount Rounding Precision\"));\n end;\n+\n+ [MessageHandler]\n+ procedure MessageHandler(Message: Text[1024])\n+ begin\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al\nindex 9bc596d4312..92b2588e89d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Costing/CalcInventoryAdjmtOrder.Codeunit.al\n@@ -158,10 +158,12 @@ codeunit 5896 \"Calc. Inventory Adjmt. - Order\"\n if HasNewCost(InventoryAdjmtEntryOrder.\"Indirect Cost\", InventoryAdjmtEntryOrder.\"Indirect Cost (ACY)\") then\n InventoryAdjustmentBuffer.AddCost(\n ItemLedgerEntry.\"Entry No.\", InventoryAdjustmentBuffer.\"Entry Type\"::\"Indirect Cost\", \"Cost Variance Type\"::\" \", InventoryAdjmtEntryOrder.\"Indirect Cost\", InventoryAdjmtEntryOrder.\"Indirect Cost (ACY)\");\n- if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n- if HasNewCost(InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\") then\n- InventoryAdjustmentBuffer.AddCost(\n- ItemLedgerEntry.\"Entry No.\", InventoryAdjustmentBuffer.\"Entry Type\"::\"Direct Cost - Non Inventory\", \"Cost Variance Type\"::\" \", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\");\n+\n+ if ItemLedgerEntry.\"Order Type\" = ItemLedgerEntry.\"Order Type\"::Production then\n+ if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n+ if HasNewCost(InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\") then\n+ InventoryAdjustmentBuffer.AddCost(\n+ ItemLedgerEntry.\"Entry No.\", InventoryAdjustmentBuffer.\"Entry Type\"::\"Direct Cost - Non Inventory\", \"Cost Variance Type\"::\" \", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inventory\", InventoryAdjmtEntryOrder.\"Direct Cost Non-Inv. (ACY)\");\n \n if Item.\"Costing Method\" <> Item.\"Costing Method\"::Standard then\n exit;\n@@ -171,11 +173,12 @@ codeunit 5896 \"Calc. Inventory Adjmt. - Order\"\n InventoryAdjustmentBuffer.\"Entry Type\"::Variance, InventoryAdjustmentBuffer.\"Variance Type\"::Material,\n InventoryAdjmtEntryOrder.\"Single-Level Material Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Material Cost (ACY)\");\n \n- if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n- if HasNewCost(InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\") then\n- InventoryAdjustmentBuffer.AddCost(ItemLedgerEntry.\"Entry No.\",\n- InventoryAdjustmentBuffer.\"Entry Type\"::Variance, InventoryAdjustmentBuffer.\"Variance Type\"::\"Material - Non Inventory\",\n- InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\");\n+ if ItemLedgerEntry.\"Order Type\" = ItemLedgerEntry.\"Order Type\"::Production then\n+ if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then\n+ if HasNewCost(InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\") then\n+ InventoryAdjustmentBuffer.AddCost(ItemLedgerEntry.\"Entry No.\",\n+ InventoryAdjustmentBuffer.\"Entry Type\"::Variance, InventoryAdjustmentBuffer.\"Variance Type\"::\"Material - Non Inventory\",\n+ InventoryAdjmtEntryOrder.\"Single-Lvl Mat. Non-Invt. Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Mat.NonInvCost(ACY)\");\n \n if HasNewCost(InventoryAdjmtEntryOrder.\"Single-Level Capacity Cost\", InventoryAdjmtEntryOrder.\"Single-Lvl Capacity Cost (ACY)\") then\n InventoryAdjustmentBuffer.AddCost(ItemLedgerEntry.\"Entry No.\",\n"} +{"metadata": {"area": "manufacturing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-206527", "base_commit": "d8e867062d4137cf5df2d9d2b8a71bb53210f685", "created_at": "2025-02-07", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137088, "functionName": ["ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\nindex 7415eaa53cc..2573227dbca 100644\n--- a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n@@ -45,6 +45,8 @@ codeunit 137088 \"SCM Order Planning - III\"\n LineExistErr: Label 'Requistion line in %1 worksheet should exist for item %2';\n PurchaseLineQuantityBaseErr: Label '%1.%2 must be nearly equal to %3.', Comment = '%1 : Purchase Line, %2 : Quantity (Base), %3 : Value.';\n BOMFixedQtyCalcFormulaErr: Label 'BOM Fixed Quantity Calculation Formula should be used to calculate the values.';\n+ RelesedProdOrderComponentQtyPerRoundingErr: Label 'Relesed Production Order Item Component Quantity per %1 Not Match With Expected Result %2';\n+ RelesedProdOrderComponentExpQtyRoundingErr: Label 'Relesed Production Order Item Component Expected Quantity %1 Not Match With Expected Result %2';\n \n [Test]\n [HandlerFunctions('MakeSupplyOrdersPageHandler')]\n@@ -2988,6 +2990,73 @@ codeunit 137088 \"SCM Order Planning - III\"\n VerifyStartingTimeOnFirmPlannedProductionOrder(StartingTime, ChildItem.\"No.\", ProductionOrderNo);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalPageHandler,ErrorMessageHandler')]\n+ procedure ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking()\n+ var\n+ BaseItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ComponentItem: Record Item;\n+ ProdOrderComp: Record \"Prod. Order Component\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ ProductItem: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ ExpectedQty: Decimal;\n+ RelesedProdOrderNo: Code[20];\n+ Status: Enum \"Production Order Status\";\n+ begin\n+ // [SCENARIO 562766] If a component's Item UOM has a 'Quantity Rounding Precision' of 1, & a Finished Good consumes partial quantity, \n+ // the Prod. Order created from the Planning of a Sales Order pulls in the Component with a 'Qty. Per' and 'Exp. Qty.' of 0.\n+ Initialize();\n+\n+ // [GIVEN] Created Component Item\n+ LibraryInventory.CreateItem(ComponentItem);\n+ ComponentItem.Validate(\"Replenishment System\", ComponentItem.\"Replenishment System\"::Purchase);\n+ ComponentItem.Validate(\"Rounding Precision\", LibraryRandom.RandPrecision());\n+ ComponentItem.Validate(\"Reordering Policy\", ComponentItem.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ ComponentItem.Validate(\"Include Inventory\", true);\n+ ComponentItem.Modify(true);\n+\n+ // [GIVEN] Set Qty. Rounding Precision = 1 for Component Item\n+ BaseItemUnitOfMeasure.Get(ComponentItem.\"No.\", ComponentItem.\"Base Unit of Measure\");\n+ BaseItemUnitOfMeasure.Validate(\"Qty. Rounding Precision\", 1);\n+ BaseItemUnitOfMeasure.Modify();\n+\n+ // [GIVEN] Created Production Bom using Component Item\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ComponentItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, ComponentItem.\"No.\", LibraryRandom.RandDecInDecimalRange(0.01, 0.99, 2));\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify();\n+\n+ // [GIVEN] Created Master Item and Production Bom Assigned to Master Item\n+ LibraryInventory.CreateItem(ProductItem);\n+ ProductItem.Validate(\"Replenishment System\", ProductItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProductItem.Validate(\"Rounding Precision\", 1);\n+ ProductItem.Validate(\"Reordering Policy\", ProductItem.\"Reordering Policy\"::Order);\n+ ProductItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProductItem.Modify(true);\n+\n+ // [GIVEN] Created Sales Order Using Master Item Quantity - 1\n+ CreateSalesOrder(SalesHeader, ProductItem.\"No.\", '', 1, 1);\n+\n+ // [WHEN] Created Released Prod. Order From Sales Order Using Planning\n+ LibraryPlanning.CreateProdOrderUsingPlanning(ProductionOrder, Status::\"Firm Planned\", SalesHeader.\"No.\", ProductItem.\"No.\");\n+ RelesedProdOrderNo := LibraryManufacturing.ChangeStatusFirmPlanToReleased(ProductionOrder.\"No.\");\n+\n+ // [WHEN] Find Released Production Order Component\n+ FindProdOrderLine(ProdOrderLine, RelesedProdOrderNo);\n+ FindProdOrderComponent(ProdOrderComp, ProdOrderLine.\"Prod. Order No.\", ComponentItem.\"No.\");\n+\n+ // [WHEN] Getting Expected result using Component Rounding Precision\n+ ExpectedQty := Round(ProductionBOMLine.\"Quantity per\" * BaseItemUnitOfMeasure.\"Qty. Rounding Precision\" / BaseItemUnitOfMeasure.\"Qty. Rounding Precision\", ComponentItem.\"Rounding Precision\");\n+\n+ // [THEN] Expected Quantity must be Equal to Production Order Component \"Quantity per\" And \"Expected Quantity\"\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Quantity per\", StrSubstNo(RelesedProdOrderComponentQtyPerRoundingErr, ProdOrderComp.\"Quantity per\", ExpectedQty));\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Expected Quantity\", StrSubstNo(RelesedProdOrderComponentExpQtyRoundingErr, ProdOrderComp.\"Expected Quantity\", ExpectedQty));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3805,6 +3874,14 @@ codeunit 137088 \"SCM Order Planning - III\"\n Assert.IsTrue(ProductionOrder.\"Starting Time\" = StartingTime, '');\n end;\n \n+ local procedure FindProdOrderLine(var ProdOrderLine: Record \"Prod. Order Line\"; ProductionOrderNo: Code[20])\n+ begin\n+ ProdOrderLine.Reset();\n+ ProdOrderLine.SetRange(Status, ProdOrderLine.Status::Released);\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProductionOrderNo);\n+ ProdOrderLine.FindFirst();\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure MakeSupplyOrdersPageHandler(var MakeSupplyOrders: Page \"Make Supply Orders\"; var Response: Action)\n@@ -3911,5 +3988,16 @@ codeunit 137088 \"SCM Order Planning - III\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ procedure ModalPageHandler(var CreateOrderFromSales: Page \"Create Order From Sales\"; var Response: Action)\n+ begin\n+ Response := Action::Yes;\n+ end;\n+\n+ [MessageHandler]\n+ procedure ErrorMessageHandler(Message: Text[1024])\n+ begin\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\nindex 36930a9e2aaa..5d44df0a5969 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n@@ -43,6 +43,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp: Record \"Prod. Order Component\";\n ProdOrderRoutingLine2: Record \"Prod. Order Routing Line\";\n ProdBOMLine: array[99] of Record \"Production BOM Line\";\n+ ProdLineItem: Record Item;\n UOMMgt: Codeunit \"Unit of Measure Management\";\n MfgCostCalcMgt: Codeunit \"Mfg. Cost Calculation Mgt.\";\n VersionMgt: Codeunit VersionManagement;\n@@ -260,8 +261,8 @@ codeunit 99000773 \"Calculate Prod. Order\"\n \n local procedure TransferBOMProcessItem(Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var ErrorOccured: Boolean)\n var\n- Item2: Record Item;\n ComponentSKU: Record \"Stockkeeping Unit\";\n+ Item2: Record Item;\n IsHandled: Boolean;\n QtyRoundPrecision: Decimal;\n begin\n@@ -297,6 +298,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp.Validate(\"Unit of Measure Code\", ProdBOMLine[Level].\"Unit of Measure Code\");\n if (ProdOrderComp.\"Item No.\" <> '') and Item2.Get(ProdOrderComp.\"Item No.\") then\n QtyRoundPrecision := UOMMgt.GetQtyRoundingPrecision(Item2, ProdBOMLine[Level].\"Unit of Measure Code\");\n+ CheckingRoundingPrecision(Item2, ProdLineItem, QtyRoundPrecision, Level);\n if QtyRoundPrecision <> 0 then\n ProdOrderComp.\"Quantity per\" := Round(ProdBOMLine[Level].\"Quantity per\" * LineQtyPerUOM / ItemQtyPerUOM, QtyRoundPrecision)\n else\n@@ -975,6 +977,21 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderLineToCheck.TestField(Quantity);\n end;\n \n+ local procedure CheckingRoundingPrecision(ChildItem: Record Item; ProdLineItem: Record Item; var QtyRoundPrecision: Decimal; Level: Integer)\n+ begin\n+ if (ChildItem.\"Rounding Precision\" = 0) or (QtyRoundPrecision = 0) then\n+ exit;\n+\n+ if (not ProdLineItem.Get(ProdOrderLine.\"Item No.\")) or (ProdLineItem.\"Replenishment System\" <> ProdLineItem.\"Replenishment System\"::\"Prod. Order\") then\n+ exit;\n+\n+ if (ChildItem.\"Base Unit of Measure\" <> ProdBOMLine[Level].\"Unit of Measure Code\") then\n+ exit;\n+ QtyRoundPrecision := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision\" := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision (Base)\" := ChildItem.\"Rounding Precision\";\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterInsertProdRoutingLine(var ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; ProdOrderLine: Record \"Prod. Order Line\")\n begin\n"} +{"metadata": {"area": "pricing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208851", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-04", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134117, "functionName": ["AmountTypeFieldDoesNotChangeOnClosePageSalesPriceList"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al b/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al\nindex 5f586214ecb..c18252ac131 100644\n--- a/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/PriceListsUI.Codeunit.al\n@@ -4366,6 +4366,39 @@ codeunit 134117 \"Price Lists UI\"\n PurchasePriceList.Caption()));\n end;\n \n+ [Test]\n+ procedure AmountTypeFieldDoesNotChangeOnClosePageSalesPriceList()\n+ var\n+ PriceListHeader: Record \"Price List Header\";\n+ CustomerDiscountGroup: Record \"Customer Discount Group\";\n+ SalesPriceList: TestPage \"Sales Price List\";\n+ PriceListHeaderCode: Code[20];\n+ begin\n+ // [SCENARIO 566994] Bug fix to ensure the field \"Amount Type\" does not change after closing the page \"Sales Price List\" \n+ Initialize(true);\n+\n+ // [GIVEN] Sales Price List for discount\n+ PriceListHeaderCode := LibraryUtility.GenerateGUID();\n+ SalesPriceList.OpenEdit();\n+ SalesPriceList.New();\n+ SalesPriceList.Code.SetValue(PriceListHeaderCode);\n+ SalesPriceList.Description.SetValue(LibraryUtility.GenerateGUID());\n+ SalesPriceList.SourceType.SetValue(\"Price Source Type\"::\"Customer Disc. Group\");\n+ SalesPriceList.AmountType.SetValue(\"Price Amount Type\"::Discount);\n+ CustomerDiscountGroup.Init();\n+ CustomerDiscountGroup.Code := LibraryUtility.GenerateGUID();\n+ CustomerDiscountGroup.Insert();\n+ SalesPriceList.AssignToNo.SetValue(CustomerDiscountGroup.Code);\n+ SalesPriceList.Status.SetValue(\"Price Status\"::Active);\n+\n+ // [WHEN] Close the page \"Sales Price List\"\n+ SalesPriceList.Close();\n+\n+ // [THEN] Check the field \"Amount Type\" has not reverted to Price & Discount\n+ PriceListHeader.Get(PriceListHeaderCode);\n+ Assert.IsTrue((PriceListHeader.\"Amount Type\" = PriceListHeader.\"Amount Type\"::Discount), 'The field \"Amount Type\" has changed after closing the page \"Sales Price List\"');\n+ end;\n+\n local procedure Initialize(Enable: Boolean)\n var\n PriceListHeader: Record \"Price List Header\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al\nindex fb6adbb607d..9e6fd459241 100644\n--- a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListHeader.Table.al\n@@ -562,6 +562,7 @@ table 7000 \"Price List Header\"\n var\n xAmountType: Enum \"Price Amount Type\";\n begin\n+ CopyTo(PriceSource);\n xAmountType := \"Amount Type\";\n if \"Source Type\" in [\"Source Type\"::\"Customer Disc. Group\", \"Source Type\"::\"Customer Price Group\"] then\n \"Amount Type\" := PriceSource.GetDefaultAmountType()\n"} +{"metadata": {"area": "sales", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208320", "base_commit": "d080f087349d4713e1782f2f2630819714cb6738", "created_at": "2025-02-27", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134386, "functionName": ["UpdateEmailAndPhoneNoWhenChangeBillToOfSalesInvoice"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al\nindex bc3ad2bbe5c..30e993b56af 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsII.Codeunit.al\n@@ -4462,6 +4462,51 @@ codeunit 134386 \"ERM Sales Documents II\"\n SalesOrder.SalesLines.\"Invoice Discount Amount\".AssertEquals(SalesHeader.\"Invoice Discount Value\");\n end;\n \n+ [HandlerFunctions('CustomerLookupHandler,ConfirmHandlerYes')]\n+ [Test]\n+ procedure UpdateEmailAndPhoneNoWhenChangeBillToOfSalesInvoice()\n+ var\n+ Contact: array[2] of Record Contact;\n+ Customer: array[2] of Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesInvoice: TestPage \"Sales Invoice\";\n+ begin\n+ // [SCENARIO 564632] The Email and Phone No. should update when selecting Another Customer in the \"Bill-to\" field of a Sales Invoice\n+ Initialize();\n+\n+ // [GIVEN] Create First Customer with First Contact with Phone = \"111111111\", Mobile Phone = \"222222222\" and Email = \"contact1@mail.com\"\n+ LibraryMarketing.CreateContactWithCustomer(Contact[1], Customer[1]);\n+ UpdateContactInfo(Contact[1], '111111111', '222222222', 'contact1@mail.com');\n+ Contact[1].Modify(true);\n+\n+ // [GIVEN] Create Second Customer with Second Contact with Phone = \"333333333\", Mobile Phone = \"444444444\" and Email = \"contact2@mail.com\"\n+ LibraryMarketing.CreateContactWithCustomer(Contact[2], Customer[2]);\n+ UpdateContactInfo(Contact[2], '333333333', '444444444', 'contact2@mail.com');\n+ Contact[2].Modify(true);\n+\n+ // [GIVEN] Create Sales Invoice with First Customer\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer[1].\"No.\");\n+\n+ // [GIVEN] Sales Invoice Card is opened\n+ LibraryVariableStorage.Enqueue(Customer[2].\"No.\");\n+ LibraryVariableStorage.Enqueue('');\n+ LibraryVariableStorage.Enqueue(true); // yes to change \"Bill-to Customer No.\"\n+ SalesInvoice.OpenEdit();\n+ SalesInvoice.FILTER.SetFilter(\"No.\", SalesHeader.\"No.\");\n+\n+ // [WHEN] Select Second Customer when lookup \"Bill-to Customer Name\"\n+ SalesInvoice.\"Bill-to Name\".Lookup();\n+\n+ // [THEN] Verify Sales Invoice \"Phone No.\" = \"333333333\"\n+ SalesInvoice.BillToContactPhoneNo.AssertEquals(Contact[2].\"Phone No.\");\n+\n+ // [THEN] Verify Sales Invoice \"Mobile Phone No.\" = \"444444444\"\n+ SalesInvoice.BillToContactMobilePhoneNo.AssertEquals(Contact[2].\"Mobile Phone No.\");\n+\n+ // [THEN] Verify Sales Invoice \"Email\" = \"contact2@mail.com\"\n+ SalesInvoice.BillToContactEmail.AssertEquals(Contact[2].\"E-Mail\");\n+ end;\n+\n [Test]\n [Scope('OnPrem')]\n procedure UpdateExtendedTextTypeNotAllowed()\n@@ -6595,5 +6640,14 @@ codeunit 134386 \"ERM Sales Documents II\"\n CustomerLookup.Filter.SetFilter(Name, LibraryVariableStorage.DequeueText());\n CustomerLookup.OK().Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ procedure CustomerLookupHandler(var CustomerLookup: TestPage \"Customer Lookup\")\n+ begin\n+ CustomerLookup.GotoKey(LibraryVariableStorage.DequeueText());\n+ Assert.AreEqual(LibraryVariableStorage.DequeueText(),\n+ CustomerLookup.Filter.GetFilter(\"Date Filter\"), 'Wrong Date Filter.');\n+ CustomerLookup.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al\nindex 1dee700e044..a3b2013773f 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrder.Page.al\n@@ -648,6 +648,23 @@ page 507 \"Blanket Sales Order\"\n Rec.SetRange(\"Bill-to Customer No.\");\n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al\nindex 84ba27e1b17..3f876b15fd0 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesCreditMemo.Page.al\n@@ -552,6 +552,23 @@ page 44 \"Sales Credit Memo\"\n \n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al\nindex ee0d93e0f64..930047f5653 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesInvoice.Page.al\n@@ -803,6 +803,25 @@ page 43 \"Sales Invoice\"\n CurrPage.Update();\n end;\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if not ((BillToOptions = BillToOptions::\"Custom Address\") and not ShouldSearchForCustByName) then begin\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al\nindex 77cf2b1863e..2a751833971 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesOrder.Page.al\n@@ -812,6 +812,25 @@ page 42 \"Sales Order\"\n CurrPage.Update();\n end;\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if not ((BillToOptions = BillToOptions::\"Custom Address\") and not ShouldSearchForCustByName) then begin\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al\nindex 7827a9ece78..5851f14e04b 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesQuote.Page.al\n@@ -763,6 +763,23 @@ page 41 \"Sales Quote\"\n \n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al b/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al\nindex e9c58725477..a0e9bb787e7 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesReturnOrder.Page.al\n@@ -613,6 +613,23 @@ page 6630 \"Sales Return Order\"\n \n CurrPage.Update();\n end;\n+\n+ trigger OnLookup(var Text: Text): Boolean\n+ var\n+ Customer: Record Customer;\n+ begin\n+ if Customer.SelectCustomer(Customer) then begin\n+ xRec := Rec;\n+ Rec.\"Bill-to Name\" := Customer.Name;\n+ Rec.Validate(\"Bill-to Customer No.\", Customer.\"No.\");\n+ end;\n+\n+ if Rec.GetFilter(\"Bill-to Customer No.\") = xRec.\"Bill-to Customer No.\" then\n+ if Rec.\"Bill-to Customer No.\" <> xRec.\"Bill-to Customer No.\" then\n+ Rec.SetRange(\"Bill-to Customer No.\");\n+\n+ CurrPage.Update();\n+ end;\n }\n field(\"Bill-to Address\"; Rec.\"Bill-to Address\")\n {\n"} +{"metadata": {"area": "inventory", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227219", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137038, "functionName": ["ReleaseTransferOrderWhenVariantMandatory"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\nindex f3c55b5f7a0..c7d556a7bc7 100644\n--- a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n@@ -49,6 +49,7 @@\n DerivedTransLineErr: Label 'Expected no Derived Transfer Line i.e. line with \"Derived From Line No.\" equal to original transfer line.';\n IncorrectSNUndoneErr: Label 'The Serial No. of the item on the transfer shipment line that was undone was different from the SN on the corresponding transfer line.';\n ApplToItemEntryErr: Label '%1 must be %2 in %3.', Comment = '%1 is Appl-to Item Entry, %2 is Item Ledger Entry No. and %3 is Transfer Line';\n+ VariantCodeMandatoryErr: Label '%1 must have a value in %2: Document No.=%3, Line No.=%4. It cannot be zero or empty.', Comment = '%1:Field Caption, %2: TableCaption, %3:Document No, %4: Line No.';\n \n [Test]\n [HandlerFunctions('MessageHandler')]\n@@ -4096,6 +4097,48 @@\n 'The cost amount of the undo transfer shipment entry should match the original transfer shipment entry (with opposite sign)');\n end;\n \n+ [Test]\n+ procedure ReleaseTransferOrderWhenVariantMandatory()\n+ var\n+ InTransitLocation: Record Location;\n+ Item: Record Item;\n+ ItemVariant: array[2] of Record \"Item Variant\";\n+ FromLocation: Record Location;\n+ ToLocation: Record Location;\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ begin\n+ // [SCENARIO 601487] Release Transfer Order when Variant Mandatory in Inventory Setup.\n+ Initialize();\n+\n+ // [GIVEN] Create From/To Locations and InTransit Location\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(FromLocation);\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(ToLocation);\n+ LibraryWarehouse.CreateInTransitLocation(InTransitLocation);\n+\n+ // [GIVEN] Create Item and two Variants\n+ LibraryInventory.CreateItem(Item);\n+ LibraryInventory.CreateItemVariant(ItemVariant[1], Item.\"No.\");\n+ LibraryInventory.CreateItemVariant(ItemVariant[2], Item.\"No.\");\n+\n+ // [GIVEN] Set Inventory Setup to require variant if exists\n+ SetVariantMandatoryInInventorySetup();\n+\n+ // [GIVEN] Create Transfer Order and Line.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, FromLocation.Code, ToLocation.Code, InTransitLocation.Code);\n+ LibraryInventory.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", LibraryRandom.RandIntInRange(10, 100));\n+\n+ // [WHEN] Try to release the transfer order\n+ asserterror LibraryWarehouse.ReleaseTransferOrder(TransferHeader);\n+\n+ // [THEN] Assert error matches expected label\n+ Assert.ExpectedError(\n+ StrSubstNo(\n+ VariantCodeMandatoryErr,\n+ TransferLine.FieldCaption(\"Variant Code\"), TransferLine.TableCaption(),\n+ TransferLine.\"Document No.\", TransferLine.\"Line No.\"));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5670,6 +5713,15 @@\n until WarehouseActivityLine.Next() = 0;\n end;\n \n+ local procedure SetVariantMandatoryInInventorySetup()\n+ var\n+ InventorySetup: Record \"Inventory Setup\";\n+ begin\n+ InventorySetup.Get();\n+ InventorySetup.Validate(\"Variant Mandatory if Exists\", true);\n+ InventorySetup.Modify(true);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al\nindex 979cdb45246..1254b0d5d0d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/ReleaseTransferDocument.Codeunit.al\n@@ -119,7 +119,7 @@ codeunit 5708 \"Release Transfer Document\"\n if IsHandled then\n exit;\n \n- TransLine.SetLoadFields(\"Document No.\", Quantity, \"Item No.\");\n+ TransLine.SetLoadFields(\"Document No.\", Quantity, \"Item No.\", \"Variant Code\");\n TransLine.SetRange(\"Document No.\", TransHeader.\"No.\");\n TransLine.SetFilter(Quantity, '<>0');\n if TransLine.IsEmpty() then\n@@ -131,6 +131,8 @@ codeunit 5708 \"Release Transfer Document\"\n Item.Get(TransLine.\"Item No.\");\n if Item.IsInventoriableType() then\n TransLine.TestField(\"Unit of Measure Code\");\n+ if Item.IsVariantMandatory() then\n+ TransLine.TestField(\"Variant Code\");\n until TransLine.Next() = 0;\n TransLine.SetFilter(\"Item No.\", '');\n end;\n"} +{"metadata": {"area": "finance", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227358", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-18", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134227, "functionName": ["RecurringJournalSuccessfullyPostedWhenUnlinkIncomingDocumentOnPostingOptionIsActivated"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\nindex 82601475bc6..adef8e520c9 100644\n--- a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n@@ -1410,6 +1410,22 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n GenJournalLine[1].\"Line No.\"));\n end;\n \n+ [Test]\n+ procedure RecurringJournalSuccessfullyPostedWhenUnlinkIncomingDocumentOnPostingOptionIsActivated()\n+ var\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ RecurringFrequency: array[6] of DateFormula;\n+ begin\n+ // [SCENARIO 602441] The changes to the Gen. Journal Line record cannot be saved because some information is not up-to-date\" error when posting Recurring General Journal and the Unlink Incoming Document on Posting option is activated.\n+ Initialize();\n+\n+ // [GIVEN] Create Recurring Journal Lines.\n+ CreateRecurringJournalLineWithVariable(GenJournalLine, RecurringFrequency);\n+\n+ // [THEN] Post Recurring Journal Lines Successfully\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"ERM PostRecurringJournal\");\n@@ -1954,6 +1970,73 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n Assert.AreEqual(GenJnlAllocation.\"Dimension Set ID\", DimensionSetID, AllocationDimensionErr);\n end;\n \n+ local procedure CreateRecurringJournalLineWithVariable(var GenJournalLine: Record \"Gen. Journal Line\"; var RecurringFrequency: array[6] of DateFormula)\n+ var\n+ GLAccount: Record \"G/L Account\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ Vendor: Record Vendor;\n+ Counter: Integer;\n+ NoOfLines: Integer;\n+ begin\n+ // Use Random Number Generator to generate the No. of lines.\n+ NoOfLines := 2 * LibraryRandom.RandInt(3);\n+\n+ //[GIVEN] Find G/L Account\n+ FindGLAccount(GLAccount);\n+\n+ //[GIVEN] Create Vendor\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ //[WHEN] Create Recurring Journal Lines with Allocation and with random values.\n+ CreateRecurringGenJournalTemplateAndBatch(GenJournalBatch);\n+ for Counter := 1 to NoOfLines do begin\n+ if Counter = 1 then begin\n+ CreateGeneralJournalLineWithAccountType(\n+ GenJournalLine, GenJournalBatch, GenJournalLine.\"Recurring Method\"::\"V Variable\", -1000,\n+ Vendor.\"No.\");\n+ RecurringFrequency[Counter] := GenJournalLine.\"Recurring Frequency\";\n+ GenJournalLine.\"Document No.\" := '123';\n+ GenJournalLine.Modify();\n+ end else\n+ CreateGeneralJournalLineDocType(\n+ GenJournalLine, GenJournalBatch, GenJournalLine.\"Recurring Method\"::\"V Variable\", 1000,\n+ GLAccount.\"No.\");\n+ GenJournalLine.\"Document No.\" := '123';\n+ GenJournalLine.Modify();\n+ GLAccount.Next();\n+ RecurringFrequency[Counter] := GenJournalLine.\"Recurring Frequency\";\n+ end;\n+ end;\n+\n+ local procedure CreateGeneralJournalLineWithAccountType(var GenJournalLine: Record \"Gen. Journal Line\"; GenJournalBatch: Record \"Gen. Journal Batch\"; RecurringMethod: Enum \"Gen. Journal Recurring Method\"; Amount: Decimal; AccountNo: Code[20])\n+ begin\n+ CreateGeneralJournalLineWithType(\n+ GenJournalLine, GenJournalBatch, RecurringMethod, GenJournalLine.\"Document Type\"::Invoice,\n+ GenJournalLine.\"Account Type\"::Vendor, AccountNo, Amount);\n+ end;\n+\n+ local procedure CreateGeneralJournalLineDocType(var GenJournalLine: Record \"Gen. Journal Line\"; GenJournalBatch: Record \"Gen. Journal Batch\"; RecurringMethod: Enum \"Gen. Journal Recurring Method\"; Amount: Decimal; AccountNo: Code[20])\n+ begin\n+ CreateGeneralJournalLineWithType(\n+ GenJournalLine, GenJournalBatch, RecurringMethod, GenJournalLine.\"Document Type\"::Invoice,\n+ GenJournalLine.\"Account Type\"::\"G/L Account\", AccountNo, Amount);\n+ end;\n+\n+ local procedure CreateRecurringGenJournalTemplateAndBatch(var GenJournalBatch: Record \"Gen. Journal Batch\")\n+ var\n+ GenJnlTemplate: Record \"Gen. Journal Template\";\n+ begin\n+ LibraryERM.FindRecurringTemplateName(GenJnlTemplate);\n+ GenJnlTemplate.Validate(Type, GenJnlTemplate.Type::General);\n+ GenJnlTemplate.Validate(Recurring, true);\n+ GenJnlTemplate.Validate(\"Bal. Account Type\", GenJnlTemplate.\"Bal. Account Type\"::\"G/L Account\");\n+ GenJnlTemplate.Validate(\"Force Doc. Balance\", true);\n+ GenJnlTemplate.Validate(\"Copy VAT Setup to Jnl. Lines\", true);\n+ GenJnlTemplate.Validate(\"Unlink Inc. Doc On Posting\", true);\n+ GenJnlTemplate.Modify(true);\n+ LibraryERM.CreateRecurringBatchName(GenJournalBatch, GenJnlTemplate.Name);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al\nindex 61aff663d95..72ec7e79918 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostBatch.Codeunit.al\n@@ -1006,6 +1006,7 @@ codeunit 13 \"Gen. Jnl.-Post Batch\"\n exit;\n if not CurrGenJnlTemplate.\"Unlink Inc. Doc On Posting\" then\n exit;\n+ GenJnlLine.GET(GenJnlLine.\"Journal Template Name\", GenJnlLine.\"Journal Batch Name\", GenJnlLine.\"Line No.\");\n GenJnlLine.\"Incoming Document Entry No.\" := 0;\n GenJnlLine.Modify();\n end;\n"} +{"metadata": {"area": "warehouse", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226004", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-07", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137055, "functionName": ["InventoryPickRoundingCausesResidualQuantity"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al\nindex 6e2c6a34131..8eaf3b44088 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehousePick.Codeunit.al\n@@ -41,6 +41,8 @@ codeunit 137055 \"SCM Warehouse Pick\"\n LocationCodeMustNotOccurErr: Label 'Location code %1 must not occur. Expected value - %2', Comment = '%1 : occured location code, %2 : expected location code.';\n ReturnQtyMismatchErr: Label 'The value in the %1 field in the %2 does not match.', Comment = '%1 :FieldCaption, %2:Table Caption';\n ReservationAction: Option AutoReserve,GetQuantities;\n+ PickQuantityErr: Label 'Expected picked quantity %1 %2, but got %3 %2', Comment = '%1, %3 - Quantity; %2 - Unit of Measure Code';\n+ ShipQtyErr: Label 'Sales line should be fully shipped with no residual quantity';\n \n [Test]\n [HandlerFunctions('ReservationPageHandler')]\n@@ -1776,6 +1778,98 @@ codeunit 137055 \"SCM Warehouse Pick\"\n StrSubstNo(ReturnQtyMismatchErr, PurchaseLine.\"Return Qty. Shipped\", PurchaseLine.TableCaption));\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('CreateInvtPutAwayPickRequestPageHandler,MessageHandler')]\n+ procedure InventoryPickRoundingCausesResidualQuantity()\n+ var\n+ Item: Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ Location: Record Location;\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ Customer: Record Customer;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ UnitOfMeasure: Record \"Unit of Measure\";\n+ Bin: Record Bin;\n+ TotalPickedQty: Decimal;\n+ QtyPerUOM: Decimal;\n+ QtyRoundingPrecision: Decimal;\n+ OrderQuantity: Decimal;\n+ BinCode: Code[20];\n+ begin\n+ // [SCENARIO 579500] Inventory pick rounding causes residual quantity When picking items with non-integer UOM conversion and very small \n+ // Quantity Rounding Precision, the pick process may result in rounding residuals\n+ Initialize();\n+\n+ // [GIVEN] Setup variables for rounding test with random values within problematic ranges\n+ SetStaticValues579500(QtyPerUOM, QtyRoundingPrecision, OrderQuantity);\n+\n+ // [GIVEN] Generate random bin code\n+ BinCode := LibraryUtility.GenerateRandomCode(SalesLine.FieldNo(\"Bin Code\"), Database::\"Sales Line\"); // Random bin code\n+\n+ // [GIVEN] Create item with specific UOM configuration for rounding test and LOT tracking with expiration dates\n+ LibraryInventory.CreateItem(Item);\n+ SetupItemTrackingWithExpirationDates(Item);\n+\n+ // [GIVEN] Add secondary UOM with problematic conversion factor and very small rounding precision\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure, Item.\"No.\", UnitOfMeasure.Code, QtyPerUOM);\n+ ItemUnitOfMeasure.Validate(\"Qty. Rounding Precision\", QtyRoundingPrecision);\n+ ItemUnitOfMeasure.Modify(true);\n+\n+ // [GIVEN] Set Sales Unit of Measure to the secondary UOM\n+ Item.Validate(\"Sales Unit of Measure\", UnitOfMeasure.Code);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Setup Location with Require Pick = YES and Pick According to FEFO = Yes\n+ LibraryWarehouse.CreateLocationWMS(Location, false, false, true, false, false);\n+ Location.Validate(\"Bin Mandatory\", true);\n+ Location.Validate(\"Pick According to FEFO\", true);\n+ Location.Modify(true);\n+\n+ // [GIVEN] Add Warehouse Employee for location\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create bin for the location\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, BinCode, '', '');\n+\n+ // [GIVEN] Add inventory for the item (sufficient for order quantity)\n+ CreateInventoryForLotAndExpiry579500(Item.\"No.\", Location.Code, Bin.Code);\n+\n+ // [GIVEN] Create Customer\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Sales Order with random quantity \n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", OrderQuantity);\n+ SalesLine.Validate(\"Location Code\", Location.Code);\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Release Sales Order\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+\n+ // [GiVEN] Create Inventory Pick from Sales Order\n+ Commit();\n+ SalesHeader.CreateInvtPutAwayPick();\n+\n+ // [WHEN] autofill Qty. to Handle, post the pick\n+ PostInventoryActivity(WarehouseActivityHeader.\"Source Document\"::\"Sales Order\", SalesHeader.\"No.\", WarehouseActivityLine.\"Activity Type\"::\"Invt. Pick\");\n+\n+ // [GIVEN] Get total picked quantity from Item Ledger Entries\n+ GetTotalPickedQuantity(Item.\"No.\", Location.Code, QtyPerUOM, TotalPickedQty);\n+\n+ // [THEN] Assert that picked quantity equals expected with tolerance for rounding\n+ Assert.AreNearlyEqual(OrderQuantity, TotalPickedQty, QtyRoundingPrecision * 10,\n+ StrSubstNo(PickQuantityErr, OrderQuantity, UnitOfMeasure.Code, TotalPickedQty));\n+\n+ // [THEN] Validate that no residual quantity remains (no second pick is required) Check that sales line is fully shipped\n+ SalesLine.Get(SalesLine.\"Document Type\", SalesLine.\"Document No.\", SalesLine.\"Line No.\");\n+ Assert.AreEqual(SalesLine.Quantity, SalesLine.\"Quantity Shipped\", ShipQtyErr);\n+ end;\n+\n local procedure Initialize()\n var\n WarehouseActivityLine: Record \"Warehouse Activity Line\";\n@@ -2604,6 +2698,128 @@ codeunit 137055 \"SCM Warehouse Pick\"\n exit(-PurchaseLine.\"Return Qty. to Ship\");\n end;\n \n+ local procedure SetupItemTrackingWithExpirationDates(var Item: Record Item)\n+ var\n+ ItemTrackingCode: Record \"Item Tracking Code\";\n+ begin\n+ LibraryInventory.CreateItemTrackingCode(ItemTrackingCode);\n+ ItemTrackingCode.Validate(\"Lot Specific Tracking\", true);\n+ ItemTrackingCode.Validate(\"Use Expiration Dates\", true);\n+ ItemTrackingCode.Validate(\"Man. Expir. Date Entry Reqd.\", true);\n+ ItemTrackingCode.Modify(true);\n+\n+ Item.Validate(\"Item Tracking Code\", ItemTrackingCode.Code);\n+ Item.Modify(true);\n+ end;\n+\n+ local procedure SetStaticValues579500(var QtyPerUOM: Decimal; var QtyRoundingPrecision: Decimal; var OrderQuantity: Decimal)\n+ begin\n+ QtyPerUOM := 2.888;\n+ QtyRoundingPrecision := 0.00001;\n+ OrderQuantity := 248;\n+ end;\n+\n+ local procedure GetTotalPickedQuantity(ItemNo: Code[20]; LocationCode: Code[10]; QtyPerUOM: Decimal; var TotalPickedQty: Decimal)\n+ var\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ begin\n+ TotalPickedQty := 0;\n+ ItemLedgerEntry.SetRange(\"Item No.\", ItemNo);\n+ ItemLedgerEntry.SetRange(\"Location Code\", LocationCode);\n+ ItemLedgerEntry.SetRange(\"Entry Type\", ItemLedgerEntry.\"Entry Type\"::Sale);\n+ if ItemLedgerEntry.FindSet() then\n+ repeat\n+ TotalPickedQty += Abs(ItemLedgerEntry.Quantity) / QtyPerUOM;\n+ until ItemLedgerEntry.Next() = 0;\n+ end;\n+\n+ local procedure PostInventoryActivity(SourceDocument: Enum \"Warehouse Activity Source Document\"; SourceNo: Code[20]; ActivityType: Enum \"Warehouse Activity Type\")\n+ var\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ begin\n+ WarehouseActivityHeader.SetRange(\"Source Document\", SourceDocument);\n+ WarehouseActivityHeader.SetRange(\"Source No.\", SourceNo);\n+ WarehouseActivityHeader.SetRange(Type, WarehouseActivityHeader.Type::\"Invt. Pick\");\n+ WarehouseActivityHeader.FindFirst();\n+\n+ // Autofill Qty. to Handle\n+ WarehouseActivityLine.SetRange(\"Activity Type\", ActivityType);\n+ WarehouseActivityLine.SetRange(\"No.\", WarehouseActivityHeader.\"No.\");\n+ WarehouseActivityLine.SetRange(\"Action Type\", WarehouseActivityLine.\"Action Type\"::Take);\n+ if WarehouseActivityLine.FindSet() then\n+ repeat\n+ WarehouseActivityLine.Validate(\"Qty. to Handle\", WarehouseActivityLine.Quantity);\n+ WarehouseActivityLine.Modify(true);\n+ until WarehouseActivityLine.Next() = 0;\n+\n+ // Post the pick (Ship)\n+ LibraryWarehouse.PostInventoryActivity(WarehouseActivityHeader, false);\n+ end;\n+\n+ local procedure CreateInventoryForLotAndExpiry579500(ItemNo: Code[20]; LocationCode: Code[10]; BinCode: Code[20])\n+ var\n+ LotNo: array[10] of Code[50];\n+ ExpiryDate: array[10] of Date;\n+ Quantity: array[10] of Decimal;\n+ i: Integer;\n+ begin\n+ LotNo[1] := 'LOT01';\n+ LotNo[2] := 'LOT03';\n+ LotNo[3] := 'LOT06';\n+ LotNo[4] := 'LOT01';\n+ LotNo[5] := 'LOT02';\n+ LotNo[6] := 'LOT03';\n+ LotNo[7] := 'LOT04';\n+ LotNo[8] := 'LOT02';\n+ LotNo[9] := 'LOT03';\n+ LotNo[10] := 'LOT05';\n+\n+ ExpiryDate[1] := 20251130D;\n+ ExpiryDate[2] := 20250925D;\n+ ExpiryDate[3] := 20250925D;\n+ ExpiryDate[4] := 20250925D;\n+ ExpiryDate[5] := 20251130D;\n+ ExpiryDate[6] := 20250925D;\n+ ExpiryDate[7] := 20250606D;\n+ ExpiryDate[8] := 20250616D;\n+ ExpiryDate[9] := 20250925D;\n+ ExpiryDate[10] := 20250713D;\n+\n+ Quantity[1] := 434.97616;\n+ Quantity[2] := 17.3126;\n+ Quantity[3] := 17.0373;\n+ Quantity[4] := 4.13394;\n+ Quantity[5] := 4.34355;\n+ Quantity[6] := 151.33333;\n+ Quantity[7] := 40.01221;\n+ Quantity[8] := 1.78787;\n+ Quantity[9] := 42.73313;\n+ Quantity[10] := 4.013;\n+\n+ for i := 1 to ArrayLen(LotNo) do\n+ UpdateItemInventoryWithLot(ItemNo, LocationCode, BinCode, Quantity[i], LotNo[i], ExpiryDate[i]);\n+ end;\n+\n+ local procedure UpdateItemInventoryWithLot(ItemNo: Code[20]; LocationCode: Code[10]; BinCode: Code[20]; Quantity: Decimal; LotNo: Code[50]; ExpiryDate: Date)\n+ var\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+ ItemJournalBatch.Validate(\"Item Tracking on Lines\", true);\n+ ItemJournalBatch.Modify(true);\n+\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", ItemNo, Quantity);\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.\"Lot No.\" := LotNo;\n+ ItemJournalLine.\"Expiration Date\" := ExpiryDate;\n+ ItemJournalLine.Modify(true);\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ReservationPageHandler(var Reservation: TestPage Reservation)\n@@ -2716,5 +2932,12 @@ codeunit 137055 \"SCM Warehouse Pick\"\n ProdOrderRouting.\"No.\".SetValue(MachineCenter.\"No.\");\n ProdOrderRouting.\"Setup Time\".SetValue(100);\n end;\n+\n+ [RequestPageHandler]\n+ procedure CreateInvtPutAwayPickRequestPageHandler(var CreateInvtPutAwayPickMvmt: TestRequestPage \"Create Invt Put-away/Pick/Mvmt\")\n+ begin\n+ CreateInvtPutAwayPickMvmt.CInvtPick.SetValue(true);\n+ CreateInvtPutAwayPickMvmt.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\nindex ee0c77f69da..dea4f3bdce6 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n@@ -420,7 +420,7 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n CreatePickOrMoveLine(\n NewWarehouseActivityLine, RemQtyToPickBase, SalesLine.\"Outstanding Qty. (Base)\", SalesLine.\"Reserved Quantity\" <> 0);\n OnCreatePickOrMoveFromSalesOnAfterCreatePickOrMoveLine(NewWarehouseActivityLine, SalesLine, CurrWarehouseActivityHeader, ShowError, AutoCreation, LineCreated);\n-\n+ CorrectQtyRounding(SalesLine, CurrWarehouseActivityHeader);\n if SalesHeader.\"Shipping Advice\" = SalesHeader.\"Shipping Advice\"::Complete then begin\n if RemQtyToPickBase < 0 then begin\n if AutoCreation then begin\n@@ -2313,6 +2313,36 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n exit(true);\n end;\n \n+ local procedure CorrectQtyRounding(SalesLine: Record \"Sales Line\"; WarehouseActivityHeader: Record \"Warehouse Activity Header\")\n+ var\n+ WareHouseActivityLine: Record \"Warehouse Activity Line\";\n+ TotalQtyPicked: Decimal;\n+ TotalQtyOutstanding: Decimal;\n+ TotalPickedQuantityCalculated: Decimal;\n+ TotalQtyOutStandingCalculated: Decimal;\n+ begin\n+ if WarehouseActivityHeader.Type <> WarehouseActivityHeader.Type::\"Invt. Pick\" then\n+ exit;\n+\n+ WareHouseActivityLine.SetSource(Database::\"Sales Line\", SalesLine.\"Document Type\".AsInteger(), SalesLine.\"Document No.\", SalesLine.\"Line No.\", 0);\n+ WareHouseActivityLine.SetRange(\"No.\", WarehouseActivityHeader.\"No.\");\n+ WareHouseActivityLine.CalcSums(Quantity, \"Qty. (Base)\", \"Qty. Outstanding\", \"Qty. Outstanding (Base)\");\n+ TotalQtyPicked := WareHouseActivityLine.Quantity;\n+ TotalQtyOutstanding := WareHouseActivityLine.\"Qty. Outstanding\";\n+ TotalPickedQuantityCalculated := Round(WareHouseActivityLine.\"Qty. (Base)\" / SalesLine.\"Qty. per Unit of Measure\", 0.00001);\n+ TotalQtyOutStandingCalculated := Round(WareHouseActivityLine.\"Qty. Outstanding (Base)\" / SalesLine.\"Qty. per Unit of Measure\", 0.00001);\n+ if TotalQtyPicked = TotalPickedQuantityCalculated then\n+ exit;\n+\n+ if Abs(TotalPickedQuantityCalculated - TotalQtyPicked) > SalesLine.\"Qty. Rounding Precision\" then\n+ exit;\n+\n+ WareHouseActivityLine.FindLast();\n+ WareHouseActivityLine.Quantity += (TotalPickedQuantityCalculated - TotalQtyPicked);\n+ WareHouseActivityLine.\"Qty. Outstanding\" += (TotalQtyOutStandingCalculated - TotalQtyOutstanding);\n+ WareHouseActivityLine.Modify();\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterAutoCreatePickOrMove(var WarehouseRequest: Record \"Warehouse Request\"; LineCreated: Boolean; var WarehouseActivityHeader: Record \"Warehouse Activity Header\"; Location: Record Location; HideDialog: Boolean)\n begin\n"} +{"metadata": {"area": "inventory", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223202", "base_commit": "071306f0d5dbae52846a3a732e27560b476295c9", "created_at": "2025-08-07", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Manufacturing"], "FAIL_TO_PASS": [{"codeunitID": 137210, "functionName": ["FirmedProdOrderStatisticsCheckOverhead"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al b/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al\nindex 57db2703546..edc1079c082 100644\n--- a/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Manufacturing/SCMCopyProductionBOM.Codeunit.al\n@@ -41,6 +41,7 @@ codeunit 137210 \"SCM Copy Production BOM\"\n ProdBOMNo: Code[20];\n CountError: Label 'Version Count Must Match.';\n OverHeadCostErr: Label 'Overhead Cost must be %1 in %2.', Comment = '%1= Field Value, %2= FieldCaption.';\n+ ManufacturingOverhead: Label 'Expected Overhead = %1, but Statistics shows = %2', Comment = '%1=Expected Overhead, %2=Overhead from Statistics page.';\n \n [Normal]\n local procedure Initialize()\n@@ -609,6 +610,86 @@ codeunit 137210 \"SCM Copy Production BOM\"\n ProductionOrderStatistics.MfgOverhead_ExpectedCost.Caption()));\n end;\n \n+ [Test]\n+ procedure FirmedProdOrderStatisticsCheckOverhead()\n+ var\n+ ParentItem: Record Item;\n+ RawItem: Record Item;\n+ ProductionOrder: Record \"Production Order\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ FirmedProductionOrder: TestPage \"Firm Planned Prod. Order\";\n+ ProductionOrderStatistics: TestPage \"Production Order Statistics\";\n+ MfgOverheadExpectedCost: Decimal;\n+ MfgOverheadExpectedCost1: Decimal;\n+ Quantity: Decimal;\n+ begin\n+ // [SCENARIO 593018] Manufacturing overhead is wrong in the production order statistics page (99000816) and report (99000791).\n+ Initialize();\n+\n+ // [GIVEN] Create Raw Item with specified Unit Cost\n+ CreateItem(RawItem, 0, 0);\n+ RawItem.Validate(Type, RawItem.Type::Inventory);\n+ RawItem.Validate(\"Unit Cost\", LibraryRandom.RandIntInRange(100, 100));\n+ RawItem.Modify(true);\n+\n+ // [GIVEN] Create Production BOM and add Raw Item with Qty = 1\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, RawItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, RawItem.\"No.\", 1);\n+ ProductionBOMHeader.Validate(\"Unit of Measure Code\", RawItem.\"Base Unit of Measure\");\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify(true);\n+\n+ // [GIVEN] Create Parent Item with Indirect Cost % and link to BOM\n+ CreateItem(ParentItem, 0, 0); // No direct cost or overhead\n+ ParentItem.Validate(\"Indirect Cost %\", LibraryRandom.RandIntInRange(10, 10));\n+ ParentItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ParentItem.Modify(true);\n+\n+ // [GIVEN] Create Firm Planned Production Order for Parent Item\n+ LibraryManufacturing.CreateProductionOrder(ProductionOrder, ProductionOrder.Status::\"Firm Planned\", ProductionOrder.\"Source Type\"::Item, '', 0);\n+\n+ // [GIVEN] Store Quantity in Variable.\n+ Quantity := LibraryRandom.RandIntInRange(20, 20);\n+\n+ // [GIVEN] Create line only (do NOT populate header)\n+ LibraryManufacturing.CreateProdOrderLine(ProdOrderLine, ProductionOrder.Status, ProductionOrder.\"No.\", ParentItem.\"No.\", '', '', Quantity);\n+\n+ // [WHEN] Refresh Prod Order with Lines = false (header only)\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, false, true, true, false);\n+\n+ MfgOverheadExpectedCost := (RawItem.\"Unit Cost\" * ParentItem.\"Indirect Cost %\" / 100 * Quantity);\n+\n+ // [GIVEN] Create Firm Planned Production Order for Parent Item\n+ LibraryManufacturing.CreateProductionOrder(ProductionOrder, ProductionOrder.Status::\"Firm Planned\", ProductionOrder.\"Source Type\"::Item, '', 0);\n+\n+ // [GIVEN] Create multiple lines (do NOT populate header)\n+ LibraryManufacturing.CreateProdOrderLine(ProdOrderLine, ProductionOrder.Status, ProductionOrder.\"No.\", ParentItem.\"No.\", '', '', LibraryRandom.RandIntInRange(10, 10));\n+ LibraryManufacturing.CreateProdOrderLine(ProdOrderLine, ProductionOrder.Status, ProductionOrder.\"No.\", ParentItem.\"No.\", '', '', LibraryRandom.RandIntInRange(10, 10));\n+\n+ // [WHEN] Refresh Prod Order with Lines = false (header only)\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, false, true, true, false);\n+\n+ // [WHEN] Open Firmed Prod Order Statistics page\n+ FirmedProductionOrder.OpenEdit();\n+ FirmedProductionOrder.GoToRecord(ProductionOrder);\n+ ProductionOrderStatistics.Trap();\n+ FirmedProductionOrder.Statistics.Invoke();\n+\n+ // [THEN] Get Mfg Overhead Expected Cost\n+ Evaluate(MfgOverheadExpectedCost1, ProductionOrderStatistics.MfgOverhead_ExpectedCost.Value());\n+\n+ // [ASSERT] Overhead in statistics equals expected overhead\n+ Assert.AreEqual(\n+ MfgOverheadExpectedCost,\n+ MfgOverheadExpectedCost1,\n+ StrSubstNo(ManufacturingOverhead,\n+ Format(MfgOverheadExpectedCost),\n+ Format(MfgOverheadExpectedCost1)));\n+ \n+ end;\n+\n [Normal]\n local procedure CreateProductionBOM(var ProductionBOMHeader: Record \"Production BOM Header\")\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al\nindex 84769ae059d..aad60ef36b9 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgCostCalculationMgt.Codeunit.al\n@@ -305,9 +305,12 @@ codeunit 99000758 \"Mfg. Cost Calculation Mgt.\"\n ExpSubDirCost := ExpSubDirCost + Round(ExpSubDirCostRtng * ShareOfTotalCapCost);\n ExpCapOvhdCost := ExpCapOvhdCost + Round(ExpCapOvhdCostRtng * ShareOfTotalCapCost);\n ExpMfgDirCost := ExpMatCost + ExpCapDirCost + ExpSubDirCost + ExpCapOvhdCost;\n- ExpOvhdCost := ExpMfgOvhdCost + ProdOrderLine.\"Overhead Rate\" * ProdOrderLine.\"Quantity (Base)\";\n- ExpMfgOvhdCost := ExpOvhdCost +\n- Round(CostCalculationMgt.CalcOvhdCost(ExpMfgDirCost, ProdOrderLine.\"Indirect Cost %\", 0, 0));\n+ ExpOvhdCost := ExpMfgOvhdCost;\n+ if ExpMfgDirCost = 0 then\n+ ExpMfgOvhdCost := ExpOvhdCost +\n+ Round(CostCalculationMgt.CalcOvhdCost(ExpMfgDirCost, ProdOrderLine.\"Indirect Cost %\", ProdOrderLine.\"Overhead Rate\", ProdOrderLine.\"Quantity (Base)\"))\n+ else\n+ ExpMfgOvhdCost := Round(CostCalculationMgt.CalcOvhdCost(ExpMfgDirCost, ProdOrderLine.\"Indirect Cost %\", ProdOrderLine.\"Overhead Rate\", ProdOrderLine.\"Quantity (Base)\"));\n \n OnAfterCalcProdOrderLineExpCost(ProdOrderLine, ShareOfTotalCapCost, ExpMatCost, ExpCapDirCost, ExpSubDirCost, ExpCapOvhdCost, ExpMfgOvhdCost);\n #if not CLEAN26\n"} +{"metadata": {"area": "finance", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-226448", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-10", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134282, "functionName": ["CheckVATEntryNonDeductibleVATPurchaseInvoicePosting"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\nindex 6d22cda27cb..2ddbcc070b0 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n@@ -285,6 +285,62 @@ codeunit 134282 \"Non-Deductible UT\"\n PurchaseLine.TestField(\"Non-Deductible VAT Amount\", 0);\n end;\n \n+ [Test]\n+ procedure CheckVATEntryNonDeductibleVATPurchaseInvoicePosting()\n+ var\n+ GenPostingSetup: Record \"General Posting Setup\";\n+ GLAccount: Record \"G/L Account\";\n+ PurchHeader: Record \"Purchase Header\";\n+ PurchLine: Record \"Purchase Line\";\n+ VATEntry: Record \"VAT Entry\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ Vendor: Record Vendor;\n+ GLAccountNo: Code[20];\n+ PostedDocumentNo: Code[20];\n+ VATRate: Decimal;\n+ begin\n+ // [SCENARIO 595966] Check VAT Entry Non-Deductible VAT on Purchase Invoice Posting with G/L Account Line.\n+ Initialize();\n+\n+ // [GIVEN] Create Vendor and set Prices Including VAT\n+ LibraryPurchase.CreateVendor(Vendor);\n+ Vendor.Validate(\"Prices Including VAT\", true);\n+ Vendor.Modify(true);\n+\n+ // [GIVEN] Enable Non-Deductible VAT in VAT Setup (with confirm handler)\n+ LibraryNonDeductibleVAT.EnableNonDeductibleVAT();\n+\n+ // [GIVEN] Create G/L Account and set posting groups/categories\n+ VATRate := 20.0;\n+ GLAccountNo := CreateGLAccountWithVATPostingSetup(VATRate);\n+ GLAccount.Get(GLAccountNo);\n+\n+ // [GIVEN] Create/Modify VAT Product Posting Group and VAT Posting Setup.\n+ LibraryERM.CreateVATPostingSetup(VATPostingSetup, Vendor.\"VAT Bus. Posting Group\", GLAccount.\"VAT Prod. Posting Group\");\n+ VATPostingSetup.Validate(\"VAT Calculation Type\", VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\");\n+ VATPostingSetup.Validate(\"Allow Non-Deductible VAT\", VATPostingSetup.\"Allow Non-Deductible VAT\"::Allow);\n+ VATPostingSetup.Validate(\"VAT %\", 20);\n+ VATPostingSetup.Validate(\"Non-Deductible VAT %\", 100);\n+ VATPostingSetup.Modify(true);\n+\n+ // [WHEN] Create and post Purchase Invoice for the vendor with G/L Account line\n+ LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader.\"Document Type\"::Invoice, Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(PurchLine, PurchHeader, PurchLine.Type::\"G/L Account\", GLAccountNo, 1);\n+ PurchLine.Validate(\"Direct Unit Cost\", 14.19);\n+ PurchLine.Modify(true);\n+ PurchHeader.Validate(\"Vendor Invoice No.\", 'Test-1001');\n+ PurchHeader.Modify(true);\n+ LibraryERM.CreateGeneralPostingSetup(GenPostingSetup, PurchLine.\"Gen. Bus. Posting Group\", PurchLine.\"Gen. Prod. Posting Group\");\n+ PostedDocumentNo := LibraryPurchase.PostPurchaseDocument(PurchHeader, false, true);\n+\n+ // [THEN] verify that Purchase Invoice is posted with 0 VAT Amount and 0 Non-Deductible VAT Amount\n+ VATEntry.SetRange(\"Document No.\", PostedDocumentNo);\n+ VATEntry.SetRange(\"Document Type\", VATEntry.\"Document Type\"::Invoice);\n+ VATEntry.FindFirst();\n+ Assert.AreEqual(0, VATEntry.Base, 'Vat Base should be 0.');\n+ Assert.AreEqual(0, VATEntry.Amount, 'Vat Amount should be 0.');\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Non-Deductible UT\");\n@@ -383,4 +439,33 @@ codeunit 134282 \"Non-Deductible UT\"\n Assert.AreEqual(ExpectedAmount, VATEntry.\"Non-Deductible VAT Base\", StrSubstNo(AmountErrorLbl, VATEntry.FieldCaption(\"Non-Deductible VAT Base\"), ExpectedAmount));\n Assert.AreEqual(ExpectedAmount, VATEntry.\"Non-Deductible VAT Amount\", StrSubstNo(AmountErrorLbl, VATEntry.FieldCaption(\"Non-Deductible VAT Amount\"), ExpectedAmount));\n end;\n+\n+ local procedure CreateGLAccountWithVATPostingSetup(var VATRate: Decimal) GLAccountNo: Code[20]\n+ var\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ begin\n+ VATRate := LibraryRandom.RandIntInRange(2, 5);\n+ LibraryERM.CreateVATPostingSetupWithAccounts(VATPostingSetup,\n+ VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\", VATRate);\n+ GLAccountNo := VATPostingSetup.\"Purchase VAT Account\";\n+ UpdateGLAccountPostingGroups(GLAccountNo,\n+ VATPostingSetup.\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ end;\n+\n+ local procedure UpdateGLAccountPostingGroups(GLAccountNo: Code[20]; VATProdPostingGroup: Code[20]; VATBusPostingGroup: Code[20])\n+ var\n+ GLAccount: Record \"G/L Account\";\n+ GenProductPostingGroup: Record \"Gen. Product Posting Group\";\n+ begin\n+ GLAccount.Get(GLAccountNo);\n+ LibraryERM.CreateGenProdPostingGroup(GenProductPostingGroup);\n+ GLAccount.\"Gen. Posting Type\" := GLAccount.\"Gen. Posting Type\"::Purchase;\n+ GLAccount.Validate(\"Account Category\", GLAccount.\"Account Category\"::Expense);\n+ GLAccount.Validate(\"Account Type\", GLAccount.\"Account Type\"::Posting);\n+ GLAccount.Validate(\"Direct Posting\", true);\n+ GLAccount.\"Gen. Prod. Posting Group\" := GenProductPostingGroup.Code;\n+ GLAccount.\"VAT Prod. Posting Group\" := VATProdPostingGroup;\n+ GLAccount.\"VAT Bus. Posting Group\" := VATBusPostingGroup;\n+ GLAccount.Modify(true);\n+ end;\n }\n\\ No newline at end of file\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex c9d976f7272..a9f725ac966 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -16,6 +16,7 @@ using Microsoft.FixedAssets.Ledger;\n using Microsoft.Foundation.Enums;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.History;\n+using Microsoft.Purchases.Vendor;\n using Microsoft.Foundation.Company;\n using Microsoft.Projects.Project.Journal;\n using Microsoft.Projects.Project.Job;\n@@ -951,6 +952,8 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n GeneralLedgerSetup.GetRecordOnce();\n UpdateNonDeductibleAmounts(GenJournalLine.\"Non-Deductible VAT Base ACY\", GenJournalLine.\"Non-Deductible VAT Amount ACY\", BaseAmountACY, VATAmountACY, GetNonDedVATPctFromGenJournalLine(GenJournalLine), GeneralLedgerSetup.\"Amount Rounding Precision\");\n AdjustVATAmounts(VATAmountACY, BaseAmountACY, GenJournalLine.\"Non-Deductible VAT Amount ACY\", GenJournalLine.\"Non-Deductible VAT Base ACY\");\n+ if IsNormalVATInvoiceForVendor(GenJournalLine) then\n+ UpdateNonDeductibleAmounts(GenJournalLine.\"Non-Deductible VAT Base LCY\", GenJournalLine.\"Non-Deductible VAT Amount LCY\", BaseAmount, VATAmount, GetNonDedVATPctFromGenJournalLine(GenJournalLine), GeneralLedgerSetup.\"Amount Rounding Precision\");\n AdjustVATAmounts(VATAmount, BaseAmount, GenJournalLine.\"Non-Deductible VAT Amount LCY\", GenJournalLine.\"Non-Deductible VAT Base LCY\");\n end;\n \n@@ -1152,6 +1155,17 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n exit(DocAmountRoundingPrecision);\n end;\n \n+ local procedure IsNormalVATInvoiceForVendor(GenJournalLine: Record \"Gen. Journal Line\"): Boolean\n+ var\n+ Vendor: Record Vendor;\n+ begin\n+ if (GenJournalLine.\"Document Type\" = GenJournalLine.\"Document Type\"::Invoice) and\n+ (GenJournalLine.\"VAT Calculation Type\" = GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\") and\n+ (Vendor.Get(GenJournalLine.\"Bill-to/Pay-to No.\") and (Vendor.\"Prices Including VAT\")) then\n+ exit(true);\n+ exit(false);\n+ end;\n+\n [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Company-Initialize\", 'OnCompanyInitialize', '', false, false)]\n local procedure CreateVATSetupOnCompanyInitialize()\n var\n"} +{"metadata": {"area": "finance", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227153", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-16", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Report"], "FAIL_TO_PASS": [{"codeunitID": 134982, "functionName": ["ReconcileCustVendAccounts_MultiplePostingGroups"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al b/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al\nindex 073ba04a94f..03f6e89bb23 100644\n--- a/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al\n+++ b/App/Layers/W1/Tests/Report/ERMFinancialReports.Codeunit.al\n@@ -1498,6 +1498,93 @@ codeunit 134982 \"ERM Financial Reports\"\n Assert.AreNotEqual(0, GLEntry.\"Source Currency Amount\", SourceCurrencyCodeErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('RHReconcileCustandVendAccs')]\n+ procedure ReconcileCustVendAccounts_MultiplePostingGroups()\n+ var\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ CustomerPostingGroup: array[2] of Record \"Customer Posting Group\";\n+ Customer: Record Customer;\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ GLAccount: array[3] of Record \"G/L Account\";\n+ ReconcileCustAndVendAccs: Report \"Reconcile Cust. and Vend. Accs\";\n+ Amount1, Amount2 : Decimal;\n+ WorkdateTxt: Text[30];\n+ begin\n+ // [SCENARIO 601857] Report Reconcile Customer and Vendor Accounts shows wrong amounts when multiple posting groups are used\n+ Initialize();\n+\n+ // [GIVEN] Enable Allow Multiple Posting Groups\n+ SalesReceivablesSetup.Get();\n+ SalesReceivablesSetup.Validate(\"Allow Multiple Posting Groups\", true);\n+ SalesReceivablesSetup.Modify(true);\n+\n+ // [GIVEN] Create two Customer Posting Groups with different Receivables Accounts\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup[1]);\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup[2]);\n+ LibrarySales.CreateAltCustomerPostingGroup(CustomerPostingGroup[1].Code, CustomerPostingGroup[2].Code);\n+\n+ // [GIVEN] Create a customer with one of the posting groups and enable multiple posting groups\n+ LibrarySales.CreateCustomer(Customer);\n+ Customer.Validate(\"Customer Posting Group\", CustomerPostingGroup[1].Code);\n+ Customer.Validate(\"Allow Multiple Posting Groups\", true);\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Create General Journal Batch\n+ LibraryJournals.CreateGenJournalBatch(GenJournalBatch);\n+\n+ // [GIVEN] Post payment 1 with first posting group\n+ Amount1 := -1 * LibraryRandom.RandDec(1000, 2);\n+ LibraryERM.CreateGLAccount(GLAccount[1]);\n+ LibraryJournals.CreateGenJournalLine(\n+ GenJournalLine,\n+ GenJournalBatch.\"Journal Template Name\",\n+ GenJournalBatch.Name,\n+ GenJournalLine.\"Document Type\"::Payment,\n+ GenJournalLine.\"Account Type\"::Customer,\n+ Customer.\"No.\",\n+ GenJournalLine.\"Bal. Account Type\"::\"G/L Account\",\n+ GLAccount[1].\"No.\",\n+ Amount1);\n+ GenJournalLine.Validate(\"Posting Group\", CustomerPostingGroup[1].Code);\n+ GenJournalLine.Modify(true);\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+\n+ // [GIVEN] Post payment 2 with second posting group\n+ Amount2 := -1 * LibraryRandom.RandDec(2000, 2);\n+ LibraryERM.CreateGLAccount(GLAccount[2]);\n+ LibraryJournals.CreateGenJournalLine(\n+ GenJournalLine,\n+ GenJournalBatch.\"Journal Template Name\",\n+ GenJournalBatch.Name,\n+ GenJournalLine.\"Document Type\"::Payment,\n+ GenJournalLine.\"Account Type\"::Customer,\n+ Customer.\"No.\",\n+ GenJournalLine.\"Bal. Account Type\"::\"G/L Account\",\n+ GLAccount[2].\"No.\",\n+ Amount2);\n+ GenJournalLine.Validate(\"Posting Group\", CustomerPostingGroup[2].Code);\n+ GenJournalLine.Modify(true);\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+\n+ // [WHEN] Run the Reconcile Cust. And Vend. Accounts report with DateFilter as Workdate\n+ WorkdateTxt := Format(WorkDate());\n+ Clear(ReconcileCustAndVendAccs);\n+ GLAccount[3].SetRange(\"Date Filter\", WorkDate());\n+ GLAccount[3].FindFirst();\n+ ReconcileCustAndVendAccs.SetTableView(GLAccount[3]);\n+ Commit();\n+ ReconcileCustAndVendAccs.Run();\n+\n+ // [THEN] Verify: Amounts are distributed to correct G/L accounts\n+ LibraryReportDataset.LoadDataSetFile();\n+ LibraryReportDataset.AssertElementWithValueExists('No_GLAccount', CustomerPostingGroup[1].\"Receivables Account\");\n+ LibraryReportDataset.AssertElementWithValueExists('No_GLAccount', CustomerPostingGroup[2].\"Receivables Account\");\n+ LibraryReportDataset.AssertElementWithValueExists('Amount', Amount1);\n+ LibraryReportDataset.AssertElementWithValueExists('Amount', Amount2);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al\nindex e033f91eb0b..2153bcde821 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/ReconcileCustandVendAccs.Report.al\n@@ -472,130 +472,88 @@ report 33 \"Reconcile Cust. and Vend. Accs\"\n \n local procedure CalcCustAccAmount(PostingGr: Code[20]): Decimal\n var\n- Cust: Record Customer;\n DtldCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n CustAccAmount: Decimal;\n begin\n- Cust.SetCurrentKey(\"Customer Posting Group\");\n- Cust.SetRange(\"Customer Posting Group\", PostingGr);\n-\n- if Cust.Find('-') then\n- repeat\n- DtldCustLedgEntry.SetCurrentKey(\"Customer No.\", \"Posting Date\");\n- DtldCustLedgEntry.SetRange(\"Customer No.\", Cust.\"No.\");\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n- DtldCustLedgEntry.CalcSums(\"Amount (LCY)\");\n- CustAccAmount := CustAccAmount + DtldCustLedgEntry.\"Amount (LCY)\";\n- until Cust.Next() = 0;\n+ DtldCustLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\");\n+ DtldCustLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n+ DtldCustLedgEntry.CalcSums(\"Amount (LCY)\");\n+ CustAccAmount := CustAccAmount + DtldCustLedgEntry.\"Amount (LCY)\";\n \n exit(CustAccAmount);\n end;\n \n local procedure CalcCustCreditAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Cust: Record Customer;\n DtldCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n CustCreditAmount: Decimal;\n begin\n- Cust.SetCurrentKey(\"Customer Posting Group\");\n- Cust.SetRange(\"Customer Posting Group\", PostingGr);\n-\n- if Cust.Find('-') then\n- repeat\n- DtldCustLedgEntry.SetCurrentKey(\"Customer No.\", \"Posting Date\", \"Entry Type\");\n- DtldCustLedgEntry.SetRange(\"Customer No.\", Cust.\"No.\");\n- DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n- DtldCustLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n- CustCreditAmount := CustCreditAmount + DtldCustLedgEntry.\"Credit Amount (LCY)\";\n- until Cust.Next() = 0;\n+ DtldCustLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldCustLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n+ DtldCustLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n+ CustCreditAmount := CustCreditAmount + DtldCustLedgEntry.\"Credit Amount (LCY)\";\n \n exit(CustCreditAmount);\n end;\n \n local procedure CalcCustDebitAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Cust: Record Customer;\n DtldCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n CustDebitAmount: Decimal;\n begin\n- Cust.SetCurrentKey(\"Customer Posting Group\");\n- Cust.SetRange(\"Customer Posting Group\", PostingGr);\n-\n- if Cust.Find('-') then\n- repeat\n- DtldCustLedgEntry.SetCurrentKey(\"Customer No.\", \"Posting Date\", \"Entry Type\");\n- DtldCustLedgEntry.SetRange(\"Customer No.\", Cust.\"No.\");\n- DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n- DtldCustLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n- CustDebitAmount := CustDebitAmount + DtldCustLedgEntry.\"Debit Amount (LCY)\";\n- until Cust.Next() = 0;\n+ DtldCustLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldCustLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldCustLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldCustLedgEntry.\"Posting Date\");\n+ DtldCustLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n+ CustDebitAmount := CustDebitAmount + DtldCustLedgEntry.\"Debit Amount (LCY)\";\n \n exit(-CustDebitAmount);\n end;\n \n local procedure CalcVendAccAmount(PostingGr: Code[20]): Decimal\n var\n- Vend: Record Vendor;\n DtldVendLedgEntry: Record \"Detailed Vendor Ledg. Entry\";\n VendAccAmount: Decimal;\n begin\n- Vend.SetCurrentKey(\"Vendor Posting Group\");\n- Vend.SetRange(\"Vendor Posting Group\", PostingGr);\n-\n- if Vend.Find('-') then\n- repeat\n- DtldVendLedgEntry.SetCurrentKey(\"Vendor No.\", \"Posting Date\");\n- DtldVendLedgEntry.SetRange(\"Vendor No.\", Vend.\"No.\");\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n- DtldVendLedgEntry.CalcSums(\"Amount (LCY)\");\n- VendAccAmount := VendAccAmount + DtldVendLedgEntry.\"Amount (LCY)\";\n- until Vend.Next() = 0;\n+ DtldVendLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\");\n+ DtldVendLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n+ DtldVendLedgEntry.CalcSums(\"Amount (LCY)\");\n+ VendAccAmount := VendAccAmount + DtldVendLedgEntry.\"Amount (LCY)\";\n \n exit(VendAccAmount);\n end;\n \n local procedure CalcVendCreditAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Vend: Record Vendor;\n DtldVendLedgEntry: Record \"Detailed Vendor Ledg. Entry\";\n VendCreditAmount: Decimal;\n begin\n- Vend.SetCurrentKey(\"Vendor Posting Group\");\n- Vend.SetRange(\"Vendor Posting Group\", PostingGr);\n-\n- if Vend.Find('-') then\n- repeat\n- DtldVendLedgEntry.SetCurrentKey(\"Vendor No.\", \"Posting Date\", \"Entry Type\");\n- DtldVendLedgEntry.SetRange(\"Vendor No.\", Vend.\"No.\");\n- DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n- DtldVendLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n- VendCreditAmount := VendCreditAmount + DtldVendLedgEntry.\"Credit Amount (LCY)\";\n- until Vend.Next() = 0;\n+ DtldVendLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldVendLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n+ DtldVendLedgEntry.CalcSums(\"Credit Amount (LCY)\");\n+ VendCreditAmount := VendCreditAmount + DtldVendLedgEntry.\"Credit Amount (LCY)\";\n \n exit(VendCreditAmount);\n end;\n \n local procedure CalcVendDebitAmount(PostingGr: Code[20]; EntryType: Enum \"Detailed CV Ledger Entry Type\"): Decimal\n var\n- Vend: Record Vendor;\n DtldVendLedgEntry: Record \"Detailed Vendor Ledg. Entry\";\n VendDebitAmount: Decimal;\n begin\n- Vend.SetCurrentKey(\"Vendor Posting Group\");\n- Vend.SetRange(\"Vendor Posting Group\", PostingGr);\n-\n- if Vend.Find('-') then\n- repeat\n- DtldVendLedgEntry.SetCurrentKey(\"Vendor No.\", \"Posting Date\", \"Entry Type\");\n- DtldVendLedgEntry.SetRange(\"Vendor No.\", Vend.\"No.\");\n- DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n- \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n- DtldVendLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n- VendDebitAmount := VendDebitAmount + DtldVendLedgEntry.\"Debit Amount (LCY)\";\n- until Vend.Next() = 0;\n+ DtldVendLedgEntry.SetCurrentKey(\"Posting Group\", \"Posting Date\", \"Entry Type\");\n+ DtldVendLedgEntry.SetRange(\"Posting Group\", PostingGr);\n+ DtldVendLedgEntry.SetRange(\"Entry Type\", EntryType);\n+ \"G/L Account\".CopyFilter(\"Date Filter\", DtldVendLedgEntry.\"Posting Date\");\n+ DtldVendLedgEntry.CalcSums(\"Debit Amount (LCY)\");\n+ VendDebitAmount := VendDebitAmount + DtldVendLedgEntry.\"Debit Amount (LCY)\";\n \n exit(-VendDebitAmount);\n end;\n"} +{"metadata": {"area": "sales", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-227240", "base_commit": "13fec5e51af6c3380265dc849cb57151fbd8ccfe", "created_at": "2025-09-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134905, "functionName": ["VerifyDueDateAfterUpdateDueDateInCustLedgerEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\nindex 71c12b1ce1a..6d8f4aaca9e 100644\n--- a/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMIssuedReminderAddnlFee.Codeunit.al\n@@ -636,6 +636,68 @@ codeunit 134905 \"ERM Issued Reminder Addnl Fee\"\n ReminderPage.ContactEmail.AssertEquals(EMail);\n end;\n \n+ [Test]\n+ procedure VerifyDueDateAfterUpdateDueDateInCustLedgerEntry()\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ Customer: Record Customer;\n+ CustomerPostingGroup: Record \"Customer Posting Group\";\n+ GLAccount: Record \"G/L Account\";\n+ ReminderFinChargeEntry: Record \"Reminder/Fin. Charge Entry\";\n+ ReminderLevel: Record \"Reminder Level\";\n+ VATProductPostingGroup: Record \"VAT Product Posting Group\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ DueDate: Date;\n+ DocumentDate: Date;\n+ IssuedReminderNo: Code[20];\n+ begin\n+ // [SCENARIO 598460] The Due date in created Reminder is updated incorrectly when changing the Due date in the Customer Ledger Entry.\n+ Initialize();\n+\n+ // [GIVEN] Create Customer and VAT Posting Setup. \n+ CreateCustomer(Customer, '');\n+ CustomerPostingGroup.Get(Customer.\"Customer Posting Group\");\n+ GLAccount.Get(CustomerPostingGroup.\"Additional Fee Account\");\n+ LibraryERM.CreateVATProductPostingGroup(VATProductPostingGroup);\n+ GLAccount.Validate(\"VAT Prod. Posting Group\", VATProductPostingGroup.Code);\n+ GLAccount.Modify(true);\n+\n+ LibraryERM.CreateVATPostingSetup(VATPostingSetup, Customer.\"VAT Bus. Posting Group\", VATProductPostingGroup.Code);\n+\n+ //[GIVEN] Create and post Sales Invoice.\n+ DueDate := CreateAndPostSalesInvoice(Customer.\"No.\", '');\n+ GetReminderLevel(ReminderLevel, Customer.\"Reminder Terms Code\");\n+ DocumentDate := CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', CalcDate(ReminderLevel.\"Grace Period\", DueDate));\n+\n+ // [GIVEN] Create and Issue Reminder.\n+ CreateReminder(Customer.\"No.\", DocumentDate, false);\n+ IssuedReminderNo := IssueReminder(DocumentDate);\n+\n+ // [WHEN] Update Due Date in forward direction for Customer Ledger Entry.\n+ DueDate := DocumentDate + LibraryRandom.RandIntInRange(16, 17);\n+ CustLedgerEntry.SetRange(\"Customer No.\", Customer.\"No.\");\n+ CustLedgerEntry.FindLast();\n+ CustLedgerEntry.Validate(\"Due Date\", DueDate);\n+ CustLedgerEntry.Modify(true);\n+\n+ // [VERIFY] Verify Due Date in Reminder/Fin. Charge Entry should be equal to Cust. Ledger Entry - Due Date.\n+ ReminderFinChargeEntry.SetRange(Type, ReminderFinChargeEntry.Type::Reminder);\n+ ReminderFinChargeEntry.SetRange(\"No.\", IssuedReminderNo);\n+ ReminderFinChargeEntry.FindFirst();\n+ Assert.AreEqual(ReminderFinChargeEntry.\"Due Date\", CustLedgerEntry.\"Due Date\", ReminderDueDateErr);\n+\n+ // [WHEN] Update Due Date in backward direction for Customer Ledger Entry.\n+ DueDate := DocumentDate - LibraryRandom.RandIntInRange(16, 17);\n+ CustLedgerEntry.Validate(\"Due Date\", DueDate);\n+ CustLedgerEntry.Modify(true);\n+\n+ // [VERIFY] Verify Due Date in Reminder/Fin. Charge Entry should be equal to Cust. Ledger Entry - Due Date.\n+ ReminderFinChargeEntry.SetRange(Type, ReminderFinChargeEntry.Type::Reminder);\n+ ReminderFinChargeEntry.SetRange(\"No.\", IssuedReminderNo);\n+ ReminderFinChargeEntry.FindFirst();\n+ Assert.AreEqual(ReminderFinChargeEntry.\"Due Date\", CustLedgerEntry.\"Due Date\", ReminderDueDateErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\nindex 9ff59101df2..ff238e73dcf 100644\n--- a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n@@ -409,9 +409,6 @@ codeunit 393 \"Reminder-Issue\"\n if IsHandled then\n exit;\n \n- if NewDueDate < ReminderEntry2.\"Due Date\" then\n- exit;\n-\n ReminderEntry2.Validate(\"Due Date\", NewDueDate);\n ReminderEntry2.Modify();\n end;\n"} {"metadata": {"area": "shopify", "image_count": 8}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-5633", "base_commit": "260795201c277427aa3bb70bc24672bb8d60c87b", "created_at": "2025-11-26T21:22:42Z", "environment_setup_version": "27.2", "project_paths": ["src\\Apps\\W1\\Shopify\\App", "src\\Apps\\W1\\Shopify\\Test"], "FAIL_TO_PASS": [{"codeunitID": 139606, "functionName": ["UnitTestExportShipmentThirdParty"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al\nindex 87c4a69e3a..2aa63a294f 100644\n--- a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al\n+++ b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al\n@@ -154,6 +154,36 @@ codeunit 139606 \"Shpfy Shipping Test\"\n LibraryAssert.IsTrue(FulfillmentRequest.Contains(StrSubstNo(QuantityLbl, SalesShipmentLine.Quantity)), 'quantity check');\n end;\n \n+ [Test]\n+ procedure UnitTestExportShipmentThirdParty()\n+ var\n+ SalesShipmentHeader: Record \"Sales Shipment Header\";\n+ FulfillmentOrderHeader: Record \"Shpfy FulFillment Order Header\";\n+ ExportShipments: Codeunit \"Shpfy Export Shipments\";\n+ ShippingHelper: Codeunit \"Shpfy Shipping Helper\";\n+ DeliveryMethodType: Enum \"Shpfy Delivery Method Type\";\n+ FulfillmentRequests: List of [Text];\n+ AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]];\n+ ShopifyOrderId: BigInteger;\n+ LocationId: BigInteger;\n+ begin\n+ // [SCENARIO] Export a Sales Shipment record into a Json token that contains the shipping info for a third-party fulfillment service\n+ // [GIVEN] A random Sales Shipment, a random LocationId for a third-party fulfillment location, a random Shop\n+ Initialize();\n+ LocationId := Any.IntegerInRange(10000, 99999);\n+ CreateThirdPartyFulfillmentLocation(Shop, LocationId);\n+ DeliveryMethodType := DeliveryMethodType::Shipping;\n+ ShopifyOrderId := ShippingHelper.CreateRandomShopifyOrder(LocationId, DeliveryMethodType);\n+ FulfillmentOrderHeader := ShippingHelper.CreateShopifyFulfillmentOrder(ShopifyOrderId, DeliveryMethodType);\n+ ShippingHelper.CreateRandomSalesShipment(SalesShipmentHeader, ShopifyOrderId);\n+\n+ // [WHEN] Invoke the function CreateFulfillmentOrderRequest()\n+ FulfillmentRequests := ExportShipments.CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType, AssignedFulfillmentOrderIds);\n+\n+ // [THEN] We must find no fulfilment data in the json token as the location is for a third-party fulfillment service\n+ LibraryAssert.AreEqual(0, FulfillmentRequests.Count, 'FulfillmentRequest count check');\n+ end;\n+\n local procedure Initialize()\n var\n CommunicationMgt: Codeunit \"Shpfy Communication Mgt.\";\n@@ -188,6 +218,17 @@ codeunit 139606 \"Shpfy Shipping Test\"\n LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::\"Shpfy Shipping Test\");\n end;\n \n+ local procedure CreateThirdPartyFulfillmentLocation(ShopifyShop: Record \"Shpfy Shop\"; LocationId: BigInteger)\n+ var\n+ ShopLocation: Record \"Shpfy Shop Location\";\n+ begin\n+ ShopLocation.\"Shop Code\" := ShopifyShop.Code;\n+ ShopLocation.Id := LocationId;\n+ ShopLocation.Name := 'Third-Party Fulfillment Service';\n+ ShopLocation.\"Is Fulfillment Service\" := true;\n+ ShopLocation.Insert();\n+ end;\n+\n [HttpClientHandler]\n internal procedure HttpSubmitHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean\n begin\n", "patch": "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\nindex 1f790f98d1..6160dcd402 100644\n--- a/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al\n+++ b/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al\n@@ -90,11 +90,13 @@ codeunit 30190 \"Shpfy Export Shipments\"\n TrackingCompany: Enum \"Shpfy Tracking Companies\";\n PrevFulfillmentOrderId: BigInteger;\n IsHandled: Boolean;\n+ EmptyFulfillment: Boolean;\n TrackingUrl: Text;\n GraphQueryStart: Text;\n GraphQuery: TextBuilder;\n LineCount: Integer;\n GraphQueries: List of [Text];\n+ UnfulfillableOrders: List of [BigInteger];\n begin\n Clear(PrevFulfillmentOrderId);\n \n@@ -165,11 +167,17 @@ codeunit 30190 \"Shpfy Export Shipments\"\n end;\n GraphQuery.Append('lineItemsByFulfillmentOrder: [');\n GraphQueryStart := GraphQuery.ToText();\n+ EmptyFulfillment := true;\n repeat\n // Skip fulfillment orders that are assigned and not accepted\n if AssignedFulfillmentOrderIds.ContainsKey(TempFulfillmentOrderLine.\"Shopify Fulfillment Order Id\") then\n continue;\n \n+ if not CanFulfillOrder(TempFulfillmentOrderLine, Shop, UnfulfillableOrders) then\n+ continue;\n+\n+ EmptyFulfillment := false;\n+\n if PrevFulfillmentOrderId <> TempFulfillmentOrderLine.\"Shopify Fulfillment Order Id\" then begin\n if PrevFulfillmentOrderId <> 0 then\n GraphQuery.Append(']},');\n@@ -202,7 +210,8 @@ codeunit 30190 \"Shpfy Export Shipments\"\n until TempFulfillmentOrderLine.Next() = 0;\n GraphQuery.Append(']}]})');\n GraphQuery.Append('{fulfillment { legacyResourceId name createdAt updatedAt deliveredAt displayStatus estimatedDeliveryAt status totalQuantity location { legacyResourceId } trackingInfo { number url company } service { serviceName type } fulfillmentLineItems(first: 10) { pageInfo { endCursor hasNextPage } nodes { id quantity originalTotalSet { presentmentMoney { amount } shopMoney { amount }} lineItem { id isGiftCard }}}}, userErrors {field,message}}}\"}');\n- GraphQueries.Add(GraphQuery.ToText());\n+ if not EmptyFulfillment then\n+ GraphQueries.Add(GraphQuery.ToText());\n end;\n exit(GraphQueries);\n end;\n@@ -225,6 +234,27 @@ codeunit 30190 \"Shpfy Export Shipments\"\n end;\n end;\n \n+ local procedure CanFulfillOrder(FulfillmentOrderLine: Record \"Shpfy FulFillment Order Line\"; Shop: Record \"Shpfy Shop\"; var UnfulfillableOrders: List of [BigInteger]): Boolean\n+ var\n+ ShopLocation: Record \"Shpfy Shop Location\";\n+ SyncLocations: Codeunit \"Shpfy Sync Shop Locations\";\n+ begin\n+ if UnfulfillableOrders.Contains(FulfillmentOrderLine.\"Shopify Fulfillment Order Id\") then\n+ exit(false);\n+\n+ if not ShopLocation.Get(Shop.Code, FulfillmentOrderLine.\"Shopify Location Id\") then\n+ exit(true);\n+\n+ if not ShopLocation.\"Is Fulfillment Service\" then\n+ exit(true);\n+\n+ if ShopLocation.Name = SyncLocations.GetFulfillmentServiceName() then\n+ exit(true);\n+\n+ UnfulfillableOrders.Add(FulfillmentOrderLine.\"Shopify Fulfillment Order Id\");\n+ exit(false);\n+ end;\n+\n local procedure GetNotifyCustomer(Shop: Record \"Shpfy Shop\"; SalesShipmmentHeader: Record \"Sales Shipment Header\"; LocationId: BigInteger): Boolean\n var\n IsHandled: Boolean;\n"} {"metadata": {"area": "shopify", "image_count": 3}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-4822", "base_commit": "f0b7291eb64a17df19a536e44be37380b2e4203d", "created_at": "2025-09-19T13:01:33Z", "environment_setup_version": "27.0", "project_paths": ["src\\Apps\\W1\\Shopify\\App", "src\\Apps\\W1\\Shopify\\Test"], "FAIL_TO_PASS": [{"codeunitID": 139539, "functionName": ["TestCreateCompanyLocationSellToBillTo"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al\nindex be8c01cb17..d27dba8d65 100644\n--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al\n+++ b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al\n@@ -23,6 +23,7 @@ codeunit 139539 \"Shpfy Company Locations Test\"\n Customer: Record Customer;\n InitializeTest: Codeunit \"Shpfy Initialize Test\";\n OutboundHttpRequests: Codeunit \"Library - Variable Storage\";\n+ Assert: Codeunit \"Library Assert\";\n IsInitialized: Boolean;\n ResponseResourceUrl: Text;\n UnexpectedAPICallsErr: Label 'More than expected API calls to Shopify detected.';\n@@ -57,6 +58,37 @@ codeunit 139539 \"Shpfy Company Locations Test\"\n ShopifyCompanies.OpenEdit();\n ShopifyCompanies.GoToRecord(ShopifyCompany);\n ShopifyCompanies.Locations.GoToRecord(CompanyLocation);\n+\n+ // Cleanup\n+ CompanyLocation.Delete();\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('HttpSubmitHandler')]\n+ procedure TestCreateCompanyLocationSellToBillTo()\n+ var\n+ ShopifyCustomer: Record \"Shpfy Customer\";\n+ CompanyAPI: Codeunit \"Shpfy Company API\";\n+ begin\n+ // [GIVEN] A valid customer and company location setup\n+ RegExpectedOutboundHttpRequests();\n+ Initialize();\n+ ShopifyCompany.GetBySystemId(CompanyLocation.\"Company SystemId\");\n+ Customer.\"Bill-to Customer No.\" := 'BILLTO';\n+ Customer.Modify(true);\n+\n+ // [WHEN] CreateCompanyLocation is called\n+ CompanyAPI.SetCompany(ShopifyCompany);\n+ CompanyAPI.SetShop(Shop);\n+ CompanyAPI.CreateCustomerAsCompanyLocation(Customer, ShopifyCompany, ShopifyCustomer);\n+\n+ // [THEN] Company location should be created successfully\n+#pragma warning disable AA0210\n+ CompanyLocation.SetRange(\"Customer Id\", Customer.SystemId);\n+#pragma warning restore AA0210\n+ CompanyLocation.FindFirst();\n+ Assert.AreEqual(Customer.\"No.\", CompanyLocation.\"Sell-to Customer No.\", 'Sell-to Customer No. mismatch');\n+ Assert.AreEqual(Customer.\"Bill-to Customer No.\", CompanyLocation.\"Bill-to Customer No.\", 'Bill-to Customer No. mismatch');\n end;\n \n [Test]\n", "patch": "diff --git a/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al b/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al\nindex 2d2014446c..d09ff272d8 100644\n--- a/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al\n+++ b/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyAPI.Codeunit.al\n@@ -523,7 +523,7 @@ codeunit 30286 \"Shpfy Company API\"\n JResponse := CommunicationMgt.ExecuteGraphQL(GraphQuery.ToText());\n if JResponse.SelectToken('$.data.companyLocationCreate.companyLocation', JCompanyLocation) then\n if not JsonHelper.IsTokenNull(JCompanyLocation) then begin\n- LocationId := CreateCustomerLocation(JCompanyLocation.AsObject(), ShopifyCompany, Customer.SystemId);\n+ LocationId := CreateCustomerLocation(JCompanyLocation.AsObject(), ShopifyCompany, Customer);\n if JsonHelper.GetJsonArray(JCompanyLocation, JContactRoles, 'company.contactRoles.edges') then begin\n foreach JItem in JContactRoles do\n CompanyContactRoles.Add(JsonHelper.GetValueAsText(JItem, 'node.name'), CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JItem, 'node.id')));\n@@ -540,7 +540,7 @@ codeunit 30286 \"Shpfy Company API\"\n /// \n /// JSON object containing the company location data from Shopify API response.\n /// The parent Shopify company record.\n- /// The GUID of the Business Central customer that was exported.\n+ /// The Business Central customer record used to populate additional fields.\n /// \n /// This procedure:\n /// - Extracts the Shopify-generated ID and creates the initial record\n@@ -552,7 +552,7 @@ codeunit 30286 \"Shpfy Company API\"\n /// The procedure assumes the JSON structure matches Shopify's companyLocationCreate response format.\n /// All text fields are properly truncated to match the field lengths in the table definition.\n /// \n- local procedure CreateCustomerLocation(JCompanyLocation: JsonObject; ShopifyCompany: Record \"Shpfy Company\"; CustomerId: Guid): BigInteger\n+ local procedure CreateCustomerLocation(JCompanyLocation: JsonObject; ShopifyCompany: Record \"Shpfy Company\"; Customer: Record Customer): BigInteger\n var\n CompanyLocation: Record \"Shpfy Company Location\";\n CompanyLocationId: BigInteger;\n@@ -580,7 +580,10 @@ codeunit 30286 \"Shpfy Company API\"\n #pragma warning restore AA0139\n CompanyLocation.Recipient := CopyStr(JsonHelper.GetValueAsText(JCompanyLocation, 'billingAddress.recipient', MaxStrLen(CompanyLocation.Recipient)), 1, MaxStrLen(CompanyLocation.Recipient));\n CompanyLocation.\"Shpfy Payment Terms Id\" := CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JCompanyLocation, 'buyerExperienceConfiguration.paymentTermsTemplate.id'));\n- CompanyLocation.\"Customer Id\" := CustomerId;\n+ CompanyLocation.\"Customer Id\" := Customer.SystemId;\n+ CompanyLocation.\"Sell-to Customer No.\" := Customer.\"No.\";\n+ if Customer.\"Bill-to Customer No.\" <> '' then\n+ CompanyLocation.\"Bill-to Customer No.\" := Customer.\"Bill-to Customer No.\";\n CompanyLocation.Modify(true);\n exit(CompanyLocationId);\n end;\n"} {"metadata": {"area": "shopify", "image_count": 5}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-4699", "base_commit": "effc43e8f96bc2b06545bcf81b9579bd08542747", "created_at": "2025-09-05T11:48:36Z", "environment_setup_version": "27.0", "project_paths": ["src\\Apps\\W1\\Shopify\\App", "src\\Apps\\W1\\Shopify\\Test"], "FAIL_TO_PASS": [{"codeunitID": 139567, "functionName": ["UnitTestCreateItemFCYToLCYConversion"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al\nindex a352529aba..f626c18258 100644\n--- a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al\n+++ b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemTest.Codeunit.al\n@@ -22,6 +22,7 @@ codeunit 139567 \"Shpfy Create Item Test\"\n \n var\n LibraryAssert: Codeunit \"Library Assert\";\n+ LibraryERM: Codeunit \"Library - ERM\";\n LibraryRandom: Codeunit \"Library - Random\";\n \n [Test]\n@@ -487,4 +488,42 @@ codeunit 139567 \"Shpfy Create Item Test\"\n LibraryAssert.RecordIsNotEmpty(ItemReference);\n until ShopifyVariant.Next() = 0;\n end;\n+\n+ [Test]\n+ procedure UnitTestCreateItemFCYToLCYConversion()\n+ var\n+ Item: Record Item;\n+ Shop: Record \"Shpfy Shop\";\n+ ShopifyVariant: Record \"Shpfy Variant\";\n+ ProductInitTest: Codeunit \"Shpfy Product Init Test\";\n+ InitializeTest: Codeunit \"Shpfy Initialize Test\";\n+ begin\n+ // [SCENARIO] Create a Item from a Shopify Product with the SKU value containing the Item No.\n+\n+ // [GIVEN] The Shop with the setting \"SKU Mapping\" = \"Item No.\";\n+ Shop := InitializeTest.CreateShop();\n+ Shop.\"SKU Mapping\" := \"Shpfy SKU Mapping\"::\"Item No.\";\n+ Shop.\"Currency Code\" := CreateCurrencyAndExchangeRate(2, 2);\n+ Shop.Modify();\n+\n+ // [GIVEN] A Shopify variant record of a standard shopify product. (The variant record always exists, even if the products don't have any variants.)\n+ ShopifyVariant := ProductInitTest.CreateStandardProduct(Shop);\n+ ShopifyVariant.Price := 10;\n+ ShopifyVariant.\"Unit Cost\" := 6;\n+ ShopifyVariant.Modify();\n+ ShopifyVariant.SetRecFilter();\n+\n+ // [WHEN] Executing the report \"Shpfy Create Item\" with the \"Shpfy Variant\" Record.\n+ Codeunit.Run(Codeunit::\"Shpfy Create Item\", ShopifyVariant);\n+\n+ // [THEN] Check Item fields\n+ LibraryAssert.IsTrue(Item.GetBySystemId(ShopifyVariant.\"Item SystemId\"), 'Get Item');\n+ LibraryAssert.AreNearlyEqual(ShopifyVariant.\"Unit Cost\" / 2, Item.\"Unit Cost\", 0.1, 'Unit Cost');\n+ LibraryAssert.AreNearlyEqual(ShopifyVariant.Price / 2, Item.\"Unit Price\", 0.1, 'Unit Price');\n+ end;\n+\n+ local procedure CreateCurrencyAndExchangeRate(ExchangeRateAmount: Decimal; AdjustmentExchangeRateAmount: Decimal): Code[10]\n+ begin\n+ exit(LibraryERM.CreateCurrencyWithExchangeRate(WorkDate() - 1, ExchangeRateAmount, AdjustmentExchangeRateAmount));\n+ end;\n }\n", "patch": "diff --git a/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al b/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al\nindex 4e6ffd2866..717c4f204b 100644\n--- a/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al\n+++ b/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyCreateItem.Codeunit.al\n@@ -8,6 +8,7 @@ namespace Microsoft.Integration.Shopify;\n using Microsoft.Inventory.Item;\n using Microsoft.Foundation.UOM;\n using Microsoft.Purchases.Vendor;\n+using Microsoft.Finance.Currency;\n using Microsoft.Inventory.Item.Catalog;\n \n /// \n@@ -230,6 +231,7 @@ codeunit 30171 \"Shpfy Create Item\"\n ItemCategory: Record \"Item Category\";\n ItemVariant: Record \"Item Variant\";\n Vendor: Record Vendor;\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n CurrentTemplateCode: Code[20];\n ItemNo: Code[20];\n Code: Text;\n@@ -258,10 +260,16 @@ codeunit 30171 \"Shpfy Create Item\"\n CreateItemUnitOfMeasure(ShopifyVariant, Item);\n \n if ShopifyVariant.\"Unit Cost\" <> 0 then\n- Item.Validate(\"Unit Cost\", ShopifyVariant.\"Unit Cost\");\n+ if Shop.\"Currency Code\" = '' then\n+ Item.Validate(\"Unit Cost\", ShopifyVariant.\"Unit Cost\")\n+ else\n+ Item.Validate(\"Unit Cost\", Round(CurrencyExchangeRate.ExchangeAmtFCYToLCY(WorkDate(), Shop.\"Currency Code\", ShopifyVariant.\"Unit Cost\", CurrencyExchangeRate.ExchangeRate(WorkDate(), Shop.\"Currency Code\"))));\n \n if ShopifyVariant.Price <> 0 then\n- Item.Validate(\"Unit Price\", ShopifyVariant.Price);\n+ if Shop.\"Currency Code\" = '' then\n+ Item.Validate(\"Unit Price\", ShopifyVariant.Price)\n+ else\n+ Item.Validate(\"Unit Price\", Round(CurrencyExchangeRate.ExchangeAmtFCYToLCY(WorkDate(), Shop.\"Currency Code\", ShopifyVariant.Price, CurrencyExchangeRate.ExchangeRate(WorkDate(), Shop.\"Currency Code\"))));\n \n if ShopifyProduct.\"Product Type\" <> '' then begin\n ItemCategory.SetFilter(Description, FilterMgt.CleanFilterValue(ShopifyProduct.\"Product Type\", MaxStrLen(ItemCategory.Description)));\n"} +{"metadata": {"area": "inventory", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223790", "base_commit": "e33326f4a8f7341c0857ef5a7013a3fe593d8146", "created_at": "2025-08-13", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137035, "functionName": ["CheckPlanningWorksheetPlanComponentwhenStockkeepingUnitsSetup"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al\nindex cd0d28c59b88..9867c364a8cb 100644\n--- a/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMPSBugsI.Codeunit.al\n@@ -45,6 +45,8 @@ codeunit 137035 \"SCM PS Bugs-I\"\n QuantityErr: Label 'Quantity update should be possible in %1.', Comment = '%1= Table Name.';\n DueDateErr: Label 'Planned production order due date not match with planning worksheet due date';\n SKUInventoryErr: Label 'Expected inventory to be blank for non-inventory item';\n+ MainItemErr: Label 'New planning worksheet line not created for main item';\n+ CompoItemErr: Label 'New planning worksheet line not created for component item';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1320,6 +1322,97 @@ codeunit 137035 \"SCM PS Bugs-I\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('SKURequestPageHandler')]\n+ procedure CheckPlanningWorksheetPlanComponentwhenStockkeepingUnitsSetup()\n+ var\n+ CompItem: Record Item;\n+ InventorySetup: Record \"Inventory Setup\";\n+ Location: Record Location;\n+ MainItem: Record Item;\n+ ManufacturingSetup: Record \"Manufacturing Setup\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ Requisitionline: Record \"Requisition Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Itemcard: TestPage \"Item Card\";\n+ SKUCardPage: TestPage \"Stockkeeping Unit Card\";\n+ ActualCount: Integer;\n+ begin\n+ // [SCENARIO 579977] Check Planning Worksheet Plan Component when Stockkeeping Units Setup for Items.\n+ Initialize();\n+\n+ // [GIVEN] Set Manufacturing Setup for Dynamic Low-Level Code and Inventory Setup for ombined MPS/MRP Calculation.\n+ ManufacturingSetup.Get();\n+ ManufacturingSetup.Validate(\"Dynamic Low-Level Code\", true);\n+ ManufacturingSetup.Modify(true);\n+ InventorySetup.Get();\n+ InventorySetup.Validate(\"Combined MPS/MRP Calculation\", true);\n+ InventorySetup.Modify(true);\n+\n+ // [GIVEN] Create Item with Replenishment System as Production Order.\n+ LibraryInventory.CreateItem(CompItem);\n+\n+ // [GIVEN] Create Location.\n+ LibraryWarehouse.CreateLocation(Location);\n+\n+ // [GIVEN] Create Stockkeeping Unit for Item and Location.\n+ Commit();\n+ LibraryVariableStorage.Enqueue(Location.Code);\n+ ItemCard.OpenView();\n+ ItemCard.GotoRecord(CompItem);\n+ ItemCard.\"&Create Stockkeeping Unit\".Invoke();\n+ ItemCard.OK().Invoke();\n+\n+ // [GIVEN] Modify Stockkeeping Unit for Item.\n+ SKUCardPage.OpenView();\n+ SKUCardPage.Filter.SetFilter(\"Item No.\", CompItem.\"No.\");\n+ SKUCardPage.Filter.SetFilter(\"Location Code\", Location.\"Code\");\n+ SKUCardPage.\"Replenishment System\".SetValue(\"Replenishment System\"::Purchase);\n+ SKUCardPage.\"Reordering Policy\".SetValue(\"Reordering Policy\"::\"Order\");\n+ SKUCardPage.Close();\n+\n+ // [GIVEN] Create BOM for the item.\n+ LibraryManufacturing.CreateCertifiedProductionBOM(ProductionBOMHeader, CompItem.\"No.\", 1);\n+\n+ // [GIVEN] Create Main Item with Replenishment System as Production Order.\n+ LibraryInventory.CreateItem(MainItem);\n+\n+ // [GIVEN] Create Stockkeeping Unit for Main Item and Location.\n+ Commit();\n+ LibraryVariableStorage.Enqueue(Location.Code);\n+ ItemCard.OpenView();\n+ ItemCard.GotoRecord(MainItem);\n+ ItemCard.\"&Create Stockkeeping Unit\".Invoke();\n+ ItemCard.OK().Invoke();\n+\n+ // [GIVEN] Modify Stockkeeping Unit Created for Main Item.\n+ SKUCardPage.OpenView();\n+ SKUCardPage.Filter.SetFilter(\"Item No.\", MainItem.\"No.\");\n+ SKUCardPage.Filter.SetFilter(\"Location Code\", Location.\"Code\");\n+ SKUCardPage.\"Replenishment System\".SetValue(\"Replenishment System\"::\"Prod. Order\");\n+ SKUCardPage.\"Reordering Policy\".SetValue(\"Reordering Policy\"::\"Lot-for-Lot\");\n+ SKUCardPage.\"Manufacturing Policy\".SetValue(\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ SKUCardPage.\"Production BOM No.\".SetValue(ProductionBOMHeader.\"No.\");\n+ SKUCardPage.Close();\n+\n+ // [WHEN] Create Sales order for Item and Location.\n+ Librarysales.CreateSalesDocumentWithItem(\n+ SalesHeader, SalesLine, SalesHeader.\"Document Type\"::Order, '', MainItem.\"No.\", 10, Location.\"Code\", WorkDate());\n+\n+ // [WHEN] Calculate regenerative plan in planning worksheet update Planning Worksheet.\n+ CalculateRegenerativePlanningWorksheet(CompItem, MainItem, WorkDate(), CalcDate('<1Y>', WorkDate()), true, false);\n+\n+ // [THEN] Verify Actual Count Match with Expected Result for Main Item Planning Worksheet Line.\n+ CountPlanningWorksheetLine(Requisitionline, ActualCount, MainItem.\"No.\", Location.\"Code\");\n+ Assert.AreEqual(1, ActualCount, MainItemErr);\n+\n+ // [THEN] Verify Actual Count Match with Expected Result for Component Item Planning Worksheet Line.\n+ CountPlanningWorksheetLine(Requisitionline, ActualCount, CompItem.\"No.\", Location.\"Code\");\n+ Assert.AreEqual(1, ActualCount, CompoItemErr);\n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -2143,6 +2236,32 @@ codeunit 137035 \"SCM PS Bugs-I\"\n Assert.AreEqual(DueDate, ProductionOrder.\"Due Date\", DueDateErr);\n end;\n \n+ local procedure CountPlanningWorksheetLine(Requisitionline: Record \"Requisition Line\"; var ActualCount: Integer; ItemNo: Code[20]; LocationCode: Code[10])\n+ begin\n+ Clear(ActualCount);\n+ Requisitionline.Reset();\n+ Requisitionline.SetRange(\"No.\", ItemNo);\n+ Requisitionline.SetRange(\"Location Code\", LocationCode);\n+ if Requisitionline.FindSet() then\n+ ActualCount := Requisitionline.Count;\n+ end;\n+\n+ local procedure CalculateRegenerativePlanningWorksheet(var CompItemRec: Record Item; var MainItemRec: Record Item; OrderDate: Date; ToDate: Date; RespectPlanningParameters: Boolean; Regenerative: Boolean)\n+ var\n+ TmpItemRec: Record Item;\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ CalculatePlanPlanWksh: Report \"Calculate Plan - Plan. Wksh.\";\n+ begin\n+ LibraryPlanning.SelectRequisitionWkshName(RequisitionWkshName, RequisitionWkshName.\"Template Type\"::Planning); // Find Requisition Worksheet Name to Calculate Plan.\n+ Commit();\n+ CalculatePlanPlanWksh.InitializeRequest(OrderDate, ToDate, RespectPlanningParameters, true, true, '', 0D, false);\n+ CalculatePlanPlanWksh.SetTemplAndWorksheet(RequisitionWkshName.\"Worksheet Template Name\", RequisitionWkshName.Name, Regenerative);\n+ TmpItemRec.SetFilter(\"No.\", '%1..%2', CompItemRec.\"No.\", MainItemRec.\"No.\");\n+ CalculatePlanPlanWksh.SetTableView(TmpItemRec);\n+ CalculatePlanPlanWksh.UseRequestPage(false);\n+ CalculatePlanPlanWksh.RunModal();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al\nindex e6df0fd1150e..bd56f5d829d5 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Location/MfgStockkeepingUnit.TableExt.al\n@@ -8,6 +8,7 @@ using Microsoft.Inventory.Item;\n using Microsoft.Manufacturing.Document;\n using Microsoft.Manufacturing.ProductionBOM;\n using Microsoft.Manufacturing.Routing;\n+using Microsoft.Manufacturing.Setup;\n \n tableextension 99000759 \"Mfg. Stockkeeping Unit\" extends \"Stockkeeping Unit\"\n {\n@@ -62,6 +63,27 @@ tableextension 99000759 \"Mfg. Stockkeeping Unit\" extends \"Stockkeeping Unit\"\n Caption = 'Production BOM No.';\n DataClassification = CustomerContent;\n TableRelation = \"Production BOM Header\";\n+ trigger OnValidate()\n+ var\n+ Item: Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ MfgSetup: Record \"Manufacturing Setup\";\n+ ProdBOMHeader: Record \"Production BOM Header\";\n+ CalculateLowLevelCode: Codeunit \"Calculate Low-Level Code\";\n+ begin\n+ if (\"Production BOM No.\" <> '') and (\"Production BOM No.\" <> xRec.\"Production BOM No.\") then begin\n+ ProdBOMHeader.Get(\"Production BOM No.\");\n+ ItemUnitOfMeasure.Get(\"Item No.\", ProdBOMHeader.\"Unit of Measure Code\");\n+ if ProdBOMHeader.Status = ProdBOMHeader.Status::Certified then begin\n+ MfgSetup.Get();\n+ Item.Get(\"Item No.\");\n+ if MfgSetup.\"Dynamic Low-Level Code\" then begin\n+ Item.\"Low-Level Code\" := CalculateLowLevelCode.CalcLevels(1, Item.\"No.\", 0, 0);\n+ CalculateLowLevelCode.SetRecursiveLevelsOnBOM(ProdBOMHeader, Item.\"Low-Level Code\" + 1, false);\n+ end;\n+ end;\n+ end;\n+ end;\n }\n field(99000765; \"Planned Order Receipt (Qty.)\"; Decimal)\n {\n"} +{"metadata": {"area": "inventory", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-223819", "base_commit": "61943a7dd68306f6b3913043e73e4654232a9476", "created_at": "2025-08-14", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Dimension"], "FAIL_TO_PASS": [{"codeunitID": 134474, "functionName": ["OverrideDimWithNewLocationsAndSalespersonOnItemJournalLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al b/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al\nindex 8e58207a24d3..3a47bcf8819f 100644\n--- a/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al\n+++ b/App/Layers/W1/Tests/Dimension/ERMDimensionLocations.Codeunit.al\n@@ -1232,6 +1232,64 @@ codeunit 134474 \"ERM Dimension Locations\"\n Assert.AreNotEqual(TransferHeader.\"Shortcut Dimension 2 Code\", TransferLine.\"Shortcut Dimension 2 Code\", DimensionsNotEqualErr);\n end;\n \n+ [Test]\n+ procedure OverrideDimWithNewLocationsAndSalespersonOnItemJournalLine()\n+ var\n+ DimensionValue: array[2] of Record \"Dimension Value\";\n+ Item: Record Item;\n+ LocationFrom: Record Location;\n+ LocationTo: Record Location;\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ SalespersonPurchaser: Record \"Salesperson/Purchaser\";\n+ begin\n+ // [SCENARIO 596687] In the Item Reclassification Journal is the Dimension value wrongly updated by adding a Sales Person to the line\n+ Initialize();\n+\n+ // [GIVEN] Global dimension 1 values \"V1\" and \"V2\".\n+ LibraryDimension.CreateDimensionValue(DimensionValue[1], LibraryERM.GetGlobalDimensionCode(1));\n+ LibraryDimension.CreateDimensionValue(DimensionValue[2], LibraryERM.GetGlobalDimensionCode(1));\n+\n+ // [GIVEN] Assign value \"V1\" to location \"BLUE\".\n+ // [GIVEN] Assign value \"V2\" to location \"RED\".\n+ LibraryInventory.CreateItem(Item);\n+ CreateLocationWithDefaultDimension(LocationFrom, DimensionValue[1]);\n+ CreateLocationWithDefaultDimension(LocationTo, DimensionValue[2]);\n+\n+ // [GIVEN] Create item reclassification journal line.\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Transfer);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJnlLineWithNoItem(\n+ ItemJournalLine, ItemJournalBatch, ItemJournalTemplate.Name, ItemJournalBatch.Name, \"Item Ledger Entry Type\"::Transfer);\n+ ItemJournalline.Validate(\"Item No.\", Item.\"No.\");\n+\n+ // [GIVEN] Set \"Location Code\" = \"BLUE\" on the item journal line.\n+ // [GIVEN] Verify that \"Shortcut Dimension 1 Code\" = \"V1\".\n+ // [GIVEN] Verify that \"Dimension Set ID\" includes value \"V1\".\n+ ItemJournalLine.Validate(\"Location Code\", LocationFrom.Code);\n+ ItemJournalLine.TestField(\"Shortcut Dimension 1 Code\", DimensionValue[1].Code);\n+ VerifyDimensionValue(ItemJournalLine.\"Dimension Set ID\", DimensionValue[1]);\n+\n+ // [WHEN] Set \"New Location Code\" = \"RED\".\n+ ItemJournalLine.Validate(\"New Location Code\", LocationTo.Code);\n+\n+ // [WHEN] Set \"Sales Person Purchaser\" = \"RED\".\n+ LibrarySales.CreateSalesperson(SalespersonPurchaser);\n+ CreateDefaultDimensionWithSpecCode(SalespersonPurchaser.Code, DATABASE::\"Salesperson/Purchaser\");\n+ ItemJournalLine.Validate(\"Salespers./Purch. Code\", SalespersonPurchaser.Code);\n+\n+ // [THEN] \"New Shortcut Dimension 1 Code\" = \"V2\".\n+ // [THEN] \"New Dimension Set ID\" includes value \"V2\".\n+ ItemJournalLine.TestField(\"New Shortcut Dimension 1 Code\", DimensionValue[2].Code);\n+ VerifyDimensionValue(ItemJournalLine.\"New Dimension Set ID\", DimensionValue[2]);\n+\n+ // [THEN] \"Shortcut Dimension 1 Code\" remains \"V1\".\n+ // [THEN] \"Dimension Set ID\" is not changed.\n+ ItemJournalLine.TestField(\"Shortcut Dimension 1 Code\", DimensionValue[1].Code);\n+ VerifyDimensionValue(ItemJournalLine.\"Dimension Set ID\", DimensionValue[1]);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"ERM Dimension Locations\");\n@@ -1340,6 +1398,25 @@ codeunit 134474 \"ERM Dimension Locations\"\n DefaultDimensionPriority.Modify(true);\n end;\n \n+ local procedure CreateDefaultDimensionWithSpecCode(AccountNo: Code[20]; TableID: Integer)\n+ var\n+ Dimension: Record Dimension;\n+ DimensionValue: Record \"Dimension Value\";\n+ DefaultDimension: Record \"Default Dimension\";\n+ begin\n+ LibraryDimension.CreateDimension(Dimension);\n+ CreateDimensionValueWithSpecCode(DimensionValue, AccountNo, Dimension.Code);\n+ LibraryDimension.CreateDefaultDimension(DefaultDimension, TableID, AccountNo, Dimension.Code, DimensionValue.Code);\n+ end;\n+\n+ local procedure CreateDimensionValueWithSpecCode(var DimensionValue: Record \"Dimension Value\"; DimensionValueCode: Code[20]; DimensionCode: Code[20])\n+ begin\n+ DimensionValue.Init();\n+ DimensionValue.Validate(\"Dimension Code\", DimensionCode);\n+ DimensionValue.Validate(Code, DimensionValueCode);\n+ DimensionValue.Insert(true);\n+ end;\n+\n [ModalPageHandler]\n procedure DefaultDimensionsMultipleModalPageHandler(var DefaultDimensionsMultiple: TestPage \"Default Dimensions-Multiple\")\n begin\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\nindex 7fc2d9853602..c0a52d871c5d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n@@ -2375,11 +2375,14 @@ table 83 \"Item Journal Line\"\n OnCreateDimOnBeforeUpdateGlobalDimFromDimSetID(Rec, xRec, CurrFieldNo, OldDimSetID, DefaultDimSource, InheritFromDimSetID, InheritFromTableNo);\n DimMgt.UpdateGlobalDimFromDimSetID(\"Dimension Set ID\", \"Shortcut Dimension 1 Code\", \"Shortcut Dimension 2 Code\");\n \n- if \"Entry Type\" = \"Entry Type\"::Transfer then begin\n- \"New Dimension Set ID\" := \"Dimension Set ID\";\n- \"New Shortcut Dimension 1 Code\" := \"Shortcut Dimension 1 Code\";\n- \"New Shortcut Dimension 2 Code\" := \"Shortcut Dimension 2 Code\";\n- end;\n+ if \"Entry Type\" = \"Entry Type\"::Transfer then\n+ if Rec.\"New Location Code\" <> '' then\n+ CreateNewDimFromDefaultDim(Rec.FieldNo(\"New Location Code\"))\n+ else begin\n+ \"New Dimension Set ID\" := \"Dimension Set ID\";\n+ \"New Shortcut Dimension 1 Code\" := \"Shortcut Dimension 1 Code\";\n+ \"New Shortcut Dimension 2 Code\" := \"Shortcut Dimension 2 Code\";\n+ end;\n end;\n \n /// \n"} +{"metadata": {"area": "sales", "image_count": 13}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-222092", "base_commit": "d4b9caabb22e77ab18779535aa89967bb58f89d9", "created_at": "2025-07-27", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134904, "functionName": ["DimensionsInGeneralLedgerEntriesWhenDimensionsModifiedInReminderBeforeIssuing"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al\nindex 47f98eaf54a8..99b8ac6fb838 100644\n--- a/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMReminderForAdditinalFee.Codeunit.al\n@@ -324,6 +324,86 @@ codeunit 134904 \"ERM Reminder For Additinal Fee\"\n Assert.AreEqual(Dim2CodeValue, ShortcutDimCode[2], StrSubstNo(DimensionValueErr, Dim2CodeValue));\n end;\n \n+ [Test]\n+ procedure DimensionsInGeneralLedgerEntriesWhenDimensionsModifiedInReminderBeforeIssuing();\n+ var\n+ Customer: Record Customer;\n+ CustomerPostingGroup: Record \"Customer Posting Group\";\n+ DefaultDimension: array[2] of Record \"Default Dimension\";\n+ DimensionValue: Record \"Dimension Value\";\n+ GLAccount: Record \"G/L Account\";\n+ GLEntry: Record \"G/L Entry\";\n+ ReminderHeader: Record \"Reminder Header\";\n+ ReminderLevel: Record \"Reminder Level\";\n+ ReminderTerms: Record \"Reminder Terms\";\n+ SalesHeader: Record \"Sales Header\";\n+ GetShortcutDimValues: Codeunit \"Get Shortcut Dimension Values\";\n+ Dim1CodeValue: array[2] of Code[20];\n+ Dim2CodeValue: Code[20];\n+ IssuedReminderNo: Code[20];\n+ ShortcutDimCode: array[8] of Code[20];\n+ begin\n+ // [SCENARIO 590674] Dimensions assigned to General Ledger Entries when the Dimensions are modified in the Reminder before issuing it.\n+ Initialize();\n+\n+ // [GIVEN] Create two Dimension Values for Global Dimension 1 Code.\n+ Dim1CodeValue[1] := LibraryUtility.GenerateGUID();\n+ Dim1CodeValue[2] := Dim1CodeValue[1] + '1';\n+ LibraryDimension.CreateDimensionValueWithCode(DimensionValue, Dim1CodeValue[1], LibraryERM.GetGlobalDimensionCode(1));\n+ LibraryDimension.CreateDimensionValueWithCode(DimensionValue, Dim1CodeValue[2], LibraryERM.GetGlobalDimensionCode(1));\n+\n+ // [GIVEN] Create Dimension Value for Global Dimension 2 Code and assign it.\n+ Dim2CodeValue := LibraryUtility.GenerateGUID();\n+ LibraryDimension.CreateDimensionValueWithCode(DimensionValue, Dim2CodeValue, LibraryERM.GetGlobalDimensionCode(2));\n+\n+ // [GIVEN] Create Reminder Terms with Post Additional Fee = True.\n+ CreateReminderTerms(ReminderLevel, '');\n+ ReminderTerms.Get(ReminderLevel.\"Reminder Terms Code\");\n+ ReminderTerms.\"Post Additional Fee\" := true;\n+ ReminderTerms.Modify(true);\n+\n+ // [GIVEN] Create Customer with Reminder Terms and Customer Posting Group.\n+ Customer.Get(CreateCustomer(ReminderLevel.\"Reminder Terms Code\", ''));\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup);\n+\n+ // [GIVEN] Create Default Dimension for Customer with global Dimension 1 Code.\n+ LibraryDimension.CreateDefaultDimensionWithNewDimValue(\n+ DefaultDimension[1], DATABASE::Customer, Customer.\"No.\",\n+ DefaultDimension[1].\"Value Posting\"::\"Code Mandatory\");\n+\n+ // [GIVEN] Find GL Account for Additional Fee Account and assign Global Dimension 1 Code and Global Dimension 2 Code.\n+ GLAccount.Get(CustomerPostingGroup.\"Additional Fee Account\");\n+ GLAccount.ValidateShortcutDimCode(1, Dim1CodeValue[1]);\n+ GLAccount.ValidateShortcutDimCode(2, Dim2CodeValue);\n+ GLAccount.Modify(true);\n+\n+ // [GIVEN] Validate Customer Posting Group in Customer.\n+ Customer.Validate(\"Customer Posting Group\", CustomerPostingGroup.Code);\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Posted Sales Invoice and Run Suggested Reminder with Additional Fee line.\n+ CreateAndPostSalesInvoice(SalesHeader, Customer.\"No.\");\n+ ReminderHeader.Get(\n+ CreateAndSuggestReminder(\n+ SalesHeader.\"Sell-to Customer No.\",\n+ CalcDate('<1D>', CalcDate(ReminderLevel.\"Grace Period\", SalesHeader.\"Due Date\"))));\n+ ReminderHeader.Validate(\"Shortcut Dimension 1 Code\", Dim1CodeValue[2]);\n+ ReminderHeader.Modify(true);\n+\n+ // [WHEN] Reminder is issued\n+ IssuedReminderNo := IssueReminderAndGetIssuedNo(ReminderHeader.\"No.\");\n+\n+ // [THEN] Find G/L Entry for Reminder with GL Account.\n+ GLEntry.SetRange(\"Document Type\", GLEntry.\"Document Type\"::Reminder);\n+ GLEntry.SetRange(\"Document No.\", IssuedReminderNo);\n+ GLEntry.SetRange(\"G/L Account No.\", GLAccount.\"No.\");\n+ GLEntry.FindFirst();\n+\n+ // [THEN] G/L Entry contains Global Dimension 1 Code as updated in Reminder Header.\n+ GetShortcutDimValues.GetShortcutDimensions(GLEntry.\"Dimension Set ID\", ShortcutDimCode);\n+ Assert.AreEqual(Dim1CodeValue[2], ShortcutDimCode[1], StrSubstNo(DimensionValueErr, Dim1CodeValue[2]));\n+ end;\n+\n [Scope('OnPrem')]\n procedure InterestAmountWithBeginningText()\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\nindex 825eb23c9503..9ff59101df20 100644\n--- a/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Reminder/ReminderIssue.Codeunit.al\n@@ -270,8 +270,8 @@ codeunit 393 \"Reminder-Issue\"\n begin\n GenJnlLine2.\"Shortcut Dimension 1 Code\" := GlobalReminderHeader.\"Shortcut Dimension 1 Code\";\n GenJnlLine2.\"Shortcut Dimension 2 Code\" := GlobalReminderHeader.\"Shortcut Dimension 2 Code\";\n- DimSetIDArr[1] := GlobalReminderHeader.\"Dimension Set ID\";\n- DimSetIDArr[2] := TempGenJnlLine.\"Dimension Set ID\";\n+ DimSetIDArr[1] := TempGenJnlLine.\"Dimension Set ID\";\n+ DimSetIDArr[2] := GlobalReminderHeader.\"Dimension Set ID\";\n GenJnlLine2.\"Dimension Set ID\" :=\n DimMgt.GetCombinedDimensionSetID(\n DimSetIDArr, GenJnlLine2.\"Shortcut Dimension 1 Code\", GenJnlLine2.\"Shortcut Dimension 2 Code\");\n"} +{"metadata": {"area": "warehouse", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218062", "base_commit": "226d490962047079ac9870319a3690af8959e6ad", "created_at": "2025-06-15", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137294, "functionName": ["NoErrorOfAvailabilityWhenCreatePickFromPickWorkSheetForProductionOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al\nindex eaf731a270b2..178112c70e63 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryMiscellaneousII.Codeunit.al\n@@ -49,6 +49,7 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n NoOfPicksCreatedMsg: Label 'Number of Invt. Pick activities created';\n WhseHandlingRequiredErr: Label 'Warehouse handling is required';\n InventoryMovementIsNotRegisteredErr: Label 'Inventory Movement is not registered.';\n+ InventoryPickNotFoundErr: Label 'Warehouse Activity Header not found for Production Order Components.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2132,6 +2133,88 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n Assert.IsTrue(RegisteredInvMovementHdr.Count > 0, InventoryMovementIsNotRegisteredErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('DummyMessageHandler,ReservationPageHandler,PickSelectionPageHandlerSingleDoc,CreatePickPageHandlerForPerWhsDoc')]\n+ [Scope('OnPrem')]\n+ procedure NoErrorOfAvailabilityWhenCreatePickFromPickWorkSheetForProductionOrder()\n+ var\n+ Bin, Bin2, Bin3 : Record Bin;\n+ CompItem, ProdItem : Record Item;\n+ Location: Record Location;\n+ ProductionOrder: array[2] of Record \"Production Order\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ WareHouseActivityHeader: Record \"Warehouse Activity Header\";\n+ begin\n+ // [SCENARIO 575862] No availability error when creating pick from pick worksheet with location setup Bin mandatory and the item reserved on the related production order\n+ Initialize();\n+\n+ // [GIVEN] Reset Warehouse Employee Default Location.\n+ ResetWarehouseEmployeeDefaultLocation();\n+\n+ // [GIVEN] Create Location with WMS enabled Bin mandatory\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, false, false, false);\n+\n+ // [GIVEN] Create Warehouse Employee for Location.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create Bins for Location.\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, Bin.Code, '', '');\n+ LibraryWarehouse.CreateBin(Bin2, Location.Code, Bin2.Code, '', '');\n+ LibraryWarehouse.CreateBin(Bin3, Location.Code, Bin3.Code, '', '');\n+\n+ // [GIVEN] Set \"Prod. Consump. Whse. Handling\" = \"Warehouse Pick (mandatory)\" and assign Bins to \"To-Production Bin Code\" and \"From-Production Bin Code\".\n+ Location.Validate(\"Prod. Consump. Whse. Handling\", Location.\"Prod. Consump. Whse. Handling\"::\"Warehouse Pick (mandatory)\");\n+ Location.Validate(\"To-Production Bin Code\", Bin.Code);\n+ Location.Validate(\"From-Production Bin Code\", Bin2.Code);\n+ Location.Modify(true);\n+\n+ // [GIVEN] Create Component Item with \"Replenishment System\" = \"Purchase\" and \"Flushing Method\" = \"Manual\".\n+ LibraryInventory.CreateItem(CompItem);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::Manual);\n+ CompItem.Modify();\n+\n+ // [GIVEN] Create Production BOM for Component Item.\n+ LibraryInventory.CreateItem(ProdItem);\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Manufacturing Policy\", ProdItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProdItem.Validate(\"Flushing Method\", ProdItem.\"Flushing Method\"::Manual);\n+ ProdItem.Validate(\"Production BOM No.\", LibraryManufacturing.CreateCertifiedProductionBOM(ProductionBOMHeader, CompItem.\"No.\", 1));\n+ ProdItem.Modify();\n+\n+ // [GIVEN] Create Inventory for Component Item.\n+ CreateInventory(CompItem, 3, Location.Code, Bin3.Code, 0);\n+\n+ // [GIVEN] Create first Production Orders for Production Item of quantity 2\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder[1], ProductionOrder[1].Status::Released, ProductionOrder[1].\"Source Type\"::Item, ProdItem.\"No.\", 2);\n+ ProductionOrder[1].Validate(\"Location Code\", Location.Code);\n+ ProductionOrder[1].Modify(true);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder[1], false, true, true, true, false);\n+\n+ // [GIVEN] Reserve Component Item on Production Order 1\n+ ReserveQuantityOnComponent(CompItem.\"No.\", ProductionOrder[1].\"No.\");\n+\n+ // [GIVEN] Create second Production Order for Production Item of quantity 1\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder[2], ProductionOrder[2].Status::Released, ProductionOrder[2].\"Source Type\"::Item, ProdItem.\"No.\", 1);\n+ ProductionOrder[2].Validate(\"Location Code\", Location.Code);\n+ ProductionOrder[2].Modify(true);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder[2], false, true, true, true, false);\n+\n+ // [GIVEN] Reserve Component Item on Production Order 2\n+ ReserveQuantityOnComponent(CompItem.\"No.\", ProductionOrder[2].\"No.\");\n+\n+ // [WHEN] Create Pick Worksheet for Production Order Components.\n+ GetWarehouseDocumentFromPickWorksheet(ProductionOrder);\n+\n+ // [THEN] Verify Warehouse Activity Header for Production Order Components.\n+ WarehouseActivityHeader.SetRange(\"Location Code\", Location.Code);\n+ WareHouseActivityHeader.FindSet();\n+ Assert.IsTrue(WareHouseActivityHeader.Count = 2, InventoryPickNotFoundErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3796,6 +3879,50 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n VerifyInventoryPickLine(SalesOrderNo, LotNos[2], Lot2Qty);\n end;\n \n+ local procedure GetWarehouseDocumentFromPickWorksheet(ProductionOrder: array[2] of Record \"Production Order\")\n+ var\n+ PickWorksheet: TestPage \"Pick Worksheet\";\n+ begin\n+ LibraryVariableStorage.Enqueue(ProductionOrder[1].\"No.\"); // Enqueue for PickSelectionPageHandler.\n+ LibraryVariableStorage.Enqueue(ProductionOrder[1].\"Location Code\"); // Enqueue PickSelectionPageHandler.\n+ PickWorksheet.OpenEdit();\n+ PickWorksheet.\"Get Warehouse Documents\".Invoke();\n+\n+ LibraryVariableStorage.Enqueue(ProductionOrder[2].\"No.\"); // Enqueue for PickSelectionPageHandler.\n+ LibraryVariableStorage.Enqueue(ProductionOrder[2].\"Location Code\"); // Enqueue PickSelectionPageHandler.\n+ PickWorksheet.\"Get Warehouse Documents\".Invoke();\n+ Commit();\n+\n+ PickWorksheet.CreatePick.Invoke();\n+ PickWorksheet.OK().Invoke();\n+ end;\n+\n+ local procedure ReserveQuantityOnComponent(ItemNo: code[20]; ProdOrderno: Code[20])\n+ var\n+ ProdOrderComponents: TestPage \"Prod. Order Components\";\n+ begin\n+ ProdOrderComponents.OpenEdit();\n+ ProdOrderComponents.FILTER.SetFilter(\"Item No.\", ItemNo);\n+ ProdOrderComponents.FILTER.SetFilter(\"Prod. Order No.\", ProdOrderno);\n+ ProdOrderComponents.Reserve.Invoke();\n+ ProdOrderComponents.Close();\n+ end;\n+\n+ local procedure CreateInventory(Item: Record Item; Quantity: Decimal; LocationCode: Code[10]; BinCode: Code[20]; UnitAmount: Decimal)\n+ var\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.CreateItemJournalBatchByType(ItemJournalBatch, ItemJournalBatch.\"Template Type\"::Item);\n+\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalBatch, Item, LocationCode, '', WorkDate(),\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Quantity, UnitAmount);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify();\n+\n+ LibraryInventory.PostItemJournalBatch(ItemJournalBatch);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure DummyMessageHandler(Message: Text[1024])\n@@ -3817,5 +3944,36 @@ codeunit 137294 \"SCM Inventory Miscellaneous II\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ReservationPageHandler(var Reservation: TestPage Reservation)\n+ begin\n+ Reservation.\"Reserve from Current Line\".Invoke();\n+ Reservation.OK().Invoke();\n+ end;\n+\n+ [RequestPageHandler]\n+ [Scope('OnPrem')]\n+ procedure CreatePickPageHandlerForPerWhsDoc(var CreatePick: TestRequestPage \"Create Pick\")\n+ begin\n+ CreatePick.PerWhseDoc.SetValue(true);\n+ CreatePick.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PickSelectionPageHandlerSingleDoc(var PickSelection: TestPage \"Pick Selection\")\n+ var\n+ DocumentNo: Variant;\n+ LocationCode: Variant;\n+ begin\n+ LibraryVariableStorage.Dequeue(DocumentNo); // Dequeue Variable.\n+ LibraryVariableStorage.Dequeue(LocationCode); // Dequeue Variable.\n+ PickSelection.Filter.SetFilter(\"Document No.\", DocumentNo);\n+ PickSelection.\"Document No.\".AssertEquals(DocumentNo);\n+ PickSelection.\"Location Code\".AssertEquals(LocationCode);\n+ PickSelection.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al\nindex 0b63877adb3b..32239d687e93 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Availability/WarehouseAvailabilityMgt.Codeunit.al\n@@ -870,7 +870,9 @@ codeunit 7314 \"Warehouse Availability Mgt.\"\n end else\n AvailQtyBase := CalcInvtAvailQty(Item, Location, WhseWorksheetLine.\"Variant Code\", TempWhseActivLine);\n \n- if Location.\"Require Pick\" then\n+ if Location.\"Require Pick\" or\n+ (Location.\"Prod. Consump. Whse. Handling\" = Location.\"Prod. Consump. Whse. Handling\"::\"Warehouse Pick (mandatory)\")\n+ then\n QtyReservedOnPickShip := CalcReservQtyOnPicksShips(WhseWorksheetLine.\"Location Code\", WhseWorksheetLine.\"Item No.\", WhseWorksheetLine.\"Variant Code\", TempWhseActivLine);\n \n QtyReservedForCurrLine :=\n"} +{"metadata": {"area": "sales", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218253", "base_commit": "db3b5298f26de0882a366877931e512984bb1001", "created_at": "2025-06-17", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134389, "functionName": ["QuantityReducedInSalesInvoiceAfterGenShipmentLineReservesTrackingInformation"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\nindex a4fa97f4520d..bc57ae20d22e 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n@@ -17,6 +17,7 @@ codeunit 134389 \"ERM Customer Statistics\"\n LibraryERM: Codeunit \"Library - ERM\";\n LibraryRandom: Codeunit \"Library - Random\";\n LibraryApplicationArea: Codeunit \"Library - Application Area\";\n+ LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n LibraryUtility: Codeunit \"Library - Utility\";\n IsInitialized: Boolean;\n OverDueBalanceErr: Label 'Customer OverDue Balance is not correct';\n@@ -29,6 +30,7 @@ codeunit 134389 \"ERM Customer Statistics\"\n EntryNoMustMatchErr: Label 'Entry No. must match.';\n PaymentsLCYAndAmountLCYMustMatchErr: Label 'Payemnts (LCY) and Amount (LCY) must match.';\n CustomerCardFactboxTotalErr: Label 'Customer card factbox total is not Correct';\n+ LotNoErr: Label 'Lot No. should have value.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1003,6 +1005,83 @@ codeunit 134389 \"ERM Customer Statistics\"\n Assert.AreEqual(SalesLine.\"Amount Including VAT\", Customer.GetTotalAmountLCY(), CustomerCardFactboxTotalErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemTrackingLinesPageHandler,EnterQuantityToCreatePageHandler,GetShipmentLinesPageHandler')]\n+ procedure QuantityReducedInSalesInvoiceAfterGenShipmentLineReservesTrackingInformation()\n+ var\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ ItemTrackingCode: Record \"Item Tracking Code\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Quantity: Integer;\n+ begin\n+ // [SCENARIO 576049] When the quantity in a Sales Invoices was changed after using 'Get Shipment lines' and an item with item tracking lines and reserve always has the tracking information.\n+ Initialize();\n+\n+ // [GIVEN] Created New Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Item Tracking Code and Validate Trackings.\n+ LibraryInventory.CreateItemTrackingCode(ItemTrackingCode);\n+ ItemTrackingCode.Validate(\"Lot Specific Tracking\", false);\n+ ItemTrackingCode.Validate(\"SN Specific Tracking\", false);\n+ ItemTrackingCode.Validate(\"SN Sales Inbound Tracking\", true);\n+ ItemTrackingCode.Validate(\"SN Sales Outbound Tracking\", true);\n+ ItemTrackingCode.Validate(\"Lot Sales Inbound Tracking\", true);\n+ ItemTrackingCode.Validate(\"Lot Sales Outbound Tracking\", true);\n+ ItemTrackingCode.Modify(true);\n+\n+ // [GIVEN] Created New Item and Validate Item Tracking Code, Serial Nos, Reserve.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Item Tracking Code\", ItemTrackingCode.Code);\n+ Item.Validate(\"Lot Nos.\", LibraryERM.CreateNoSeriesCode());\n+ Item.Validate(\"Serial Nos.\", LibraryERM.CreateNoSeriesCode());\n+ Item.Validate(Reserve, Item.Reserve::Always);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Store quantity in Variable.\n+ Quantity := LibraryRandom.RandIntInRange(10, 10);\n+\n+ // [GIVEN] Created Item Inventory By Posting Item Journal.\n+ CreateItemInventory(Item, Quantity);\n+\n+ // [GIVEN] Create new Sales Header.\n+ CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\", WorkDate());\n+\n+ // [GIVEN] Create Sales line and Validate Unit Price.\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", Quantity);\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandDec(1000, 0));\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Enqueue Quantity and assign Tracking Lines\n+ LibraryVariableStorage.Enqueue(true);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ SalesLine.OpenItemTrackingLines();\n+\n+ // [GIVEN] Post Sales Order invoked with \"Shipped\" selected.\n+ LibrarySales.PostSalesDocument(SalesHeader, true, false);\n+\n+ // [GIVEN] Create New Sales Invoice And Get Shipment Line Through GetShipmentLines.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, Customer.\"No.\");\n+ SalesLine.Validate(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.Validate(\"Document No.\", SalesHeader.\"No.\");\n+ LibrarySales.GetShipmentLines(SalesLine);\n+\n+ // [GIVEN] Find the Sales Line.\n+ SalesLine.SetRange(\"Document No.\", SalesHeader.\"No.\");\n+ SalesLine.SetRange(Type, SalesLine.Type::Item);\n+ SalesLine.FindFirst();\n+\n+ // [WHEN] Validate Quantity with random integer less than previous quanitity.\n+ SalesLine.Validate(Quantity, LibraryRandom.RandInt(5));\n+ SalesLine.Modify(true);\n+\n+ // [THEN] Tracking Lines is not deleted.\n+ LibraryVariableStorage.Enqueue(false);\n+ SalesLine.OpenItemTrackingLines();\n+ end;\n+\n local procedure Initialize()\n var\n Currency: Record Currency;\n@@ -1506,4 +1585,26 @@ codeunit 134389 \"ERM Customer Statistics\"\n begin\n GetShipmentLines.OK().Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ procedure ItemTrackingLinesPageHandler(var ItemTrackingLines: TestPage \"Item Tracking Lines\")\n+ var\n+ AssignSerial: Boolean;\n+ begin\n+ AssignSerial := LibraryVariableStorage.DequeueBoolean();\n+ if AssignSerial then\n+ ItemTrackingLines.\"Assign Serial No.\".Invoke();\n+\n+ if not AssignSerial then\n+ Assert.IsTrue(ItemTrackingLines.\"Lot No.\".Value() <> '', LotNoErr);\n+ ItemTrackingLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ procedure EnterQuantityToCreatePageHandler(var EnterQuantitytoCreate: TestPage \"Enter Quantity to Create\")\n+ begin\n+ EnterQuantitytoCreate.QtyToCreate.SetValue(LibraryVariableStorage.DequeueInteger());\n+ EnterQuantitytoCreate.CreateNewLotNo.SetValue(true);\n+ EnterQuantitytoCreate.OK().Invoke();\n+ end;\n }\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al\nindex 15a14be1bfcb..b95b0aa54eb2 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesLineReserve.Codeunit.al\n@@ -1304,6 +1304,9 @@ codeunit 99000832 \"Sales Line-Reserve\"\n if (NewSalesLine.Type <> NewSalesLine.Type::Item) or (NewSalesLine.Quantity = 0) or (NewSalesLine.Reserve <> NewSalesLine.Reserve::Always) then\n exit(false);\n \n+ if ShipmentExists(NewSalesLine) then\n+ exit(false);\n+\n Item.SetLoadFields(\"Costing Method\");\n Item.Get(NewSalesLine.\"No.\");\n \n@@ -1313,6 +1316,15 @@ codeunit 99000832 \"Sales Line-Reserve\"\n exit(NewSalesLine.Quantity < OldSalesLine.Quantity);\n end;\n \n+ local procedure ShipmentExists(SalesLine: Record \"Sales Line\"): Boolean\n+ var\n+ SalesShipmentLine: Record \"Sales Shipment Line\";\n+ begin\n+ SalesShipmentLine.SetRange(\"Document No.\", SalesLine.\"Shipment No.\");\n+ SalesShipmentLine.SetRange(\"Line No.\", SalesLine.\"Shipment Line No.\");\n+ exit(not SalesShipmentLine.IsEmpty());\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterReservQuantity(SalesLine: Record \"Sales Line\"; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)\n begin\n"} +{"metadata": {"area": "project", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218995", "base_commit": "26bcb2715129beebf0d07da7f19e06fe66636119", "created_at": "2025-06-24", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136306, "functionName": ["PostPurchaseCreditMemoWithNonInventoryItemLinkedToProject"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\nindex 3f5a305f277c..8683b7e13047 100644\n--- a/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobInvoicing.Codeunit.al\n@@ -4082,6 +4082,47 @@ codeunit 136306 \"Job Invoicing\"\n Assert.IsFalse(JobPlanningLine.\"System-Created Entry\", ValueFalseErr);\n end;\n \n+ [Test]\n+ procedure PostPurchaseCreditMemoWithNonInventoryItemLinkedToProject()\n+ var\n+ Item: Record Item;\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ begin\n+ // [SCENARIO 580434] Error when posting a Purchase Credit Memo for 'Non-Inventory' item with Project No. selected\n+ Initialize();\n+\n+ // [GIVEN] Create Non-Inventory Item\n+ LibraryInventory.CreateNonInventoryTypeItem(Item);\n+\n+ // [GIVEN] Create Job with Customer\n+ CreateJobWithCustomer(Job);\n+\n+ // [GIVEN] Create Job Task\n+ LibraryJob.CreateJobTask(Job, JobTask);\n+\n+ // [GIVEN] Create Vendor\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ // [GIVEN] Create Purchase Credit Memo\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::\"Credit Memo\", Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item.\"No.\", 1);\n+\n+ // [GIVEN] Set Job No., Job Task No. and Job Line Type as Billable\n+ PurchaseLine.Validate(\"Job No.\", Job.\"No.\");\n+ PurchaseLine.Validate(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ PurchaseLine.Validate(\"Job Line Type\", PurchaseLine.\"Job Line Type\"::Billable);\n+ PurchaseLine.Modify(true);\n+\n+ // [WHEN] Post Purchase Credit Memo\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true);\n+\n+ // [THEN] No error should come, as posting for Non-Inventory Item.\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al\nindex a913f1c1ea1b..bd54e22b3b45 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Posting/JobPostLine.Codeunit.al\n@@ -478,6 +478,9 @@ codeunit 1001 \"Job Post-Line\"\n if IsHandled then\n exit;\n \n+ if PurchaseLine.IsNonInventoriableItem() then\n+ exit;\n+\n Job.Get(PurchaseLine.\"Job No.\");\n if Job.GetQuantityAvailable(PurchaseLine.\"No.\", PurchaseLine.\"Location Code\", PurchaseLine.\"Variant Code\", 0, 2) <\n -PurchaseLine.\"Return Qty. to Ship (Base)\"\n"} +{"metadata": {"area": "warehouse", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-218786", "base_commit": "a0daccc2bd96d0bd4269d1b5eae4cc44ddd34673", "created_at": "2025-06-21", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137065, "functionName": ["WarehousePickUpdateQuantityInOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al\nindex 9251a2965f1f..fda235875212 100644\n--- a/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMReservationII.Codeunit.al\n@@ -58,6 +58,7 @@ codeunit 137065 \"SCM Reservation II\"\n PostJnlLinesMsg: Label 'Do you want to post the journal lines';\n SuggestedBackGroundRunQst: Label 'Would you like to run the low-level code calculation as a background job?';\n ActionMessageEntryExistErr: Label 'Action Message Entry exist for item %1', Comment = '%1 = Item No.';\n+ QuantityErr: Label 'Quantity must be equal to %1', Comment = '%1 = Quantity';\n \n [Test]\n [HandlerFunctions('ProdOrderComponentsHandler')]\n@@ -2997,6 +2998,84 @@ codeunit 137065 \"SCM Reservation II\"\n VerifyThereIsNoDamagedReservationEntryForSurplus(Database::\"Sales Line\", SalesHeader[2].\"No.\", ReservationEntry.\"Reservation Status\"::Surplus);//, -SalesLine[2].\"Quantity (Base)\");\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure WarehousePickUpdateQuantityInOrder()\n+ var\n+ Bin: array[8] of Record Bin;\n+ CompItem, ProdItem : Record Item;\n+ Location: Record Location;\n+ ProductionOrder: Record \"Production Order\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ Quantity: Decimal;\n+ UpdatedQuantity: Decimal;\n+ begin\n+ // [SCENARIO 581104] Manually change quantity of \"Take Line\" in Warehouse Pick changes the quantity of the correct \"Place Lines\"\n+ Initialize();\n+\n+ // [GIVEN] Set Quantity and UpdatedQuantity.\n+ Quantity := LibraryRandom.RandIntInRange(900, 1000);\n+ UpdatedQuantity := LibraryRandom.RandIntInRange(400, 500);\n+\n+ // [GIVEN] Reset Warehouse Employee Default Location.\n+ ResetWarehouseEmployeeDefaultLocation();\n+\n+ // [GIVEN] Create Location with WMS enabled Bin mandatory\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create Warehouse Employee for Location.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create Bins for Location.\n+ CreateBin(Bin, Location.Code);\n+\n+ // [GIVEN] Set \"Prod. Consump. Whse. Handling\" = \"Warehouse Pick (mandatory)\" and assign Bins to \"To-Production Bin Code\" and \"From-Production Bin Code\".\n+ Location.Validate(\"Prod. Consump. Whse. Handling\", Location.\"Prod. Consump. Whse. Handling\"::\"Warehouse Pick (mandatory)\");\n+ Location.Validate(\"To-Production Bin Code\", Bin[1].Code);\n+ Location.Validate(\"From-Production Bin Code\", Bin[2].Code);\n+ Location.Validate(\"Open Shop Floor Bin Code\", Bin[3].Code);\n+ Location.Modify(true);\n+\n+ // [GIVEN] Create Component Item with \"Replenishment System\" = \"Purchase\" and \"Flushing Method\" = \"Manual\".\n+ LibraryInventory.CreateItem(CompItem);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::\"Pick + Manual\");\n+ CompItem.Validate(\"Allow Whse. Overpick\", true);\n+ CompItem.Modify();\n+\n+ // [GIVEN] Create Production BOM for Component Item.\n+ LibraryInventory.CreateItem(ProdItem);\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Manufacturing Policy\", ProdItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProdItem.Validate(\"Flushing Method\", ProdItem.\"Flushing Method\"::Manual);\n+ ProdItem.Validate(\"Production BOM No.\", LibraryManufacturing.CreateCertifiedProductionBOM(ProductionBOMHeader, CompItem.\"No.\", 1));\n+ ProdItem.Modify();\n+\n+ // [GIVEN] Create Inventory for Component Item for five different Bins.\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[4].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[5].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[6].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[7].Code, 0);\n+ CreateInventoryWithBin(CompItem, Quantity, Location.Code, Bin[8].Code, 0);\n+\n+ // [GIVEN] Create Production Orders for Production Item of quantity Quantity * 5.\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder, ProductionOrder.Status::Released, ProductionOrder.\"Source Type\"::Item, ProdItem.\"No.\", Quantity * 5);\n+ ProductionOrder.Validate(\"Location Code\", Location.Code);\n+ ProductionOrder.Modify(true);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+\n+ // [GIVEN] Create Warehouse Pick from Production Order.\n+ LibraryWarehouse.CreateWhsePickFromProduction(ProductionOrder);\n+\n+ // [WHEN] Update quantity in Warehouse Pick Lines.\n+ UpdateQuantityWarehousePickFromPage(ProductionOrder.\"No.\", Location.Code, UpdatedQuantity);\n+\n+ // [THEN] Verify that the Warehouse Activity Lines are updated correctly.\n+ VerifyWareHouseActivityLinesForQuantity(ProductionOrder.\"No.\", Location, Quantity, UpdatedQuantity);\n+ end;\n+\n local procedure Initialize()\n var\n AllProfile: Record \"All Profile\";\n@@ -4693,6 +4772,72 @@ codeunit 137065 \"SCM Reservation II\"\n asserterror ReservationEntry.FindFirst();\n end;\n \n+ local procedure ResetWarehouseEmployeeDefaultLocation()\n+ var\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ begin\n+ WarehouseEmployee.SetRange(\"User ID\", UserId());\n+ WarehouseEmployee.SetRange(Default, true);\n+ WarehouseEmployee.ModifyAll(Default, false);\n+ end;\n+\n+ local procedure VerifyWareHouseActivityLinesForQuantity(ProductionOrderNo: Code[20]; Location: Record Location; Quantity: Decimal; UpdatedQuantity: Decimal)\n+ var\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ begin\n+ FindWarehouseActivityLine(WarehouseActivityLine, ProductionOrderNo, WarehouseActivityLine.\"Source Document\"::\"Prod. Consumption\", WarehouseActivityLine.\"Action Type\"::Place);\n+ WarehouseActivityLine.SetRange(\"Bin Code\", Location.\"To-Production Bin Code\");\n+ WarehouseActivityLine.FindFirst();\n+ Assert.IsTrue(WarehouseActivityLine.\"Qty. (Base)\" = Quantity, StrSubstNo(QuantityErr, Quantity));\n+\n+ WarehouseActivityLine.Reset();\n+ FindWarehouseActivityLine(WarehouseActivityLine, ProductionOrderNo, WarehouseActivityLine.\"Source Document\"::\"Prod. Consumption\", WarehouseActivityLine.\"Action Type\"::Place);\n+ WarehouseActivityLine.SetRange(\"Bin Code\", Location.\"To-Production Bin Code\");\n+ WarehouseActivityLine.FindLast();\n+ Assert.IsTrue(WarehouseActivityLine.\"Qty. (Base)\" = UpdatedQuantity, StrSubstNo(QuantityErr, UpdatedQuantity));\n+ end;\n+\n+ local procedure UpdateQuantityWarehousePickFromPage(ProductionOrderNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal)\n+ var\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ WarehousePickPage: TestPage \"Warehouse Pick\";\n+ begin\n+ WarehouseActivityLine.SetRange(\"Source Document\", WarehouseActivityHeader.\"Source Document\"::\"Prod. Consumption\");\n+ WarehouseActivityLine.SetRange(\"Source No.\", ProductionOrderNo);\n+ WarehouseActivityLine.SetRange(\"Location Code\", LocationCode);\n+ WarehouseActivityLine.FindFirst();\n+ WarehouseActivityHeader.Get(WarehouseActivityHeader.Type::Pick, WarehouseActivityLine.\"No.\");\n+ WarehousePickPage.OpenEdit();\n+ WarehousePickPage.GoToRecord(WarehouseActivityHeader);\n+ WarehousePickPage.WhseActivityLines.Last();\n+ WarehousePickPage.WhseActivityLines.Previous();\n+ WarehousePickPage.WhseActivityLines.Quantity.SetValue(Quantity);\n+ end;\n+\n+ local procedure CreateInventoryWithBin(Item: Record Item; Quantity: Decimal; LocationCode: Code[10]; BinCode: Code[20]; UnitAmount: Decimal)\n+ var\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.CreateItemJournalBatchByType(ItemJournalBatch, ItemJournalBatch.\"Template Type\"::Item);\n+\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalBatch, Item, LocationCode, '', WorkDate(),\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Quantity, UnitAmount);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify();\n+\n+ LibraryInventory.PostItemJournalBatch(ItemJournalBatch);\n+ end;\n+\n+ local procedure CreateBin(var Bin: array[8] of Record Bin; LocationCode: Code[10])\n+ var\n+ i: Integer;\n+ begin\n+ for i := 1 to arraylen(Bin) do\n+ LibraryWarehouse.CreateBin(Bin[i], LocationCode, Bin[i].Code, '', '');\n+ end;\n+\n [PageHandler]\n [Scope('OnPrem')]\n procedure ProdOrderComponentsHandler(var ProdOrderComponents: TestPage \"Prod. Order Components\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al b/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al\nindex 0b806569d9b4..a4b3f3fb5f23 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/WarehouseActivityLine.Table.al\n@@ -3102,6 +3102,7 @@ table 5767 \"Warehouse Activity Line\"\n var\n Item: Record Item;\n WhseActivityLine: Record \"Warehouse Activity Line\";\n+ QuantityUpdated: Boolean;\n begin\n if CurrFieldNo = 0 then\n exit;\n@@ -3125,10 +3126,21 @@ table 5767 \"Warehouse Activity Line\"\n Item.Get(FromWhseActivityLine.\"Item No.\");\n Item.TestField(\"Allow Whse. Overpick\");\n \n+ SetFilterFromWhseActivityLineToUpdateQty(WhseActivityLine, FromWhseActivityLine, xWhseActivityLine, QuantityUpdated);\n+ if QuantityUpdated then\n+ WhseActivityLine.Modify(true);\n+ end;\n+\n+ local procedure SetFilterFromWhseActivityLineToUpdateQty(\n+ var WhseActivityLine: Record \"Warehouse Activity Line\";\n+ FromWhseActivityLine: Record \"Warehouse Activity Line\";\n+ xWhseActivityLine: Record \"Warehouse Activity Line\";\n+ var QuantityUpdated: Boolean)\n+ begin\n WhseActivityLine.SetLoadFields(\"Activity Type\", \"No.\", \"Line No.\", \"Item No.\", \"Variant Code\", \"Location Code\", \"Action Type\", Quantity, \"Lot No.\", \"Serial No.\", \"Source No.\", \"Source Line No.\", \"Source Document\");\n WhseActivityLine.SetRange(\"Activity Type\", FromWhseActivityLine.\"Activity Type\");\n WhseActivityLine.SetRange(\"No.\", FromWhseActivityLine.\"No.\");\n- WhseActivityLine.SetFilter(\"Line No.\", '<>%1', FromWhseActivityLine.\"Line No.\");\n+ WhseActivityLine.SetFilter(\"Line No.\", '>%1', FromWhseActivityLine.\"Line No.\");\n WhseActivityLine.SetRange(\"Item No.\", FromWhseActivityLine.\"Item No.\");\n WhseActivityLine.SetRange(\"Variant Code\", FromWhseActivityLine.\"Variant Code\");\n WhseActivityLine.SetRange(\"Location Code\", FromWhseActivityLine.\"Location Code\");\n@@ -3139,11 +3151,18 @@ table 5767 \"Warehouse Activity Line\"\n WhseActivityLine.SetRange(\"Source Document\", FromWhseActivityLine.\"Source Document\");\n WhseActivityLine.SetRange(\"Source No.\", FromWhseActivityLine.\"Source No.\");\n WhseActivityLine.SetRange(\"Source Line No.\", FromWhseActivityLine.\"Source Line No.\");\n+ if WhseActivityLine.FindFirst() then begin\n+ WhseActivityLine.Validate(Quantity, FromWhseActivityLine.Quantity);\n+ QuantityUpdated := true;\n+ exit;\n+ end;\n \n- WhseActivityLine.FindFirst();\n-\n- WhseActivityLine.Validate(Quantity, FromWhseActivityLine.Quantity);\n- WhseActivityLine.Modify(true);\n+ WhseActivityLine.SetRange(\"Line No.\");\n+ WhseActivityLine.SetFilter(\"Line No.\", '<>%1', FromWhseActivityLine.\"Line No.\");\n+ if WhseActivityLine.FindFirst() then begin\n+ WhseActivityLine.Validate(Quantity, FromWhseActivityLine.Quantity);\n+ QuantityUpdated := true;\n+ end\n end;\n \n [IntegrationEvent(false, false)]\n"} +{"metadata": {"area": "utilities", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-217974", "base_commit": "645334f664bea223d7a58bdcd730164852241728", "created_at": "2025-06-13", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137156, "functionName": ["MoveNegativeLines_SetsReturnOrderShipToAddressToCompany"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al\nindex 670a87576340..2c5a96d5e372 100644\n--- a/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMOrdersIV.Codeunit.al\n@@ -72,6 +72,7 @@ codeunit 137156 \"SCM Orders IV\"\n DocumentLineSourceNoErr: label 'Expected source on document line is %1 but found %2.', Comment = '%1 = Expected Source No., %2 = Actual Source No.';\n ReservationFromStockErr: Label 'Reservation from Stock must be %1 in %2.', Comment = '%1= Field Value, %2 =Table Caption.';\n PurchasingCodeOnSalesInvoiceErr: Label 'The Purchasing Code should be blank for item %1 on the sales invoice because it is used only for the drop shipment process.', Comment = '%1= Item No.';\n+ ShipToAddressErr: Label 'Ship-to Address on Return Order should be company address';\n \n #if not CLEAN25\n [Test]\n@@ -3553,6 +3554,43 @@ codeunit 137156 \"SCM Orders IV\"\n Assert.ExpectedError(StrSubstNo(PurchasingCodeOnSalesInvoiceErr, Item.\"No.\"));\n end;\n \n+ [Test]\n+ procedure MoveNegativeLines_SetsReturnOrderShipToAddressToCompany()\n+ var\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ CompanyInfo: Record \"Company Information\";\n+ begin\n+ // [SCENARIO 580640] Verify Ship to Address of Return Order when Move Negative Lines on the Sales Order.\n+ Initialize();\n+\n+ // [GIVEN] Create Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Sales Header with Document Type as Order.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+\n+ // [GIVEN] Create SalesLine with Negative Quantity.\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, LibraryInventory.CreateItem(Item), LibraryRandom.RandIntInRange(-5, -10));\n+\n+ // [WHEN] Move Negative Lines\n+ MoveNegativeLinesOnSalesOrder(SalesHeader);\n+\n+ // [GIVEN] Get company address\n+ CompanyInfo.Get();\n+\n+ // [THEN] Sales Return Order is created with Ship to Address as Company Address.\n+ SalesHeader.SetRange(\"Document Type\", SalesHeader.\"Document Type\"::\"Return Order\");\n+ SalesHeader.SetRange(\"Sell-to Customer No.\", Customer.\"No.\");\n+ SalesHeader.FindFirst();\n+ Assert.AreEqual(\n+ CompanyInfo.\"Ship-to Address\", SalesHeader.\"Ship-to Address\", ShipToAddressErr);\n+ Assert.AreEqual(\n+ CompanyInfo.\"Ship-to City\", SalesHeader.\"Ship-to City\", ShipToAddressErr);\n+ end;\n+\n local procedure Initialize()\n var\n PriceListLine: Record \"Price List Line\";\n@@ -5405,8 +5443,8 @@ codeunit 137156 \"SCM Orders IV\"\n begin\n WarehouseActivityLine.SetRange(\"Action Type\", ActionType);\n FindWarehouseActivityLine(\n- WarehouseActivityLine, WarehouseActivityLine.\"Source Document\"::\"Purchase Order\", SourceNo,\n- WarehouseActivityLine.\"Activity Type\"::\"Put-away\");\n+WarehouseActivityLine, WarehouseActivityLine.\"Source Document\"::\"Purchase Order\", SourceNo,\n+WarehouseActivityLine.\"Activity Type\"::\"Put-away\");\n WarehouseActivityLine.ModifyAll(\"Zone Code\", ZoneCode, true);\n WarehouseActivityLine.ModifyAll(\"Bin Code\", BinCode, true);\n end;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al b/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al\nindex 780de254f475..452e82783b47 100644\n--- a/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Utilities/CopyDocumentMgt.Codeunit.al\n@@ -747,6 +747,7 @@ codeunit 6620 \"Copy Document Mgt.\"\n begin\n FromSalesHeader.CalcFields(\"Work Description\");\n ToSalesHeader.TransferFields(FromSalesHeader, false);\n+ UpdateShipToAddress(ToSalesHeader);\n UpdateSalesHeaderWhenCopyFromSalesHeader(ToSalesHeader, OldSalesHeader, FromDocType);\n SetReceivedFromCountryCode(FromDocType, ToSalesHeader);\n OnAfterCopySalesHeader(ToSalesHeader, OldSalesHeader, FromSalesHeader, FromDocType);\n"} +{"metadata": {"area": "warehouse", "image_count": 10}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-222488", "base_commit": "34f4bd6914204e9f211b9f09a3b0c3a09954da33", "created_at": "2025-07-30", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137152, "functionName": ["RegisterPutAwayWithBreakBulkFilterShouldRegisterAllLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al\nindex d40ac8d858c1..e83bdf59b1cc 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseReceiving.Codeunit.al\n@@ -4302,6 +4302,63 @@ codeunit 137152 \"SCM Warehouse - Receiving\"\n VerifyWarehouseActivityLineWithBin(Item.\"No.\", Bin[3].Code, Bin[1].Code);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerTrue')]\n+ procedure RegisterPutAwayWithBreakBulkFilterShouldRegisterAllLines()\n+ var\n+ Item: Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ UOM: Record \"Unit of Measure\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ WarehouseEntry: Record \"Warehouse Entry\";\n+ PutAwayPage: TestPage \"Warehouse Put-away\";\n+ ExpectedLinesCount: Integer;\n+ begin\n+ // [SCENARIO 592107] Verify all put away lines are registered, when register a warehouse put away with the break bulk filter set to yes\n+ Initialize();\n+\n+ // [GIVEN] Create Warehouse Employee for location WHITE.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, LocationWhite.Code, true);\n+\n+ // [GIVEN] Create an Item and assign Put-away Unit of Measure Code.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Put-away Unit of Measure Code\", Item.\"Base Unit of Measure\");\n+ Item.Modify(true);\n+\n+ // [GIVEN] Create Unit of Measure and Item Unit of Measure with Qty. per Unit of Measure as 48.\n+ LibraryInventory.CreateUnitOfMeasureCode(UOM);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure, Item.\"No.\", UOM.Code, 48);\n+\n+ // [GIVEN] Create Purchase Order and Post Warehouse Receipt.\n+ CreatePurchaseOrderAndPostWarehouseReceipt(\n+ PurchaseHeader, LocationWhite.Code, Item.\"No.\", LibraryRandom.RandDec(10, 2), UOM.Code);\n+\n+ // [GIVEN] Find Warehouse Put-away\n+ WarehouseActivityLine.SetRange(\"Activity Type\", WarehouseActivityLine.\"Activity Type\"::\"Put-away\");\n+ WarehouseActivityLine.SetRange(\"Source Document\", WarehouseActivityLine.\"Source Document\"::\"Purchase Order\");\n+ WarehouseActivityLine.SetRange(\"Source No.\", PurchaseHeader.\"No.\");\n+ WarehouseActivityLine.FindSet();\n+ ExpectedLinesCount := WarehouseActivityLine.Count();\n+\n+ // [GIVEN] Open Warehouse Put-away page\n+ PutAwayPage.OpenEdit();\n+ PutAwayPage.FILTER.SetFilter(\"No.\", WarehouseActivityLine.\"No.\");\n+\n+ // [GIVEN] Set Break Bulk filter = Yes\n+ PutAwayPage.\"Breakbulk Filter\".SetValue(true);\n+\n+ // [WHEN] Register Warehouse Put-Away.\n+ PutAwayPage.\"&Register Put-away\".Invoke();\n+\n+ // [THEN] Verify Put-Away should be registered and all lines should be posted in Warehouse Entry table\n+ WarehouseEntry.SetRange(\"Entry Type\", WarehouseEntry.\"Entry Type\"::Movement);\n+ WarehouseEntry.SetRange(\"Source Document\", WarehouseEntry.\"Source Document\"::\"P. Order\");\n+ WarehouseEntry.SetRange(\"Source No.\", PurchaseHeader.\"No.\");\n+ Assert.RecordCount(WarehouseEntry, ExpectedLinesCount);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al b/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al\nindex 07db37f9fc83..680830c4c772 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/WhsePutawaySubform.Page.al\n@@ -482,9 +482,17 @@ page 5771 \"Whse. Put-away Subform\"\n \n procedure RegisterPutAwayYesNo()\n var\n+ WhseActivityHeader: Record \"Warehouse Activity Header\";\n WhseActivLine: Record \"Warehouse Activity Line\";\n begin\n- WhseActivLine.Copy(Rec);\n+ WhseActivityHeader.Get(Rec.\"Activity Type\", Rec.\"No.\");\n+ if (Rec.\"Activity Type\"::\"Put-away\" = Rec.\"Activity Type\"::\"Put-away\") and WhseActivityHeader.\"Breakbulk Filter\" then begin\n+ WhseActivLine.SetRange(\"Activity Type\", WhseActivLine.\"Activity Type\"::\"Put-away\");\n+ WhseActivLine.SetRange(\"No.\", Rec.\"No.\");\n+ WhseActivLine.FindSet();\n+ end\n+ else\n+ WhseActivLine.Copy(Rec);\n WhseActivLine.FilterGroup(3);\n WhseActivLine.SetRange(Breakbulk);\n WhseActivLine.FilterGroup(0);\n"} +{"metadata": {"area": "warehouse", "image_count": 14}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-222484", "base_commit": "a60a6b56b858f370ae21d8d0241ed67f72d6202c", "created_at": "2025-07-30", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137260, "functionName": ["RegisterPickWithNoErrorForFEFOLocation"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al\nindex df8ad3bb4d4b..de51c3ce8532 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryItemTracking.Codeunit.al\n@@ -47,6 +47,7 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n JournalPostedMsg: Label 'The journal lines were successfully posted.';\n CouldNotRegisterWhseActivityErr: Label 'Could not register Warehouse Activity.';\n OrderToOrderBindingOnSalesLineQst: Label 'Registering the pick will remove the existing order-to-order reservation for the sales order.\\Do you want to continue?';\n+ ILELotNotMatchedErr: Label 'Item Ledger Entry Lot No. %1 should be equal to the first lot with FEFO.', Comment = '%1 - Lot No.';\n \n [Test]\n [HandlerFunctions('WhseItemTrackingLinesPageHandler,RegisterWhseMessageHandler,ConfirmHandler')]\n@@ -2080,6 +2081,77 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n Assert.ExpectedError(StrSubstNo(CannotMatchItemTrackingErr, SalesLine.\"Document No.\", SalesLine.\"Line No.\", SalesLine.\"No.\", SalesLine.Description));\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemTrackingLinesPageHandler,ReservationFromCurrentLineHandler')]\n+ [Scope('OnPrem')]\n+ procedure RegisterPickWithNoErrorForFEFOLocation()\n+ var\n+ Location: Record Location;\n+ Bin: Record Bin;\n+ Item: Record Item;\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ SalesHeader: array[2] of Record \"Sales Header\";\n+ WarehouseShipmentHeader: Record \"Warehouse Shipment Header\";\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ ExpirationDate: Date;\n+ ShipmentBinCode: Code[20];\n+ LotNo: array[2] of Code[10];\n+ begin\n+\n+ // [SCENARIO 572962] No Error when Lot No. LOT0001 is available on inventory, when trying to register pick for item with reservation and item tracking with location set up FEFO\n+ Initialize();\n+\n+ // [GIVEN] Set up Expiration Date for the Lot No.\n+ ExpirationDate := CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', WorkDate());\n+\n+ // [GIVEN] Create Location with pick according to FEFO.\n+ CreateLocationWithPostingSetupAndPickAccordingTOFEFO(Location, ShipmentBinCode);\n+\n+ // [GIVEN] Item with Lot No. tracking.\n+ LibraryInventory.CreateTrackedItem(Item, '', '', CreateItemTrackingCode(false, true, true, false, true));\n+\n+ // [GIVEN] Positive adjustment with Lot = \"X\" and ExpirationDate = D1 , Lot = \"Y\" and ExpirationDate = D2 and D2 > D1.\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, LibraryUtility.GenerateGUID(), '', '');\n+ SelectItemJournalAndPostItemJournalLine(\n+ LotNo[1], Bin.Code, '', Item.\"No.\", Location.Code, '', 1, ExpirationDate,\n+ ItemJournalBatch.\"Template Type\"::Item, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", false);\n+ SelectItemJournalAndPostItemJournalLine(\n+ LotNo[2], Bin.Code, '', Item.\"No.\", Location.Code, '', 1,\n+ CalcDate('<' + Format(LibraryRandom.RandInt(5)) + 'D>', ExpirationDate),\n+ ItemJournalBatch.\"Template Type\"::Item, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", false);\n+\n+ // [GIVEN] Create Sales order and reserve the first Lot No. \"LOT0001\" with Expiration Date = D1.\n+ CreateSOAndTrackInventory(SalesHeader[1], Item.\"No.\", Location.Code, 1);\n+\n+ // Create seconf sales order and reserve the second Lot No. \"LOT0002\" with Expiration Date = D2.\n+ CreateSOAndTrackInventory(SalesHeader[2], Item.\"No.\", Location.Code, 1);\n+\n+ // [GIVEN] Create Warehouse Shipment from Sales Order second.\n+ CreateWhseShipmentFromSO(WarehouseShipmentHeader, SalesHeader[2]);\n+\n+ // [WHEN] CreatePick From Warehouse Shipment.\n+ LibraryWarehouse.CreatePick(WarehouseShipmentHeader);\n+\n+ // [WHEN] Register Pick should not fail with error \"Lot No. is not available on inventory\" for the first Lot No. \"LOT0001\" with Expiration Date = D1.\n+ WarehouseActivityLine.SetRange(\"Item No.\", Item.\"No.\");\n+ WarehouseActivityLine.SetRange(\"Action Type\", WarehouseActivityLine.\"Action Type\"::Take);\n+ WarehouseActivityLine.FindFirst();\n+ WarehouseActivityHeader.Get(WarehouseActivityLine.\"Activity Type\", WarehouseActivityLine.\"No.\");\n+ LibraryWarehouse.RegisterWhseActivity(WarehouseActivityHeader);\n+\n+ // [WHEN] Post Warehouse Shipment.\n+ LibraryWarehouse.PostWhseShipment(WarehouseShipmentHeader, false);\n+\n+ // [THEN] Item Ledger Entry for the first Lot No. \"LOT0001\" with Expiration Date = D1 should be created.\n+ ItemLedgerEntry.SetRange(\"Entry Type\", ItemLedgerEntry.\"Entry Type\"::Sale);\n+ ItemLedgerEntry.SetRange(\"Item No.\", Item.\"No.\");\n+ ItemLedgerEntry.FindFirst();\n+ Assert.AreEqual(LotNo[1], ItemLedgerEntry.\"Lot No.\", StrSubstNo(ILELotNotMatchedErr, LotNo[1]));\n+ end;\n+\n local procedure Initialize()\n var\n InventorySetup: Record \"Inventory Setup\";\n@@ -3485,6 +3557,19 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n LibrarySales.UndoSalesShipmentLine(SalesShipmentLine);\n end;\n \n+ local procedure CreateSOAndTrackInventory(var SalesHeader: Record \"Sales Header\"; ItemNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal)\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, LibrarySales.CreateCustomerNo());\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, ItemNo, Quantity);\n+ SalesLine.Validate(\"Location Code\", LocationCode);\n+ LibraryVariableStorage.Enqueue(SalesLine.Quantity);\n+ SalesLine.Modify(true);\n+ SalesLine.ShowReservation();\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(ConfirmMessage: Text[1024]; var Reply: Boolean)\n@@ -3687,6 +3772,14 @@ codeunit 137260 \"SCM Inventory Item Tracking\"\n ProductionJournal.Post.Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ReservationFromCurrentLineHandler(var Reservation: TestPage Reservation)\n+ begin\n+ Reservation.\"Reserve from Current Line\".Invoke();\n+ Reservation.OK().Invoke();\n+ end;\n+\n local procedure AssignLotNos(var ItemTrackingLines: TestPage \"Item Tracking Lines\")\n var\n LinesToProcess: Integer;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al\nindex 06bc64083218..cc14d68c515b 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al\n@@ -2044,6 +2044,7 @@ codeunit 7307 \"Whse.-Activity-Register\"\n if Item.\"Reserved Qty. on Inventory\" > 0 then begin\n xReservedQty := Item.\"Reserved Qty. on Inventory\";\n WhseActivityItemTrackingSetup.CopyTrackingFromWhseActivityLine(WhseActivLine);\n+ RemoveNonSpecificreservations(WhseActivLine, WhseItemTrackingSetup, QtyToRelease);\n LateBindingMgt.ReleaseForReservation(\n WhseActivLine.\"Item No.\", WhseActivLine.\"Variant Code\", WhseActivLine.\"Location Code\",\n WhseActivityItemTrackingSetup, QtyToRelease);\n@@ -2127,6 +2128,40 @@ codeunit 7307 \"Whse.-Activity-Register\"\n until WarehouseActivityLine.Next() = 0;\n end;\n \n+ local procedure RemoveNonSpecificreservations(WhseActivLine: Record \"Warehouse Activity Line\"; WhseItemTrackingSetup: Record \"Item Tracking Setup\"; QtyToRelease: Decimal)\n+ var\n+ ReservationEntry: Record \"Reservation Entry\";\n+ SalesLine: Record \"Sales Line\";\n+ QtyToPick: Decimal;\n+ begin\n+ if not WhseItemTrackingSetup.TrackingRequired() then\n+ exit;\n+ if not (WhseActivLine.\"Source Type\" = Database::\"Sales Line\") then\n+ exit;\n+\n+ QtyToPick := QtyToRelease;\n+ SalesLine.Get(WhseActivLine.\"Source Subtype\", WhseActivLine.\"Source No.\", WhseActivLine.\"Source Line No.\");\n+ ReservationEntry.SetSourceFilter(WhseActivLine.\"Source Type\", WhseActivLine.\"Source Subtype\", WhseActivLine.\"Source No.\", WhseActivLine.\"Source Line No.\", true);\n+ ReservationEntry.SetRange(Positive, false);\n+ if ReservationEntry.FindSet() then\n+ repeat\n+ DeleteNonSpecificReservationEntries(ReservationEntry, SalesLine, QtyToPick);\n+ until (ReservationEntry.Next() = 0) or (QtyToPick >= 0);\n+ end;\n+\n+ local procedure DeleteNonSpecificReservationEntries(ReservationEntry: Record \"Reservation Entry\"; SalesLine: Record \"Sales Line\"; var QtyToPick: Decimal)\n+ var\n+ ReservationManagement: Codeunit \"Reservation Management\";\n+ begin\n+ if ReservationEntry.TrackingExists() then\n+ exit;\n+\n+ ReservationManagement.SetReservSource(SalesLine);\n+ ReservationManagement.DeleteReservEntries(false, ReservationEntry.\"Quantity (Base)\");\n+ QtyToPick += ReservationEntry.\"Quantity (Base)\"\n+ end;\n+\n+\n [IntegrationEvent(false, false)]\n local procedure OnBeforeCode(var WarehouseActivityLine: Record \"Warehouse Activity Line\")\n begin\n"} +{"metadata": {"area": "inventory", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220314", "base_commit": "96c641e94b94056dda25b90907bef9b77622e31d", "created_at": "2025-07-08", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137275, "functionName": ["ItemReclassJournalUnitOfMeasureUpdatedWhenItemChanged"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al\nindex 436478abba92..b3bf0372e39c 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryJournals.Codeunit.al\n@@ -1800,6 +1800,54 @@ codeunit 137275 \"SCM Inventory Journals\"\n Codeunit.Run(Codeunit::\"Item Jnl.-Post Batch\", ItemJournalLine);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure ItemReclassJournalUnitOfMeasureUpdatedWhenItemChanged()\n+ var\n+ Item: array[2] of Record Item;\n+ UnitOfMeasure: array[2] of Record \"Unit of Measure\";\n+ ItemUnitOfMeasure: array[2] of Record \"Item Unit of Measure\";\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemReclassJournal: TestPage \"Item Reclass. Journal\";\n+ i: Integer;\n+ begin\n+ // [SCENARIO 581983] Unit of Measure Code should be updated automatically when Item No. is changed in Item Reclassification Journal\n+ Initialize();\n+\n+ // [GIVEN] Create two items with different base unit of measure codes\n+ for i := 1 to 2 do begin\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure[i]);\n+ LibraryInventory.CreateItem(Item[i]);\n+ LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure[i], Item[i].\"No.\", UnitOfMeasure[i].Code, 1);\n+ Item[i].Validate(\"Base Unit of Measure\", UnitOfMeasure[i].Code);\n+ Item[i].Modify(true);\n+ end;\n+\n+ // [GIVEN] Setup Item Reclassification Journal template and batch\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Transfer);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type::Transfer, ItemJournalTemplate.Name);\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+\n+ // [WHEN] Open Item Reclassification Journal page\n+ ItemReclassJournal.OpenEdit();\n+ ItemReclassJournal.CurrentJnlBatchName.SetValue(ItemJournalBatch.Name);\n+\n+ // [WHEN] Enter first item no. and verify unit of measure is set\n+ ItemReclassJournal.\"Item No.\".SetValue(Item[1].\"No.\");\n+ ItemReclassJournal.\"Unit of Measure Code\".AssertEquals(UnitOfMeasure[1].Code);\n+\n+ // [WHEN] Change item no. to second item\n+ ItemReclassJournal.\"Item No.\".SetValue(Item[2].\"No.\");\n+\n+ // [THEN] Verify unit of measure code is updated to second item's base unit of measure\n+ ItemReclassJournal.\"Unit of Measure Code\".AssertEquals(UnitOfMeasure[2].Code);\n+\n+ // [THEN] Verify no error occurs when changing item number\n+ // This test verifies the fix for the bug where changing Item No. with different Unit of Measure Codes caused validation errors\n+ ItemReclassJournal.Close();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\nindex fb9253b7ae77..ad41ac368015 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Journal/ItemJournalLine.Table.al\n@@ -76,6 +76,7 @@ table 83 \"Item Journal Line\"\n if \"Item No.\" <> xRec.\"Item No.\" then begin\n \"Variant Code\" := '';\n \"Bin Code\" := '';\n+ \"Unit of Measure Code\" := '';\n if CurrFieldNo <> 0 then begin\n GetItem();\n if Item.IsInventoriableType() then\n"} +{"metadata": {"area": "sales", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-214926", "base_commit": "2ed9a2df09bf29573bbaf9e087313bec188ce69b", "created_at": "2025-05-07", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134389, "functionName": ["CheckCustomerCardStatisticsTotalOnFactBox"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\nindex 12e3e3ea3927..4ddc570573df 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al\n@@ -28,6 +28,7 @@ codeunit 134389 \"ERM Customer Statistics\"\n FieldIsNotHiddenErr: Label 'Field is hidden';\n EntryNoMustMatchErr: Label 'Entry No. must match.';\n PaymentsLCYAndAmountLCYMustMatchErr: Label 'Payemnts (LCY) and Amount (LCY) must match.';\n+ CustomerCardFactboxTotalErr: Label 'Customer card factbox total is not Correct';\n \n [Test]\n [Scope('OnPrem')]\n@@ -964,6 +965,44 @@ codeunit 134389 \"ERM Customer Statistics\"\n CustomerCard.Close();\n end;\n \n+ [Test]\n+ [HandlerFunctions('GetShipmentLinesPageHandler')]\n+ procedure CheckCustomerCardStatisticsTotalOnFactBox()\n+ var\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ // [SCENARIO 574648] Check Customer Card Statistics Total On FactBox When Sales Order Only Shiped and Sales Invoice \n+ // Created By GetShipmentLines without Posting.\n+ Initialize();\n+\n+ // [GIVEN] Created New Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Created New Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Created Item Inventory By Posting Item Journal With Qty 10.\n+ CreateItemInventory(Item, 10);\n+\n+ // [WHEN] Created New Sales Order With Qty 10.\n+ CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\", WorkDate());\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", 10);\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandDec(1000, 0));\n+ SalesLine.Modify(true);\n+\n+ // [WHEN] \"SO\" Post invoked with \"Shipped\" selected.\n+ LibrarySales.PostSalesDocument(SalesHeader, true, false);\n+\n+ // [WHEN] Create New Sales Invoice And Get Shipment Line Through GetShipmentLines.\n+ CreateAndReleaseSalesInvoiceUsingGetShipmentLines(SalesHeader.\"Sell-to Customer No.\");\n+\n+ // [THEN] Check Customer Card Statistics Total is Equal To SalesLine.\"Amount Including VAT\" and Not Multiply.\n+ Assert.AreEqual(SalesLine.\"Amount Including VAT\", Customer.GetTotalAmountLCY(), CustomerCardFactboxTotalErr);\n+ end;\n+\n local procedure Initialize()\n var\n Currency: Record Currency;\n@@ -1400,6 +1439,31 @@ codeunit 134389 \"ERM Customer Statistics\"\n DetailedCustLedgEntry.Insert();\n end;\n \n+ local procedure CreateAndReleaseSalesInvoiceUsingGetShipmentLines(CustomerNo: Code[20])\n+ var\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Invoice, CustomerNo);\n+ SalesLine.Validate(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.Validate(\"Document No.\", SalesHeader.\"No.\");\n+ LibrarySales.GetShipmentLines(SalesLine);\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+ end;\n+\n+ local procedure CreateItemInventory(var Item: Record Item; Qty: Decimal)\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Item);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type::Item, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", Qty);\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerYes(Message: Text; var Response: Boolean)\n@@ -1450,5 +1514,11 @@ codeunit 134389 \"ERM Customer Statistics\"\n CreditLimitNotification.CreditLimitDetails.OverdueBalance.AssertEquals(Customer.\"Balance Due (LCY)\");\n CreditLimitNotification.CreditLimitDetails.\"Credit Limit (LCY)\".AssertEquals(Customer.\"Credit Limit (LCY)\");\n end;\n+\n+ [ModalPageHandler]\n+ procedure GetShipmentLinesPageHandler(var GetShipmentLines: TestPage \"Get Shipment Lines\")\n+ begin\n+ GetShipmentLines.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\nindex ebeb6ca13f79..1fcc2d218ab3 100644\n--- a/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Customer/Customer.Table.al\n@@ -2353,6 +2353,8 @@ table 18 Customer\n AdditionalAmountLCY: Decimal;\n IsHandled: Boolean;\n TotalAmountLCY: Decimal;\n+ ShippedFromOrderLCY: Decimal;\n+ ShippedOutstandingInvoicesLCY: Decimal;\n begin\n IsHandled := false;\n OnBeforeGetTotalAmountLCYCommon(Rec, AdditionalAmountLCY, IsHandled);\n@@ -2362,10 +2364,13 @@ table 18 Customer\n SalesOutstandingAmountFromShipment := SalesLine.OutstandingInvoiceAmountFromShipment(\"No.\");\n InvoicedPrepmtAmountLCY := GetInvoicedPrepmtAmountLCY();\n RetRcdNotInvAmountLCY := GetReturnRcdNotInvAmountLCY();\n+ ShippedFromOrderLCY := GetShippedFromOrderLCYAmountLCY();\n+ ShippedOutstandingInvoicesLCY := GetShippedOutstandingInvoicesAmountLCY();\n \n TotalAmountLCY :=\n- \"Balance (LCY)\" + \"Outstanding Orders (LCY)\" + \"Shipped Not Invoiced (LCY)\" + \"Outstanding Invoices (LCY)\" +\n- SalesOutstandingAmountFromShipment - InvoicedPrepmtAmountLCY - RetRcdNotInvAmountLCY + AdditionalAmountLCY;\n+ \"Balance (LCY)\" + \"Outstanding Orders (LCY)\" + (\"Shipped Not Invoiced (LCY)\" - ShippedFromOrderLCY) +\n+ (\"Outstanding Invoices (LCY)\" - ShippedOutstandingInvoicesLCY) + SalesOutstandingAmountFromShipment -\n+ InvoicedPrepmtAmountLCY - RetRcdNotInvAmountLCY + AdditionalAmountLCY;\n \n OnAfterGetTotalAmountLCYCommon(Rec, TotalAmountLCY);\n exit(TotalAmountLCY);\n@@ -3451,6 +3456,33 @@ table 18 Customer\n OnAfterGetVATRegistrationNo(Rec, VATRegNo);\n end;\n \n+ procedure GetShippedOutstandingInvoicesAmountLCY(): Decimal\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ SalesLine.SetRange(\"Bill-to Customer No.\", \"No.\");\n+ SalesLine.SetRange(\"Document Type\", SalesLine.\"Document Type\"::Invoice);\n+ SalesLine.SetFilter(\"Shipment No.\", '<>%1', '');\n+ SalesLine.SetFilter(\"Shipment Line No.\", '<>%1', 0);\n+ SalesLine.CalcSums(\"Outstanding Amount (LCY)\");\n+ exit(SalesLine.\"Outstanding Amount (LCY)\");\n+ end;\n+\n+ procedure GetShippedFromOrderLCYAmountLCY(): Decimal\n+ var\n+ SalesShippedNotInvoicedLCY: Query \"Sales Shipped Not Invoiced LCY\";\n+ ShippedFromOrderLCY: Decimal;\n+ begin\n+ ShippedFromOrderLCY := 0;\n+ SalesShippedNotInvoicedLCY.SetRange(BillToCustomerNo, \"No.\");\n+ SalesShippedNotInvoicedLCY.SetFilter(OrderNo, '<>%1', '');\n+ SalesShippedNotInvoicedLCY.SetFilter(OrderLineNo, '<>%1', 0);\n+ if SalesShippedNotInvoicedLCY.Open() then\n+ while SalesShippedNotInvoicedLCY.Read() do\n+ ShippedFromOrderLCY += SalesShippedNotInvoicedLCY.ShippedNotInvoicedLCY;\n+ exit(ShippedFromOrderLCY);\n+ end;\n+\n [InherentPermissions(PermissionObjectType::TableData, Database::\"My Customer\", 'rm')]\n local procedure UpdateMyCustomer(CallingFieldNo: Integer)\n var\ndiff --git a/App/Layers/W1/BaseApp/Sales/Customer/SalesShippedNotInvoicedLCY.Query.al b/App/Layers/W1/BaseApp/Sales/Customer/SalesShippedNotInvoicedLCY.Query.al\nnew file mode 100644\nindex 000000000000..3640fed3530f\n--- /dev/null\n+++ b/App/Layers/W1/BaseApp/Sales/Customer/SalesShippedNotInvoicedLCY.Query.al\n@@ -0,0 +1,31 @@\n+namespace Microsoft.Sales.Customer;\n+\n+using Microsoft.Sales.Document;\n+using Microsoft.Sales.History;\n+\n+query 115 \"Sales Shipped Not Invoiced LCY\"\n+{\n+ Caption = 'Sales Shipped Not Invoiced (LCY)';\n+ QueryType = Normal;\n+ DataAccessIntent = ReadOnly;\n+\n+ elements\n+ {\n+ dataitem(SalesShipmentLine; \"Sales Shipment Line\")\n+ {\n+ column(BillToCustomerNo; \"Bill-to Customer No.\") { }\n+ column(OrderNo; \"Order No.\") { }\n+ column(OrderLineNo; \"Order Line No.\") { }\n+ filter(BillToCustomerNoFilter; \"Bill-to Customer No.\") { }\n+ filter(OrderNoFilter; \"Order No.\") { }\n+ filter(OrderLineNoFilter; \"Order Line No.\") { }\n+ dataitem(SalesLine; \"Sales Line\")\n+ {\n+ DataItemTableFilter = \"Document Type\" = const(Order);\n+ DataItemLink = \"Document No.\" = SalesShipmentLine.\"Order No.\",\n+ \"Line No.\" = SalesShipmentLine.\"Order Line No.\";\n+ column(ShippedNotInvoicedLCY; \"Shipped Not Invoiced (LCY)\") { }\n+ }\n+ }\n+ }\n+}\n\\ No newline at end of file\n"} +{"metadata": {"area": "inventory", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-215972", "base_commit": "09f92492d0cfe5dbba4cebef931acf5b33578799", "created_at": "2025-05-19", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137140, "functionName": ["ReservationShouldNotPossibleOnTransferOrderIfItemReserveSetAsNever"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al\nindex 6e9a6abd3cd6..3253f5221abc 100644\n--- a/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMInventoryDocuments.Codeunit.al\n@@ -41,6 +41,7 @@ codeunit 137140 \"SCM Inventory Documents\"\n SpecialEquipmentCodeShouldBeVisibleErr: Label 'Special Equipment Code should be visible.';\n DueDateBeforeWorkDateMsg: Label 'is before work date';\n TransferOrderErr: Label 'Transfer Order has not been posted successfully.';\n+ ReserveMustNotBeNeverErr: Label 'Reserve must not be Never';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2069,6 +2070,44 @@ codeunit 137140 \"SCM Inventory Documents\"\n Assert.IsTrue(DirectTransHeader.FindFirst(), TransferOrderErr);\n end;\n \n+ [Test]\n+ procedure ReservationShouldNotPossibleOnTransferOrderIfItemReserveSetAsNever()\n+ var\n+ Item: Record Item;\n+ LocationA: Record Location;\n+ LocationB: Record Location;\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ begin\n+ // [SCENARIO 578318] Reservation of an Item possible with in a Transfer order if the item is set to reserve=never\n+ Initialize();\n+\n+ // [GIVEN] Create Two locations: \"A\" and \"B\" without Warehouse Setup\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(LocationA);\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(LocationB);\n+\n+ // [GIVEN] Create an Item with Reserve = Never\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(Reserve, Item.Reserve::Never);\n+ Item.Modify();\n+\n+ // [GIVEN] Create and Post Item Journal Line\n+ CreateAndPostItemJournalLine(Item.\"No.\", LocationA.Code, '');\n+\n+ // [GIVEN] Create a Direct Transfer Order from Location \"A\" to location \"B\" and Reserve From Inventory\n+ CreateDirectTransferHeader(TransferHeader, LocationA.code, LocationB.Code);\n+ TransferHeader.Validate(\"Posting Date\", WorkDate());\n+ TransferHeader.Modify(true);\n+\n+ // [WHEN] Create transfer line with Item with Reserve set as Never and Show Reservation\n+ LibraryWarehouse.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", 10);\n+ asserterror TransferLine.ShowReservation();\n+\n+ // [THEN] Verify Reserve must not be Never error\n+ Assert.ExpectedErrorCode('TestField');\n+ Assert.ExpectedError(ReserveMustNotBeNeverErr);\n+ end;\n+\n local procedure PostWhseShipmentFromTO(DocumentNo: Code[20])\n var\n WhseShipmentLine: Record \"Warehouse Shipment Line\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al\nindex 9ab054c5f5c3..d012f240926e 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferLine.Table.al\n@@ -1592,6 +1592,8 @@ table 5741 \"Transfer Line\"\n exit;\n \n TestField(\"Item No.\");\n+ Item.Get(\"Item No.\");\n+ Item.TestField(Reserve);\n Clear(Reservation);\n OptionNumber := StrMenu(Text011);\n if OptionNumber > 0 then begin\n"} +{"metadata": {"area": "inventory", "image_count": 20}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-216057", "base_commit": "eb4658a742a755d408f23b5f96668caaba44842b", "created_at": "2025-05-20", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137045, "functionName": ["NoDuplicateSurplusReservationEntriesOnRecalculateRequisitionWorksheet"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\nindex 70fa87435bd0..c841fa564264 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n@@ -1038,6 +1038,62 @@ codeunit 137045 \"SCM Bugfixes\"\n Assert.AreEqual(4, ActualCount, AssemblyCommentLineErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemTrackingLinesModalPageHandler')]\n+ procedure NoDuplicateSurplusReservationEntriesOnRecalculateRequisitionWorksheet()\n+ var\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Vendor: Record Vendor;\n+ RequisitionLine: Record \"Requisition Line\";\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ NewPurchOrderChoice: Option \" \",\"Make Purch. Orders\",\"Make Purch. Orders & Print\",\"Copy to Req. Wksh\";\n+ Qty: Decimal;\n+ begin\n+ // [SCENARIO 575040] When recalculating an item in a requisition or planning worksheet with no planning results lead to wrong surplus entries in the reservation table whic are added to the item tracking page.\n+ Initialize();\n+\n+ // [GIVEN] Created Lot Tracked Item with Reordering Policy:Lot-for-Lot.\n+ CreateTrackedItem(Item);\n+\n+ // [GIVEN] Created Sales Order with 1 Item and 100 quantity.\n+ Qty := 100;\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, '');\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", Qty);\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+\n+ // [GIVEN] Calculate requisition plan\n+ CalculateRequisitionPlan(RequisitionWkshName, Item);\n+\n+ // [GIVEN] Find Requisition Line\n+ FindRequisitionLine(RequisitionLine, RequisitionWkshName, RequisitionLine.\"Action Message\"::New);\n+\n+ // [GIVEN] Update Vendor No., Planning Flexibility with None and change the quantity to 150\n+ RequisitionLine.Validate(\"Vendor No.\", LibraryPurchase.CreateVendor(Vendor));\n+ RequisitionLine.Validate(\"Planning Flexibility\", RequisitionLine.\"Planning Flexibility\"::None);\n+ RequisitionLine.Validate(Quantity, 150);\n+ RequisitionLine.Modify(true);\n+\n+ // [GIVEN] Assign the Lot On Item tracking Line\n+ RequisitionLine.OpenItemTrackingLines();\n+\n+ // [GIVEN] Set \"Accept Action Message\" on all Requisition lines.\n+ LibraryPlanning.CarryOutPlanWksh(RequisitionLine, 0, NewPurchOrderChoice::\"Make Purch. Orders\", 0, 0, '', '', '', '');\n+\n+ // [GIVEN] Check at reservation entries for Purchase Order created, only 2 reservation entries should exist for the PO\n+ PurchaseHeader.SetRange(\"Buy-from Vendor No.\", Vendor.\"No.\");\n+ PurchaseHeader.FindLast();\n+ AssertReservationEntryCount(PurchaseHeader, 2);\n+\n+ // [WHEN] Calculate Plan again for same item from requisition worksheet\n+ CalculateRequisitionPlan(RequisitionWkshName, Item);\n+\n+ // [THEN] After recalculation, a new reservation entry should NOT be created for the PO\n+ AssertReservationEntryCount(PurchaseHeader, 2);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1740,6 +1796,15 @@ codeunit 137045 \"SCM Bugfixes\"\n CalculatePlanPlanWksh.RunModal();\n end;\n \n+ local procedure AssertReservationEntryCount(PurchaseHeader: Record \"Purchase Header\"; ExpectedCount: Integer)\n+ var\n+ ReservationEntry: Record \"Reservation Entry\";\n+ begin\n+ ReservationEntry.SetRange(\"Source Type\", Database::\"Purchase Line\");\n+ ReservationEntry.SetRange(\"Source ID\", PurchaseHeader.\"No.\");\n+ Assert.RecordCount(ReservationEntry, ExpectedCount);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListModalPageHandler(var ContactLookup: Page \"Contact List\"; var Response: Action)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\nindex ca1799815e42..c1b41b1585bc 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/ReservationEntry.Table.al\n@@ -11,6 +11,7 @@ using Microsoft.Inventory.Journal;\n using Microsoft.Inventory.Ledger;\n using Microsoft.Inventory.Location;\n using Microsoft.Inventory.Requisition;\n+using Microsoft.Purchases.Document;\n using Microsoft.Sales.Document;\n using Microsoft.Utilities;\n using Microsoft.Warehouse.Activity;\n@@ -1021,6 +1022,10 @@ table 337 \"Reservation Entry\"\n CreateReservEntry.TransferReservEntry(\n SourceType, SourceSubtype, SourceID, SourceBatchName, SourceProdOrderLine, SourceRefNo,\n QtyPerUOM, OldReservEntry, TransferQty);\n+\n+ if (OldReservEntry.\"Reservation Status\" = OldReservEntry.\"Reservation Status\"::Prospect) and (SourceType = Database::\"Purchase Line\") and (SourceSubtype in [1, 2]) then\n+ ChangeReservationStatusToSurplus(SourceType, SourceSubtype, SourceID, SourceRefNo);\n+\n OnTransferReservationsOnAfterSecondOldReservEntryLoop(OldReservEntry, NewReservEntry, SourceType, SourceSubtype, SourceID);\n until (OldReservEntry.Next() = 0) or (TransferQty = 0);\n end;\n@@ -1125,6 +1130,18 @@ table 337 \"Reservation Entry\"\n OnUpdateSourceCost(Rec, UnitCost);\n end;\n \n+ local procedure ChangeReservationStatusToSurplus(SourceType: Integer; SourceSubtype: Option; SourceID: Code[20]; SourceRefNo: Integer)\n+ var\n+ NewReservationEntry: Record \"Reservation Entry\";\n+ begin\n+ NewReservationEntry.SetSourceFilter(SourceType, SourceSubtype, SourceID, SourceRefNo, true);\n+ NewReservationEntry.SetRange(\"Reservation Status\", NewReservationEntry.\"Reservation Status\"::Prospect);\n+ if NewReservationEntry.FindFirst() then begin\n+ NewReservationEntry.\"Reservation Status\" := NewReservationEntry.\"Reservation Status\"::Surplus;\n+ NewReservationEntry.Modify(true);\n+ end;\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterCopyTrackingFromItemLedgEntry(var ReservationEntry: Record \"Reservation Entry\"; ItemLedgerEntry: Record \"Item Ledger Entry\")\n begin\n"} +{"metadata": {"area": "finance", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-216572", "base_commit": "74df6483b659ca304abb6f7adda003cda1424db7", "created_at": "2025-05-26", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134227, "functionName": ["CheckDimensionOfRecurringJournalImportAllocationFromAllocationAccount"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\nindex ff710ce5b0e2..aa89a458bd93 100644\n--- a/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMPostRecurringJournal.Codeunit.al\n@@ -19,6 +19,7 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n LibraryPurchase: Codeunit \"Library - Purchase\";\n LibrarySales: Codeunit \"Library - Sales\";\n+ LibraryDimension: Codeunit \"Library - Dimension\";\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n GenJnlDocType: Enum \"Gen. Journal Document Type\";\n GenJnlAccountType: Enum \"Gen. Journal Account Type\";\n@@ -31,6 +32,7 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n SkippedLineMsg: Label 'One or more lines has not been posted because the amount is zero.';\n DocumentOutOfBalanceErr: Label 'Document No. %1 is out of balance', Locked = true;\n AllocAccountImportWrongAccTypeErr: Label 'Import from Allocation Account is only allowed for G/L Account Destination account type.', Locked = true;\n+ AllocationDimensionErr: Label 'Allocation dimension is not correct';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1298,6 +1300,48 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n \n end;\n \n+ [Test]\n+ [HandlerFunctions('HandleEditDimensionSetEntriesPage,AllocationAccountListPageHandler,ConfirmHandlerYes')]\n+ procedure CheckDimensionOfRecurringJournalImportAllocationFromAllocationAccount()\n+ var\n+ AllocationAccount: Record \"Allocation Account\";\n+ FirstDimensionValue: Record \"Dimension Value\";\n+ GenJnlAllocation: Record \"Gen. Jnl. Allocation\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ SecondDimensionValue: Record \"Dimension Value\";\n+ GLAccounts: array[2] of Record \"G/L Account\";\n+ AllocationShares: array[2] of Decimal;\n+ DimensionSetID: array[2] of Integer;\n+ begin\n+ // [SCENARIO 579186] In Recurring General Journals Import from Allocation Accounts does not import dimensions.\n+ Initialize();\n+\n+ // [GIVEN] Create Recurring General Journal Batch.\n+ CreateRecurringGenJournalBatch(GenJournalBatch);\n+\n+ // [GIVEN] Create Recurring Journal with a line.\n+ CreateRecurringJnlLine(GenJournalLine, GenJournalBatch, WorkDate(), 0D, LibraryRandom.RandInt(10));\n+\n+ // [GIVEN] Create allocation for general journal line.\n+ LibraryERM.CreateGenJnlAllocation(GenJnlAllocation, GenJournalLine.\"Journal Template Name\", GenJournalLine.\"Journal Batch Name\", GenJournalLine.\"Line No.\");\n+\n+ // [GIVEN] Dimension With Value.\n+ CreateDimensionsWithValues(FirstDimensionValue, SecondDimensionValue);\n+\n+ // [GIVEN] Allocation Account \"XXX\" with 2 lines exists for different G/L Accounts and different Allocation Shares with Dimension.\n+ CreateAllocationAccountWithTwoGLAccLines(AllocationAccount, GLAccounts, AllocationShares, FirstDimensionValue, SecondDimensionValue, DimensionSetID);\n+\n+ // [WHEN] Invoke Import from Allocation Account. Handler chooses Allocation Account \"XXX\" in lookup\n+ LibraryVariableStorage.Enqueue(AllocationAccount.\"No.\");\n+ GenJnlAllocation.ChooseAndImportFromAllocationAccount();\n+ // UI Handled by handler\n+\n+ // [THEN] There are 2 Gen Journal Allocations with the same Dimension as in Allocation Account\n+ VerifyGenJnlAllocationDimension(GenJnlAllocation, GenJournalLine, GLAccounts[1], DimensionSetID[1]);\n+ VerifyGenJnlAllocationDimension(GenJnlAllocation, GenJournalLine, GLAccounts[2], DimensionSetID[2]);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"ERM PostRecurringJournal\");\n@@ -1769,6 +1813,79 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n VendorLedgerEntry.TestField(\"Due Date\", PostingDate + 1);\n end;\n \n+ local procedure CreateDimensionsWithValues(var FirstDimensionValue: Record \"Dimension Value\"; var SecondDimensionValue: Record \"Dimension Value\")\n+ var\n+ Dimension: Record Dimension;\n+ begin\n+ LibraryDimension.CreateDimension(Dimension);\n+ LibraryDimension.CreateDimensionValue(FirstDimensionValue, Dimension.Code);\n+ LibraryDimension.CreateDimensionValue(SecondDimensionValue, Dimension.Code);\n+ end;\n+\n+ local procedure CreateAllocationAccountWithTwoGLAccLines(var AllocationAccount: Record \"Allocation Account\"; var GLAccounts: array[2] of Record \"G/L Account\"; var AllocationShares: array[2] of Decimal; FirstDimensionValue: Record \"Dimension Value\"; SecondDimensionValue: Record \"Dimension Value\"; var DimensionSetID: array[2] of Integer)\n+ var\n+ AllocAccountDistribution: Record \"Alloc. Account Distribution\";\n+ AllocationAccountPage: TestPage \"Allocation Account\";\n+ FixedAllocationAccountCode: Code[20];\n+ begin\n+ FixedAllocationAccountCode := CreateAllocationAccountWithFixedDistribution(AllocationAccountPage);\n+ AddGLDestinationAccountForFixedDistributionWithDimension(AllocationAccountPage, GLAccounts[1]);\n+ AllocationShares[1] := LibraryRandom.RandDecInRange(1, 100, 2);\n+ AllocationAccountPage.FixedAccountDistribution.Share.SetValue(AllocationShares[1]);\n+ SetDimensionToCurrentVariableLine(AllocationAccountPage, FirstDimensionValue);\n+\n+ AllocAccountDistribution.SetRange(\"Allocation Account No.\", FixedAllocationAccountCode);\n+ AllocAccountDistribution.SetRange(\"Account Type\", AllocAccountDistribution.\"Account Type\"::Fixed);\n+ AllocAccountDistribution.SetRange(\"Destination Account Number\", GLAccounts[1].\"No.\");\n+ AllocAccountDistribution.FindFirst();\n+ DimensionSetID[1] := AllocAccountDistribution.\"Dimension Set ID\";\n+\n+ AllocationAccountPage.FixedAccountDistribution.New();\n+ AddGLDestinationAccountForFixedDistributionWithDimension(AllocationAccountPage, GLAccounts[2]);\n+ AllocationShares[2] := LibraryRandom.RandDecInRange(1, 100, 2);\n+ AllocationAccountPage.FixedAccountDistribution.Share.SetValue(AllocationShares[2]);\n+ SetDimensionToCurrentVariableLine(AllocationAccountPage, SecondDimensionValue);\n+\n+ AllocAccountDistribution.Reset();\n+ AllocAccountDistribution.SetRange(\"Allocation Account No.\", FixedAllocationAccountCode);\n+ AllocAccountDistribution.SetRange(\"Account Type\", AllocAccountDistribution.\"Account Type\"::Fixed);\n+ AllocAccountDistribution.SetRange(\"Destination Account Number\", GLAccounts[2].\"No.\");\n+ AllocAccountDistribution.FindFirst();\n+ AllocationAccountPage.FixedAccountDistribution.GoToRecord(AllocAccountDistribution);\n+ DimensionSetID[2] := AllocAccountDistribution.\"Dimension Set ID\";\n+\n+ AllocationAccountPage.Close();\n+\n+ AllocationAccount.Get(FixedAllocationAccountCode);\n+ end;\n+\n+ local procedure SetDimensionToCurrentVariableLine(var AllocationAcccount: TestPage \"Allocation Account\"; var DimensionValue: Record \"Dimension Value\")\n+ begin\n+ LibraryVariableStorage.Enqueue(DimensionValue.SystemId);\n+ AllocationAcccount.FixedAccountDistribution.Dimensions.Invoke();\n+ end;\n+\n+ local procedure AddGLDestinationAccountForFixedDistributionWithDimension(var AllocationAccountPage: TestPage \"Allocation Account\"; var GLAccount: Record \"G/L Account\")\n+ var\n+ DummyAllocAccountDistribution: Record \"Alloc. Account Distribution\";\n+ begin\n+ if GLAccount.\"No.\" = '' then\n+ GLAccount.Get(LibraryERM.CreateGLAccountNoWithDirectPosting());\n+\n+ AllocationAccountPage.FixedAccountDistribution.\"Destination Account Type\".SetValue(DummyAllocAccountDistribution.\"Destination Account Type\"::\"G/L Account\");\n+ AllocationAccountPage.FixedAccountDistribution.\"Destination Account Number\".SetValue(GLAccount.\"No.\");\n+ end;\n+\n+ local procedure VerifyGenJnlAllocationDimension(GenJnlAllocation: Record \"Gen. Jnl. Allocation\"; GenJournalLine: Record \"Gen. Journal Line\"; GLAccount: Record \"G/L Account\"; DimensionSetID: Integer)\n+ begin\n+ GenJnlAllocation.SetRange(\"Journal Template Name\", GenJournalLine.\"Journal Template Name\");\n+ GenJnlAllocation.SetRange(\"Journal Batch Name\", GenJournalLine.\"Journal Batch Name\");\n+ GenJnlAllocation.SetRange(\"Journal Line No.\", GenJournalLine.\"Line No.\");\n+ GenJnlAllocation.SetRange(\"Account No.\", GLAccount.\"No.\");\n+ GenJnlAllocation.FindFirst();\n+ Assert.AreEqual(GenJnlAllocation.\"Dimension Set ID\", DimensionSetID, AllocationDimensionErr);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean)\n@@ -1821,5 +1938,19 @@ codeunit 134227 \"ERM PostRecurringJournal\"\n NameValueBuffer.ID := LibraryUtility.GetNewRecNo(NameValueBuffer, NameValueBuffer.FieldNo(ID));\n NameValueBuffer.Insert();\n end;\n+\n+ [ModalPageHandler]\n+ procedure HandleEditDimensionSetEntriesPage(var EditDimensionSetEntriesPage: TestPage \"Edit Dimension Set Entries\")\n+ var\n+ DimensionValue: Record \"Dimension Value\";\n+ DimensionValueSystemId: Text;\n+ begin\n+ DimensionValueSystemId := LibraryVariableStorage.DequeueText();\n+ DimensionValue.GetBySystemId(DimensionValueSystemId);\n+ EditDimensionSetEntriesPage.New();\n+ EditDimensionSetEntriesPage.\"Dimension Code\".SetValue(DimensionValue.\"Dimension Code\");\n+ EditDimensionSetEntriesPage.DimensionValueCode.SetValue(DimensionValue.Code);\n+ EditDimensionSetEntriesPage.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al\nindex 130b3e0f3456..7a287e4fb7f1 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al\n@@ -669,6 +669,10 @@ table 221 \"Gen. Jnl. Allocation\"\n begin\n Rec.Validate(\"Account No.\", AllocAccountDistribution.\"Destination Account Number\");\n Rec.Validate(\"Allocation %\", AllocAccountDistribution.Percent);\n+ Rec.Validate(\"Shortcut Dimension 1 Code\", AllocAccountDistribution.\"Global Dimension 1 Code\");\n+ Rec.Validate(\"Shortcut Dimension 2 Code\", AllocAccountDistribution.\"Global Dimension 2 Code\");\n+ Rec.Validate(\"Dimension Set ID\", AllocAccountDistribution.\"Dimension Set ID\");\n+ Rec.Modify(true);\n end;\n \n local procedure CheckGLAccount(var GLAccount: Record \"G/L Account\")\n"} +{"metadata": {"area": "inventory", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-217797", "base_commit": "055fbb3433b4edcc3fc5709cf9b0cf7e48a372ac", "created_at": "2025-06-11", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137009, "functionName": ["LookupItemAvailabilityByEventOnItemCardOpenTheCorrectPlanningWorksheetBatch"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al\nindex 63f145ed7b95..cce6dab13ec0 100644\n--- a/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMAvailabilitybyEvent.Codeunit.al\n@@ -24,6 +24,7 @@ codeunit 137009 \"SCM Availability by Event\"\n LibraryPurchase: Codeunit \"Library - Purchase\";\n LibraryAssembly: Codeunit \"Library - Assembly\";\n LibraryPatterns: Codeunit \"Library - Patterns\";\n+ LibraryPlanning: Codeunit \"Library - Planning\";\n LibraryRandom: Codeunit \"Library - Random\";\n LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n@@ -531,6 +532,62 @@ codeunit 137009 \"SCM Availability by Event\"\n TempInvtPageData.TestField(\"Remaining Forecast\", -ForecastQty + SalesQty);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemAvailabilityByEventPageHandler,PlanningWorksheetModalPageHandler')]\n+ procedure LookupItemAvailabilityByEventOnItemCardOpenTheCorrectPlanningWorksheetBatch()\n+ var\n+ Item: Record Item;\n+ NewPlanningWorkSheetBatchName: Code[10];\n+ OldPlanningWorkSheetBatchName: Code[10];\n+ ItemCard: TestPage \"Item Card\";\n+ PlanningWorksheet: TestPage \"Planning Worksheet\";\n+ begin\n+ // [SCENARIO 575726] Verify that the 'Lookup Item Availability by Event' on the item card opens the correct planning worksheet batch.\n+ Initialize();\n+\n+ // [GIVEN] Create a Item.\n+ LibraryInventory.CreateItem(Item);\n+ LibraryVariableStorage.Enqueue(Item.\"No.\");\n+\n+ // [GIEVN] Get old planning worksheet batch name.\n+ OldPlanningWorkSheetBatchName := GetRequisitionWkshBatch();\n+\n+ // [GIVEN] Open planning worksheet batch.\n+ PlanningWorksheet.OpenEdit();\n+ PlanningWorksheet.New();\n+\n+ // [GIVEN] Set the old planning worksheet batch name.\n+ PlanningWorksheet.CurrentWkshBatchName.SetValue(OldPlanningWorkSheetBatchName);\n+ LibraryVariableStorage.Enqueue(OldPlanningWorkSheetBatchName);\n+\n+ // [GIVEN] Set the item number and quantity in the planning worksheet.\n+ PlanningWorksheet.\"No.\".SetValue(Item.\"No.\");\n+ PlanningWorksheet.Quantity.SetValue(LibraryRandom.RandIntInRange(10, 20));\n+ PlanningWorksheet.Close();\n+\n+ // [GIVEN] Set new planning worksheet batch.\n+ NewPlanningWorkSheetBatchName := CreateRequisitionWkshBatch();\n+ PlanningWorksheet.OpenEdit();\n+ PlanningWorksheet.CurrentWkshBatchName.SetValue(NewPlanningWorkSheetBatchName);\n+ PlanningWorksheet.Close();\n+\n+ // [THEN] Verify the current planning worksheet batch name.\n+ PlanningWorksheet.OpenView();\n+ Assert.Equal(NewPlanningWorkSheetBatchName, PlanningWorksheet.CurrentWkshBatchName.Value);\n+\n+ // [GIVEN] Open Item Card.\n+ ItemCard.OpenEdit();\n+ ItemCard.GoToRecord(Item);\n+\n+ // [WHEN] Invoke Item Availability by Event Action.\n+ ItemCard.\"\".Invoke();\n+ ItemCard.Close();\n+\n+ // [THEN] Verify Lookup Item Availability by Event on the item card opens the correct planning worksheet batch.\n+ // It was verified on the PlanningWorksheetModalPageHandler. \n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n local procedure AutoReservePurchaseLine(PurchaseLine: Record \"Purchase Line\")\n var\n ReservMgt: Codeunit \"Reservation Management\";\n@@ -671,6 +728,35 @@ codeunit 137009 \"SCM Availability by Event\"\n ProdOrderComponent.Insert();\n end;\n \n+ local procedure GetRequisitionWkshBatch(): Code[10]\n+ var\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ begin\n+ RequisitionWkshName.SetRange(\"Template Type\", RequisitionWkshName.\"Template Type\"::Planning);\n+ RequisitionWkshName.FindFirst();\n+\n+ exit(RequisitionWkshName.Name);\n+ end;\n+\n+ local procedure GetRequisitionWkshTemplate(): Code[10]\n+ var\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ begin\n+ RequisitionWkshName.SetRange(\"Template Type\", RequisitionWkshName.\"Template Type\"::Planning);\n+ RequisitionWkshName.FindFirst();\n+\n+ exit(RequisitionWkshName.\"Worksheet Template Name\");\n+ end;\n+\n+ local procedure CreateRequisitionWkshBatch(): Code[10]\n+ var\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ begin\n+ LibraryPlanning.CreateRequisitionWkshName(RequisitionWkshName, GetRequisitionWkshTemplate());\n+\n+ exit(RequisitionWkshName.Name);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ItemAvailabilityByLocationPageHandler(var ItemAvailabilitybyLocation: TestPage \"Item Availability by Location\")\n@@ -722,5 +808,28 @@ codeunit 137009 \"SCM Availability by Event\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ procedure ItemAvailabilityByEventPageHandler(var ItemAvailabilitybyEvent: TestPage \"Item Availability by Event\")\n+ var\n+ InventoryPageDataType: Enum \"Inventory Page Data Type\";\n+ begin\n+ ItemAvailabilitybyEvent.IncludePlanningSuggestions.SetValue(true);\n+ ItemAvailabilitybyEvent.Filter.SetFilter(Type, Format(InventoryPageDataType::Plan));\n+ ItemAvailabilitybyEvent.\"Show Document\".Invoke();\n+ ItemAvailabilitybyEvent.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ procedure PlanningWorksheetModalPageHandler(var PlanningWorksheet: TestPage \"Planning Worksheet\")\n+ var\n+ CurrentWkshBatchName: Variant;\n+ ItemNo: Variant;\n+ begin\n+ ItemNo := LibraryVariableStorage.DequeueText();\n+ CurrentWkshBatchName := LibraryVariableStorage.DequeueText();\n+ PlanningWorksheet.CurrentWkshBatchName.AssertEquals(CurrentWkshBatchName);\n+ PlanningWorksheet.\"No.\".AssertEquals(ItemNo);\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al b/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al\nindex 2eaf3fe58c79..986790155380 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/PlanningWorksheet.Page.al\n@@ -953,7 +953,7 @@ page 99000852 \"Planning Worksheet\"\n // if called from API (such as edit-in-excel), do not filter \n if ClientTypeManagement.GetCurrentClientType() = CLIENTTYPE::ODataV4 then\n exit;\n- OpenedFromBatch := (Rec.\"Journal Batch Name\" <> '') and (Rec.\"Worksheet Template Name\" = '');\n+ OpenedFromBatch := (Rec.\"Journal Batch Name\" <> '') and (Rec.\"Worksheet Template Name\" <> '');\n if OpenedFromBatch then begin\n CurrentWkshBatchName := Rec.\"Journal Batch Name\";\n ReqJnlManagement.OpenJnl(CurrentWkshBatchName, Rec);\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al\nindex a2b07ee7538a..033dc48d99c5 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/ReqJnlManagement.Codeunit.al\n@@ -98,7 +98,10 @@ codeunit 330 ReqJnlManagement\n begin\n OnBeforeOpenJnl(CurrentJnlBatchName, ReqLine);\n \n- CheckTemplateName(ReqLine.GetRangeMax(\"Worksheet Template Name\"), CurrentJnlBatchName);\n+ if (ReqLine.\"Worksheet Template Name\" <> '') and (ReqLine.GetFilter(\"Journal Batch Name\") = '') then\n+ CheckTemplateName(ReqLine.\"Worksheet Template Name\", CurrentJnlBatchName)\n+ else\n+ CheckTemplateName(ReqLine.GetRangeMax(\"Worksheet Template Name\"), CurrentJnlBatchName);\n ReqLine.FilterGroup := 2;\n ReqLine.SetRange(\"Journal Batch Name\", CurrentJnlBatchName);\n ReqLine.FilterGroup := 0;\n"} +{"metadata": {"area": "inventory", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-214557", "base_commit": "72ed0651950681ae8b8c302d37d00d3b6f32692b", "created_at": "2025-05-01", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137075, "functionName": ["ReqLineIsNotCreatedWhenCalcRegenPlanForCompItemPresentInRelProdOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al\nindex 66bf5a9fce6e..d5d73bcc3bcc 100644\n--- a/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMPlanningOrderTracking.Codeunit.al\n@@ -861,6 +861,69 @@\n // [THEN] Order Tracking page is opened with 2 lines for Item \"I\" and quantity = 1(checked in OrderTrackingWithLinesModalPageHandler handler)\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure ReqLineIsNotCreatedWhenCalcRegenPlanForCompItemPresentInRelProdOrder()\n+ var\n+ Item: array[4] of Record Item;\n+ ProductionBOMHeader: array[2] of Record \"Production BOM Header\";\n+ productionBOMLine: array[3] of Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ RequisitionLine: Record \"Requisition Line\";\n+ begin\n+ // [SCENARIO 563946] Requition Line is not created when Stan runs Calculate Regenerative \n+ // Plan action for Component Item if the that Item is present in a Released Production Order \n+ // with required Quantity in its Prod. Order Line.\n+ Initialize();\n+\n+ // [GIVEN] Create four Items.\n+ CreateItem(Item[1]);\n+ CreateItem(Item[2]);\n+ CreateItem(Item[3]);\n+ CreateItem(Item[4]);\n+\n+ // [GIVEN] Create a Production BOM for Item [2] and Item [3].\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader[1], Item[2].\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader[1], ProductionBOMLine[1], '', ProductionBOMLine[1].Type::Item, Item[2].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader[1], ProductionBOMLine[2], '', ProductionBOMLine[2].Type::Item, Item[3].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Validate \"Status\" in Production BOM Header [1].\n+ ProductionBOMHeader[1].Validate(\"Status\", ProductionBOMHeader[1].Status::Certified);\n+ ProductionBOMHeader[1].Modify(true);\n+\n+ // [GIVEN] Create a Production BOM for Item [4].\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader[2], Item[4].\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader[2], ProductionBOMLine[3], '', ProductionBOMLine[3].Type::Item, Item[4].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Validate \"Status\" in Production BOM Header [2].\n+ ProductionBOMHeader[2].Validate(\"Status\", ProductionBOMHeader[2].Status::Certified);\n+ ProductionBOMHeader[2].Modify(true);\n+\n+ // [GIVEN] Validate \"Production BOM No.\" in Item [1].\n+ Item[1].Validate(\"Production BOM No.\", ProductionBOMHeader[1].\"No.\");\n+ Item[1].Modify(true);\n+\n+ // [GIVEN] Validate \"Production BOM No.\" in Item [2].\n+ Item[2].Validate(\"Production BOM No.\", ProductionBOMHeader[2].\"No.\");\n+ Item[2].Modify(true);\n+\n+ // [GIVEN] Validate \"Production BOM No.\" in Item [3].\n+ Item[3].Validate(\"Production BOM No.\", ProductionBOMHeader[2].\"No.\");\n+ Item[3].Modify(true);\n+\n+ // [GIVEN] Create and Refresh Released Production Order.\n+ CreateAndRefreshReleasedProductionOrder(ProductionOrder, Item[1].\"No.\", LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Calculate Regenerative Plan for Planning Worksheet.\n+ CalculateRegenPlanForPlanningWorksheet(Item[4]);\n+\n+ // [WHEN] Find Requisition Line.\n+ RequisitionLine.SetRange(\"No.\", Item[4].\"No.\");\n+\n+ // [THEN] Requisition Line is not found.\n+ Assert.IsTrue(RequisitionLine.IsEmpty(), StrSubstNo(ReqLineShouldNotExistErr, ''));\n+ end;\n+\n local procedure Initialize()\n var\n RequisitionLine: Record \"Requisition Line\";\n@@ -1597,6 +1660,15 @@\n ReservationEntry.Insert();\n end;\n \n+ local procedure CreateItem(var Item: Record Item)\n+ begin\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Replenishment System\", Item.\"Replenishment System\"::\"Prod. Order\");\n+ Item.Validate(\"Reordering Policy\", Item.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ Item.Validate(\"Manufacturing Policy\", Item.\"Manufacturing Policy\"::\"Make-to-Order\");\n+ Item.Modify(true);\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure CalculatePlanPlanWkshRequestPageHandler(var CalculatePlanPlanWksh: TestRequestPage \"Calculate Plan - Plan. Wksh.\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al\nindex e3a6cf2ff5fb..2acbb26614e2 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/InventoryProfileOffsetting.Codeunit.al\n@@ -15,6 +15,7 @@ using Microsoft.Inventory.Planning;\n using Microsoft.Inventory.Requisition;\n using Microsoft.Inventory.Setup;\n using Microsoft.Inventory.Transfer;\n+using Microsoft.Manufacturing.Document;\n using Microsoft.Pricing.Calculation;\n using Microsoft.Purchases.Document;\n using Microsoft.Purchases.Vendor;\n@@ -982,6 +983,9 @@ codeunit 99000854 \"Inventory Profile Offsetting\"\n CanBeRescheduled: Boolean;\n ItemInventoryExists: Boolean;\n begin\n+ if CheckDemandAndSupplyQuantityAreEqual(SupplyInvtProfile, DemandInvtProfile) then\n+ exit;\n+\n xDemandInvtProfile.CopyFilters(DemandInvtProfile);\n xSupplyInvtProfile.CopyFilters(SupplyInvtProfile);\n ItemInventoryExists := CheckItemInventoryExists(SupplyInvtProfile);\n@@ -1097,6 +1101,28 @@ codeunit 99000854 \"Inventory Profile Offsetting\"\n OnAfterMatchAttributes(SupplyInvtProfile, DemandInvtProfile, TempTrkgReservEntry);\n end;\n \n+ local procedure CheckDemandAndSupplyQuantityAreEqual(var SupplyInvtProfile: Record \"Inventory Profile\"; var DemandInvtProfile: Record \"Inventory Profile\"): Boolean\n+ var\n+ TotalDemandQty: Decimal;\n+ TotalSupplyQty: Decimal;\n+ begin\n+ if (SupplyInvtProfile.\"Source Type\" <> Database::\"Prod. Order Line\") or (DemandInvtProfile.\"Source Type\" <> Database::\"Prod. Order Component\") then\n+ exit(false);\n+\n+ if DemandInvtProfile.FindSet() then\n+ repeat\n+ TotalDemandQty += DemandInvtProfile.Quantity;\n+ until DemandInvtProfile.Next() = 0;\n+\n+ if SupplyInvtProfile.FindSet() then\n+ repeat\n+ TotalSupplyQty += SupplyInvtProfile.Quantity;\n+ until SupplyInvtProfile.Next() = 0;\n+\n+ if TotalSupplyQty = TotalDemandQty then\n+ exit(true);\n+ end;\n+\n local procedure DecreaseQtyForMaxQty(var SupplyInvtProfile: Record \"Inventory Profile\"; ReduceQty: Decimal)\n begin\n if ReduceQty > 0 then begin\n"} +{"metadata": {"area": "manufacturing", "image_count": 11}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-212355", "base_commit": "a7de1e6b1a271e60b86657a69a98e863b2b85d33", "created_at": "2025-04-06", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137154, "functionName": ["InputQtyAndStartingDateTimeIsRecalculatedWhenReplanProdOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\nindex 972aa5e52834..c2e1e71567ec 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n@@ -64,6 +64,8 @@ codeunit 137154 \"SCM Warehouse Management II\"\n ReceiptLinesNotCreatedErr: Label 'There are no warehouse receipt lines created.';\n ItemTrackingMode: Option \" \",\"Assign Lot No.\",\"Assign Multiple Lot No.\",\"Assign Serial No.\",\"Assign Lot And Serial\",\"Select Entries\",\"Blank Quantity Base\",\"Assign Lot No. & Expiration Date\",\"Assign Manual Lot Nos\",\"Show Entries\";\n DescriptionMustBeSame: Label 'Description must be same.';\n+ InputQtyErr: Label 'Input Quantity Must be %1 in %2', Comment = '1% = Remaining Quanity value, %2 = Prod. Order Routing Line';\n+ StartingDateTimeErr: Label 'Starting Date-Time must not be %1 in %2', Comment = '%1 = StartingDateTime value, %2 = Prod. Order Routing Line.';\n \n [Test]\n [HandlerFunctions('ReservationPageHandler')]\n@@ -3447,6 +3449,97 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryWarehouse.PostWhseShipment(WarehouseShipmentHeader, false);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ProductionJournalPageHandler,ConfirmHandlerYes,MessageHandlerNotext')]\n+ procedure InputQtyAndStartingDateTimeIsRecalculatedWhenReplanProdOrder()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ RoutingHeader: Record \"Routing Header\";\n+ ProductionOrder: Record \"Production Order\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProdOrderRoutingLine: Record \"Prod. Order Routing Line\";\n+ WorkCenter: Record \"Work Center\";\n+ Direction: Option Forward,Backward;\n+ CalcMethod: Option \"No Levels\",\"One level\",\"All levels\";\n+ StartingDateTime: DateTime;\n+ begin\n+ // [SCENARIO 565975] \"Input Quantity\" and \"Starting Date-Time\" in Prod. Order Routing Line is \n+ // recalculated when Production Journal is posted and Stan runs Replan Production Order Report.\n+ Initialize();\n+\n+ // [GIVEN] Create a Component Item and Validate \"Replenishment System\", \n+ // \"Manufacturing Policy\" and \"Flushing Method\".\n+ LibraryInventory.CreateItem(CompItem);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(\"Manufacturing Policy\", CompItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::\"Pick + Manual\");\n+ CompItem.Modify(true);\n+\n+ // [GIVEN] Create a Work Center.\n+ CreateWorkCenter(WorkCenter);\n+\n+ // [GIVEN] Create and Certify Routing.\n+ CreateAndCertifyRouting(RoutingHeader, WorkCenter);\n+\n+ // [GIVEN] Create and Certify Production BOM.\n+ CreateAndCertifyProductionBOM(ProductionBOMLine, CompItem, LibraryRandom.RandIntInRange(10, 10));\n+\n+ // [GIVEN] Create a Production Item and Validate \"Replenishment System\", \n+ // \"Manufacturing Policy\", \"Routing No.\" and \"Production BOM No.\".\n+ LibraryInventory.CreateItem(ProdItem);\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Manufacturing Policy\", ProdItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProdItem.Validate(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMLine.\"Production BOM No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Set Item Inventory.\n+ SetItemInventory(CompItem, LibraryRandom.RandIntInRange(500, 500));\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProductionOrder(ProductionOrder, ProdItem.\"No.\", LibraryRandom.RandIntInRange(50, 50));\n+\n+ // [GIVEN] Find Prod. Order Routing Line.\n+ ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdOrderRoutingLine.FindFirst();\n+\n+ // [GIVEN] Generate and save Starting Date-Time in a Variable.\n+ StartingDateTime := ProdOrderRoutingLine.\"Starting Date-Time\";\n+\n+ // [GIVEN] Open Production Journal.\n+ OpenProductionJournal(ProductionOrder.\"No.\");\n+\n+ // [GIVEN] Run Replan Production Order Report.\n+ LibraryManufacturing.RunReplanProductionOrder(ProductionOrder, Direction::Backward, CalcMethod::\"No Levels\");\n+\n+ // [GIVEN] Find Prod. Order Line.\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProductionOrder.\"No.\");\n+ ProdOrderLine.FindFirst();\n+\n+ // [WHEN] Find Prod. Order Routing Line.\n+ ProdOrderRoutingLine.SetRange(\"Routing No.\", RoutingHeader.\"No.\");\n+ ProdOrderRoutingLine.FindFirst();\n+\n+ // [THEN] \"Input Quantity\" in Prod. Order Routing Line is equal to \"Remaining Quantity\" of Prod. Order Line.\n+ Assert.AreEqual(\n+ ProdOrderLine.\"Remaining Quantity\",\n+ ProdOrderRoutingLine.\"Input Quantity\",\n+ StrSubstNo(\n+ InputQtyErr,\n+ ProdOrderLine.\"Remaining Quantity\",\n+ ProdOrderRoutingLine.TableCaption()));\n+\n+ // [THEN] \"Starting Date-Time\" in Prod. Order Routing Line is equal to StartingDateTime.\n+ Assert.AreNotEqual(\n+ StartingDateTime,\n+ ProdOrderRoutingLine.\"Starting Date-Time\",\n+ StrSubstNo(\n+ StartingDateTimeErr,\n+ StartingDateTime,\n+ ProdOrderRoutingLine.TableCaption()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5174,6 +5267,71 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryInventory.PostItemJournalBatch(ItemJournalBatch);\n end;\n \n+ local procedure CreateAndRefreshProductionOrder(var ProductionOrder: Record \"Production Order\"; ItemNo: Code[20]; Quantity: Decimal)\n+ begin\n+ LibraryManufacturing.CreateProductionOrder(\n+ ProductionOrder, ProductionOrder.Status::Released, ProductionOrder.\"Source Type\"::Item, ItemNo, Quantity);\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+ end;\n+\n+ local procedure SetItemInventory(Item: Record Item; Quantity: Decimal)\n+ var\n+ ItemJnlTemplate: Record \"Item Journal Template\";\n+ ItemJnlBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ Item.TestField(\"No.\");\n+\n+ LibraryInventory.CreateItemJournalTemplate(ItemJnlTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJnlBatch, ItemJnlTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJnlTemplate.Name, ItemJnlBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", Quantity);\n+\n+ LibraryInventory.PostItemJournalLine(ItemJnlTemplate.Name, ItemJnlBatch.Name);\n+ end;\n+\n+ local procedure OpenProductionJournal(No: Code[20])\n+ var\n+ ReleasedProductionOrder: TestPage \"Released Production Order\";\n+ begin\n+ ReleasedProductionOrder.OpenEdit();\n+ ReleasedProductionOrder.FILTER.SetFilter(\"No.\", No);\n+ ReleasedProductionOrder.ProdOrderLines.ProductionJournal.Invoke();\n+ end;\n+\n+ local procedure CreateWorkCenter(var WorkCenter: Record \"Work Center\")\n+ begin\n+ LibraryManufacturing.CreateWorkCenterWithCalendar(WorkCenter);\n+ WorkCenter.Validate(\"Unit Cost\", LibraryRandom.RandDec(100, 2));\n+ WorkCenter.Validate(Capacity, LibraryRandom.RandIntInRange(3, 3));\n+ WorkCenter.Validate(Efficiency, LibraryRandom.RandIntInRange(100, 100));\n+ WorkCenter.Modify(true);\n+ end;\n+\n+ local procedure CreateAndCertifyRouting(var RoutingHeader: Record \"Routing Header\"; WorkCenter: Record \"Work Center\")\n+ var\n+ RoutingLine: Record \"Routing Line\";\n+ begin\n+ LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial);\n+ LibraryManufacturing.CreateRoutingLine(RoutingHeader, RoutingLine, '', Format(LibraryRandom.RandIntInRange(10, 10)), RoutingLine.Type::\"Work Center\", WorkCenter.\"No.\");\n+ RoutingLine.Validate(\"Setup Time\", LibraryRandom.RandIntInRange(10, 10));\n+ RoutingLine.Validate(\"Run Time\", LibraryRandom.RandIntInRange(10, 10));\n+ RoutingLine.Modify(true);\n+\n+ RoutingHeader.Validate(Status, RoutingHeader.Status::Certified);\n+ RoutingHeader.Modify(true);\n+ end;\n+\n+ local procedure CreateAndCertifyProductionBOM(var ProductionBOMLine: Record \"Production BOM Line\"; Item: Record Item; Qty: Decimal)\n+ var\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ begin\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, Item.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, Item.\"No.\", Qty);\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify(true);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure EnterQuantityToCreatePageHandler(var EnterQuantityToCreate: TestPage \"Enter Quantity to Create\")\n@@ -5347,6 +5505,19 @@ codeunit 137154 \"SCM Warehouse Management II\"\n SourceDocumentFilterCard.Run.Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandler(var ProductionJournal: TestPage \"Production Journal\")\n+ begin\n+ ProductionJournal.First();\n+ ProductionJournal.Quantity.SetValue(LibraryRandom.RandIntInRange(200, 200));\n+ ProductionJournal.Next();\n+ ProductionJournal.\"Setup Time\".SetValue(LibraryRandom.RandIntInRange(10, 10));\n+ ProductionJournal.\"Run Time\".SetValue(LibraryRandom.RandIntInRange(10, 10));\n+ ProductionJournal.\"Output Quantity\".SetValue(LibraryRandom.RandIntInRange(20, 20));\n+ ProductionJournal.Post.Invoke();\n+ end;\n+\n [PageHandler]\n [Scope('OnPrem')]\n procedure GLPostingPreviewPageHandler(var ShowAllEntries: TestPage \"G/L Posting Preview\")\n@@ -5372,6 +5543,11 @@ codeunit 137154 \"SCM Warehouse Management II\"\n Assert.IsTrue(StrPos(Message, LocalMessage) > 0, Message);\n end;\n \n+ [MessageHandler]\n+ procedure MessageHandlerNotext(Message: Text[1024])\n+ begin\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(ConfirmMessage: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al b/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\nindex 33305adaa10c..25cb5cb00d64 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Document/ReplanProductionOrder.Report.al\n@@ -65,7 +65,7 @@ report 99001026 \"Replan Production Order\"\n \"Ending Time\" := \"Prod. Order Line\".\"Ending Time\";\n Modify();\n end;\n- CalcProdOrderRtngLine.CalculateRoutingLine(\"Prod. Order Routing Line\", Direction, true);\n+ CalcProdOrderRtngLine.ReplanRoutingLine(\"Prod. Order Routing Line\", Direction, true);\n end;\n Modify();\n end;\ndiff --git a/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\nindex c46c8c20688a..1481dab83903 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Routing/CalculateRoutingLine.Codeunit.al\n@@ -1261,6 +1261,7 @@ codeunit 99000774 \"Calculate Routing Line\"\n OnCalculateRoutingLineOnBeforeProdOrderCapNeedReset(ProdOrderRoutingLine, ProdOrderRoutingLine2);\n \n ProdOrderCapNeed.Reset();\n+ ProdOrderCapNeed.SetLoadFields(Status, \"Prod. Order No.\", \"Requested Only\", \"Routing No.\", \"Routing Reference No.\", \"Operation No.\");\n ProdOrderCapNeed.SetRange(Status, ProdOrderRoutingLine.Status);\n ProdOrderCapNeed.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n ProdOrderCapNeed.SetRange(\"Requested Only\", false);\n@@ -2114,6 +2115,118 @@ codeunit 99000774 \"Calculate Routing Line\"\n CalendarEntry.SetRange(\"Ending Date-Time\", 0DT, CreateDateTime(DateValue + 1, TimeValue));\n end;\n \n+ procedure ReplanRoutingLine(var ProdOrderRoutingLine2: Record \"Prod. Order Routing Line\"; Direction: Option Forward,Backward; CalcStartEndDate: Boolean)\n+ var\n+ ProdOrderCapacityNeed: Record \"Prod. Order Capacity Need\";\n+ MfgCostCalcMgt: Codeunit \"Mfg. Cost Calculation Mgt.\";\n+ ExpectedOperOutput: Decimal;\n+ ActualOperOutput: Decimal;\n+ TotalQtyPerOperation: Decimal;\n+ TotalCapacityPerOperation: Decimal;\n+ begin\n+ MfgSetup.Get();\n+\n+ ProdOrderRoutingLine := ProdOrderRoutingLine2;\n+\n+ WaitTimeOnly :=\n+ (ProdOrderRoutingLine.\"Setup Time\" = 0) and (ProdOrderRoutingLine.\"Run Time\" = 0) and\n+ (ProdOrderRoutingLine.\"Move Time\" = 0);\n+\n+ if ProdOrderRoutingLine.\"Ending Time\" = 0T then\n+ ProdOrderRoutingLine.\"Ending Time\" := 000000T;\n+\n+ if ProdOrderRoutingLine.\"Starting Time\" = 0T then\n+ ProdOrderRoutingLine.\"Starting Time\" := 000000T;\n+\n+ ProdOrderRoutingLine.\"Expected Operation Cost Amt.\" := 0;\n+ ProdOrderRoutingLine.\"Expected Capacity Ovhd. Cost\" := 0;\n+ ProdOrderRoutingLine.\"Expected Capacity Need\" := 0;\n+\n+ ProdOrderCapacityNeed.Reset();\n+ ProdOrderCapacityNeed.SetRange(Status, ProdOrderRoutingLine.Status);\n+ ProdOrderCapacityNeed.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Requested Only\", false);\n+ ProdOrderCapacityNeed.SetRange(\"Routing No.\", ProdOrderRoutingLine.\"Routing No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Routing Reference No.\", ProdOrderRoutingLine.\"Routing Reference No.\");\n+ ProdOrderCapacityNeed.SetRange(\"Operation No.\", ProdOrderRoutingLine.\"Operation No.\");\n+ ProdOrderCapacityNeed.DeleteAll();\n+\n+ NextCapNeedLineNo := 1;\n+\n+ ProdOrderRoutingLine.TestField(\"Work Center No.\");\n+\n+ CurrentWorkCenterNo := '';\n+ Workcenter.Get(ProdOrderRoutingLine.\"Work Center No.\");\n+ if ProdOrderRoutingLine.Type = ProdOrderRoutingLine.Type::\"Machine Center\" then begin\n+ MachineCenter.Get(ProdOrderRoutingLine.\"No.\");\n+ Workcenter.\"Queue Time\" := MachineCenter.\"Queue Time\";\n+ Workcenter.\"Queue Time Unit of Meas. Code\" := MachineCenter.\"Queue Time Unit of Meas. Code\";\n+ end;\n+ if not CalcStartEndDate then\n+ Clear(Workcenter.\"Queue Time\");\n+ ProdOrder.Get(ProdOrderRoutingLine.Status, ProdOrderRoutingLine.\"Prod. Order No.\");\n+\n+ ProdOrderQty := 0;\n+ TotalScrap := 0;\n+ TotalLotSize := 0;\n+ ProdOrderLine.SetRange(Status, ProdOrderRoutingLine.Status);\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProdOrderRoutingLine.\"Prod. Order No.\");\n+ ProdOrderLine.SetRange(\"Routing Reference No.\", ProdOrderRoutingLine.\"Routing Reference No.\");\n+ ProdOrderLine.SetRange(\"Routing No.\", ProdOrderRoutingLine.\"Routing No.\");\n+ ProdOrderLine.SetLoadFields(\"Quantity (Base)\", \"Scrap %\", \"Prod. Order No.\", \"Line No.\", Status, \"Routing No.\", \"Routing Version Code\", \"Ending Date\", \"Ending Time\");\n+ if ProdOrderLine.Find('-') then begin\n+ ExpectedOperOutput := 0;\n+ repeat\n+ ExpectedOperOutput := ExpectedOperOutput + ProdOrderLine.\"Quantity (Base)\";\n+ TotalScrap := TotalScrap + ProdOrderLine.\"Scrap %\";\n+ until ProdOrderLine.Next() = 0;\n+ ActualOperOutput := MfgCostCalcMgt.CalcActOutputQtyBase(ProdOrderLine, ProdOrderRoutingLine);\n+ ProdOrderQty := ExpectedOperOutput - ActualOperOutput;\n+ if ProdOrderQty < 0 then\n+ ProdOrderQty := 0;\n+ end;\n+\n+ MaxLotSize :=\n+ ProdOrderQty *\n+ (1 + ProdOrderRoutingLine.\"Scrap Factor % (Accumulated)\") *\n+ (1 + TotalScrap / 100) +\n+ ProdOrderRoutingLine.\"Fixed Scrap Qty. (Accum.)\";\n+\n+ ProdOrderRoutingLine.\"Input Quantity\" := MaxLotSize;\n+\n+ if ActualOperOutput > 0 then\n+ TotalQtyPerOperation :=\n+ ExpectedOperOutput *\n+ (1 + ProdOrderRoutingLine.\"Scrap Factor % (Accumulated)\") *\n+ (1 + TotalScrap / 100) +\n+ ProdOrderRoutingLine.\"Fixed Scrap Qty. (Accum.)\"\n+ else\n+ TotalQtyPerOperation := MaxLotSize;\n+\n+ TotalCapacityPerOperation :=\n+ Round(\n+ TotalQtyPerOperation *\n+ ProdOrderRoutingLine.RunTimePer() *\n+ CalendarMgt.QtyperTimeUnitofMeasure(\n+ ProdOrderRoutingLine.\"Work Center No.\", ProdOrderRoutingLine.\"Run Time Unit of Meas. Code\"),\n+ UOMMgt.QtyRndPrecision());\n+\n+ if MfgSetup.\"Cost Incl. Setup\" then\n+ CalcCostInclSetup(ProdOrderRoutingLine, TotalCapacityPerOperation);\n+\n+ CalcExpectedCost(ProdOrderRoutingLine, TotalQtyPerOperation, TotalCapacityPerOperation);\n+\n+ if ProdOrderRoutingLine.\"Schedule Manually\" then\n+ CalculateRoutingLineFixed()\n+ else\n+ if Direction = Direction::Backward then\n+ CalcRoutingLineBack(CalcStartEndDate)\n+ else\n+ CalcRoutingLineForward(CalcStartEndDate);\n+\n+ ProdOrderRoutingLine2 := ProdOrderRoutingLine;\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterCalcCostInclSetup(ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; var TotalCapacityPerOperation: Decimal)\n begin\n"} +{"metadata": {"area": "project", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-214825", "base_commit": "9a03d309156dd751b1a508767c678093c9516506", "created_at": "2025-05-06", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136350, "functionName": ["CheckUnavailableItemQtyWhenAddProjectPlanningLinesBeforeThePreviousOne"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al b/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\nindex bb7f40e246dc..8aac1963c2d5 100644\n--- a/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/UTTJob.Codeunit.al\n@@ -2248,6 +2248,36 @@ codeunit 136350 \"UT T Job\"\n Assert.IsFalse(PurchaseLine.IsEmpty, 'Purchase Line not created for Job Task' + JobTask.\"Job Task No.\");\n end;\n \n+ [Test]\n+ [HandlerFunctions('CheckPurchOrderFromJobModalPageHandlerHaveLines')]\n+ procedure CheckUnavailableItemQtyWhenAddProjectPlanningLinesBeforeThePreviousOne()\n+ var\n+ Item, Item2 : Record Item;\n+ JobPlanningLines: TestPage \"Job Planning Lines\";\n+ begin\n+ // [SCENARIO 574938] Create Purchase Order from Project not working as expected if we add Project Planning Lines before the previous ones.\n+ Initialize();\n+\n+ // [GIVEN] Create 2 New Item.\n+ LibraryInventory.CreateItem(Item);\n+ LibraryInventory.CreateItem(Item2);\n+\n+ // [GIVEN] Create Job X with Job Task and 2 Job Planning Lines.\n+ CreateJobAndJobTask();\n+ CreateJobPlanningLineWithItem(JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\", Item.\"No.\", LibraryRandom.RandInt(100));\n+ CreateJobPlanningLineBeforePreviousLine(JobPlanningLine.\"Line Type\"::\"Both Budget and Billable\", Item2.\"No.\", LibraryRandom.RandInt(100));\n+\n+ // [WHEN] Open Job Planning Lines.\n+ JobPlanningLines.OpenEdit();\n+ JobPlanningLines.GoToRecord(JobPlanningLine);\n+ LibraryVariableStorage.Clear();\n+ LibraryVariableStorage.Enqueue(Item.\"No.\");\n+\n+ // [WHEN] Create Purchase Order from Job Planning Lines.\n+ JobPlanningLines.CreatePurchaseOrder.Invoke();//assert check\n+ LibraryVariableStorage.AssertEmpty();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -2617,6 +2647,30 @@ codeunit 136350 \"UT T Job\"\n until DefaultDimension.Next() = 0;\n end;\n \n+ local procedure CreateJobPlanningLineBeforePreviousLine(LineType: Enum \"Job Planning Line Line Type\"; ItemNo: Code[20]; Quantity: Decimal)\n+ var\n+ JobPlanLine: Record \"Job Planning Line\";\n+ LineNo: Integer;\n+ begin\n+ JobPlanLine.SetRange(\"Job No.\", JobTask.\"Job No.\");\n+ JobPlanLine.SetRange(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ if JobPlanLine.FindFirst() then;\n+ LineNo := JobPlanLine.\"Line No.\" / 2;\n+ JobPlanningLine.Init();\n+ JobPlanningLine.Validate(\"Job No.\", JobTask.\"Job No.\");\n+ JobPlanningLine.Validate(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ JobPlanningLine.Validate(\"Line No.\", LineNo);\n+ JobPlanningLine.Insert(true);\n+\n+ JobPlanningLine.Validate(\"Planning Date\", WorkDate());\n+ JobPlanningLine.Validate(\"Line Type\", LineType);\n+ JobPlanningLine.Validate(Type, JobPlanningLine.Type::Item);\n+ JobPlanningLine.Validate(Description, LibraryUtility.GenerateGUID());\n+ JobPlanningLine.Validate(\"No.\", ItemNo);\n+ JobPlanningLine.Validate(Quantity, Quantity);\n+ JobPlanningLine.Modify(true);\n+ end;\n+\n [EventSubscriber(ObjectType::Table, Database::\"Job\", 'OnAfterModifyEvent', '', false, false)]\n local procedure InsertNameValueBufferOnJobModify(var Rec: Record Job; var xRec: Record Job; RunTrigger: Boolean)\n var\n@@ -2730,6 +2784,13 @@ codeunit 136350 \"UT T Job\"\n PurchOrderFromSalesOrder.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ procedure CheckPurchOrderFromJobModalPageHandlerHaveLines(var PurchOrderFromSalesOrder: TestPage \"Purch. Order From Sales Order\")\n+ begin\n+ //[THEN] Check Purch. Order From Sales Order Page have Record.\n+ PurchOrderFromSalesOrder.\"No.\".AssertEquals(LibraryVariableStorage.DequeueText());\n+ end;\n+\n [MessageHandler]\n procedure MessageHandler(Message: Text[1024])\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\nindex 604bb9158a26..2da4897165fb 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Job/PurchaseDocFromJob.Codeunit.al\n@@ -78,6 +78,7 @@ codeunit 1018 \"Purchase Doc. From Job\"\n JobPlanningLine.SetRange(\"Job Task No.\", JobTask.\"Job Task No.\");\n if JobPlanningLine.IsEmpty() then\n exit;\n+ JobPlanningLine.SetCurrentKey(\"Job Contract Entry No.\");\n JobPlanningLine.FindSet();\n RecRef.GetTable(JobPlanningLine);\n ContractEntryNoFilter := SelectionFilterMgt.GetSelectionFilter(RecRef, JobPlanningLine.FieldNo(\"Job Contract Entry No.\"));\n"} {"metadata": {"area": "subscription billing", "image_count": 0}, "repo": "microsoft/BCApps", "instance_id": "microsoft__BCApps-4766", "base_commit": "700d04453d3f0851ce7b7e34eb50b283f7c10e52", "created_at": "2025-09-15T15:39:32Z", "environment_setup_version": "27.0", "project_paths": ["src\\Apps\\W1\\Subscription Billing\\App", "src\\Apps\\W1\\Subscription Billing\\Test"], "FAIL_TO_PASS": [{"codeunitID": 148155, "functionName": ["ContractLineDisconnectServiceOnNoChange"]}, {"codeunitID": 148154, "functionName": ["ContractLineDisconnectServiceOnNoChange"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al b/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\nindex 7e485c8c43..e945075fa8 100644\n--- a/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\n+++ b/src/Apps/W1/Subscription Billing/Test/Customer Contracts/ContractsTest.Codeunit.al\n@@ -613,23 +613,62 @@ codeunit 148155 \"Contracts Test\"\n CustomerContractLine: Record \"Cust. Sub. Contract Line\";\n ServiceCommitment: Record \"Subscription Line\";\n ServiceObject: Record \"Subscription Header\";\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after Type has changed.', Locked = true;\n EntryNo: Integer;\n begin\n- // Test: Subscription Line should be disconnected from the contract when the line type changes\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the line type changes\n Initialize();\n \n+ // [GIVEN] A customer contract with a connected Subscription Line\n SetupNewContract(false, ServiceObject, CustomerContract);\n \n- CustomerContractLine.Reset();\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n CustomerContractLine.SetRange(\"Subscription Contract No.\", CustomerContract.\"No.\");\n CustomerContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n CustomerContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n CustomerContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n CustomerContractLine.FindFirst();\n EntryNo := CustomerContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The contract line type is changed from Item to Comment\n CustomerContractLine.Validate(\"Contract Line Type\", CustomerContractLine.\"Contract Line Type\"::Comment);\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n+ ServiceCommitment.Get(EntryNo);\n+ Assert.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('ExchangeRateSelectionModalPageHandler,MessageHandler')]\n+ procedure ContractLineDisconnectServiceOnNoChange()\n+ var\n+ CustomerContract: Record \"Customer Subscription Contract\";\n+ CustomerContractLine: Record \"Cust. Sub. Contract Line\";\n+ ServiceCommitment: Record \"Subscription Line\";\n+ ServiceObject: Record \"Subscription Header\";\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after No. has changed.', Locked = true;\n+ EntryNo: Integer;\n+ begin\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the Item No. is cleared\n+ Initialize();\n+\n+ // [GIVEN] A customer contract with a connected Subscription Line\n+ SetupNewContract(false, ServiceObject, CustomerContract);\n+\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n+ CustomerContractLine.SetRange(\"Subscription Contract No.\", CustomerContract.\"No.\");\n+ CustomerContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n+ CustomerContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n+ CustomerContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n+ CustomerContractLine.FindFirst();\n+ EntryNo := CustomerContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The Item No. is cleared on the contract line\n+ CustomerContractLine.Validate(\"No.\", '');\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n ServiceCommitment.Get(EntryNo);\n- ServiceCommitment.TestField(\"Subscription Contract No.\", '');\n+ Assert.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n end;\n \n [Test]\ndiff --git a/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al b/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\nindex c47f577102..b827f99217 100644\n--- a/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\n+++ b/src/Apps/W1/Subscription Billing/Test/Vendor Contracts/VendorContractsTest.Codeunit.al\n@@ -338,11 +338,15 @@ codeunit 148154 \"Vendor Contracts Test\"\n procedure ContractLineDisconnectServiceOnTypeChange()\n var\n EntryNo: Integer;\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after Type has changed.', Locked = true;\n begin\n- // Test: Subscription Line should be disconnected from the contract when the line type changes\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the line type changes\n Initialize();\n+\n+ // [GIVEN] A vendor contract with a connected Subscription Line\n SetupNewContract(false);\n \n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n VendorContractLine.Reset();\n VendorContractLine.SetRange(\"Subscription Contract No.\", VendorContract.\"No.\");\n VendorContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n@@ -350,9 +354,43 @@ codeunit 148154 \"Vendor Contracts Test\"\n VendorContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n VendorContractLine.FindFirst();\n EntryNo := VendorContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The contract line type is changed from Item to Comment\n VendorContractLine.Validate(\"Contract Line Type\", VendorContractLine.\"Contract Line Type\"::Comment);\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n+ ServiceCommitment.Get(EntryNo);\n+ AssertThat.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n+ end;\n+\n+ [Test]\n+ [HandlerFunctions('ExchangeRateSelectionModalPageHandler,MessageHandler')]\n+ procedure ContractLineDisconnectServiceOnNoChange()\n+ var\n+ EntryNo: Integer;\n+ SubscriptionLineDisconnectErr: Label 'Subscription Line should be disconnected from the contract after No. has changed.', Locked = true;\n+ begin\n+ // [SCENARIO] Subscription Line should be disconnected from the contract when the Item No. is cleared\n+ Initialize();\n+\n+ // [GIVEN] A vendor contract with a connected Subscription Line\n+ SetupNewContract(false);\n+\n+ // [GIVEN] Find a contract line that has a connected Subscription Line\n+ VendorContractLine.Reset();\n+ VendorContractLine.SetRange(\"Subscription Contract No.\", VendorContract.\"No.\");\n+ VendorContractLine.SetRange(\"Contract Line Type\", Enum::\"Contract Line Type\"::Item);\n+ VendorContractLine.SetFilter(\"Subscription Header No.\", '<>%1', '');\n+ VendorContractLine.SetFilter(\"Subscription Line Entry No.\", '<>%1', 0);\n+ VendorContractLine.FindFirst();\n+ EntryNo := VendorContractLine.\"Subscription Line Entry No.\";\n+\n+ // [WHEN] The Item No. is cleared on the contract line\n+ VendorContractLine.Validate(\"No.\", '');\n+\n+ // [THEN] The Subscription Line should be disconnected from the contract\n ServiceCommitment.Get(EntryNo);\n- ServiceCommitment.TestField(\"Subscription Contract No.\", '');\n+ AssertThat.AreEqual('', ServiceCommitment.\"Subscription Contract No.\", SubscriptionLineDisconnectErr);\n end;\n \n [Test]\n", "patch": "diff --git a/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al b/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\nindex 91f83b18b3..a092d10f19 100644\n--- a/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\n+++ b/src/Apps/W1/Subscription Billing/App/Customer Contracts/Tables/CustSubContractLine.Table.al\n@@ -49,23 +49,25 @@ table 8062 \"Cust. Sub. Contract Line\"\n GLAccount: Record \"G/L Account\";\n TempCustomerContractLine: Record \"Cust. Sub. Contract Line\" temporary;\n begin\n- case \"Contract Line Type\" of\n- \"Contract Line Type\"::Item:\n- begin\n- if not Item.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n- if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n- Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n- end;\n- \"Contract Line Type\"::\"G/L Account\":\n- begin\n- if not GLAccount.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n- if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n- Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n- end;\n- end;\n+ if \"No.\" <> '' then\n+ case \"Contract Line Type\" of\n+ \"Contract Line Type\"::Item:\n+ begin\n+ if not Item.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n+ if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n+ Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n+ end;\n+ \"Contract Line Type\"::\"G/L Account\":\n+ begin\n+ if not GLAccount.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n+ if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n+ Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n+ end;\n+ end;\n \n+ CheckAndDisconnectContractLine();\n TempCustomerContractLine := Rec;\n Init();\n SystemId := TempCustomerContractLine.SystemId;\n@@ -170,6 +172,8 @@ table 8062 \"Cust. Sub. Contract Line\"\n ServiceObject: Record \"Subscription Header\";\n ServiceCommitment: Record \"Subscription Line\";\n begin\n+ if \"No.\" = '' then\n+ exit;\n CustomerContract.Get(\"Subscription Contract No.\");\n ServiceObject.InitForSourceNo(\"Contract Line Type\", \"No.\");\n ServiceObject.UpdateCustomerDataFromCustomerContract(CustomerContract);\ndiff --git a/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al b/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\nindex 533581b5a2..38ecf0e9c3 100644\n--- a/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\n+++ b/src/Apps/W1/Subscription Billing/App/Vendor Contracts/Tables/VendSubContractLine.Table.al\n@@ -46,23 +46,25 @@ table 8065 \"Vend. Sub. Contract Line\"\n GLAccount: Record \"G/L Account\";\n TempVendorContractLine: Record \"Vend. Sub. Contract Line\" temporary;\n begin\n- case \"Contract Line Type\" of\n- \"Contract Line Type\"::Item:\n- begin\n- if not Item.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n- if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n- Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n- end;\n- \"Contract Line Type\"::\"G/L Account\":\n- begin\n- if not GLAccount.Get(\"No.\") then\n- Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n- if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n- Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n- end;\n- end;\n+ if \"No.\" <> '' then\n+ case \"Contract Line Type\" of\n+ \"Contract Line Type\"::Item:\n+ begin\n+ if not Item.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, Item.TableCaption, \"No.\");\n+ if Item.Blocked or Item.\"Subscription Option\" in [\"Item Service Commitment Type\"::\"Sales without Service Commitment\", \"Item Service Commitment Type\"::\"Sales without Service Commitment\"] then\n+ Error(ItemBlockedOrWithoutServiceCommitmentsErr, \"No.\");\n+ end;\n+ \"Contract Line Type\"::\"G/L Account\":\n+ begin\n+ if not GLAccount.Get(\"No.\") then\n+ Error(EntityDoesNotExistErr, GLAccount.TableCaption, \"No.\");\n+ if GLAccount.Blocked or not GLAccount.\"Direct Posting\" or (GLAccount.\"Account Type\" <> GLAccount.\"Account Type\"::Posting) then\n+ Error(GLAccountBlockedOrNotForDirectPostingErr, \"No.\");\n+ end;\n+ end;\n \n+ CheckAndDisconnectContractLine();\n TempVendorContractLine := Rec;\n Init();\n SystemId := TempVendorContractLine.SystemId;\n@@ -161,6 +163,8 @@ table 8065 \"Vend. Sub. Contract Line\"\n ServiceObject: Record \"Subscription Header\";\n ServiceCommitment: Record \"Subscription Line\";\n begin\n+ if \"No.\" = '' then\n+ exit;\n VendorContract.Get(\"Subscription Contract No.\");\n ServiceObject.InitForSourceNo(\"Contract Line Type\", \"No.\");\n ServiceObject.\"Created in Contract line\" := true;\n"} +{"metadata": {"area": "service", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-210200", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-03-15", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Service"], "FAIL_TO_PASS": [{"codeunitID": 136119, "functionName": ["ReservationEntryMustBeCreatedWhenReserveIsAlwaysInServiceLine"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al b/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al\nindex 7027c534363e..e65fb66d63d3 100644\n--- a/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Service/ServiceStandardCodes.Codeunit.al\n@@ -9,6 +9,8 @@ using Microsoft.Finance.GeneralLedger.Journal;\n using Microsoft.Finance.GeneralLedger.Ledger;\n using Microsoft.Finance.VAT.Ledger;\n using Microsoft.Inventory.Item;\n+using Microsoft.Inventory.Journal;\n+using Microsoft.Inventory.Location;\n using Microsoft.Projects.Resources.Ledger;\n using Microsoft.Sales.Customer;\n using Microsoft.Sales.Receivables;\n@@ -40,6 +42,7 @@ codeunit 136119 \"Service Standard Codes\"\n LibrarySales: Codeunit \"Library - Sales\";\n LibraryUtility: Codeunit \"Library - Utility\";\n LibraryERM: Codeunit \"Library - ERM\";\n+ LibraryWarehouse: Codeunit \"Library - Warehouse\";\n ServiceItemGroupCode2: Code[10];\n StandardServiceCode2: Code[10];\n isInitialized: Boolean;\n@@ -52,6 +55,7 @@ codeunit 136119 \"Service Standard Codes\"\n QuantityMustbePositive: Label '%1 must be positive in %2 %3=''%4'',%5=''%6''.';\n ServiceLineMustNotExist: Label 'There is no %1 within the filter.Filters: %2: %3, %4: %5';\n ExpectedConfirm: Label 'The Credit Memo doesn''t have a Corrected Invoice No. Do you want to continue?';\n+ ValueMustBeEqualErr: Label '%1 must be equal to %2 in %3', Comment = '%1 = Field Caption , %2 = Expected Value , %3 = Table Caption';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1026,6 +1030,75 @@ codeunit 136119 \"Service Standard Codes\"\n StandardServiceLine.TestField(\"No.\", Item.\"No.\");\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalFormHandlerServItemGroup')]\n+ procedure ReservationEntryMustBeCreatedWhenReserveIsAlwaysInServiceLine()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ Customer: Record Customer;\n+ ServiceItem: Record \"Service Item\";\n+ ServiceHeader: Record \"Service Header\";\n+ ServiceLine: Record \"Service Line\";\n+ ServiceItemLine: Record \"Service Item Line\";\n+ StandardServiceCode: Record \"Standard Service Code\";\n+ StandardServiceItemGrCode: Record \"Standard Service Item Gr. Code\";\n+ ExpectedQuantity: Integer;\n+ begin\n+ // [SCENARIO 566581] Verify Reservation Entry must be created When Item that has Reserve = Always in the Service Line.\n+ // when \"Get Std. Service Codes.\" is executed.\n+ Initialize();\n+\n+ // [GIVEN] Create a Customer.\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ // [GIVEN] Create Location with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Create an item with Reserve = Always.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Reordering Policy\", Item.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ Item.Validate(Reserve, Item.Reserve::Always);\n+ Item.Modify();\n+\n+ // [GIVEN] Generate Quantity.\n+ ExpectedQuantity := LibraryRandom.RandInt(20);\n+\n+ // [GIVEN] Post inventory.\n+ SetItemInventory(Item, ExpectedQuantity, Location.Code);\n+\n+ // [GIVEN] Create Service Item.\n+ LibraryService.CreateServiceItem(ServiceItem, Customer.\"No.\");\n+\n+ // [GIVEN] Create Standard Service Code with Item and Quantity.\n+ LibraryService.CreateStandardServiceCode(StandardServiceCode);\n+ CreateStdServiceLineWithItem(StandardServiceCode.Code, Item.\"No.\", ExpectedQuantity);\n+\n+ // [GIVEN] Create Service Order with Location.\n+ LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ ServiceHeader.Validate(\"Location Code\", Location.Code);\n+ ServiceHeader.Modify();\n+\n+ // [GIVEN] Create Service Item Line.\n+ LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, '');\n+\n+ // [GIVEN] Delete Standard Service Group Code.\n+ StandardServiceItemGrCode.DeleteAll();\n+\n+ // [WHEN] Insert Service Line through Standard Service Code.\n+ ServiceItemGroupCode2 := '';\n+ StandardServiceCode2 := StandardServiceCode.Code;\n+ StandardServiceItemGrCode.InsertServiceLines(ServiceItemLine);\n+\n+ // [THEN] Verify \"Reserved Qty. (Base)\" must be updated in the Service Line.\n+ FindServiceLine(ServiceLine, ServiceHeader.\"Document Type\", ServiceHeader.\"No.\");\n+ ServiceLine.CalcFields(\"Reserved Qty. (Base)\");\n+ Assert.AreEqual(\n+ ExpectedQuantity,\n+ ServiceLine.\"Reserved Qty. (Base)\",\n+ StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption(\"Reserved Qty. (Base)\"), ExpectedQuantity, ServiceLine.TableCaption()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1597,6 +1670,33 @@ codeunit 136119 \"Service Standard Codes\"\n VATEntry.TestField(\"Posting Date\", PostingDate);\n end;\n \n+ local procedure SetItemInventory(Item: Record Item; Quantity: Decimal; LocationCode: Code[10])\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.CreateItemJournalTemplate(ItemJournalTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJournalBatch, ItemJournalTemplate.Name);\n+\n+ LibraryInventory.CreateItemJournalLine(ItemJournalLine, ItemJournalTemplate.Name, ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", Quantity);\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Modify();\n+\n+ LibraryInventory.PostItemJournalLine(ItemJournalTemplate.Name, ItemJournalLine.\"Journal Batch Name\");\n+ end;\n+\n+ local procedure CreateStdServiceLineWithItem(StandardServiceCode: Code[10]; ItemNo: Code[20]; Quantity: Decimal)\n+ var\n+ StandardServiceLine: Record \"Standard Service Line\";\n+ begin\n+ LibraryService.CreateStandardServiceLine(StandardServiceLine, StandardServiceCode);\n+ StandardServiceLine.Validate(Type, StandardServiceLine.Type::Item);\n+ StandardServiceLine.Validate(\"No.\", ItemNo);\n+ StandardServiceLine.Validate(Quantity, Quantity);\n+ StandardServiceLine.Modify(true);\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al b/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al\nindex 33f69be4c731..53eb121209b6 100644\n--- a/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al\n+++ b/App/Layers/W1/BaseApp/Service/Item/StandardServiceItemGrCode.Table.al\n@@ -159,6 +159,11 @@ table 5998 \"Standard Service Item Gr. Code\"\n ServLine.\"Line No.\" := ServLine.GetLineNo();\n OnBeforeInsertServLine(ServLine);\n ServLine.Insert(true);\n+\n+ if ServLine.Type = ServLine.Type::Item then\n+ if ServLine.Reserve = ServLine.Reserve::Always then\n+ ServLine.AutoReserve(false);\n+\n InsertExtendedText(ServLine);\n end;\n until StdServLine.Next() = 0;\n"} +{"metadata": {"area": "manufacturing", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208649", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-03-03", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137088, "functionName": ["ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\nindex 7415eaa53ccd..2573227dbca7 100644\n--- a/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMOrderPlanningIII.Codeunit.al\n@@ -45,6 +45,8 @@ codeunit 137088 \"SCM Order Planning - III\"\n LineExistErr: Label 'Requistion line in %1 worksheet should exist for item %2';\n PurchaseLineQuantityBaseErr: Label '%1.%2 must be nearly equal to %3.', Comment = '%1 : Purchase Line, %2 : Quantity (Base), %3 : Value.';\n BOMFixedQtyCalcFormulaErr: Label 'BOM Fixed Quantity Calculation Formula should be used to calculate the values.';\n+ RelesedProdOrderComponentQtyPerRoundingErr: Label 'Relesed Production Order Item Component Quantity per %1 Not Match With Expected Result %2';\n+ RelesedProdOrderComponentExpQtyRoundingErr: Label 'Relesed Production Order Item Component Expected Quantity %1 Not Match With Expected Result %2';\n \n [Test]\n [HandlerFunctions('MakeSupplyOrdersPageHandler')]\n@@ -2988,6 +2990,73 @@ codeunit 137088 \"SCM Order Planning - III\"\n VerifyStartingTimeOnFirmPlannedProductionOrder(StartingTime, ChildItem.\"No.\", ProductionOrderNo);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalPageHandler,ErrorMessageHandler')]\n+ procedure ReleasedProdOrderQuantityPerandExpectedQtyRoundingPrecisionChecking()\n+ var\n+ BaseItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ComponentItem: Record Item;\n+ ProdOrderComp: Record \"Prod. Order Component\";\n+ ProdOrderLine: Record \"Prod. Order Line\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ ProductItem: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ ExpectedQty: Decimal;\n+ RelesedProdOrderNo: Code[20];\n+ Status: Enum \"Production Order Status\";\n+ begin\n+ // [SCENARIO 562766] If a component's Item UOM has a 'Quantity Rounding Precision' of 1, & a Finished Good consumes partial quantity, \n+ // the Prod. Order created from the Planning of a Sales Order pulls in the Component with a 'Qty. Per' and 'Exp. Qty.' of 0.\n+ Initialize();\n+\n+ // [GIVEN] Created Component Item\n+ LibraryInventory.CreateItem(ComponentItem);\n+ ComponentItem.Validate(\"Replenishment System\", ComponentItem.\"Replenishment System\"::Purchase);\n+ ComponentItem.Validate(\"Rounding Precision\", LibraryRandom.RandPrecision());\n+ ComponentItem.Validate(\"Reordering Policy\", ComponentItem.\"Reordering Policy\"::\"Lot-for-Lot\");\n+ ComponentItem.Validate(\"Include Inventory\", true);\n+ ComponentItem.Modify(true);\n+\n+ // [GIVEN] Set Qty. Rounding Precision = 1 for Component Item\n+ BaseItemUnitOfMeasure.Get(ComponentItem.\"No.\", ComponentItem.\"Base Unit of Measure\");\n+ BaseItemUnitOfMeasure.Validate(\"Qty. Rounding Precision\", 1);\n+ BaseItemUnitOfMeasure.Modify();\n+\n+ // [GIVEN] Created Production Bom using Component Item\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ComponentItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, ComponentItem.\"No.\", LibraryRandom.RandDecInDecimalRange(0.01, 0.99, 2));\n+ ProductionBOMHeader.Validate(Status, ProductionBOMHeader.Status::Certified);\n+ ProductionBOMHeader.Modify();\n+\n+ // [GIVEN] Created Master Item and Production Bom Assigned to Master Item\n+ LibraryInventory.CreateItem(ProductItem);\n+ ProductItem.Validate(\"Replenishment System\", ProductItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProductItem.Validate(\"Rounding Precision\", 1);\n+ ProductItem.Validate(\"Reordering Policy\", ProductItem.\"Reordering Policy\"::Order);\n+ ProductItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProductItem.Modify(true);\n+\n+ // [GIVEN] Created Sales Order Using Master Item Quantity - 1\n+ CreateSalesOrder(SalesHeader, ProductItem.\"No.\", '', 1, 1);\n+\n+ // [WHEN] Created Released Prod. Order From Sales Order Using Planning\n+ LibraryPlanning.CreateProdOrderUsingPlanning(ProductionOrder, Status::\"Firm Planned\", SalesHeader.\"No.\", ProductItem.\"No.\");\n+ RelesedProdOrderNo := LibraryManufacturing.ChangeStatusFirmPlanToReleased(ProductionOrder.\"No.\");\n+\n+ // [WHEN] Find Released Production Order Component\n+ FindProdOrderLine(ProdOrderLine, RelesedProdOrderNo);\n+ FindProdOrderComponent(ProdOrderComp, ProdOrderLine.\"Prod. Order No.\", ComponentItem.\"No.\");\n+\n+ // [WHEN] Getting Expected result using Component Rounding Precision\n+ ExpectedQty := Round(ProductionBOMLine.\"Quantity per\" * BaseItemUnitOfMeasure.\"Qty. Rounding Precision\" / BaseItemUnitOfMeasure.\"Qty. Rounding Precision\", ComponentItem.\"Rounding Precision\");\n+\n+ // [THEN] Expected Quantity must be Equal to Production Order Component \"Quantity per\" And \"Expected Quantity\"\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Quantity per\", StrSubstNo(RelesedProdOrderComponentQtyPerRoundingErr, ProdOrderComp.\"Quantity per\", ExpectedQty));\n+ Assert.AreEqual(ExpectedQty, ProdOrderComp.\"Expected Quantity\", StrSubstNo(RelesedProdOrderComponentExpQtyRoundingErr, ProdOrderComp.\"Expected Quantity\", ExpectedQty));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3805,6 +3874,14 @@ codeunit 137088 \"SCM Order Planning - III\"\n Assert.IsTrue(ProductionOrder.\"Starting Time\" = StartingTime, '');\n end;\n \n+ local procedure FindProdOrderLine(var ProdOrderLine: Record \"Prod. Order Line\"; ProductionOrderNo: Code[20])\n+ begin\n+ ProdOrderLine.Reset();\n+ ProdOrderLine.SetRange(Status, ProdOrderLine.Status::Released);\n+ ProdOrderLine.SetRange(\"Prod. Order No.\", ProductionOrderNo);\n+ ProdOrderLine.FindFirst();\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure MakeSupplyOrdersPageHandler(var MakeSupplyOrders: Page \"Make Supply Orders\"; var Response: Action)\n@@ -3911,5 +3988,16 @@ codeunit 137088 \"SCM Order Planning - III\"\n begin\n Reply := true;\n end;\n+\n+ [ModalPageHandler]\n+ procedure ModalPageHandler(var CreateOrderFromSales: Page \"Create Order From Sales\"; var Response: Action)\n+ begin\n+ Response := Action::Yes;\n+ end;\n+\n+ [MessageHandler]\n+ procedure ErrorMessageHandler(Message: Text[1024])\n+ begin\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\nindex 36930a9e2aaa..23674793f0e1 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al\n@@ -43,6 +43,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp: Record \"Prod. Order Component\";\n ProdOrderRoutingLine2: Record \"Prod. Order Routing Line\";\n ProdBOMLine: array[99] of Record \"Production BOM Line\";\n+ ProdLineItem: Record Item;\n UOMMgt: Codeunit \"Unit of Measure Management\";\n MfgCostCalcMgt: Codeunit \"Mfg. Cost Calculation Mgt.\";\n VersionMgt: Codeunit VersionManagement;\n@@ -297,6 +298,7 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderComp.Validate(\"Unit of Measure Code\", ProdBOMLine[Level].\"Unit of Measure Code\");\n if (ProdOrderComp.\"Item No.\" <> '') and Item2.Get(ProdOrderComp.\"Item No.\") then\n QtyRoundPrecision := UOMMgt.GetQtyRoundingPrecision(Item2, ProdBOMLine[Level].\"Unit of Measure Code\");\n+ CheckingRoundingPrecision(Item2, ProdLineItem, QtyRoundPrecision, Level);\n if QtyRoundPrecision <> 0 then\n ProdOrderComp.\"Quantity per\" := Round(ProdBOMLine[Level].\"Quantity per\" * LineQtyPerUOM / ItemQtyPerUOM, QtyRoundPrecision)\n else\n@@ -975,6 +977,21 @@ codeunit 99000773 \"Calculate Prod. Order\"\n ProdOrderLineToCheck.TestField(Quantity);\n end;\n \n+ local procedure CheckingRoundingPrecision(ChildItem: Record Item; ProdLineItem: Record Item; var QtyRoundPrecision: Decimal; Level: Integer)\n+ begin\n+ if (ChildItem.\"Rounding Precision\" = 0) or (QtyRoundPrecision = 0) then\n+ exit;\n+\n+ if (not ProdLineItem.Get(ProdOrderLine.\"Item No.\")) or (ProdLineItem.\"Replenishment System\" <> ProdLineItem.\"Replenishment System\"::\"Prod. Order\") then\n+ exit;\n+\n+ if (ChildItem.\"Base Unit of Measure\" <> ProdBOMLine[Level].\"Unit of Measure Code\") then\n+ exit;\n+ QtyRoundPrecision := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision\" := ChildItem.\"Rounding Precision\";\n+ ProdOrderComp.\"Qty. Rounding Precision (Base)\" := ChildItem.\"Rounding Precision\";\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterInsertProdRoutingLine(var ProdOrderRoutingLine: Record \"Prod. Order Routing Line\"; ProdOrderLine: Record \"Prod. Order Line\")\n begin\n"} +{"metadata": {"area": "sales", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209496", "base_commit": "d080f087349d4713e1782f2f2630819714cb6738", "created_at": "2025-03-10", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134979, "functionName": ["AddTextforLanguageInReminderLevelCommunication"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\nindex ca7812c9329a..746513941686 100644\n--- a/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ReminderAutomationTests.Codeunit.al\n@@ -814,6 +814,30 @@ codeunit 134979 \"Reminder Automation Tests\"\n ReminderAutomationCard.Close();\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerFalse,ReminderLevelCommunicationPageHandler,LanguagesPageHandler')]\n+ procedure AddTextforLanguageInReminderLevelCommunication()\n+ var\n+ ReminderTerms: Record \"Reminder Terms\";\n+ ReminderLevel: Record \"Reminder Level\";\n+ ReminderTermSetupPage: TestPage \"Reminder Terms Setup\";\n+ begin\n+ // [SCENARIO 568005] Adding text for language in Reminder Level Communication.\n+ Initialize();\n+\n+ // [GIVEN] Create Reminder Term with levels\n+ LibraryErm.CreateReminderTerms(ReminderTerms);\n+ LibraryErm.CreateReminderLevel(ReminderLevel, ReminderTerms.Code);\n+\n+ // [WHEN] Open Reminder Term Setup page and add text for language\n+ ReminderTermSetupPage.OpenEdit();\n+ ReminderTermSetupPage.GoToRecord(ReminderTerms);\n+ ReminderTermSetupPage.ReminderLevelSetup.First();\n+\n+ // [THEN] Varify that the text for language is added in Reminder Level Communication.\n+ ReminderTermSetupPage.ReminderLevelSetup.CustomerCommunications.Invoke();\n+ end;\n+\n local procedure CreateReminderAttachmentText(ReminderTerms: Record \"Reminder Terms\"; LanguageCode: Code[10])\n var\n ReminderLevel: Record \"Reminder Level\";\n@@ -1211,6 +1235,25 @@ codeunit 134979 \"Reminder Automation Tests\"\n exit(true);\n end;\n \n+ [ConfirmHandler]\n+ procedure ConfirmHandlerFalse(QuestionText: Text[1024]; var Relpy: Boolean)\n+ begin\n+ Relpy := false;\n+ end;\n+\n+ [PageHandler]\n+ procedure ReminderLevelCommunicationPageHandler(var ReminderLevelCommunication: TestPage \"Reminder Level Communication\")\n+ begin\n+ ReminderLevelCommunication.\"Add New Language\".Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ procedure LanguagesPageHandler(var Languages: TestPage \"Languages\")\n+ begin\n+ Languages.Filter.SetFilter(\"Code\", 'ENG');\n+ Languages.OK().Invoke();\n+ end;\n+\n var\n LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n LibraryUtility: Codeunit \"Library - Utility\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al b/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al\nindex 10d284cc0688..23e132dc418b 100644\n--- a/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al\n+++ b/App/Layers/W1/BaseApp/Sales/Reminder/TermsAndLevels/ReminderLevelCommunication.Page.al\n@@ -304,17 +304,19 @@ page 835 \"Reminder Level Communication\"\n var\n ReminderAttachmentText: Record \"Reminder Attachment Text\";\n ReminderEmailText: Record \"Reminder Email Text\";\n+ ReminderLevel: Record \"Reminder Level\";\n begin\n if LanguageCode = '' then\n exit;\n \n CurrentLanguage.SetRange(Code, LanguageCode);\n CurrentLanguage.FindFirst();\n+ ReminderLevel.Get(Rec.\"Reminder Terms Code\", Rec.\"No.\");\n \n- if not ReminderAttachmentText.Get(Rec.\"Reminder Attachment Text\", CurrentLanguage.Code) then\n+ if not ReminderAttachmentText.Get(ReminderLevel.\"Reminder Attachment Text\", CurrentLanguage.Code) then\n if CreateNewEntry then begin\n- ReminderAttachmentText.SetDefaultContentForNewLanguage(Rec.\"Reminder Attachment Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n- ReminderEmailText.SetDefaultContentForNewLanguage(Rec.\"Reminder Email Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n+ ReminderAttachmentText.SetDefaultContentForNewLanguage(ReminderLevel.\"Reminder Attachment Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n+ ReminderEmailText.SetDefaultContentForNewLanguage(ReminderLevel.\"Reminder Email Text\", CurrentLanguage.Code, Enum::\"Reminder Text Source Type\"::\"Reminder Level\");\n end\n else\n Error(NoTextForSelectedLanguageErr, CurrentLanguage.Code);\n"} +{"metadata": {"area": "sales", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-208748", "base_commit": "d080f087349d4713e1782f2f2630819714cb6738", "created_at": "2025-03-03", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134377, "functionName": ["CheckMultipleExtendedTextFromBlanketSalesOrderToSalesOrder"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al\nindex da968e20f561..e56565d8c806 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesBlanketOrder.Codeunit.al\n@@ -33,6 +33,7 @@ codeunit 134377 \"ERM Sales Blanket Order\"\n BlanketOrderLineNoFieldError: Label 'Blanket Order Line No. missing on related Sales Credit Memo';\n UnitPriceIsChangedErr: Label 'Unit Price is changed on Quantity update.';\n ValueMustBeEqualErr: Label '%1 must be equal to %2 in the %3.', Comment = '%1 = Field Caption , %2 = Expected Value, %3 = Table Caption';\n+ TotalRecordCountErr: Label 'Total record count must be equal to %1', Comment = '%1 = Record Count.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1377,10 +1378,45 @@ codeunit 134377 \"ERM Sales Blanket Order\"\n until SalesLine.Next() = 0;\n end;\n \n+ [Test]\n+ procedure CheckMultipleExtendedTextFromBlanketSalesOrderToSalesOrder()\n+ var\n+ BlanketSalesHeader: Record \"Sales Header\";\n+ SalesOrderLine: Record \"Sales Line\";\n+ NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n+ BlanketSalesOrder: TestPage \"Blanket Sales Order\";\n+ CustomerNo: Code[20];\n+ OrderNo: Code[20];\n+ begin\n+ // [SCENARIO 567891] Verify the multiple extended texts line when converting a blanket sales order to a sales order.\n+ Initialize();\n+\n+ // [GIVEN] Create Blanket Sales Order With Multiple Extended Items.\n+ CustomerNo := CreateBlanketSalesOrder(BlanketSalesOrder);\n+\n+ // [GIVEN] Find Blanket Sales Order.\n+ BlanketSalesHeader.SetRange(\"Sell-to Customer No.\", CustomerNo);\n+ BlanketSalesHeader.FindFirst();\n+\n+ // [WHEN] Convert the blanket sales order into a sales order.\n+ OrderNo := LibrarySales.BlanketSalesOrderMakeOrder(BlanketSalesHeader);\n+\n+ // [THEN] Calculate no. of Sales order line record.\n+ SalesOrderLine.SetRange(\"Document Type\", SalesOrderLine.\"Document Type\"::Order);\n+ SalesOrderLine.SetRange(\"Document No.\", OrderNo);\n+\n+ // [THEN] Verify the sales order line record count with the extended text records.\n+ Assert.AreEqual(\n+ SalesOrderLine.Count(), CalculateBlanketSalesOrderLineRecords(BlanketSalesHeader),\n+ StrSubstNo(TotalRecordCountErr, SalesOrderLine.Count()));\n+\n+ NotificationLifecycleMgt.RecallAllNotifications();\n+ end;\n+\n local procedure Initialize()\n var\n- LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"ERM Sales Blanket Order\");\n LibrarySetupStorage.Restore();\n@@ -1716,6 +1752,61 @@ codeunit 134377 \"ERM Sales Blanket Order\"\n exit(Purchasing.Code);\n end;\n \n+ local procedure CreateBlanketSalesOrder(var BlanketSalesOrder: TestPage \"Blanket Sales Order\"): Code[20]\n+ var\n+ Customer: Record Customer;\n+ Item: array[3] of Record Item;\n+ i: Integer;\n+ begin\n+ LibrarySales.CreateCustomer(Customer);\n+ BlanketSalesOrder.OpenNew();\n+ BlanketSalesOrder.\"Sell-to Customer No.\".SetValue(Customer.\"No.\");\n+ for i := 1 to LibraryRandom.RandIntInRange(3, 3) do begin\n+ CreateMultipleItemWithExtendedText(Item[i]);\n+ CreateBlanketSalesLineFromSubformPage(BlanketSalesOrder, Item[i]);\n+ end;\n+ BlanketSalesOrder.Close();\n+\n+ exit(Customer.\"No.\");\n+ end;\n+\n+ local procedure CreateMultipleItemWithExtendedText(var Item: Record Item)\n+ var\n+ ExtendedTextHeader: Record \"Extended Text Header\";\n+ ExtendedTextLine: Record \"Extended Text Line\";\n+ begin\n+ Item.Get(CreateItem());\n+ Item.Validate(\"Automatic Ext. Texts\", true);\n+ Item.Modify(true);\n+\n+ LibraryInventory.CreateExtendedTextHeaderItem(ExtendedTextHeader, Item.\"No.\");\n+ LibraryInventory.CreateExtendedTextLineItem(ExtendedTextLine, ExtendedTextHeader);\n+ ExtendedTextLine.Validate(Text, Item.\"No.\");\n+ ExtendedTextLine.Modify(true);\n+ end;\n+\n+ local procedure CreateBlanketSalesLineFromSubformPage(var BlanketSalesOrder: TestPage \"Blanket Sales Order\"; Item: Record Item)\n+ var\n+ SalesLineType: Enum \"Sales Line Type\";\n+ begin\n+ BlanketSalesOrder.SalesLines.New();\n+ BlanketSalesOrder.SalesLines.Type.SetValue(SalesLineType::Item);\n+ BlanketSalesOrder.SalesLines.\"No.\".SetValue(Item.\"No.\");\n+ BlanketSalesOrder.SalesLines.Quantity.SetValue(LibraryRandom.RandInt(10));\n+ Commit();\n+ BlanketSalesOrder.SalesLines.Next();\n+ end;\n+\n+ local procedure CalculateBlanketSalesOrderLineRecords(BlanketSalesOrder: Record \"Sales Header\"): Integer\n+ var\n+ BlanketSalesLine: Record \"Sales Line\";\n+ begin\n+ BlanketSalesLine.SetRange(\"Document Type\", BlanketSalesOrder.\"Document Type\");\n+ BlanketSalesLine.SetRange(\"Document No.\", BlanketSalesOrder.\"No.\");\n+\n+ exit(BlanketSalesLine.Count);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al\nindex afe6215fb8bd..c200af6e4f0f 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/BlanketSalesOrdertoOrder.Codeunit.al\n@@ -203,7 +203,7 @@ codeunit 87 \"Blanket Sales Order to Order\"\n SalesLineOrder.\"Qty. to Asm. to Order (Base)\" := SalesLineOrder.\"Quantity (Base)\";\n end;\n SalesLineOrder.DefaultDeferralCode();\n- if IsSalesOrderLineToBeInserted(SalesLineOrder) then begin\n+ if IsSalesOrderLineToBeInserted(SalesLineOrder, SalesLineBlanketOrder) then begin\n OnBeforeInsertSalesOrderLine(SalesLineOrder, SalesHeaderOrder, SalesLineBlanketOrder, SalesHeaderBlanketOrder);\n SalesLineOrder.Insert();\n OnAfterInsertSalesOrderLine(SalesLineOrder, SalesHeaderOrder, SalesLineBlanketOrder, SalesHeaderBlanketOrder);\n@@ -447,15 +447,12 @@ codeunit 87 \"Blanket Sales Order to Order\"\n ItemCheckAvail.RaiseUpdateInterruptedError();\n end;\n \n- local procedure IsSalesOrderLineToBeInserted(SalesOrderLine: Record \"Sales Line\"): Boolean\n- var\n- AttachedToSalesLine: Record \"Sales Line\";\n+ local procedure IsSalesOrderLineToBeInserted(SalesOrderLine: Record \"Sales Line\"; BlanketSalesOrderLine: Record \"Sales Line\"): Boolean\n begin\n if not SalesOrderLine.IsExtendedText() then\n exit(true);\n- exit(\n- AttachedToSalesLine.Get(\n- SalesOrderLine.\"Document Type\", SalesOrderLine.\"Document No.\", SalesOrderLine.\"Attached to Line No.\"));\n+\n+ exit(BlanketSalesOrderLine.\"Attached to Line No.\" <> 0);\n end;\n \n [IntegrationEvent(false, false)]\n"} +{"metadata": {"area": "project", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209450", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-03-10", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136302, "functionName": ["PurchaseLineNotReservedWhenItemTypeNonInventoryOrService"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al b/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al\nindex 4e0f927efe26..2324fe2d413a 100644\n--- a/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobConsumptionPurchase.Codeunit.al\n@@ -4339,6 +4339,73 @@ codeunit 136302 \"Job Consumption Purchase\"\n JobLedgerEntry.TestField(\"Lot No.\", LotNo);\n end;\n \n+ [Test]\n+ [HandlerFunctions('PurchaseOrderReserveFromCurrentLineHandler2')]\n+ procedure PurchaseLineNotReservedWhenItemTypeNonInventoryOrService()\n+ var\n+ Item: array[3] of Record Item;\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ JobTask: Record \"Job Task\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ PurchaseOrder: TestPage \"Purchase Order\";\n+ i: Integer;\n+ Quantity: Decimal;\n+ begin\n+ // [SCENARIO 563482] Verify that it is not possible to reserve a sales line when the item type is Non-Inventory or Service.\n+ Initialize();\n+ Quantity := LibraryRandom.RandIntInRange(100, 200);\n+\n+ // [GIVEN] Create Inventory, Non Inventory & Service type item.\n+ LibraryInventory.CreateItem(Item[1]);\n+ LibraryInventory.CreateNonInventoryTypeItem(Item[2]);\n+ LibraryInventory.CreateServiceTypeItem(Item[3]);\n+\n+ // [GIVEN] Create Job and Job Task.\n+ CreateJobWithJobTask(JobTask);\n+\n+ // [GIVEN] Create Purchase Header.\n+ LibraryPurchase.CreatePurchHeader(\n+ PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, LibraryPurchase.CreateVendorNo());\n+\n+ // [GIVEN] Set the Work Date to be later than the Purchase Document date.\n+ WorkDate := WorkDate() + 1;\n+\n+ for i := 1 to LibraryRandom.RandIntInRange(3, 3) do begin\n+ // [GIVEN] Create a job planning line for Inventory, Non-Inventory, and Service type items.\n+ CreateJobPlanningLine(\n+ JobPlanningLine, JobTask, JobPlanningLine.Type::Item, Item[i].\"No.\", Quantity, true);\n+ JobPlanningLine.Validate(Reserve, JobPlanningLine.Reserve::Optional);\n+ JobPlanningLine.Validate(\"Unit Cost\", LibraryRandom.RandDec(1000, 2));\n+ JobPlanningLine.Modify(true);\n+\n+ // [GIVEN] Create a purchase line for Inventory, Non-Inventory, and Service type items.\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item[i].\"No.\", Quantity);\n+\n+ Commit();\n+ // [GIVEN] Open Purchase Order Page\n+ PurchaseOrder.OpenEdit();\n+ PurchaseOrder.Filter.SetFilter(\"No.\", PurchaseHeader.\"No.\");\n+ PurchaseOrder.PurchLines.Filter.SetFilter(\"No.\", Item[i].\"No.\");\n+\n+ // [WHEN] Item type Inventory\n+ if Item[i].IsInventoriableType() then\n+ PurchaseOrder.PurchLines.Reserve.Invoke()\n+ else\n+ asserterror PurchaseOrder.PurchLines.Reserve.Invoke();\n+ PurchaseOrder.Close();\n+ end;\n+\n+ // [GIVEN] Post the Purchase Document\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false);\n+\n+ // [THEN] Verify Remaining Quantity on Item Ledger Entry.\n+ VerifyItemLedgerEntry(Item[1], Quantity); // Item Type Inventory.\n+ VerifyItemLedgerEntry(Item[2], 0); // Item Type Non Inventory.\n+ VerifyItemLedgerEntry(Item[3], 0); // Item Type Service.\n+ end;\n+\n local procedure Initialize()\n var\n WarehouseEmployee: Record \"Warehouse Employee\";\n@@ -6702,6 +6769,14 @@ codeunit 136302 \"Job Consumption Purchase\"\n CreateInvtPutawayPickMvmt.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PurchaseOrderReserveFromCurrentLineHandler2(var Reservation: TestPage Reservation)\n+ begin\n+ Reservation.\"Reserve from Current Line\".Invoke();\n+ Reservation.OK().Invoke();\n+ end;\n+\n local procedure UndoPurchReciptAndAdjustCostItemEntries(var PurchaseLine: Record \"Purchase Line\"; var Item: Record Item)\n begin\n UndoPurchRcpt(PurchaseLine);\n@@ -6790,5 +6865,20 @@ codeunit 136302 \"Job Consumption Purchase\"\n PostedWhseReceiptLine.SetRange(\"Source Line No.\", PurchaseLine.\"Line No.\");\n PostedWhseReceiptLine.FindFirst();\n end;\n+\n+ local procedure VerifyItemLedgerEntry(Item: Record Item; Quantity: Decimal)\n+ var\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ begin\n+ ItemLedgerEntry.SetRange(\"Item No.\", Item.\"No.\");\n+ ItemLedgerEntry.FindFirst();\n+ ItemLedgerEntry.CalcFields(\"Reserved Quantity\");\n+ if Item.IsInventoriableType() then\n+ Assert.AreEqual(ItemLedgerEntry.\"Reserved Quantity\", Quantity,\n+ StrSubstNo(ValueMustMatchErr, ItemLedgerEntry.\"Reserved Quantity\", Quantity))\n+ else\n+ Assert.AreEqual(ItemLedgerEntry.\"Reserved Quantity\", Quantity,\n+ StrSubstNo(ValueMustMatchErr, ItemLedgerEntry.\"Reserved Quantity\", Quantity))\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al\nindex bd599bfee8d8..b3988a5302d9 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLineReserve.Codeunit.al\n@@ -10,10 +10,11 @@ using Microsoft.Inventory.Planning;\n using Microsoft.Inventory.Requisition;\n using Microsoft.Inventory.Tracking;\n using Microsoft.Inventory.Ledger;\n-using Microsoft.Projects.Project.Job;\n using Microsoft.Foundation.Navigate;\n using Microsoft.Foundation.UOM;\n+using Microsoft.Projects.Project.Job;\n using Microsoft.Projects.Project.Ledger;\n+using Microsoft.Purchases.Document;\n \n codeunit 1032 \"Job Planning Line-Reserve\"\n {\n@@ -37,6 +38,7 @@ codeunit 1032 \"Job Planning Line-Reserve\"\n InvalidLineTypeErr: Label 'must be %1 or %2', Comment = '%1 and %2 are line type options, fx. Budget or Billable';\n SummaryTypeTxt: Label '%1, %2', Locked = true;\n SourceDoc2Txt: Label '%1 %2', Locked = true;\n+ NonInvReserveTypeErr: Label 'Non-inventory and service items cannot be reserved.';\n \n procedure CreateReservation(JobPlanningLine: Record \"Job Planning Line\"; Description: Text[100]; ExpectedReceiptDate: Date; Quantity: Decimal; QuantityBase: Decimal; ForReservEntry: Record \"Reservation Entry\")\n var\n@@ -848,6 +850,7 @@ codeunit 1032 \"Job Planning Line-Reserve\"\n if IsReserved then\n exit;\n \n+ CheckItemType(CalcReservEntry);\n JobPlanningLine.SetAutoCalcFields(\"Reserved Qty. (Base)\");\n JobPlanningLine.FilterLinesForReservation(\n CalcReservEntry, ReservSummEntryNo - 131, sender.GetAvailabilityFilter(AvailabilityDate), Positive);\n@@ -873,6 +876,23 @@ codeunit 1032 \"Job Planning Line-Reserve\"\n until (JobPlanningLine.Next(NextStep) = 0) or (RemainingQtyToReserveBase = 0);\n end;\n \n+ local procedure CheckItemType(CalcReservEntry: Record \"Reservation Entry\")\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ if (CalcReservEntry.\"Source Type\" <> Database::\"Purchase Line\") or (CalcReservEntry.\"Source Subtype\" <> CalcReservEntry.\"Source Subtype\"::\"1\") then\n+ exit;\n+\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseLine.\"Document Type\"::Order);\n+ PurchaseLine.SetRange(\"Document No.\", CalcReservEntry.\"Source ID\");\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);\n+ PurchaseLine.SetRange(\"No.\", CalcReservEntry.\"Item No.\");\n+ PurchaseLine.SetRange(\"Special Order\", false);\n+ if PurchaseLine.FindFirst() then\n+ if PurchaseLine.IsNonInventoriableItem() then\n+ Error(NonInvReserveTypeErr);\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterReservQuantity(JobPlanningLine: Record \"Job Planning Line\"; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)\n begin\n"} {"metadata": {"area": "shopify", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-201169", "base_commit": "2fe81026ed3d6c42bfc6e4de6a3c71b2f8fd3726", "created_at": "2024-11-26", "environment_setup_version": "26.0", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139581, "functionName": ["UnitTestLogItemEmptyDescription"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al b/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al\nindex 60adc2f06fad..063e50b4cbc1 100644\n--- a/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al\n+++ b/App/Apps/W1/Shopify/test/Logs/ShpfySkippedRecordLogTest.Codeunit.al\n@@ -91,6 +91,35 @@ codeunit 139581 \"Shpfy Skipped Record Log Test\"\n LibraryAssert.AreEqual('Item is blocked or sales blocked.', SkippedRecord.\"Skipped Reason\", 'Skipped reason is not as expected');\n end;\n \n+ [Test]\n+\n+ [HandlerFunctions('AddItemToShopifyHandler')]\n+ procedure UnitTestLogItemEmptyDescription()\n+ var\n+\n+ Item: Record Item;\n+ SkippedRecord: Record \"Shpfy Skipped Record\";\n+ AddItemToShopify: Report \"Shpfy Add Item to Shopify\";\n+ begin\n+ // [SCENARIO] Log skipped record when item description is empty\n+ Initialize();\n+\n+ // [GIVEN] An item record that has empty description\n+ CreateItem(Item);\n+ Commit();\n+\n+ // [WHEN] Run report Add Items to Shopify\n+ Item.SetRange(\"No.\", Item.\"No.\");\n+ AddItemToShopify.SetShop(Shop.Code);\n+ AddItemToShopify.SetTableView(Item);\n+ AddItemToShopify.Run();\n+\n+ // [THEN] Related record is created in shopify skipped record table\n+ SkippedRecord.SetRange(\"Record ID\", Item.RecordId);\n+ LibraryAssert.IsTrue(SkippedRecord.FindFirst(), 'Skipped record is not created');\n+ LibraryAssert.AreEqual('Item description is empty.', SkippedRecord.\"Skipped Reason\", 'Skipped reason is not as expected');\n+ end;\n+\n [Test]\n procedure UnitTestLogItemVariantBlocked()\n var\n@@ -841,13 +870,19 @@ codeunit 139581 \"Shpfy Skipped Record Log Test\"\n SalesShipmentLine.Insert(false);\n end;\n \n- local procedure CreateBlockedItem(var Item: Record Item)\n+ local procedure CreateItem(var Item: Record Item)\n begin\n Item.Init();\n Item.\"No.\" := Any.AlphanumericText(20);\n+ Item.Insert(false);\n+ end;\n+\n+ local procedure CreateBlockedItem(var Item: Record Item)\n+ begin\n+ CreateItem(Item);\n Item.Blocked := true;\n Item.\"Sales Blocked\" := true;\n- Item.Insert(false);\n+ Item.Modify(false);\n end;\n \n local procedure CreateBlockedItemVariant(Item: Record Item; var ItemVariant: Record \"Item Variant\")\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al b/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al\nindex 38d77856d51a..965c1f8db398 100644\n--- a/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al\n+++ b/App/Apps/W1/Shopify/app/src/Products/Codeunits/ShpfyCreateProduct.Codeunit.al\n@@ -57,7 +57,9 @@ codeunit 30174 \"Shpfy Create Product\"\n ProductId := ProductApi.CreateProduct(TempShopifyProduct, TempShopifyVariant, TempShopifyTag)\n else\n ProductId := TempShopifyProduct.Id;\n- ProductExport.UpdateProductTranslations(ProductId, Item);\n+\n+ if ProductId <> 0 then\n+ ProductExport.UpdateProductTranslations(ProductId, Item);\n end;\n \n internal procedure CreateTempProduct(Item: Record Item; var TempShopifyProduct: Record \"Shpfy Product\" temporary; var TempShopifyVariant: Record \"Shpfy Variant\" temporary; var TempShopifyTag: Record \"Shpfy Tag\" temporary)\ndiff --git a/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al b/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al\nindex b99f15d3c8bc..7ede7561af67 100644\n--- a/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al\n+++ b/App/Apps/W1/Shopify/app/src/Products/Reports/ShpfyAddItemtoShopify.Report.al\n@@ -57,18 +57,24 @@ report 30106 \"Shpfy Add Item to Shopify\"\n var\n SkippedRecord: Codeunit \"Shpfy Skipped Record\";\n begin\n- if Item.Blocked or Item.\"Sales Blocked\" then\n- SkippedRecord.LogSkippedRecord(Item.RecordId, ItemIsBlockedLbl, ShopifyShop)\n- else begin\n- if GuiAllowed then begin\n- CurrItemNo := Item.\"No.\";\n- ProcessDialog.Update();\n- end;\n+ if Item.Blocked or Item.\"Sales Blocked\" then begin\n+ SkippedRecord.LogSkippedRecord(Item.RecordId, ItemIsBlockedLbl, ShopifyShop);\n+ exit;\n+ end;\n \n- ShopifyCreateProduct.Run(Item);\n+ if Item.Description = '' then begin\n+ SkippedRecord.LogSkippedRecord(Item.RecordId, ItemDescriptionIsEmptyLbl, ShopifyShop);\n+ exit;\n+ end;\n \n- ProductFilter += Format(ShopifyCreateProduct.GetProductId()) + '|';\n+ if GuiAllowed then begin\n+ CurrItemNo := Item.\"No.\";\n+ ProcessDialog.Update();\n end;\n+\n+ ShopifyCreateProduct.Run(Item);\n+\n+ ProductFilter += Format(ShopifyCreateProduct.GetProductId()) + '|';\n end;\n \n trigger OnPostDataItem()\n@@ -190,6 +196,7 @@ report 30106 \"Shpfy Add Item to Shopify\"\n ChangeDefaultLocationLbl: Label 'Change default location';\n ChangeSKUMappingLbl: Label 'Change SKU mapping';\n ItemIsBlockedLbl: Label 'Item is blocked or sales blocked.';\n+ ItemDescriptionIsEmptyLbl: Label 'Item description is empty.';\n \n /// \n /// Set Shop.\n"} +{"metadata": {"area": "inventory", "image_count": 10}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209835", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-12", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137045, "functionName": ["CarryOutPlanWkshActionMsgFilterCheckGenerateLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\nindex 70e088d9fb0c..6032fbc7e22b 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBugfixes.Codeunit.al\n@@ -35,6 +35,7 @@ codeunit 137045 \"SCM Bugfixes\"\n WrongSKUUnitCostErr: Label 'Stockkeeping unit''s unit cost must be equal to item unit cost';\n EmailNotAutomaticallySetErr: Label 'Expected BuyFromContactEmail to automatically be set to the email of the contact, but it wasnt.';\n UseInTransitLocationErr: Label 'You can use In-Transit location %1 for transfer orders only.', Comment = '%1: Location code';\n+ PurchaseOrderErr: Label 'Unexpected new purchase order created';\n \n [Test]\n [Scope('OnPrem')]\n@@ -929,6 +930,53 @@ codeunit 137045 \"SCM Bugfixes\"\n OpenOrderPromisingPage(SalesHeader.\"No.\")\n end;\n \n+ [Test]\n+ procedure CarryOutPlanWkshActionMsgFilterCheckGenerateLines()\n+ var\n+ Item: Record Item;\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ ReqLine: Record \"Requisition Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ NewPurchOrderChoice: Option \" \",\"Make Purch. Orders\",\"Make Purch. Orders & Print\",\"Copy to Req. Wksh\";\n+ ActualCount: Integer;\n+ begin\n+ // [SCENARIO 563852] When a Filter is set in the Planning Worksheet to a specific Action Message (e.g. Cancel) , Carry Out Action Message Only Process\n+ // Filtered Planning Worksheet Lines.\n+ Initialize();\n+\n+ // [GIVEN] New Item Created with Reordering Policy Order.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Reordering Policy\", Item.\"Reordering Policy\"::Order);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Created New Purchase Order with New Item with 4 Qty.\n+ CreatePurchaseOrder(PurchaseHeader, Item.\"No.\", 4);\n+\n+ // [GIVEN] Created New Sales Order with New Item with 4 Qty and Future Shipment Date.\n+ CreateSalesOrder(SalesHeader, Item.\"No.\", '', 4, SalesHeader.\"Document Type\"::Order);\n+ SalesLine.Get(SalesLine.\"Document Type\"::Order, SalesHeader.\"No.\", 10000);\n+ SalesLine.Validate(\"Shipment Date\", CalcDate('<1W>', WorkDate()));\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Calculate regenerative plan in planning worksheet update Planning Worksheet.\n+ CalculatePlanOnPlanningWorksheet(Item, WorkDate(), CalcDate('<1Y>', WorkDate()), true, false);\n+\n+ // [GIVEN] Set \"Accept Action Message\" on all Requisition lines.\n+ UpdatePlanningWorkSheetwithVendor(ReqLine, Item.\"No.\", PurchaseHeader.\"Buy-from Vendor No.\");\n+\n+ // [WHEN] Running Carry Out Action Message For Requisition lines \"Action Message\"::Cancel.\n+ ReqLine.SetRange(\"Action Message\", ReqLine.\"Action Message\"::Cancel);\n+ LibraryPlanning.CarryOutPlanWksh(ReqLine, 0, NewPurchOrderChoice::\"Make Purch. Orders\", 0, 0, '', '', '', '');\n+\n+ // [WHEN] Count Actual Purchase Lines.\n+ CountActualPurchaseLine(Item, PurchaseLine, ActualCount);\n+\n+ // [THEN] Verify Actual Count Match with Expected Result.\n+ Assert.AreEqual(0, ActualCount, PurchaseOrderErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1547,6 +1595,50 @@ codeunit 137045 \"SCM Bugfixes\"\n SalesOrder.SalesLines.OrderPromising.Invoke();\n end;\n \n+ local procedure CountActualPurchaseLine(Item: Record Item; PurchaseLine: Record \"Purchase Line\"; var ActualCount: Integer)\n+ begin\n+ Clear(ActualCount);\n+ PurchaseLine.Reset();\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseLine.\"Document Type\"::Order);\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);\n+ PurchaseLine.SetRange(\"No.\", Item.\"No.\");\n+ if PurchaseLine.FindSet() then\n+ ActualCount := PurchaseLine.Count;\n+ end;\n+\n+ local procedure CalculatePlanOnPlanningWorksheet(var ItemRec: Record Item; OrderDate: Date; ToDate: Date; RespectPlanningParameters: Boolean; Regenerative: Boolean)\n+ var\n+ TmpItemRec: Record Item;\n+ RequisitionWkshName: Record \"Requisition Wksh. Name\";\n+ CalculatePlanPlanWksh: Report \"Calculate Plan - Plan. Wksh.\";\n+ begin\n+ LibraryPlanning.SelectRequisitionWkshName(RequisitionWkshName, RequisitionWkshName.\"Template Type\"::Planning); // Find Requisition Worksheet Name to Calculate Plan.\n+ Commit();\n+ CalculatePlanPlanWksh.InitializeRequest(OrderDate, ToDate, RespectPlanningParameters, true, true, '', 0D, false);\n+ CalculatePlanPlanWksh.SetTemplAndWorksheet(RequisitionWkshName.\"Worksheet Template Name\", RequisitionWkshName.Name, Regenerative);\n+ if ItemRec.HasFilter then\n+ TmpItemRec.CopyFilters(ItemRec)\n+ else begin\n+ ItemRec.Get(ItemRec.\"No.\");\n+ TmpItemRec.SetRange(\"No.\", ItemRec.\"No.\");\n+ end;\n+ CalculatePlanPlanWksh.SetTableView(TmpItemRec);\n+ CalculatePlanPlanWksh.UseRequestPage(false);\n+ CalculatePlanPlanWksh.RunModal();\n+ end;\n+\n+ local procedure UpdatePlanningWorkSheetwithVendor(var RequisitionLine: Record \"Requisition Line\"; ItemNo: Code[20]; VendorNo: Code[20])\n+ begin\n+ RequisitionLine.SetRange(Type, RequisitionLine.Type::Item);\n+ RequisitionLine.SetRange(\"No.\", ItemNo);\n+ RequisitionLine.FindSet();\n+ repeat\n+ RequisitionLine.Validate(\"Vendor No.\", VendorNo);\n+ RequisitionLine.Validate(\"Accept Action Message\", true);\n+ RequisitionLine.Modify(true);\n+ until RequisitionLine.Next() = 0;\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure ContactListModalPageHandler(var ContactLookup: Page \"Contact List\"; var Response: Action)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al\nindex ef8b6ccb7c96..e302df62ef99 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutActionMsgPlan.Report.al\n@@ -469,8 +469,10 @@ report 99001020 \"Carry Out Action Msg. - Plan.\"\n \"Requisition Line\".SetRange(\"Worksheet Template Name\", CurrReqWkshTemp);\n if CurrReqWkshTemp <> '' then\n \"Requisition Line\".SetRange(\"Journal Batch Name\", CurrReqWkshName);\n+ \"Requisition Line\".FilterGroup(2);\n \"Requisition Line\".SetRange(Type, \"Requisition Line\".Type::Item);\n \"Requisition Line\".SetFilter(\"Action Message\", '<>%1', \"Requisition Line\".\"Action Message\"::\" \");\n+ \"Requisition Line\".FilterGroup(0);\n OnAfterSetReqLineFilters(\"Requisition Line\");\n end;\n \n"} +{"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-211548", "base_commit": "90ae5af1c2b3627dcfb41b03c59fe32ddec31c6d", "created_at": "2025-03-28", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\General Journal"], "FAIL_TO_PASS": [{"codeunitID": 134832, "functionName": ["GeneralJournalPostingWithMultipleAllocationAccountLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al b/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al\nindex c48ce3167512..fd84cef1d0ad 100644\n--- a/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al\n+++ b/App/Layers/W1/Tests/General Journal/AllocAccJounralE2ETests.Codeunit.al\n@@ -1362,9 +1362,52 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n VerifyGLEntryAmount(GLEntry, 0, 1);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerTrue,MessageHandler,GeneralJournalTemplateHandler')]\n+ procedure GeneralJournalPostingWithMultipleAllocationAccountLines()\n+ var\n+ DestinationGLAccount: Record \"G/L Account\";\n+ BalancingGLAccount: Record \"G/L Account\";\n+ AllocationAccount: array[2] of Record \"Allocation Account\";\n+ GLEntry: Record \"G/L Entry\";\n+ GeneralJournalPage: TestPage \"General Journal\";\n+ DocumentNumber: Code[10];\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO 569036] Issue with posting General Journals that contain Allocation Account lines with 10 entries resulting an error\n+ Initialize();\n+\n+ // [GIVEN] Create Destination and Balancing G/L Account\n+ DestinationGLAccount.Get(LibraryERM.CreateGLAccountNoWithDirectPosting());\n+ BalancingGLAccount.Get(LibraryERM.CreateGLAccountNoWithDirectPosting());\n+\n+ // [GIVEN] An Allocation Account with variable GL distributions\n+ CreateAllocationAccountwithSpecificNoOfFixedGLDistributionLines(AllocationAccount[1], DestinationGLAccount, LibraryRandom.RandIntInRange(10, 10));\n+ CreateAllocationAccountwithSpecificNoOfFixedGLDistributionLines(AllocationAccount[2], DestinationGLAccount, LibraryRandom.RandIntInRange(10, 10));\n+ Amount := LibraryRandom.RandDecInDecimalRange(10000, 10000, 0);\n+\n+ // [GIVEN] The General Journal line with Allocation Account\n+ CreateBalancingLinesOnGeneralJournalWithTwoAllocationAccount(\n+ DocumentNumber,\n+ GeneralJournalPage,\n+ AllocationAccount,\n+ BalancingGLAccount.\"No.\",\n+ Amount);\n+\n+ // [WHEN] The General Journal line is posted\n+ GeneralJournalPage.Post.Invoke();\n+\n+ // [THEN] Verify the General Journal Posted Successfylly\n+ GLEntry.SetRange(\"Document No.\", DocumentNumber);\n+ GLEntry.SetRange(\"G/L Account No.\", DestinationGLAccount.\"No.\");\n+ Assert.AreEqual(20, GLEntry.Count(), 'Wrong number of G/L Entries created for the destination account');\n+ GLEntry.CalcSums(Amount);\n+ Assert.AreEqual(Amount, GLEntry.Amount, 'The rounding amount was not distributed correctly');\n+ end;\n+\n local procedure CreateLineOnCashReceiptJournal(var DocumentNumber: Code[10]; var CashReceiptJournalPage: TestPage \"Cash Receipt Journal\"; AccountType: Enum \"Gen. Journal Account Type\"; AccountNo: Code[20];\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20])\n var\n GenJournalBatch: Record \"Gen. Journal Batch\";\n GenJournalTemplateType: Enum \"Gen. Journal Template Type\";\n@@ -1405,8 +1448,8 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n end;\n \n local procedure CreateLineOnSalesJournal(var DocumentNumber: Code[10]; var SalesJournalPage: TestPage \"Sales Journal\"; AccountType: Enum \"Gen. Journal Account Type\"; AccountNo: Code[20];\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20])\n var\n GenJournalBatch: Record \"Gen. Journal Batch\";\n GenJournalTemplateType: Enum \"Gen. Journal Template Type\";\n@@ -1429,8 +1472,8 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n end;\n \n local procedure CreateLineOnPurchaseJournal(var DocumentNumber: Code[10]; var PurchaseJournalPage: TestPage \"Purchase Journal\"; AccountType: Enum \"Gen. Journal Account Type\"; AccountNo: Code[20];\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20])\n var\n GenJournalBatch: Record \"Gen. Journal Batch\";\n GenJournalTemplateType: Enum \"Gen. Journal Template Type\";\n@@ -1869,15 +1912,15 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n var GenJournalLine: Record \"Gen. Journal Line\";\n AccountNo: Code[20];\n AccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountType: Enum \"Gen. Journal Account Type\";\n- BalancingAccountNo: Code[20];\n- Amount: Decimal;\n- DocumentNo: Code[20];\n- GenJournalBatch: Record \"Gen. Journal Batch\";\n- VATBusPostingGroup: Code[20];\n- VATProdPostingGroup: Code[20];\n- CurrencyCode: Code[20];\n- SelectedAllocAccountNo: Code[20])\n+ BalancingAccountType: Enum \"Gen. Journal Account Type\";\n+ BalancingAccountNo: Code[20];\n+ Amount: Decimal;\n+ DocumentNo: Code[20];\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ VATBusPostingGroup: Code[20];\n+ VATProdPostingGroup: Code[20];\n+ CurrencyCode: Code[20];\n+ SelectedAllocAccountNo: Code[20])\n begin\n LibraryJournals.CreateGenJournalLine(\n GenJournalLine,\n@@ -1898,6 +1941,59 @@ codeunit 134832 \"Alloc. Acc. Jounral E2E Tests\"\n GenJournalLine.Modify(true);\n end;\n \n+ local procedure CreateAllocationAccountwithSpecificNoOfFixedGLDistributionLines(\n+ var AllocationAccount: Record \"Allocation Account\";\n+ DestinationGLAccount: Record \"G/L Account\"; NoOfFixedAccountDistributionLines: Integer)\n+ var\n+ AllocationAccountPage: TestPage \"Allocation Account\";\n+ FixedAllocationAccountCode: Code[20];\n+ i: Integer;\n+ begin\n+ FixedAllocationAccountCode := CreateAllocationAccountWithFixedDistribution(AllocationAccountPage);\n+\n+ for i := 1 to NoOfFixedAccountDistributionLines do begin\n+ AddGLDestinationAccountForFixedDistribution(AllocationAccountPage, DestinationGLAccount);\n+ AllocationAccountPage.FixedAccountDistribution.Share.SetValue(LibraryRandom.RandDecInDecimalRange(10, 10, 0));\n+ if i <> NoOfFixedAccountDistributionLines then\n+ AllocationAccountPage.FixedAccountDistribution.New();\n+ end;\n+ AllocationAccountPage.Close();\n+\n+ AllocationAccount.Get(FixedAllocationAccountCode);\n+ end;\n+\n+ local procedure CreateBalancingLinesOnGeneralJournalWithTwoAllocationAccount(\n+ var DocumentNumber: Code[10];\n+ var GeneralJournalPage: TestPage \"General Journal\";\n+ AllocationAccount: array[2] of Record \"Allocation Account\";\n+ BalancingAccountNo: Code[20];\n+ Amount: Decimal)\n+ var\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ AccountType: Enum \"Gen. Journal Account Type\";\n+ i: Integer;\n+ begin\n+ CreateGeneralJournalBatch(GenJournalBatch);\n+ LibraryVariableStorage.Enqueue(GenJournalBatch.\"Journal Template Name\");\n+ GeneralJournalPage.OpenEdit();\n+ DocumentNumber := LibraryRandom.RandText(10);\n+ GeneralJournalPage.\"Document No.\".SetValue(DocumentNumber);\n+ GeneralJournalPage.\"Account Type\".SetValue(AccountType::\"G/L Account\");\n+ GeneralJournalPage.\"Account No.\".SetValue(BalancingAccountNo);\n+ GeneralJournalPage.Description.SetValue(DocumentNumber);\n+ GeneralJournalPage.Amount.SetValue(-Amount);\n+\n+ for i := 1 to ArrayLen(AllocationAccount) do begin\n+ GeneralJournalPage.New();\n+ GeneralJournalPage.\"Document No.\".SetValue(DocumentNumber);\n+ GeneralJournalPage.\"Account Type\".SetValue(AccountType::\"Allocation Account\");\n+ GeneralJournalPage.\"Account No.\".SetValue(AllocationAccount[i].\"No.\");\n+ GeneralJournalPage.Description.SetValue(DocumentNumber);\n+ GeneralJournalPage.Amount.SetValue(Amount / 2);\n+\n+ end;\n+ end;\n+\n [ModalPageHandler]\n procedure HandleEditDimensionSetEntriesPage(var EditDimensionSetEntriesPage: TestPage \"Edit Dimension Set Entries\")\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al b/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al\nindex fbe1c90d5d49..5d91bbcfd787 100644\n--- a/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/AllocationAccount/GenJournalAllocAccMgt.Codeunit.al\n@@ -470,13 +470,13 @@ codeunit 2677 \"Gen. Journal Alloc. Acc. Mgt.\"\n exit(-1);\n \n if Increment >= 1000 then\n- exit(1000);\n+ exit(100);\n \n if Increment >= 100 then\n- exit(100);\n+ exit(10);\n \n if Increment >= 10 then\n- exit(10);\n+ exit(1);\n \n exit(Increment);\n end;\n"} +{"metadata": {"area": "sales", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-209737", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-12", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137408, "functionName": ["InvDiscPctAndAmtInSOIsNotZeroWhenCreateAndShipInvPickFromSOHavingInvDiscPctAndAmt"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al\nindex c2a61ccd9648..7e9f79d98dc2 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseVI.Codeunit.al\n@@ -38,6 +38,7 @@ codeunit 137408 \"SCM Warehouse VI\"\n AbsoluteValueEqualToQuantityErr: Label 'Absolute value of %1.%2 must be equal to the test quantity.', Comment = '%1 - tablename, %2 - fieldname.';\n RegisteringPickInterruptedErr: Label 'Registering pick has been interrupted.';\n LotNoNotAvailableInInvtErr: Label 'Lot No. %1 is not available in inventory, it has already been reserved for another document, or the quantity available is lower than the quantity to handle specified on the line.', Comment = '%1: Lot No.';\n+ InvtPickCreatedTxt: Label 'Number of Invt. Pick activities created';\n \n [Test]\n [HandlerFunctions('ItemTrackingLinesHandler,ItemTrackingSummaryHandler,MessageHandler,WhseItemTrackingLinesHandler,ConfirmHandlerTrue')]\n@@ -4143,6 +4144,115 @@ codeunit 137408 \"SCM Warehouse VI\"\n VerifyWarehouseJournalLineWithReasonCode(WarehouseJournalBatch, WarehouseJournalLine, ReasonCode.Code);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ [Scope('OnPrem')]\n+ procedure InvDiscPctAndAmtInSOIsNotZeroWhenCreateAndShipInvPickFromSOHavingInvDiscPctAndAmt()\n+ var\n+ Bin: Record Bin;\n+ Customer: Record Customer;\n+ Item: Record Item;\n+ Location: Record Location;\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ WhseActivityPost: Codeunit \"Whse.-Activity-Post\";\n+ SalesOrder: TestPage \"Sales Order\";\n+ InvDiscountPct: Decimal;\n+ begin\n+ // [SCENARIO 256471] It should not be allowed to change location code in an inventory pick that has lines\n+ Initialize();\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create a Location.\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create a Bin.\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, Bin.Code, '', '');\n+\n+ // [GIVEN] Create a Warehouse Employee.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, true);\n+\n+ // [GIVEN] Create a Customer and Validate \"Currency Code\".\n+ LibrarySales.CreateCustomer(Customer);\n+ Customer.Validate(\"Currency Code\", CreateCurrency());\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Create an Item Journal Line and Post it.\n+ CreateItemJournalLine(ItemJournalLine, Item.\"No.\", Location.Code, LibraryRandom.RandIntInRange(20, 20), WorkDate(), Bin.Code, Item.\"Base Unit of Measure\");\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+\n+ // [GIVEN] Update Work Date.\n+ WorkDate(CalcDate('', WorkDate()));\n+\n+ // [GIVEN] Create a Sales Header.\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ SalesHeader.Validate(\"Currency Factor\", LibraryRandom.RandIntInRange(2, 2));\n+ SalesHeader.Modify(true);\n+\n+ // [GIVEN] Create a Sales Line and Validate \"Location Code\" and \"Unit Price\".\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", LibraryRandom.RandInt(0));\n+ SalesLine.Validate(\"Location Code\", Location.Code);\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandIntInRange(1000, 1000));\n+ SalesLine.Modify(true);\n+\n+ // [GIVEN] Generate and save Invoice Discount % in a Variable.\n+ InvDiscountPct := LibraryRandom.RandIntInRange(10, 10);\n+\n+ // [GIVEN] Open Sales Order page and Set Invoice Disc. Pct.\n+ SalesOrder.OpenEdit();\n+ SalesOrder.GoToRecord(SalesHeader);\n+ SalesOrder.SalesLines.\"Invoice Disc. Pct.\".SetValue(InvDiscountPct);\n+ SalesOrder.Close();\n+\n+ // [GIVEN] Find Sales Header.\n+ SalesHeader.Get(SalesHeader.\"Document Type\", SalesHeader.\"No.\");\n+\n+ // [GIVEN] Release Sales Order.\n+ LibrarySales.ReleaseSalesDocument(SalesHeader);\n+\n+ // [GIVEN] Create Invt. Pick from Sales Order.\n+ LibraryVariableStorage.Enqueue(InvtPickCreatedTxt);\n+ LibraryWarehouse.CreateInvtPutPickMovement(\n+ WarehouseActivityHeader.\"Source Document\"::\"Sales Order\", SalesHeader.\"No.\", false, true, false);\n+\n+ // [GIVEN] Find Warehouse Activity Line.\n+ FindWarehouseActivityLine(\n+ WarehouseActivityLine, WarehouseActivityLine.\"Source Document\"::\"Sales Order\", SalesHeader.\"No.\",\n+ WarehouseActivityLine.\"Activity Type\"::\"Invt. Pick\");\n+\n+ // [GIVEN] Find Warehouse Activity Header and Validate \"Posting Date\".\n+ WarehouseActivityHeader.Get(WarehouseActivityLine.\"Activity Type\", WarehouseActivityLine.\"No.\");\n+ WarehouseActivityHeader.Validate(\"Posting Date\", CalcDate('', WorkDate()));\n+ WarehouseActivityHeader.Modify(true);\n+\n+ // [GIVEN] Validate \"Qty. to Handle\" in Warehouse Activity Line.\n+ WarehouseActivityLine.Validate(\"Qty. to Handle\", WarehouseActivityLine.Quantity);\n+ WarehouseActivityLine.Modify(true);\n+\n+ // [GIVEN] Update Work Date.\n+ WorkDate(WarehouseActivityHeader.\"Posting Date\");\n+\n+ // [GIVEN] Post Inventory Pick.\n+ WhseActivityPost.Run(WarehouseActivityLine);\n+\n+ // [GIVEN] Find Sales Header.\n+ SalesHeader.Get(SalesHeader.\"Document Type\", SalesHeader.\"No.\");\n+\n+ // [WHEN] Open Sales Order page.\n+ SalesOrder.OpenEdit();\n+ SalesOrder.GoToRecord(SalesHeader);\n+\n+ // [THEN] Invoice Disc. Pct. is equal to InvDiscountPct.\n+ SalesOrder.SalesLines.\"Invoice Disc. Pct.\".AssertEquals(InvDiscountPct);\n+ SalesOrder.Close();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -6187,6 +6297,65 @@ codeunit 137408 \"SCM Warehouse VI\"\n RunCalculateCountingPeriodFromWarehousePhysicalInventoryJournalReasonCode(WarehouseJournalBatch, LocationCode, ReasonCode);\n end;\n \n+ local procedure CreateItemJournalLine(var ItemJournalLine: Record \"Item Journal Line\"; ItemNo: Code[20]; LocationCode: Code[10]; Quantity: Decimal; PostingDate: Date; BinCode: Code[20]; UnitOfMeasureCode: Code[10])\n+ begin\n+ LibraryInventory.CreateItemJnlLine(\n+ ItemJournalLine, ItemJournalLine.\"Entry Type\"::Purchase, PostingDate, ItemNo,\n+ Quantity, LocationCode);\n+ ItemJournalLine.Validate(\"Unit of Measure Code\", UnitOfMeasureCode);\n+ if BinCode <> '' then\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n+ local procedure FindWarehouseActivityLine(var WarehouseActivityLine: Record \"Warehouse Activity Line\"; SourceDocument: Enum \"Warehouse Activity Source Document\"; SourceNo: Code[20]; ActivityType: Enum \"Warehouse Activity Type\")\n+ begin\n+ FilterWarehouseActivityLine(WarehouseActivityLine, SourceDocument, SourceNo, ActivityType);\n+ WarehouseActivityLine.FindFirst();\n+ end;\n+\n+ local procedure FilterWarehouseActivityLine(var WarehouseActivityLine: Record \"Warehouse Activity Line\"; SourceDocument: Enum \"Warehouse Activity Source Document\"; SourceNo: Code[20]; ActivityType: Enum \"Warehouse Activity Type\")\n+ begin\n+ WarehouseActivityLine.SetRange(\"Source Document\", SourceDocument);\n+ if SourceNo <> '' then\n+ WarehouseActivityLine.SetRange(\"Source No.\", SourceNo);\n+ WarehouseActivityLine.SetRange(\"Activity Type\", ActivityType);\n+ end;\n+\n+ local procedure CreateCurrency(): Code[10]\n+ var\n+ Currency: Record Currency;\n+ begin\n+ LibraryERM.CreateCurrency(Currency);\n+ LibraryERM.SetCurrencyGainLossAccounts(Currency);\n+ Currency.Validate(\"Residual Gains Account\", Currency.\"Realized Gains Acc.\");\n+ Currency.Validate(\"Residual Losses Account\", Currency.\"Realized Losses Acc.\");\n+ Currency.Validate(\"Currency Factor\", LibraryRandom.RandDecInDecimalRange(1.176471, 1.176471, 0));\n+ Currency.Modify(true);\n+ CreateCurrExchangeRate(Currency.Code, CalcDate('', WorkDate()), LibraryRandom.RandDecInDecimalRange(0.5, 0.5, 0));\n+ CreateCurrExchangeRate(Currency.Code, CalcDate('', WorkDate()), LibraryRandom.RandDecInDecimalRange(0.75, 0.75, 0));\n+ CreateCurrExchangeRate(Currency.Code, CalcDate('', WorkDate()), LibraryRandom.RandDecInDecimalRange(0.85, 0.85, 0));\n+ exit(Currency.Code);\n+ end;\n+\n+ procedure CreateCurrExchangeRate(CurrencyCode: Code[10]; StartingDate: Date; RelExchRateAmt: Decimal)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ CurrencyExchangeRate.Init();\n+ CurrencyExchangeRate.Validate(\"Currency Code\", CurrencyCode);\n+ CurrencyExchangeRate.Validate(\"Starting Date\", StartingDate);\n+ CurrencyExchangeRate.Insert(true);\n+\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", LibraryRandom.RandDecInDecimalRange(1.0, 1.0, 0));\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", LibraryRandom.RandDecInDecimalRange(1.0, 1.0, 0));\n+\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", RelExchRateAmt);\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", RelExchRateAmt);\n+ CurrencyExchangeRate.Validate(\"Fix Exchange Rate Amount\", CurrencyExchangeRate.\"Fix Exchange Rate Amount\"::Currency);\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Whse.-Activity-Register\", 'OnBeforeAutoReserveForSalesLine', '', false, false)]\n local procedure InvokeErrorOnRegisteringWarehousePick(var TempWhseActivLineToReserve: Record \"Warehouse Activity Line\" temporary; var IsHandled: Boolean)\n begin\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\nindex 46625d5d87be..a6b8616014e4 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n@@ -4483,7 +4483,8 @@ table 36 \"Sales Header\"\n SalesLine.Validate(\"Shipment Date\", \"Shipment Date\");\n FieldNo(\"Currency Factor\"):\n if SalesLine.Type <> SalesLine.Type::\" \" then begin\n- SalesLine.Validate(\"Unit Price\");\n+ if SalesLine.\"Line Discount %\" <> 0 then\n+ SalesLine.Validate(\"Unit Price\");\n SalesLine.Validate(\"Unit Cost (LCY)\");\n if SalesLine.\"Job No.\" <> '' then\n JobTransferLine.FromSalesHeaderToPlanningLine(SalesLine, \"Currency Factor\");\n"} +{"metadata": {"area": "crm", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-211521", "base_commit": "b626cb16a65cd529d91527d1d5dac501d6ecb06e", "created_at": "2025-03-28", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Marketing"], "FAIL_TO_PASS": [{"codeunitID": 136201, "functionName": ["TaskListPageHasFixedSystemTaskTypeFilterAsOrganiserOrContactAttendee"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al b/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al\nindex 415be9b03958..5d64f93de20a 100644\n--- a/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al\n+++ b/App/Layers/W1/Tests/Marketing/MarketingContacts.Codeunit.al\n@@ -6029,6 +6029,39 @@ codeunit 136201 \"Marketing Contacts\"\n Assert.AreEqual(VerifyInteractionLogEntry.\"Duration (Min.)\", DurationMin, ValueMustMatch);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ModalPageHandlerForTask')]\n+ procedure TaskListPageHasFixedSystemTaskTypeFilterAsOrganiserOrContactAttendee()\n+ var\n+ Contact: Record Contact;\n+ Task: Record \"To-do\";\n+ TempTask: Record \"To-do\" temporary;\n+ ContactCard: TestPage \"Contact Card\";\n+ TaskList: TestPage \"Task List\";\n+ begin\n+ // [SCENARIO 568324] Task List page has a fixed System Task Type filter as 'Organizer|Contact Attendee' when Next Task Date Drilldown on Contact card\n+ Initialize();\n+\n+ // [GIVEN] Create Contact\n+ LibraryMarketing.CreateCompanyContact(Contact);\n+\n+ // [GIVEN] Create Task for Contact\n+ Task.SetRange(\"Contact No.\", Contact.\"No.\");\n+ TempTask.CreateTaskFromTask(Task);\n+\n+ // [WHEN] Open Contact Card and Drilldonw 'Next Task Date' also Trap Task List\n+ ContactCard.OpenView();\n+ ContactCard.GoToRecord(Contact);\n+ TaskList.Trap();\n+ ContactCard.\"Next Task Date\".Drilldown();\n+\n+ // [THEN] Verify Correct filter has been set on the page\n+ TaskList.\"Contact No.\".AssertEquals(Contact.\"No.\");\n+ Assert.AreEqual(\n+ StrSubstNo('%1|%2', Task.\"System To-do Type\"::Organizer, Task.\"System To-do Type\"::\"Contact Attendee\"),\n+ TaskList.Filter.GetFilter(\"System To-do Type\"), 'Wrong filter was set');\n+ end;\n+\n local procedure Initialize()\n var\n MarketingSetup: Record \"Marketing Setup\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al b/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al\nindex 0abd1f7a2168..9afd469a9661 100644\n--- a/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al\n+++ b/App/Layers/W1/BaseApp/CRM/Contact/Contact.Table.al\n@@ -567,7 +567,7 @@ table 5050 Contact\n CalcFormula = min(\"To-do\".Date where(\"Contact Company No.\" = field(\"Company No.\"),\n \"Contact No.\" = field(filter(\"Lookup Contact No.\")),\n Closed = const(false),\n- \"System To-do Type\" = const(\"Contact Attendee\")));\n+ \"System To-do Type\" = filter(Organizer | \"Contact Attendee\")));\n Caption = 'Next Task Date';\n Editable = false;\n FieldClass = FlowField;\n"} +{"metadata": {"area": "inventory", "image_count": 13}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213683", "base_commit": "2c11d98aa3150d7339d436f8d55436c71d8219ac", "created_at": "2025-04-21", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134385, "functionName": ["RenameItemNoExistsInValueEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al\nindex 6a941857a14b..e7111913cd47 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesDocument.Codeunit.al\n@@ -55,6 +55,7 @@\n AmountNotMatchedErr: Label 'Amount not matched.';\n AmountMustSameErr: Label 'Amount must be same';\n QtyHandleMustSameErr: Label 'Qty to handle must equal';\n+ CannotRenameItemErr: Label 'You cannot rename %1 in a %2 because it is used in Sales Document lines.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -4819,6 +4820,57 @@\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure RenameItemNoExistsInValueEntry()\n+ var\n+ Item: Record Item;\n+ Item2: Record Item;\n+ ItemVariant: Record \"Item Variant\";\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ NewItemCode: Code[20];\n+ begin\n+ // [SCENARIO 574250] Verify Rename Item No. After Posting and Generating Value Entries with Variant Codes and blank Variant Code.\n+ Initialize();\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create an Item Variant for Item.\n+ LibraryInventory.CreateItemVariant(ItemVariant, Item.\"No.\");\n+\n+ // [GIVEN] Create and Post Item Journal with and without Variant Code.\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Item);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJournalBatch, ItemJournalTemplate.Type::Item, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", LibraryRandom.RandDecInRange(10, 20, 2));\n+ ItemJournalLine.Validate(\"Variant Code\", ItemVariant.Code);\n+ ItemJournalLine.Modify(true);\n+\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", LibraryRandom.RandDecInRange(10, 20, 2));\n+\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+\n+ // [GIVEN] Create and Post Sales Invoice with Variant Code.\n+ LibrarySales.CreateSalesInvoice(SalesHeader, SalesLine, Item, '', ItemVariant.Code, LibraryRandom.RandDecInRange(5, 10, 2), WorkDate(), LibraryRandom.RandDecInRange(100, 200, 2));\n+ LibrarySales.PostSalesDocument(SalesHeader, true, true);\n+\n+ // [WHEN] Rename Item No. on Item. \n+ NewItemCode := LibraryUtility.GenerateRandomCode(Item.FieldNo(\"No.\"), Database::Item);\n+ Item2.Get(Item.\"No.\");\n+ Item2.Rename(NewItemCode);\n+\n+ // [THEN] Verify Item No. should be renamed with new Item No.\n+ Assert.AreEqual(NewItemCode, Item2.\"No.\", StrSubstNo(CannotRenameItemErr, Item2.FieldCaption(\"No.\"), Item2.TableCaption()));\n+ end;\n+\n local procedure Initialize()\n var\n AllProfile: Record \"All Profile\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al\nindex 9735e4b2417a..b22bbc4e706e 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Inventory/Item/MfgItemIntegration.Codeunit.al\n@@ -161,7 +161,7 @@ codeunit 99000795 \"Mfg. Item Integration\"\n end;\n \n [EventSubscriber(ObjectType::Table, Database::\"Item Variant\", 'OnBeforeRenameEvent', '', false, false)]\n- local procedure OnBeforeRenameItemVariant(var Rec: Record \"Item Variant\"; var xRec: Record \"Item Variant\")\n+ local procedure OnBeforeRenameItemVariant(var Rec: Record \"Item Variant\"; var xRec: Record \"Item Variant\"; RunTrigger: Boolean)\n var\n BOMComponent: Record \"BOM Component\";\n AssemblyHeader: Record \"Assembly Header\";\n@@ -176,6 +176,9 @@ codeunit 99000795 \"Mfg. Item Integration\"\n ItemLedgerEntry: Record \"Item Ledger Entry\";\n ProdOrderLine: Record \"Prod. Order Line\";\n begin\n+ if not RunTrigger then\n+ exit;\n+\n if xRec.\"Item No.\" <> Rec.\"Item No.\" then begin\n ProdOrderLine.SetRange(\"Item No.\", xRec.\"Item No.\");\n ProdOrderLine.SetRange(\"Variant Code\", xRec.Code);\n"} +{"metadata": {"area": "crm", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-213671", "base_commit": "ca1a8ca2e11612d9b6b4876b9f855ed854b79aa4", "created_at": "2025-04-19", "environment_setup_version": "27.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Marketing"], "FAIL_TO_PASS": [{"codeunitID": 136209, "functionName": ["BuildCaptionLengthIssueOnOpportunitiesListPage"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al b/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al\nindex 435658251b18..e8a08e0f2c3f 100644\n--- a/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al\n+++ b/App/Layers/W1/Tests/Marketing/MarketingOpportunityMgmt.Codeunit.al\n@@ -1818,6 +1818,45 @@ codeunit 136209 \"Marketing Opportunity Mgmt\"\n Opportunity.CloseOpportunity();\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure BuildCaptionLengthIssueOnOpportunitiesListPage()\n+ var\n+ Opportunity: Record Opportunity;\n+ Contact: Record Contact;\n+ OpportunityList: TestPage \"Opportunity List\";\n+ FilterText: Text;\n+ i: Integer;\n+ begin\n+ // [SCENARIO 574639] The length of the string is XX but it must be less than or equal to 20 characters when working with Opportunities\n+ Initialize();\n+\n+ // [GIVEN] Create contact and it's opportunity\n+ LibraryMarketing.CreateCompanyContact(Contact);\n+ LibraryMarketing.CreateOpportunity(Opportunity, Contact.\"No.\");\n+\n+ // [GIVEN] Prepare Filter Text with Salesperson Code\n+ for i := 1 to LibraryRandom.RandIntInRange(20, 20) do\n+ FilterText += Opportunity.\"Salesperson Code\" + '|';\n+ FilterText += Opportunity.\"Salesperson Code\";\n+\n+ // [THEN] Open Opportunities list page and apply salesperson code filter without issue\n+ Clear(FilterText);\n+ OpportunityList.OpenView();\n+ OpportunityList.Filter.SetFilter(\"Salesperson Code\", FilterText);\n+ OpportunityList.Close();\n+\n+ // [GIVEN] Prepare Filter Text with Contact No\n+ for i := 1 to LibraryRandom.RandIntInRange(20, 20) do\n+ FilterText += Contact.\"No.\" + '|';\n+ FilterText += Contact.\"No.\";\n+\n+ // [THEN] Open Opportunities list page and contacts filter without issue\n+ OpportunityList.OpenView();\n+ OpportunityList.Filter.SetFilter(\"Contact No.\", FilterText);\n+ OpportunityList.Close();\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"Marketing Opportunity Mgmt\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al b/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al\nindex c70c6c1e7b4f..816671802677 100644\n--- a/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al\n+++ b/App/Layers/W1/BaseApp/CRM/Opportunity/OpportunityList.Page.al\n@@ -630,7 +630,7 @@ page 5123 \"Opportunity List\"\n if Filter <> '' then begin\n RecRef.GetTable(RecVar);\n IndexFieldRef := RecRef.Field(IndexFieldNo);\n- IndexFieldRef.SetRange(Filter);\n+ IndexFieldRef.SetFilter(Filter);\n if RecRef.FindFirst() then begin\n TextFieldRef := RecRef.Field(TextFieldNo);\n CaptionText := CopyStr(Format(IndexFieldRef.Value) + ' ' + Format(TextFieldRef.Value), 1, MaxStrLen(CaptionText));\n"} {"metadata": {"area": "subscription billing", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-215645", "base_commit": "b9e347e7aad6087240fd3d30e0b566e35d96697f", "created_at": "2025-05-15", "environment_setup_version": "26.3", "project_paths": ["App\\Apps\\W1\\SubscriptionBilling\\App", "App\\Apps\\W1\\SubscriptionBilling\\Test"], "FAIL_TO_PASS": [{"codeunitID": 148155, "functionName": ["SalesInvoiceShowsSubtotalForServCommItem"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al b/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al\nindex af155cbc15d6..571455d8853c 100644\n--- a/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al\n+++ b/App/Apps/W1/SubscriptionBilling/Test/Customer Contracts/ContractsTest.Codeunit.al\n@@ -1116,9 +1116,10 @@ codeunit 148155 \"Contracts Test\"\n SalesLine: Record \"Sales Line\";\n SalesQuote: TestPage \"Sales Quote\";\n begin\n+ // [SCENARIO] Sales Quote containing Items with \"Subscription Option\" = \"Subscription Item\" excludes such items from document totals\n Initialize();\n \n- // [GIVEN] Sales Document with Sales Line and Item with \"Subscription Option\" = \"Subscription Item\"\n+ // [GIVEN] Sales Quote with Sales Line and Item with \"Subscription Option\" = \"Subscription Item\"\n LibrarySales.CreateSalesHeader(SalesHeader, Enum::\"Sales Document Type\"::Quote, '');\n ContractTestLibrary.CreateItemWithServiceCommitmentOption(Item, Enum::\"Item Service Commitment Type\"::\"Service Commitment Item\");\n ContractTestLibrary.UpdateItemUnitCostAndPrice(Item, LibraryRandom.RandDec(1000, 2), LibraryRandom.RandDec(1000, 2), true);\n@@ -1136,6 +1137,38 @@ codeunit 148155 \"Contracts Test\"\n SalesQuote.Close();\n end;\n \n+ [Test]\n+ procedure SalesInvoiceShowsSubtotalForServCommItem()\n+ var\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ SubContractsItemManagement: Codeunit \"Sub. Contracts Item Management\";\n+ SalesInvoice: TestPage \"Sales Invoice\";\n+ begin\n+ // [SCENARIO] Sales Invoice containing Items with \"Subscription Option\" = \"Subscription Item\" excludes such items from document totals\n+ Initialize();\n+\n+ // [GIVEN] Sales Invoice with Sales Line and Item with \"Subscription Option\" = \"Subscription Item\"\n+ LibrarySales.CreateSalesHeader(SalesHeader, Enum::\"Sales Document Type\"::Invoice, '');\n+ ContractTestLibrary.CreateItemWithServiceCommitmentOption(Item, Enum::\"Item Service Commitment Type\"::\"Service Commitment Item\");\n+ ContractTestLibrary.UpdateItemUnitCostAndPrice(Item, LibraryRandom.RandDec(1000, 2), LibraryRandom.RandDec(1000, 2), true);\n+\n+ SubContractsItemManagement.SetAllowInsertOfInvoicingItem(true);\n+ \n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", LibraryRandom.RandDec(10, 2));\n+\n+ // [THEN] Total Amount should be filled in Sales Invoice page\n+ SalesLine.TestField(\"Line Amount\");\n+ SalesLine.TestField(\"Exclude from Doc. Total\", false);\n+\n+ // Sales Line Total in Sales Quote should not have a value\n+ SalesInvoice.OpenView();\n+ SalesInvoice.GoToRecord(SalesHeader);\n+ SalesInvoice.SalesLines.\"Total Amount Excl. VAT\".AssertEquals(Item.\"Unit Price\" * SalesLine.Quantity);\n+ SalesInvoice.Close();\n+ end;\n+\n [Test]\n [HandlerFunctions('ConfirmHandler,ExchangeRateSelectionModalPageHandler,MessageHandler')]\n procedure TestChangeOfHarmonizedBillingFieldInContractType()\n", "patch": "diff --git a/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al b/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al\nindex 92df07efd5e2..8e828e4915df 100644\n--- a/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al\n+++ b/App/Apps/W1/SubscriptionBilling/App/Sales Service Commitments/Table Extensions/SalesLine.TableExt.al\n@@ -265,8 +265,9 @@ tableextension 8054 \"Sales Line\" extends \"Sales Line\"\n if Rec.IsTypeServiceObject() then\n Rec.Validate(\"Exclude from Doc. Total\", IsContractRenewalLocal);\n end else\n- if (Rec.Type = Rec.Type::Item) and (Rec.\"No.\" <> '') and (not Rec.IsLineAttachedToBillingLine()) then\n- Rec.Validate(\"Exclude from Doc. Total\", ItemManagement.IsServiceCommitmentItem(Rec.\"No.\"));\n+ if Rec.IsSalesDocumentTypeWithServiceCommitments() then\n+ if ((Rec.Type = Rec.Type::Item) and (Rec.\"No.\" <> '')) then\n+ Rec.Validate(\"Exclude from Doc. Total\", ItemManagement.IsServiceCommitmentItem(Rec.\"No.\"));\n end;\n \n internal procedure IsLineWithServiceObject(): Boolean\n"} {"metadata": {"area": "shopify", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-220452", "base_commit": "7fa3b4c98fd61863789ab144cce8af4062900df2", "created_at": "2025-07-09", "environment_setup_version": "27.0", "project_paths": ["App\\Apps\\W1\\Shopify\\app", "App\\Apps\\W1\\Shopify\\test"], "FAIL_TO_PASS": [{"codeunitID": 139648, "functionName": ["UnitTestSuggestShopifyPaymentsDocumentLink"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\nindex cf234743596b..aed3df1a0d5c 100644\n--- a/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n+++ b/App/Apps/W1/Shopify/test/Payments/ShpfySuggestPaymentTest.Codeunit.al\n@@ -26,7 +26,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(10000, 20000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n@@ -59,7 +59,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(20000, 30000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n@@ -86,6 +86,60 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n until SuggestPayment.Next() = 0;\n end;\n \n+ [Test]\n+ procedure UnitTestSuggestShopifyPaymentsDocumentLink()\n+ var\n+ Item: Record Item;\n+ Customer: Record Customer;\n+ OrderTransaction: Record \"Shpfy Order Transaction\";\n+ SuggestPayment: Record \"Shpfy Suggest Payment\";\n+ DocLinkToDoc: Record \"Shpfy Doc. Link To Doc.\";\n+ SuggestPayments: Report \"Shpfy Suggest Payments\";\n+ OrderId1: BigInteger;\n+ OrderId2: BigInteger;\n+ SalesInvoiceNo: Code[20];\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO] Suggest Shopify payments to create Cash Receipt Journal line for linked Sales Invoice\n+ // [GIVEN] Invoice is posted\n+ Initialize();\n+ Amount := Any.IntegerInRange(10000, 99999);\n+ OrderId1 := Any.IntegerInRange(30000, 40000);\n+ OrderId2 := Any.IntegerInRange(40000, 50000);\n+ CreateItem(Item, Amount);\n+ LibrarySales.CreateCustomer(Customer);\n+ SalesInvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 2, 0);\n+\n+ // [GIVEN] Shopify transactions are imported\n+ CreateOrderTransaction(OrderId1, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+ CreateOrderTransaction(OrderId2, Amount, 'manual', OrderTransaction.Type::Sale, OrderTransaction.Status::Success);\n+\n+ // [GIVEN] Link to Sales Invoice is set\n+ DocLinkToDoc.\"Shopify Document Type\" := DocLinkToDoc.\"Shopify Document Type\"::\"Shopify Shop Order\";\n+ DocLinkToDoc.\"Shopify Document Id\" := OrderId1;\n+ DocLinkToDoc.\"Document Type\" := DocLinkToDoc.\"Document Type\"::\"Posted Sales Invoice\";\n+ DocLinkToDoc.\"Document No.\" := SalesInvoiceNo;\n+ DocLinkToDoc.Insert();\n+ DocLinkToDoc.\"Shopify Document Id\" := OrderId2;\n+ DocLinkToDoc.Insert();\n+\n+ // [WHEN] Create Shopify transactions are run\n+#pragma warning disable AA0210\n+ OrderTransaction.SetFilter(\"Shopify Order Id\", '%1|%2', OrderId1, OrderId2);\n+#pragma warning restore AA0210\n+ OrderTransaction.FindSet();\n+ repeat\n+ SuggestPayments.GetOrderTransactions(OrderTransaction);\n+ until OrderTransaction.Next() = 0;\n+\n+ // [THEN] Temporary suggest payment records are created\n+ SuggestPayments.GetTempSuggestPayment(SuggestPayment);\n+ SuggestPayment.FindSet();\n+ repeat\n+ LibraryAssert.AreEqual(SuggestPayment.Amount, Amount, 'Amounts should match');\n+ until SuggestPayment.Next() = 0;\n+ end;\n+\n [HandlerFunctions('SuggestShopifyPaymentsRequestPageHandler')]\n [Test]\n procedure UnitTestSuggestShopifyPaymentsFailedTransaction()\n@@ -103,7 +157,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(50000, 60000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId);\n@@ -143,9 +197,9 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId1 := Any.IntegerInRange(10000, 99999);\n- OrderId2 := Any.IntegerInRange(10000, 99999);\n- OrderId3 := Any.IntegerInRange(10000, 99999);\n+ OrderId1 := Any.IntegerInRange(60000, 70000);\n+ OrderId2 := Any.IntegerInRange(70000, 80000);\n+ OrderId3 := Any.IntegerInRange(80000, 90000);\n CreateItem(Item, Amount);\n LibrarySales.CreateCustomer(Customer);\n CreateAndPostSalesInvoice(Item, Customer, 1, OrderId1);\n@@ -185,7 +239,7 @@ codeunit 139648 \"Shpfy Suggest Payment Test\"\n // [GIVEN] Invoice is posted\n Initialize();\n Amount := Any.IntegerInRange(10000, 99999);\n- OrderId := Any.IntegerInRange(10000, 99999);\n+ OrderId := Any.IntegerInRange(90000, 99999);\n RefundId := Any.IntegerInRange(10000, 99999);\n CreateRefund(OrderId, RefundId, Amount);\n CreateItem(Item, Amount);\n", "patch": "diff --git a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\nindex 62d92a55c036..cd9c900bf53e 100644\n--- a/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n+++ b/App/Apps/W1/Shopify/app/src/Transactions/Reports/ShpfySuggestPayments.Report.al\n@@ -211,8 +211,8 @@ report 30118 \"Shpfy Suggest Payments\"\n var\n SalesInvoiceHeader: Record \"Sales Invoice Header\";\n SalesCreditMemoHeader: Record \"Sales Cr.Memo Header\";\n- CustLedgerEntry: Record \"Cust. Ledger Entry\";\n RefundHeader: Record \"Shpfy Refund Header\";\n+ DocLinkToDoc: Record \"Shpfy Doc. Link To Doc.\";\n AmountToApply: Decimal;\n Applied: Boolean;\n begin\n@@ -221,27 +221,28 @@ report 30118 \"Shpfy Suggest Payments\"\n case OrderTransaction.Type of\n OrderTransaction.Type::Capture, OrderTransaction.Type::Sale:\n begin\n- SalesInvoiceHeader.SetLoadFields(\"No.\", \"Shpfy Order Id\");\n+ SalesInvoiceHeader.SetLoadFields(\"No.\", \"Shpfy Order Id\", Closed);\n SalesInvoiceHeader.SetRange(\"Shpfy Order Id\", OrderTransaction.\"Shopify Order Id\");\n SalesInvoiceHeader.SetRange(Closed, false);\n- if SalesInvoiceHeader.FindSet() then begin\n+ if SalesInvoiceHeader.FindSet() then\n repeat\n- CustLedgerEntry.SetAutoCalcFields(\"Remaining Amount\");\n- CustLedgerEntry.SetRange(\"Open\", true);\n- CustLedgerEntry.SetRange(\"Applies-to ID\", '');\n- CustLedgerEntry.SetRange(\"Document Type\", CustLedgerEntry.\"Document Type\"::Invoice);\n- CustLedgerEntry.SetRange(\"Document No.\", SalesInvoiceHeader.\"No.\");\n- if CustLedgerEntry.FindSet() then begin\n- Applied := true;\n- repeat\n- CreateSuggestPaymentDocument(CustLedgerEntry, AmountToApply, true);\n- until CustLedgerEntry.Next() = 0;\n- end;\n- until SalesInvoiceHeader.Next() = 0;\n-\n- if Applied and (AmountToApply > 0) then\n- CreateSuggestPaymentGLAccount(AmountToApply, true);\n+ ApplyCustomerLedgerEntries(SalesInvoiceHeader.\"No.\", \"Gen. Journal Document Type\"::Invoice, AmountToApply, Applied);\n+ until SalesInvoiceHeader.Next() = 0\n+ else begin\n+ DocLinkToDoc.SetRange(\"Shopify Document Type\", DocLinkToDoc.\"Shopify Document Type\"::\"Shopify Shop Order\");\n+ DocLinkToDoc.SetRange(\"Shopify Document Id\", OrderTransaction.\"Shopify Order Id\");\n+ DocLinkToDoc.SetRange(\"Document Type\", DocLinkToDoc.\"Document Type\"::\"Posted Sales Invoice\");\n+ if DocLinkToDoc.FindSet() then\n+ repeat\n+ SalesInvoiceHeader.Get(DocLinkToDoc.\"Document No.\");\n+ if SalesInvoiceHeader.Closed then\n+ continue;\n+ ApplyCustomerLedgerEntries(SalesInvoiceHeader.\"No.\", \"Gen. Journal Document Type\"::Invoice, AmountToApply, Applied);\n+ until DocLinkToDoc.Next() = 0;\n end;\n+\n+ if Applied and (AmountToApply > 0) then\n+ CreateSuggestPaymentGLAccount(AmountToApply, true);\n end;\n OrderTransaction.Type::Refund:\n begin\n@@ -254,17 +255,7 @@ report 30118 \"Shpfy Suggest Payments\"\n SalesCreditMemoHeader.SetRange(Paid, false);\n if SalesCreditMemoHeader.FindSet() then\n repeat\n- CustLedgerEntry.SetAutoCalcFields(\"Remaining Amount\");\n- CustLedgerEntry.SetRange(\"Open\", true);\n- CustLedgerEntry.SetRange(\"Applies-to ID\", '');\n- CustLedgerEntry.SetRange(\"Document Type\", CustLedgerEntry.\"Document Type\"::\"Credit Memo\");\n- CustLedgerEntry.SetRange(\"Document No.\", SalesCreditMemoHeader.\"No.\");\n- if CustLedgerEntry.FindSet() then begin\n- Applied := true;\n- repeat\n- CreateSuggestPaymentDocument(CustLedgerEntry, AmountToApply, false);\n- until CustLedgerEntry.Next() = 0;\n- end;\n+ ApplyCustomerLedgerEntries(SalesCreditMemoHeader.\"No.\", \"Gen. Journal Document Type\"::\"Credit Memo\", AmountToApply, Applied);\n until SalesCreditMemoHeader.Next() = 0;\n until RefundHeader.Next() = 0;\n \n@@ -275,6 +266,23 @@ report 30118 \"Shpfy Suggest Payments\"\n end;\n end;\n \n+ local procedure ApplyCustomerLedgerEntries(DocumentNo: Code[20]; DocumentType: Enum \"Gen. Journal Document Type\"; var AmountToApply: Decimal; var Applied: Boolean)\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ begin\n+ CustLedgerEntry.SetAutoCalcFields(\"Remaining Amount\");\n+ CustLedgerEntry.SetRange(\"Open\", true);\n+ CustLedgerEntry.SetRange(\"Applies-to ID\", '');\n+ CustLedgerEntry.SetRange(\"Document Type\", DocumentType);\n+ CustLedgerEntry.SetRange(\"Document No.\", DocumentNo);\n+ if CustLedgerEntry.FindSet() then begin\n+ Applied := true;\n+ repeat\n+ CreateSuggestPaymentDocument(CustLedgerEntry, AmountToApply, DocumentType = \"Gen. Journal Document Type\"::Invoice);\n+ until CustLedgerEntry.Next() = 0;\n+ end;\n+ end;\n+\n local procedure CreateSuggestPaymentDocument(var CustLedgerEntry: Record \"Cust. Ledger Entry\"; var AmountToApply: Decimal; IsInvoice: Boolean)\n begin\n TempSuggestPayment.Init();\n"} +{"metadata": {"area": "inventory", "image_count": 1}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-206135", "base_commit": "cb96582bf92b7e7c5ad99abd5b8138b4c1f4634b", "created_at": "2025-02-03", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137154, "functionName": ["WarehouseShipmentPageRemainsOpenWhenRunPreviewPostAndCloseGLPostingPreviewPage"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\nindex 507d0c55edc6..d844f818a807 100644\n--- a/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMWarehouseManagementII.Codeunit.al\n@@ -3345,6 +3345,61 @@ codeunit 137154 \"SCM Warehouse Management II\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('CloseGLPostingPreviewPageHandler')]\n+ procedure WarehouseShipmentPageRemainsOpenWhenRunPreviewPostAndCloseGLPostingPreviewPage()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ WarehouseEmployee: Record \"Warehouse Employee\";\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ WarehouseShipmentHeader: Record \"Warehouse Shipment Header\";\n+ WarehouseShipment: TestPage \"Warehouse Shipment\";\n+ Quatity: Decimal;\n+ begin\n+ // [SCENARIO 563377] When Preview Posts Warehouse Shipment and closes G/L Posting Preview page then\n+ // Warehouse Shipment page remains open.\n+ Initialize();\n+\n+ // [GIVEN] Create a location with Require Receive and Require Shipment.\n+ CreateAndUpdateLocation(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create Warehouse Employee.\n+ LibraryWarehouse.CreateWarehouseEmployee(WarehouseEmployee, Location.Code, false);\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create Quantity.\n+ Quatity := LibraryRandom.RandInt(10);\n+\n+ // [GIVEN] Post Positive Adjustment for the Item and Location.\n+ LibraryInventory.PostPositiveAdjustment(Item, Location.Code, '', '', Quatity, WorkDate(), Quatity);\n+\n+ // [GIVEN] Create and Release Transfer Order.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, Location.Code, LocationYellow.Code, LocationInTransit.Code);\n+ LibraryInventory.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", Quatity);\n+ LibraryInventory.ReleaseTransferOrder(TransferHeader);\n+\n+ // [GIVEN] Create Warehouse Shipment from Transfer Order.\n+ LibraryWarehouse.CreateWhseShipmentFromTO(TransferHeader);\n+\n+ // [GIVEN] Find Warehouse Shipment Header.\n+ WarehouseShipmentHeader.SetRange(\"Location Code\", Location.Code);\n+ WarehouseShipmentHeader.FindFirst();\n+ Commit();\n+\n+ // [WHEN] Open Warehouse Shipment page and run Preview Posting action.\n+ WarehouseShipment.OpenEdit();\n+ WarehouseShipment.GoToRecord(WarehouseShipmentHeader);\n+ WarehouseShipment.PreviewPosting.Invoke();\n+\n+ // [THEN] Warehouse Shipment remains Open.\n+ WarehouseShipment.\"No.\".AssertEquals(Format(WarehouseShipmentHeader.\"No.\"));\n+ end;\n+\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al\nindex ce405d49e7d3..a6dc48170492 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferOrderPostShipment.Codeunit.al\n@@ -192,7 +192,7 @@ codeunit 5704 \"TransferOrder-Post Shipment\"\n if WhseShip then\n WhseShptLine.LockTable();\n TransHeader.LockTable();\n- if WhseShip then begin\n+ if WhseShip and (not PreviewMode) then begin\n WhsePostShpt.PostUpdateWhseDocuments(WhseShptHeader);\n TempWhseShptHeader.Delete();\n end;\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al\nindex 497b9a81930d..df69dac3bdac 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferWhsePostShipment.Codeunit.al\n@@ -326,6 +326,7 @@ codeunit 5748 \"Transfer Whse. Post Shipment\"\n else begin\n TransferOrderPostShipment.SetWhseShptHeader(WhseShptHeader);\n TransferOrderPostShipment.SetSuppressCommit(WhsePostParameters.\"Suppress Commit\" or WhsePostParameters.\"Preview Posting\");\n+ TransferOrderPostShipment.SetPreviewMode(WhsePostParameters.\"Preview Posting\");\n TransferOrderPostShipment.RunWithCheck(TransHeader);\n CounterSourceDocOK := CounterSourceDocOK + 1;\n end;\n"} {"metadata": {"area": "finance", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-217104", "base_commit": "f1558c6f6f5278f463c0193d05a43182953067a7", "created_at": "2025-06-02", "environment_setup_version": "27.0", "project_paths": ["App\\Apps\\W1\\AutomaticAccountCodes\\app", "App\\Apps\\W1\\AutomaticAccountCodes\\test"], "FAIL_TO_PASS": [{"codeunitID": 139598, "functionName": ["PostGenJnlLineWithAmountDivisionWithAccGroup"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al b/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al\nindex 6626b2b43cdf..7cc4e5edb615 100644\n--- a/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al\n+++ b/App/Apps/W1/AutomaticAccountCodes/test/src/AACAutoAccGroupPosting.Codeunit.al\n@@ -26,8 +26,8 @@ codeunit 139598 \"AAC Auto. Acc. Group Posting\"\n CopyFromOption: Option AccGroup,GenJournal,AccGroupAndGenJnl;\n DimensionDoesNotExistsErr: Label 'Dimension value %1 %2 does not exists for G/L Entry No. %3.', Comment = '%1 = Dimension Code, %2 = DimensionValue Code, %3 = GLEntry Entry No';\n WrongValueErr: Label 'Wrong value of field %1 in table %2, entry no. %3.', Comment = '%1 = Additional-Currency Amount, %2 = GLEntry TableCaption, %3 = GLEntry Entry No';\n-\n WrongAmountGLEntriesErr: Label 'Wrong Amount in G/L Entry.';\n+ GLEntryCountErr: Label 'Posted g/l entry count not match with expected count';\n \n [Test]\n [Scope('OnPrem')]\n@@ -756,6 +756,31 @@ codeunit 139598 \"AAC Auto. Acc. Group Posting\"\n VerifyCopiedGenJnlLines(GenJournalBatch, GenJournalBatch, 2);\n end;\n \n+ [Test]\n+ procedure PostGenJnlLineWithAmountDivisionWithAccGroup()\n+ var\n+ GenJnlLine: Record \"Gen. Journal Line\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ AutoAccGroupNo: Code[10];\n+ CurrencyCode: Code[10];\n+ GLAccountNo: array[3] of Code[20];\n+ begin\n+ // [SCENARIO 575346] Rounding issue leading to \"Inconsistency\" error when trying to post with different currency and automatic accounting in Swedish localisation.\n+ Initialize();\n+\n+ // [GIVEN] Currency with specific exchange rates.\n+ CurrencyCode := CreateCurrencyAndExchangeRate(1, 10.97223, WorkDate());\n+\n+ // [GIVEN] Created Auto Account Group With 3 GL Account with Allocation 50,50,-100.\n+ AutoAccGroupNo := CreateAutoAccGroupWithThreeLines(GLAccountNo[1], GLAccountNo[2], GLAccountNo[3]);\n+\n+ // [WHEN] \"General Journal Line\" - \"GJL\", GJL.\"Auto Acc. Group\" = AAG, GJL.\"Amount\" = \"A\"\n+ CreateAndPostTwoGenJnlLineWithAutoAccGroup(CurrencyCode, GenJournalBatch, GenJnlLine, AutoAccGroupNo, GLAccountNo[2], GLAccountNo[3]);\n+\n+ // [THEN] Check Posted GL Entry count Match with Expected.\n+ CountGLEntryLines(GenJnlLine);//assert\n+ end;\n+\n local procedure Initialize()\n begin\n LibrarySetupStorage.Restore();\n@@ -1538,6 +1563,82 @@ codeunit 139598 \"AAC Auto. Acc. Group Posting\"\n until PostedGenJournalLine.Next() = 0;\n end;\n \n+ local procedure CreateCurrencyAndExchangeRate(Rate: Decimal; RelationalRate: Decimal; FromDate: Date): Code[10]\n+ var\n+ Currency: Record Currency;\n+ begin\n+ LibraryERM.CreateCurrency(Currency);\n+ LibraryERM.SetCurrencyGainLossAccounts(Currency);\n+ Currency.Validate(\"Residual Gains Account\", Currency.\"Realized Gains Acc.\");\n+ Currency.Validate(\"Residual Losses Account\", Currency.\"Realized Losses Acc.\");\n+ Currency.Modify(true);\n+ CreateExchangeRate(Currency.Code, Rate, RelationalRate, FromDate);\n+ exit(Currency.Code);\n+ end;\n+\n+ local procedure CreateExchangeRate(CurrencyCode: Code[10]; Rate: Decimal; RelationalRate: Decimal; FromDate: Date)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ LibraryERM.CreateExchRate(CurrencyExchangeRate, CurrencyCode, FromDate);\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", Rate);\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", Rate);\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", RelationalRate);\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", RelationalRate);\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n+ local procedure CreateAndPostTwoGenJnlLineWithAutoAccGroup(CurrencyCode: Code[20]; var GenJournalBatch: Record \"Gen. Journal Batch\"; var GenJnlLine: Record \"Gen. Journal Line\"; AutoAccGroupNo: Code[10]; GLAccountNo2: Code[20]; GLAccountNo3: Code[20])\n+ var\n+ DocNo: Code[20];\n+ begin\n+ CreateGenJournalTemplateAndBatch(GenJournalBatch);\n+ LibraryJournals.CreateGenJournalLine(GenJnlLine, GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name, GenJnlLine.\"Document Type\"::Invoice,\n+ GenJnlLine.\"Account Type\"::\"G/L Account\", GLAccountNo2, GenJnlLine.\"Bal. Account Type\"::\"G/L Account\", '', 480);\n+ GenJnlLine.Validate(\"Automatic Account Group\", AutoAccGroupNo);\n+ GenJnlLine.Validate(\"Currency Code\", CurrencyCode);\n+ GenJnlLine.Modify(true);\n+ DocNo := GenJnlLine.\"Document No.\";\n+\n+ LibraryJournals.CreateGenJournalLine(GenJnlLine, GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name, GenJnlLine.\"Document Type\"::Invoice,\n+ GenJnlLine.\"Account Type\"::\"G/L Account\", GLAccountNo3, GenJnlLine.\"Bal. Account Type\"::\"G/L Account\", '', -480);\n+ GenJnlLine.Validate(\"Document No.\", DocNo);\n+ GenJnlLine.Validate(\"Currency Code\", CurrencyCode);\n+ GenJnlLine.Modify(true);\n+\n+ LibraryERM.PostGeneralJnlLine(GenJnlLine);\n+ end;\n+\n+ local procedure CreateAutoAccGroupWithThreeLines(var GLAccountNo1: Code[20]; var GLAccountNo2: Code[20]; var GLAccountNo3: Code[20]) AutoAccGroupNo: Code[10]\n+ begin\n+ GLAccountNo1 := LibraryERM.CreateGLAccountNo();\n+ GLAccountNo2 := LibraryERM.CreateGLAccountNo();\n+ GLAccountNo3 := LibraryERM.CreateGLAccountNo();\n+ AutoAccGroupNo := CreateAutomaticAccGroupWithTwoLinesAndBalanceLine(GLAccountNo1, GLAccountNo2, GLAccountNo3);\n+ end;\n+\n+ local procedure CreateAutomaticAccGroupWithTwoLinesAndBalanceLine(GLAccountNo1: Code[20]; GLAccountNo2: Code[20]; GLAccountNo3: Code[20]): Code[10]\n+ var\n+ AutomaticAccountHeader: Record \"Automatic Account Header\";\n+ begin\n+ LibraryAAC.CreateAutomaticAccountHeader(AutomaticAccountHeader);\n+\n+ CreateAutoAccLine(AutomaticAccountHeader.\"No.\", GLAccountNo1, 50, '');\n+ CreateAutoAccLine(AutomaticAccountHeader.\"No.\", GLAccountNo2, 50, '');\n+ CreateAutoAccLine(AutomaticAccountHeader.\"No.\", GLAccountNo3, -100, '');\n+ Commit();\n+ exit(AutomaticAccountHeader.\"No.\");\n+ end;\n+\n+ local procedure CountGLEntryLines(GenJnlLine: Record \"Gen. Journal Line\")\n+ var\n+ GLEntry: Record \"G/L Entry\";\n+ begin\n+ GLEntry.SetRange(\"Document No.\", GenJnlLine.\"Document No.\");\n+ GLEntry.FindSet();\n+ Assert.AreEqual(5, GLEntry.Count, GLEntryCountErr);\n+ end;\n+\n [ModalPageHandler]\n [Scope('OnPrem')]\n procedure CopyGenJournalParametersHandler(var CopyGenJournalParameters: TestPage \"Copy Gen. Journal Parameters\")\n", "patch": "diff --git a/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al b/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al\nindex 0e4bcfe3e0a6..ccaef63d9ca9 100644\n--- a/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al\n+++ b/App/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/AACodesPostingHelper.Codeunit.al\n@@ -72,12 +72,14 @@ codeunit 4850 \"AA Codes Posting Helper\"\n NoOfAutoAccounts: Decimal;\n TotalAmount: Decimal;\n TotalAltAmount: Decimal;\n+ TotalAltAmountLCY: Decimal;\n SourceCurrBaseAmount: Decimal;\n AccLine: Integer;\n begin\n GLSetup.Get();\n GenJnlLine.TestField(\"Account Type\", GenJnlLine.\"Account Type\"::\"G/L Account\");\n Clear(TotalAmount);\n+ Clear(TotalAltAmountLCY);\n AccLine := 0;\n TotalAmount := 0;\n AutoAccHeader.Get(GenJnlLine.\"Automatic Account Group\");\n@@ -117,10 +119,13 @@ codeunit 4850 \"AA Codes Posting Helper\"\n AccLine := AccLine + 1;\n TotalAmount := TotalAmount + GenJnlLine2.Amount;\n TotalAltAmount := TotalAltAmount + GenJnlLine2.\"Source Currency Amount\";\n+ TotalAltAmountLCY := TotalAltAmountLCY + GenJnlLine2.\"Amount (LCY)\";\n if (AccLine = NoOfAutoAccounts) and (TotalAmount <> 0) then\n GenJnlLine2.Validate(Amount, GenJnlLine2.Amount - TotalAmount);\n if (AccLine = NoOfAutoAccounts) and (TotalAltAmount <> 0) then\n GenJnlLine2.Validate(\"Source Currency Amount\", GenJnlLine2.\"Source Currency Amount\" - TotalAltAmount);\n+ if (AccLine = NoOfAutoAccounts) and (TotalAltAmountLCY <> 0) and (TotalAmount = 0) then\n+ GenJnlLine2.Validate(\"Amount (LCY)\", GenJnlLine2.\"Amount (LCY)\" - TotalAltAmountLCY);\n GenJnlCheckLine.RunCheck(GenJnlLine2);\n \n sender.InitGLEntry(GenJnlLine2, GLEntry,\n"} +{"metadata": {"area": "inventory", "image_count": 12}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207247", "base_commit": "c15e5b3fd9ea5d42fbff7dffad96160f5c6838dd", "created_at": "2025-02-17", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137067, "functionName": ["CommentOnProdBOMCompTransferredToCompLinesForFirmPlannedProdOrderWhenPositionFieldUsed"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al\nindex 4391387a6954..dcbb2cc63126 100644\n--- a/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMPlanReqWksht.Codeunit.al\n@@ -61,6 +61,7 @@\n QuantityErr: Label '%1 must be %2 in %3', Comment = '%1 = Quantity, %2 = Minimum Order Quanity, %3 = Requisition Line';\n MPSOrderErr: Label '%1 must be true', Comment = '%1 = MPS Order';\n PlanningComponentMustNotBeFoundErr: Label 'Planning Component must not be found.';\n+ BOMLineCommnetAndFirmProdOrderBOMLineCommentMustMatchErr: Label 'BOM Line Comment and Firm Prod. Order BOM Line Comment must match.';\n \n [Test]\n [HandlerFunctions('MessageHandler')]\n@@ -4904,6 +4905,72 @@\n Assert.AreEqual(StockkeepingUnit[2].\"Order Multiple\", RequisitionLine.Quantity, '');\n end;\n \n+ [Test]\n+ procedure CommentOnProdBOMCompTransferredToCompLinesForFirmPlannedProdOrderWhenPositionFieldUsed()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: array[2] of Record \"Production BOM Line\";\n+ ProductionBOMCommentLine: array[2] of Record \"Production BOM Comment Line\";\n+ ProdOrderCompCmtLine: array[2] of Record \"Prod. Order Comp. Cmt Line\";\n+ RequisitionLine: Record \"Requisition Line\";\n+ Salesheader: Record \"Sales Header\";\n+ UnitOfMeasure: Record \"Unit of Measure\";\n+ begin\n+ // [SCENARIO 563855] When Comment store on a production order line that includes the same component in different positions, transferred to the Component Lines \n+ // for the Firm Planned Production Order via Planning Worksheet.\n+ Initialize();\n+\n+ // [GIVEN] Create Unit of Measure Code.\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure);\n+\n+ // [GIVEN] Create Component Items.\n+ CreateItemWithReorderPolicy(CompItem, UnitOfMeasure, ItemUnitOfMeasure, CompItem.\"Replenishment System\"::Purchase, CompItem.\"Reordering Policy\"::\" \");\n+\n+ // [GIVEN] Create Production Item.\n+ CreateItemWithReorderPolicy(ProdItem, UnitOfMeasure, ItemUnitOfMeasure, ProdItem.\"Replenishment System\"::\"Prod. Order\", ProdItem.\"Reordering Policy\"::Order);\n+\n+ // [GIVEN] Create Production BOM Header.\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ProdItem.\"Base Unit of Measure\");\n+\n+ // [GIVEN] Create Production BOM Lines.\n+ CreateProductionBOMLineInSpecifiedPosition(ProductionBOMHeader, ProductionBOMLine[1], CompItem.\"No.\", LibraryRandom.RandInt(0));\n+ CreateProductionBOMLineInSpecifiedPosition(ProductionBOMHeader, ProductionBOMLine[2], CompItem.\"No.\", LibraryRandom.RandInt(0));\n+\n+ // [GIVEN] Create Production BOM Comment Line for Production BOM Line.\n+ LibraryManufacturing.CreateProductionBOMCommentLine(ProductionBOMLine[1]);\n+ LibraryManufacturing.CreateProductionBOMCommentLine(ProductionBOMLine[2]);\n+\n+ // [GIVEN] Update Production BOM Status.\n+ LibraryManufacturing.UpdateProductionBOMStatus(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+\n+ // [GIVEN] Validate Production BOM No. in Production Item.\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Create and Release Sales Order.\n+ CreateSalesOrder(Salesheader, ProdItem);\n+ LibrarySales.ReleaseSalesDocument(Salesheader);\n+\n+ // [GIVEN] Run Calculate Regenerative Plan.\n+ RunCalculateRegenerativePlan(ProdItem.\"No.\", '');\n+\n+ // [GIVEN] Accept Action Message on Requisition Line.\n+ AcceptActionMessageOnReqLine(RequisitionLine, ProdItem.\"No.\");\n+\n+ // [GIVEN] Run Carry Out Action Plan.\n+ CarryOutActionPlanForFirmPlannedProdOrder(RequisitionLine);\n+\n+ // [WHEN] Find Prod. Order Comp. Cmt Line for both Position.\n+ GetProductionBOMCommnetLine(ProductionBOMLine[1], ProductionBOMCommentLine[1], ProdOrderCompCmtLine[1]);\n+ GetProductionBOMCommnetLine(ProductionBOMLine[2], ProductionBOMCommentLine[2], ProdOrderCompCmtLine[2]);\n+\n+ // [VERIFY] Comment in Production BOM Comment Line and Prod. Order Comp. Cmt Line is same.\n+ Assert.AreEqual(ProductionBOMCommentLine[1].Comment, ProdOrderCompCmtLine[1].Comment, BOMLineCommnetAndFirmProdOrderBOMLineCommentMustMatchErr);\n+ Assert.AreEqual(ProductionBOMCommentLine[2].Comment, ProdOrderCompCmtLine[2].Comment, BOMLineCommnetAndFirmProdOrderBOMLineCommentMustMatchErr);\n+ end;\n+\n local procedure Initialize()\n var\n AllProfile: Record \"All Profile\";\n@@ -6649,6 +6716,48 @@ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name\n StockkeepingUnit.Modify(true);\n end;\n \n+ local procedure CreateProductionBOMLineInSpecifiedPosition(var ProductionBOMHeader: Record \"Production BOM Header\"; var ProductionBOMLine: Record \"Production BOM Line\"; ItemNo: Code[20]; QuantityPer: Decimal)\n+ begin\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, ItemNo, QuantityPer);\n+ ProductionBOMLine.Validate(Position, LibraryUtility.GenerateGUID());\n+ ProductionBOMLine.Modify(true);\n+ end;\n+\n+ local procedure CarryOutActionPlanForFirmPlannedProdOrder(var ReqLine: Record \"Requisition Line\")\n+ var\n+ MfgUserTemplate: Record \"Manufacturing User Template\";\n+ CarryOutActionMsgPlan: Report \"Carry Out Action Msg. - Plan.\";\n+ begin\n+ MfgUserTemplate.Init();\n+ MfgUserTemplate.Validate(\"Create Production Order\", MfgUserTemplate.\"Create Production Order\"::\"Firm Planned\");\n+\n+ ReqLine.SetRecFilter();\n+ CarryOutActionMsgPlan.UseRequestPage(false);\n+ CarryOutActionMsgPlan.SetDemandOrder(ReqLine, MfgUserTemplate);\n+ CarryOutActionMsgPlan.RunModal();\n+ end;\n+\n+ local procedure GetProductionBOMCommnetLine(ProductionBOMLine: record \"Production BOM Line\"; var ProductionBOMCommentLine: Record \"Production BOM Comment Line\"; var ProdOrderCompCmtLine: Record \"Prod. Order Comp. Cmt Line\")\n+ var\n+ ProductionOrderComp: Record \"Prod. Order Component\";\n+ begin\n+ ProductionOrderComp.SetRange(\"Status\", ProductionOrderComp.Status::\"Firm Planned\");\n+ ProductionOrderComp.SetRange(\"Item No.\", ProductionBOMLine.\"No.\");\n+ ProductionOrderComp.SetRange(Position, ProductionBOMLine.Position);\n+ ProductionOrderComp.FindFirst();\n+\n+ ProductionBOMCommentLine.SetRange(\"Production BOM No.\", ProductionBOMLine.\"Production BOM No.\");\n+ ProductionBOMCommentLine.SetRange(\"BOM Line No.\", ProductionOrderComp.\"Line No.\");\n+ ProductionBOMCommentLine.FindFirst();\n+\n+ ProdOrderCompCmtLine.SetRange(\"Status\", ProductionOrderComp.Status::\"Firm Planned\");\n+ ProdOrderCompCmtLine.SetRange(\"Prod. Order No.\", ProductionOrderComp.\"Prod. Order No.\");\n+ ProdOrderCompCmtLine.SetRange(\"Prod. Order Line No.\", ProductionOrderComp.\"Prod. Order Line No.\");\n+ ProdOrderCompCmtLine.SetRange(\"Prod. Order BOM Line No.\", ProductionOrderComp.\"Line No.\");\n+ ProdOrderCompCmtLine.FindFirst();\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure CalculatePlanPlanWkshRequestPageHandler(var CalculatePlanPlanWksh: TestRequestPage \"Calculate Plan - Plan. Wksh.\")\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al\nindex bd370429da5f..50bcb4c52bdc 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Requisition/CarryOutAction.Codeunit.al\n@@ -1541,6 +1541,7 @@ codeunit 99000813 \"Carry Out Action\"\n ProductionBOMLine.SetRange(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n ProductionBOMLine.SetRange(Type, ProductionBOMLine.Type::Item);\n ProductionBOMLine.SetRange(\"No.\", ProdOrderComponent.\"Item No.\");\n+ ProductionBOMLine.SetRange(Position, ProdOrderComponent.Position);\n if ProductionBOMLine.FindSet() then\n repeat\n ProductionBOMCommentLine.SetRange(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n"} +{"metadata": {"area": "inventory", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207177", "base_commit": "64e8e373597b75054ede11d7304783567504707e", "created_at": "2025-02-16", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137413, "functionName": ["VerifyNoBlankEntryInsertedInItemAttributeValue"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al\nindex f743727e528e..cdba6765ce88 100644\n--- a/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMItemAttributes.Codeunit.al\n@@ -2551,6 +2551,39 @@ codeunit 137413 \"SCM Item Attributes\"\n Assert.AreNotEqual(0, ItemAttributeValue.\"Numeric Value\", NumericValueShouldNotBeZeroErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('ItemAttributeValueListHandler')]\n+ procedure VerifyNoBlankEntryInsertedInItemAttributeValue()\n+ var\n+ Item: Record Item;\n+ ItemAttribute: Record \"Item Attribute\";\n+ ItemAttributeValue: Record \"Item Attribute Value\";\n+ ItemCard: TestPage \"Item Card\";\n+ begin\n+ // [SCENARIO 565898] An empty attribute value was not created through the item Card\n+ Initialize();\n+\n+ // [GIVEN] An item and a set of item attributes\n+ CreateTestOptionItemAttributes();\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Open the Item Card\n+ ItemCard.OpenEdit();\n+ ItemCard.GotoRecord(Item);\n+\n+ // [WHEN] The user assigns some attribute values to the item \n+ ItemAttribute.FindFirst();\n+ AssignItemAttributeViaItemCard(ItemAttribute, ItemAttributeValue, ItemCard);\n+\n+ // [THEN] No blank Item attribute Value Inserted in the table\n+ ItemAttributeValue.SetRange(\"Attribute ID\", ItemAttribute.ID);\n+ ItemAttributeValue.SetRange(Value, '');\n+ asserterror ItemAttributeValue.FindFirst();\n+\n+ // [THEN] Verify there is nothing inside the filter\n+ Assert.AssertNothingInsideFilter();\n+ end;\n+\n local procedure Initialize()\n var\n ItemAttribute: Record \"Item Attribute\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al b/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al\nindex a84b05588031..4d5435ff41d6 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Item/Attribute/ItemAttributeValueList.Page.al\n@@ -33,7 +33,6 @@ page 7504 \"Item Attribute Value List\"\n trigger OnValidate()\n var\n ItemAttributeValue: Record \"Item Attribute Value\";\n- ItemAttributeValueMapping: Record \"Item Attribute Value Mapping\";\n ItemAttribute: Record \"Item Attribute\";\n begin\n OnBeforeCheckAttributeName(Rec, RelatedRecordCode);\n@@ -42,19 +41,10 @@ page 7504 \"Item Attribute Value List\"\n DeleteItemAttributeValueMapping(ItemAttribute.ID);\n end;\n \n- if not Rec.FindAttributeValue(ItemAttributeValue) then\n+ if (Rec.Value <> '') and not Rec.FindAttributeValue(ItemAttributeValue) then\n Rec.InsertItemAttributeValue(ItemAttributeValue, Rec);\n \n- if ItemAttributeValue.Get(ItemAttributeValue.\"Attribute ID\", ItemAttributeValue.ID) then begin\n- ItemAttributeValueMapping.Reset();\n- ItemAttributeValueMapping.Init();\n- ItemAttributeValueMapping.\"Table ID\" := Database::Item;\n- ItemAttributeValueMapping.\"No.\" := RelatedRecordCode;\n- ItemAttributeValueMapping.\"Item Attribute ID\" := ItemAttributeValue.\"Attribute ID\";\n- ItemAttributeValueMapping.\"Item Attribute Value ID\" := ItemAttributeValue.ID;\n- OnBeforeItemAttributeValueMappingInsert(ItemAttributeValueMapping, ItemAttributeValue, Rec);\n- ItemAttributeValueMapping.Insert();\n- end;\n+ InsertItemAttributeValueMapping(ItemAttributeValue);\n end;\n }\n field(Value; Rec.Value)\n@@ -74,6 +64,7 @@ page 7504 \"Item Attribute Value List\"\n if not Rec.FindAttributeValue(ItemAttributeValue) then\n Rec.InsertItemAttributeValue(ItemAttributeValue, Rec);\n \n+ InsertItemAttributeValueMapping(ItemAttributeValue);\n ItemAttributeValueMapping.SetRange(\"Table ID\", Database::Item);\n ItemAttributeValueMapping.SetRange(\"No.\", RelatedRecordCode);\n ItemAttributeValueMapping.SetRange(\"Item Attribute ID\", ItemAttributeValue.\"Attribute ID\");\n@@ -154,6 +145,24 @@ page 7504 \"Item Attribute Value List\"\n ItemAttribute.RemoveUnusedArbitraryValues();\n end;\n \n+ local procedure InsertItemAttributeValueMapping(ItemAttributeValue: Record \"Item Attribute Value\")\n+ var\n+ ItemAttributeValueMapping: Record \"Item Attribute Value Mapping\";\n+ begin\n+ if not ItemAttributeValue.Get(ItemAttributeValue.\"Attribute ID\", ItemAttributeValue.ID) or\n+ ItemAttributeValueMapping.Get(Database::Item, RelatedRecordCode, ItemAttributeValue.\"Attribute ID\") then\n+ exit;\n+\n+ ItemAttributeValueMapping.Reset();\n+ ItemAttributeValueMapping.Init();\n+ ItemAttributeValueMapping.\"Table ID\" := Database::Item;\n+ ItemAttributeValueMapping.\"No.\" := RelatedRecordCode;\n+ ItemAttributeValueMapping.\"Item Attribute ID\" := ItemAttributeValue.\"Attribute ID\";\n+ ItemAttributeValueMapping.\"Item Attribute Value ID\" := ItemAttributeValue.ID;\n+ OnBeforeItemAttributeValueMappingInsert(ItemAttributeValueMapping, ItemAttributeValue, Rec);\n+ ItemAttributeValueMapping.Insert();\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterItemAttributeValueMappingDelete(AttributeToDeleteID: Integer; RelatedRecordCode: Code[20]; ItemAttributeValueSelection: Record \"Item Attribute Value Selection\")\n begin\n"} +{"metadata": {"area": "sales", "image_count": 10}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207236", "base_commit": "b63e4162ab18e1a516cafcc0771489065f902c43", "created_at": "2025-02-17", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134391, "functionName": ["BatchPostSaleInvoiceWithReplacePostingDateAndCurrencyCode"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al\nindex 5bc6879cc7c4..59ee4c8edca0 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesBatchPosting.Codeunit.al\n@@ -1573,6 +1573,37 @@ codeunit 134391 \"ERM Sales Batch Posting\"\n VerifyPostedSalesOrder(SalesHeader.\"No.\", SalesHeader.\"Posting Date\" + 1, false);\n end;\n \n+ [Test]\n+ [HandlerFunctions('RequestPageHandlerBatchPostSalesInvoicesWithReplaceAllDates,MessageHandler')]\n+ [Scope('OnPrem')]\n+ procedure BatchPostSaleInvoiceWithReplacePostingDateAndCurrencyCode()\n+ var\n+ Currency: Record Currency;\n+ SalesHeader: Record \"Sales Header\";\n+ LibraryJobQueue: Codeunit \"Library - Job Queue\";\n+ Amount: Decimal;\n+ begin\n+ // [SCENARIO 562713] Post sales invoice with currency code via Post Batch, but the posted data has not been changed.\n+ Initialize();\n+\n+ // [GIVEN] Set Post with Job queue on Sales & Receivables Setup\n+ LibrarySales.SetPostWithJobQueue(true);\n+\n+ // [GIVEN] Bind subscription and do not handle Job queue event as true\n+ BindSubscription(LibraryJobQueue);\n+ LibraryJobQueue.SetDoNotHandleCodeunitJobQueueEnqueueEvent(true);\n+\n+ // [GIVEN] Create Sales Invoice with Currency Code.\n+ Amount := CreateSalesDocumentWithCurrency(SalesHeader, Currency, SalesHeader.\"Document Type\"::Invoice, false);\n+\n+ // [WHEN] Run Post Batch with Replace Posting Date, Replace Document Date & Replace VAT Date options.\n+ RunBatchPostSales(SalesHeader.\"Document Type\", SalesHeader.\"No.\", SalesHeader.\"Posting Date\" + 10, false);\n+ LibraryJobQueue.FindAndRunJobQueueEntryByRecordId(SalesHeader.RecordId);\n+\n+ // [THEN] The amount was not changed in the posted sales invoice line\n+ VerifyPostedSalesInvoiceAmount(SalesHeader.\"No.\", SalesHeader.\"Posting Date\" + 10, Amount);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1890,6 +1921,52 @@ codeunit 134391 \"ERM Sales Batch Posting\"\n Assert.RecordCount(JobQueueEntry, 1);\n end;\n \n+ local procedure CreateSalesDocumentWithCurrency(var SalesHeader: Record \"Sales Header\"; var Currency: Record Currency; DocumentType: Enum \"Sales Document Type\"; InvDisc: Boolean): Decimal\n+ var\n+ Item: Record Item;\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ LibrarySales.CreateSalesHeader(SalesHeader, DocumentType, CreateCustomer(InvDisc));\n+ CreateCurrencyWithExchangeRate(Currency);\n+ SalesHeader.Validate(\"Currency Code\", Currency.Code);\n+ SalesHeader.Modify(true);\n+\n+ LibraryInventory.CreateItem(Item);\n+ LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item.\"No.\", LibraryRandom.RandInt(10));\n+ SalesLine.Validate(\"Unit Price\", LibraryRandom.RandInt(100));\n+ SalesLine.Validate(\"Line Discount %\", LibraryRandom.RandInt(20));\n+ SalesLine.Modify(true);\n+\n+ exit(SalesLine.\"Amount Including VAT\");\n+ end;\n+\n+ local procedure CreateCurrencyWithExchangeRate(var Currency: Record Currency)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ Currency.Get(LibraryERM.CreateCurrencyWithGLAccountSetup());\n+\n+ LibraryERM.CreateExchRate(CurrencyExchangeRate, Currency.Code, WorkDate());\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n+ local procedure VerifyPostedSalesInvoiceAmount(PreAssignedNo: Code[20]; PostingDate: Date; Amount: Decimal)\n+ var\n+ SalesInvoiceHeader: Record \"Sales Invoice Header\";\n+ SalesInvoiceLine: Record \"Sales Invoice Line\";\n+ begin\n+ SalesInvoiceHeader.SetRange(\"Pre-Assigned No.\", PreAssignedNo);\n+ SalesInvoiceHeader.FindFirst();\n+ Assert.Equal(SalesInvoiceHeader.\"Posting Date\", PostingDate);\n+ SalesInvoiceLine.SetFilter(\"Document No.\", SalesInvoiceHeader.\"No.\");\n+ SalesInvoiceLine.FindFirst();\n+ Assert.Equal(Amount, SalesInvoiceLine.\"Amount Including VAT\");\n+ end;\n+\n [RequestPageHandler]\n [Scope('OnPrem')]\n procedure RequestPageHandlerBatchPostSalesInvoices(var BatchPostSalesInvoices: TestRequestPage \"Batch Post Sales Invoices\")\n@@ -2195,5 +2272,26 @@ codeunit 134391 \"ERM Sales Batch Posting\"\n Assert.AreEqual(PostBatchForm.PrintDoc.AsBoolean(), true, 'Expected value to be restored.');\n end;\n end;\n+\n+ [RequestPageHandler]\n+ procedure RequestPageHandlerBatchPostSalesInvoicesWithReplaceAllDates(var BatchPostSalesInvoices: TestRequestPage \"Batch Post Sales Invoices\")\n+ var\n+ SalesHeader: Record \"Sales Header\";\n+ DocumentNoFilter: Variant;\n+ PostingDate: Variant;\n+ RunReplacePostingDate: Boolean;\n+ begin\n+ LibraryVariableStorage.Dequeue(DocumentNoFilter);\n+ LibraryVariableStorage.Dequeue(PostingDate);\n+\n+ BatchPostSalesInvoices.\"Sales Header\".SetFilter(\"No.\", DocumentNoFilter);\n+ BatchPostSalesInvoices.\"Sales Header\".SetFilter(\"Document Type\", Format(SalesHeader.\"Document Type\"::Invoice));\n+\n+ BatchPostSalesInvoices.PostingDate.SetValue(PostingDate);\n+ RunReplacePostingDate := Format(PostingDate) <> '';\n+ BatchPostSalesInvoices.ReplacePostingDate.SetValue(RunReplacePostingDate);\n+ BatchPostSalesInvoices.ReplaceVATDate.SetValue(RunReplacePostingDate);\n+ BatchPostSalesInvoices.OK().Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\nindex fbf39fce2b5f..9f88c95dbfc2 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al\n@@ -4154,7 +4154,7 @@ table 36 \"Sales Header\"\n \n if UpdateCurrencyExchangeRates.ExchangeRatesForCurrencyExist(CurrencyDate, \"Currency Code\") then begin\n \"Currency Factor\" := CurrExchRate.ExchangeRate(CurrencyDate, \"Currency Code\");\n- if \"Currency Code\" <> xRec.\"Currency Code\" then\n+ if (\"Currency Code\" <> xRec.\"Currency Code\") and (xRec.\"No.\" <> '') then\n RecreateSalesLines(FieldCaption(\"Currency Code\"));\n end else\n UpdateCurrencyExchangeRates.ShowMissingExchangeRatesNotification(\"Currency Code\");\n@@ -7038,7 +7038,10 @@ table 36 \"Sales Header\"\n exit;\n \n \"Posting Date\" := PostingDateReq;\n- Validate(\"Currency Code\");\n+ if \"Currency Code\" <> '' then begin\n+ UpdateCurrencyFactor();\n+ UpdateSalesLinesByFieldNo(SalesHeader.FieldNo(\"Currency Factor\"), false);\n+ end;\n \n if ReplaceVATDate then\n \"VAT Reporting Date\" := VATDateReq;\ndiff --git a/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al b/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al\nindex e5855273a6ae..f1849388fe0e 100644\n--- a/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/Posting/SalesBatchPostMgt.Codeunit.al\n@@ -138,22 +138,25 @@ codeunit 1371 \"Sales Batch Post Mgt.\"\n \n local procedure PrepareSalesHeader(var SalesHeader: Record \"Sales Header\"; var BatchConfirm: Option)\n var\n- CalcInvoiceDiscont: Boolean;\n+ CalcInvoiceDiscount: Boolean;\n ReplacePostingDate, ReplaceVATDate, ReplaceDocumentDate : Boolean;\n+ ManualReopen: Boolean;\n PostingDate, VATDate : Date;\n begin\n- BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Calculate Invoice Discount\", CalcInvoiceDiscont);\n+ BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Calculate Invoice Discount\", CalcInvoiceDiscount);\n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Replace Posting Date\", ReplacePostingDate);\n BatchProcessingMgt.GetDateParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Posting Date\", PostingDate);\n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Replace VAT Date\", ReplaceVATDate);\n BatchProcessingMgt.GetDateParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"VAT Date\", VATDate);\n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::\"Replace Document Date\", ReplaceDocumentDate);\n \n- if CalcInvoiceDiscont then\n+ if CalcInvoiceDiscount then\n CalculateInvoiceDiscount(SalesHeader);\n \n SalesHeader.BatchConfirmUpdateDeferralDate(BatchConfirm, ReplacePostingDate, PostingDate, ReplaceVATDate, VATDate);\n+ PerformManualReleaseOrReopenSalesHeader(SalesHeader, ManualReopen, ReplacePostingDate);\n SalesHeader.BatchConfirmUpdatePostingDate(ReplacePostingDate, PostingDate, ReplaceVATDate, VATDate, ReplaceDocumentDate);\n+ PerformManualReleaseOrReopenSalesHeader(SalesHeader, ManualReopen, ReplacePostingDate);\n OnPrepareSalesHeaderOnAfterBatchConfirmUpdateDeferralDate(SalesHeader, BatchProcessingMgt);\n \n BatchProcessingMgt.GetBooleanParameter(SalesHeader.RecordId, Enum::\"Batch Posting Parameter Type\"::Ship, SalesHeader.Ship);\n@@ -310,6 +313,23 @@ codeunit 1371 \"Sales Batch Post Mgt.\"\n JobQueueEntry.Insert(true);\n end;\n \n+ local procedure PerformManualReleaseOrReopenSalesHeader(var SalesHeader: Record \"Sales Header\"; var ManualReopen: Boolean; ReplacePostingDate: Boolean)\n+ var\n+ ReleaseSalesDoc: Codeunit \"Release Sales Document\";\n+ begin\n+ if (not ReplacePostingDate) or (SalesHeader.\"Currency Code\" = '') then\n+ exit;\n+ if not SalesHeader.Invoice and not (SalesHeader.\"Document Type\" = SalesHeader.\"Document Type\"::Invoice) then\n+ exit;\n+\n+ if ManualReopen then\n+ ReleaseSalesHeader(SalesHeader)\n+ else begin\n+ ReleaseSalesDoc.PerformManualReopen(SalesHeader);\n+ ManualReopen := true;\n+ end;\n+ end;\n+\n [EventSubscriber(ObjectType::Codeunit, Codeunit::\"Batch Processing Mgt.\", 'OnBeforeBatchProcessing', '', false, false)]\n local procedure PrepareSalesHeaderOnBeforeBatchProcessing(var RecRef: RecordRef; var BatchConfirm: Option)\n var\n"} +{"metadata": {"area": "assembly", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-206977", "base_commit": "9832a8d1748921e7eeff9d8c3c6e55af9c562260", "created_at": "2025-02-13", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\SCM-Assembly"], "FAIL_TO_PASS": [{"codeunitID": 137096, "functionName": ["ShowDocumentOnAssemblyLinesForBlanketOrderPageShouldOpenCorrectPage"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al b/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al\nindex 7629f2ebe001..3e0eab3eb6a9 100644\n--- a/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM-Assembly/SCMKittingATO.Codeunit.al\n@@ -5510,6 +5510,54 @@ codeunit 137096 \"SCM Kitting - ATO\"\n Assert.IsTrue(AssembleToOrderLink.IsEmpty(), ATOLinkShouldNotBeFoundErr);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MsgHandler')]\n+ procedure ShowDocumentOnAssemblyLinesForBlanketOrderPageShouldOpenCorrectPage()\n+ var\n+ AssembleToOrderLink: Record \"Assemble-to-Order Link\";\n+ AssemblyHeader: Record \"Assembly Header\";\n+ AssemblyLine: Record \"Assembly Line\";\n+ Item: Record Item;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ AssemblyLines: TestPage \"Assembly Lines\";\n+ BlanketAssemblyOrder: TestPage \"Blanket Assembly Order\";\n+ begin\n+ // [SCENARIO 564531] Show document in Assembly order line page opens the wrong page when the Assembly order line belongs a blanket assembly order.\n+ Initialize();\n+\n+ // [GIVEN] Assembled item \"I\".\n+ CreateAssembledItem(Item, \"Assembly Policy\"::\"Assemble-to-Order\", 2, 0, 0, 1, Item.\"Costing Method\"::FIFO);\n+\n+ // [GIVEN] Create sales blanket order with item \"I\", set \"Qty. to Assemble to Order\" = \"Quantity\".\n+ // [GIVEN] A linked assembly blanket order is created in the background.\n+ LibrarySales.CreateSalesDocumentWithItem(\n+ SalesHeader, SalesLine, SalesHeader.\"Document Type\"::\"Blanket Order\",\n+ '', Item.\"No.\", LibraryRandom.RandInt(10), '', WorkDate());\n+ SetQtyToAssembleToOrder(SalesLine, SalesLine.Quantity);\n+\n+ // [GIVEN] Clear \"Qty. to Assemble to Order\".\n+ // [GIVEN] That deletes the assembly blanket order together the Assemble-to-Order link.\n+ SetQtyToAssembleToOrder(SalesLine, 0);\n+ Assert.IsFalse(AssembleToOrderLink.AsmExistsForSalesLine(SalesLine), '');\n+\n+ // [WHEN] Set \"Qty. to Assemble to Order\" back to \"Quantity\".\n+ SetQtyToAssembleToOrder(SalesLine, SalesLine.Quantity);\n+\n+ // [THEN] A new linked assembly blanket order is created.\n+ FindLinkedAssemblyOrder(AssemblyHeader, SalesHeader.\"Document Type\", SalesHeader.\"No.\");\n+ FindAssemblyLine(AssemblyHeader, AssemblyLine);\n+\n+ // [WHEN] Open Assembly Lines Page and invoke show document action\n+ AssemblyLines.OpenEdit();\n+ BlanketAssemblyOrder.Trap();\n+ AssemblyLines.GoToRecord(AssemblyLine);\n+ AssemblyLines.\"Show Document\".Invoke();\n+\n+ // [THEN] Verify Blanket Assembly Order Page opened\n+ BlanketAssemblyOrder.\"No.\".AssertEquals(AssemblyHeader.\"No.\");\n+ end;\n+\n local procedure VerifyAssembleToOrderLinesPageOpened(SalesHeader: Record \"Sales Header\"; QtyAssembleToOrder: Decimal)\n var\n SalesQuote: TestPage \"Sales Quote\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\nindex 9ae5cd9eb8eb..1aa3ac9b5ca2 100644\n--- a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n@@ -2060,6 +2060,21 @@ table 901 \"Assembly Line\"\n end;\n end;\n \n+ internal procedure ShowAssemblyDocument()\n+ var\n+ AssemblyHeader: Record \"Assembly Header\";\n+ begin\n+ AssemblyHeader.Get(Rec.\"Document Type\", Rec.\"Document No.\");\n+ case AssemblyHeader.\"Document Type\" of\n+ AssemblyHeader.\"Document Type\"::Quote:\n+ Page.Run(Page::\"Assembly Quote\", AssemblyHeader);\n+ AssemblyHeader.\"Document Type\"::Order:\n+ Page.Run(Page::\"Assembly Order\", AssemblyHeader);\n+ AssemblyHeader.\"Document Type\"::\"Blanket Order\":\n+ Page.Run(Page::\"Blanket Assembly Order\", AssemblyHeader);\n+ end;\n+ end;\n+\n procedure SuspendDeletionCheck(Suspend: Boolean)\n begin\n CalledFromHeader := Suspend;\ndiff --git a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al\nindex 0877c357bc37..9c9e4b15045c 100644\n--- a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al\n+++ b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLines.Page.al\n@@ -157,11 +157,8 @@ page 903 \"Assembly Lines\"\n ToolTip = 'Open the document that the information on the line comes from.';\n \n trigger OnAction()\n- var\n- AssemblyHeader: Record \"Assembly Header\";\n begin\n- AssemblyHeader.Get(Rec.\"Document Type\", Rec.\"Document No.\");\n- PAGE.Run(PAGE::\"Assembly Order\", AssemblyHeader);\n+ Rec.ShowAssemblyDocument();\n end;\n }\n action(\"Reservation Entries\")\n"} {"metadata": {"area": "finance", "image_count": 1}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-191624", "base_commit": "ca83d8b5c6ef9be7a2965d4ac40dc55884f12551", "created_at": "2024-08-15", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\ExcelReports\\app", "App\\Apps\\W1\\ExcelReports\\test"], "FAIL_TO_PASS": [{"codeunitID": 139545, "functionName": ["FirstTimeOpeningRequestPageOfFixedAssetAnalysisShouldInsertPostingTypes"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/ExcelReports/test/src/FixedAssetExcelReports.Codeunit.al b/App/Apps/W1/ExcelReports/test/src/FixedAssetExcelReports.Codeunit.al\nnew file mode 100644\nindex 000000000000..3ee86701f253\n--- /dev/null\n+++ b/App/Apps/W1/ExcelReports/test/src/FixedAssetExcelReports.Codeunit.al\n@@ -0,0 +1,43 @@\n+namespace Microsoft.Finance.ExcelReports.Test;\n+using Microsoft.FixedAssets.Posting;\n+using Microsoft.Finance.ExcelReports;\n+\n+codeunit 139545 \"Fixed Asset Excel Reports\"\n+{\n+ Subtype = Test;\n+ TestPermissions = Disabled;\n+\n+ var\n+ Assert: Codeunit Assert;\n+\n+ [Test]\n+ [HandlerFunctions('EXRFixedAssetAnalysisExcelHandler')]\n+ procedure FirstTimeOpeningRequestPageOfFixedAssetAnalysisShouldInsertPostingTypes()\n+ var\n+ RequestPageXml: Text;\n+ begin\n+ // [SCENARIO 544231] First time opening the Fixed Asset Analysis Excel report requestpage should insert the FixedAssetTypes required by the report\n+ // [GIVEN] There is no FA Posting Type\n+ CleanupFixedAssetData();\n+ Commit();\n+ Assert.TableIsEmpty(Database::\"FA Posting Type\");\n+ // [WHEN] Opening the requestpage of the Fixed Asset Analysis report\n+ RequestPageXml := Report.RunRequestPage(Report::\"EXR Fixed Asset Analysis Excel\", RequestPageXml);\n+ // [THEN] The default FA Posting Type's are inserted\n+ Assert.TableIsNotEmpty(Database::\"FA Posting Type\");\n+ end;\n+\n+ local procedure CleanupFixedAssetData()\n+ var\n+ FAPostingType: Record \"FA Posting Type\";\n+ begin\n+ FAPostingType.DeleteAll();\n+ end;\n+\n+ [RequestPageHandler]\n+ procedure EXRFixedAssetAnalysisExcelHandler(var EXRFixedAssetAnalysisExcel: TestRequestPage \"EXR Fixed Asset Analysis Excel\")\n+ begin\n+ EXRFixedAssetAnalysisExcel.OK().Invoke();\n+ end;\n+\n+}\n\\ No newline at end of file\n", "patch": "diff --git a/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al b/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al\nindex 686231b5140a..35b007c8373b 100644\n--- a/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al\n+++ b/App/Apps/W1/ExcelReports/app/src/Financials/EXRFixedAssetAnalysisExcel.Report.al\n@@ -124,6 +124,7 @@ report 4412 \"EXR Fixed Asset Analysis Excel\"\n trigger OnOpenPage()\n var\n DepreciationBook: Record \"Depreciation Book\";\n+ FixedAssetPostingType: Record \"FA Posting Type\";\n FASetup: Record \"FA Setup\";\n begin\n EndingDate := WorkDate();\n@@ -135,6 +136,7 @@ report 4412 \"EXR Fixed Asset Analysis Excel\"\n if FASetup.\"Default Depr. Book\" <> '' then\n DepreciationBookCode := FASetup.\"Default Depr. Book\";\n end;\n+ FixedAssetPostingType.CreateTypes();\n end;\n }\n rendering\n"} {"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-195193", "base_commit": "170e0b11453b4f93d5f38cb92c0e288988df7cb7", "created_at": "2024-09-23", "environment_setup_version": "25.0", "project_paths": ["App\\Apps\\W1\\ExcelReports\\app", "App\\Apps\\W1\\ExcelReports\\test"], "FAIL_TO_PASS": [{"codeunitID": 139544, "functionName": ["TrialBalanceBufferNetChangeSplitsIntoDebitAndCreditWhenCalledSeveralTimes"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al b/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al\nindex 1a7bf318b260..734e4fdd4242 100644\n--- a/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al\n+++ b/App/Apps/W1/ExcelReports/test/src/TrialBalanceExcelReports.Codeunit.al\n@@ -298,6 +298,56 @@ codeunit 139544 \"Trial Balance Excel Reports\"\n asserterror LibraryReportDataset.RunReportAndLoad(Report::\"EXR Consolidated Trial Balance\", Variant, RequestPageXml);\n end;\n \n+ [Test]\n+ procedure TrialBalanceBufferNetChangeSplitsIntoDebitAndCreditWhenCalledSeveralTimes()\n+ var\n+ EXRTrialBalanceBuffer: Record \"EXR Trial Balance Buffer\";\n+ ValuesToSplitInCreditAndDebit: array[3] of Decimal;\n+ begin\n+ // [SCENARIO 547558] Trial Balance Buffer data split into Debit and Credit correctly, even if called multiple times.\n+ // [GIVEN] Trial Balance Buffer filled with positive Balance/Net Change\n+ ValuesToSplitInCreditAndDebit[1] := 837;\n+ // [GIVEN] Trial Balance Buffer filled with negative Balance/Net Change\n+ ValuesToSplitInCreditAndDebit[2] := -110;\n+ // [GIVEN] Trial Balance Buffer filled with positive Balance/Net Change\n+ ValuesToSplitInCreditAndDebit[3] := 998;\n+ // [WHEN] Trial Balance Buffer entries are inserted\n+ EXRTrialBalanceBuffer.\"G/L Account No.\" := 'A';\n+ EXRTrialBalanceBuffer.Validate(\"Net Change\", ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Validate(Balance, ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Validate(\"Net Change (ACY)\", ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Validate(\"Balance (ACY)\", ValuesToSplitInCreditAndDebit[1]);\n+ EXRTrialBalanceBuffer.Insert();\n+ EXRTrialBalanceBuffer.\"G/L Account No.\" := 'B';\n+ EXRTrialBalanceBuffer.Validate(\"Net Change\", ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Validate(Balance, ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Validate(\"Net Change (ACY)\", ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Validate(\"Balance (ACY)\", ValuesToSplitInCreditAndDebit[2]);\n+ EXRTrialBalanceBuffer.Insert();\n+ EXRTrialBalanceBuffer.\"G/L Account No.\" := 'C';\n+ EXRTrialBalanceBuffer.Validate(\"Net Change\", ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Validate(Balance, ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Validate(\"Net Change (ACY)\", ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Validate(\"Balance (ACY)\", ValuesToSplitInCreditAndDebit[3]);\n+ EXRTrialBalanceBuffer.Insert();\n+ // [THEN] All Entries have the right split in Credit and Debit\n+ EXRTrialBalanceBuffer.FindSet();\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit)\" + EXRTrialBalanceBuffer.\"Net Change (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Balance (Debit)\" + EXRTrialBalanceBuffer.\"Balance (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Net Change (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[1], Abs(EXRTrialBalanceBuffer.\"Balance (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Balance (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ EXRTrialBalanceBuffer.Next();\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit)\" + EXRTrialBalanceBuffer.\"Net Change (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Balance (Debit)\" + EXRTrialBalanceBuffer.\"Balance (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Net Change (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(-ValuesToSplitInCreditAndDebit[2], Abs(EXRTrialBalanceBuffer.\"Balance (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Balance (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ EXRTrialBalanceBuffer.Next();\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit)\" + EXRTrialBalanceBuffer.\"Net Change (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Balance (Debit)\" + EXRTrialBalanceBuffer.\"Balance (Credit)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Net Change (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Net Change (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ Assert.AreEqual(ValuesToSplitInCreditAndDebit[3], Abs(EXRTrialBalanceBuffer.\"Balance (Debit) (ACY)\" + EXRTrialBalanceBuffer.\"Balance (Credit) (ACY)\"), 'Split in line in credit and debit should be the same as the inserted value.');\n+ end;\n+\n local procedure CreateSampleBusinessUnits(HowMany: Integer)\n var\n BusinessUnit: Record \"Business Unit\";\n", "patch": "diff --git a/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al b/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al\nindex 00c238ae4020..3359f9e94814 100644\n--- a/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al\n+++ b/App/Apps/W1/ExcelReports/app/src/Financials/EXRTrialBalanceBuffer.Table.al\n@@ -44,10 +44,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Net Change\" > 0) then\n- Validate(\"Net Change (Debit)\", \"Net Change\")\n- else\n+ if (\"Net Change\" > 0) then begin\n+ Validate(\"Net Change (Debit)\", \"Net Change\");\n+ Validate(\"Net Change (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Net Change (Credit)\", -\"Net Change\");\n+ Validate(\"Net Change (Debit)\", 0);\n+ end;\n end;\n }\n field(11; \"Net Change (Debit)\"; Decimal)\n@@ -64,10 +68,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Balance\" > 0) then\n- Validate(\"Balance (Debit)\", \"Balance\")\n- else\n+ if (\"Balance\" > 0) then begin\n+ Validate(\"Balance (Debit)\", \"Balance\");\n+ Validate(\"Balance (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Balance (Credit)\", -\"Balance\");\n+ Validate(\"Balance (Debit)\", 0);\n+ end;\n end;\n }\n field(14; \"Balance (Debit)\"; Decimal)\n@@ -100,10 +108,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Net\" > 0) then\n- Validate(\"Last Period Net (Debit)\", \"Last Period Net\")\n- else\n+ if (\"Last Period Net\" > 0) then begin\n+ Validate(\"Last Period Net (Debit)\", \"Last Period Net\");\n+ Validate(\"Last Period Net (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Net (Credit)\", -\"Last Period Net\");\n+ Validate(\"Last Period Net (Debit)\", 0);\n+ end;\n end;\n }\n field(51; \"Last Period Net (Debit)\"; Decimal)\n@@ -120,10 +132,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Bal.\" > 0) then\n- Validate(\"Last Period Bal. (Debit)\", \"Last Period Bal.\")\n- else\n+ if (\"Last Period Bal.\" > 0) then begin\n+ Validate(\"Last Period Bal. (Debit)\", \"Last Period Bal.\");\n+ Validate(\"Last Period Bal. (Credit)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Bal. (Credit)\", -\"Last Period Bal.\");\n+ Validate(\"Last Period Bal. (Debit)\", 0);\n+ end;\n end;\n }\n field(61; \"Last Period Bal. (Debit)\"; Decimal)\n@@ -156,10 +172,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Net Change\" > 0) then\n- Validate(\"Net Change (Debit) (ACY)\", \"Net Change (ACY)\")\n- else\n+ if (\"Net Change\" > 0) then begin\n+ Validate(\"Net Change (Debit) (ACY)\", \"Net Change (ACY)\");\n+ Validate(\"Net Change (Credit) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Net Change (Credit) (ACY)\", -\"Net Change (ACY)\");\n+ Validate(\"Net Change (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(111; \"Net Change (Debit) (ACY)\"; Decimal)\n@@ -176,10 +196,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Balance\" > 0) then\n- Validate(\"Balance (Debit) (ACY)\", \"Balance (ACY)\")\n- else\n+ if (\"Balance\" > 0) then begin\n+ Validate(\"Balance (Debit) (ACY)\", \"Balance (ACY)\");\n+ Validate(\"Balance (Credit) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Balance (Credit) (ACY)\", -\"Balance (ACY)\");\n+ Validate(\"Balance (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(114; \"Balance (Debit) (ACY)\"; Decimal)\n@@ -196,10 +220,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Net\" > 0) then\n- Validate(\"Last Period Net (Debit) (ACY)\", \"Last Period Net (ACY)\")\n- else\n+ if (\"Last Period Net\" > 0) then begin\n+ Validate(\"Last Period Net (Debit) (ACY)\", \"Last Period Net (ACY)\");\n+ Validate(\"Last Period Net (Credit) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Net (Credit) (ACY)\", -\"Last Period Net (ACY)\");\n+ Validate(\"Last Period Net (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(151; \"Last Period Net (Debit) (ACY)\"; Decimal)\n@@ -216,10 +244,14 @@ table 4402 \"EXR Trial Balance Buffer\"\n \n trigger OnValidate()\n begin\n- if (\"Last Period Bal.\" > 0) then\n- Validate(\"Last Period Bal. (Debit) (ACY)\", \"Last Period Bal. (ACY)\")\n- else\n+ if (\"Last Period Bal.\" > 0) then begin\n+ Validate(\"Last Period Bal. (Debit) (ACY)\", \"Last Period Bal. (ACY)\");\n+ Validate(\"Last Period Bal. (Cred.) (ACY)\", 0);\n+ end\n+ else begin\n Validate(\"Last Period Bal. (Cred.) (ACY)\", -\"Last Period Bal. (ACY)\");\n+ Validate(\"Last Period Bal. (Debit) (ACY)\", 0);\n+ end;\n end;\n }\n field(161; \"Last Period Bal. (Debit) (ACY)\"; Decimal)\ndiff --git a/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al b/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al\nindex 7cf0915e376f..2e171cf03e3e 100644\n--- a/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al\n+++ b/App/Apps/W1/ExcelReports/app/src/Financials/TrialBalance.Codeunit.al\n@@ -119,6 +119,7 @@ codeunit 4410 \"Trial Balance\"\n \n local procedure InsertTrialBalanceDataForGLAccountWithFilters(var GLAccount: Record \"G/L Account\"; Dimension1ValueCode: Code[20]; Dimension2ValueCode: Code[20]; BusinessUnitCode: Code[20]; var TrialBalanceData: Record \"EXR Trial Balance Buffer\"; var Dimension1Values: Record \"Dimension Value\" temporary; var Dimension2Values: Record \"Dimension Value\" temporary)\n begin\n+ Clear(TrialBalanceData);\n GlAccount.CalcFields(\"Net Change\", \"Balance at Date\", \"Additional-Currency Net Change\", \"Add.-Currency Balance at Date\", \"Budgeted Amount\", \"Budget at Date\");\n TrialBalanceData.\"G/L Account No.\" := GlAccount.\"No.\";\n TrialBalanceData.\"Dimension 1 Code\" := Dimension1ValueCode;\n"} +{"metadata": {"area": "assembly", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-207878", "base_commit": "ba9818faf02363b70a42a3a224274fb2520c502c", "created_at": "2025-02-24", "environment_setup_version": "26.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Dimension"], "FAIL_TO_PASS": [{"codeunitID": 134381, "functionName": ["AvailWarningAssemblyOrdersConsideringDueDates"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al b/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al\nindex 2628814efa25..b2bfa55eddbe 100644\n--- a/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al\n+++ b/App/Layers/W1/Tests/Dimension/ERMDimensionPriority.Codeunit.al\n@@ -25,9 +25,20 @@ codeunit 134381 \"ERM Dimension Priority\"\n LibraryWarehouse: Codeunit \"Library - Warehouse\";\n LibraryManufacturing: Codeunit \"Library - Manufacturing\";\n SystemActionTriggers: Codeunit \"System Action Triggers\";\n+ LibraryAssembly: Codeunit \"Library - Assembly\";\n+ NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n isInitialized: Boolean;\n WrongDimValueCodeErr: Label 'Wrong dimension value code.';\n DefaultDimPrioritiesNotificationIdTxt: Label '69CE42D9-0580-4907-8BC9-0EEB59DA96C9', Locked = true;\n+ ItemAvaibilityIsLowNotificationIdTxt: Label '2712ad06-c48b-4c20-820e-347a60c9ad00', Locked = true;\n+ AvailWarningYesMsg: Label 'Avail. warning should be Yes';\n+ AvailWarningNoMsg: Label 'Avail. warning should be No';\n+ DueDateBeforeWDFromLineMsg: Label 'Due Date %1 is before work date %2.';\n+ DueDateBeforeWDFromHeaderMsg: Label 'Due Date %1 is before work date %2 in one or more of the assembly lines.';\n+ NewLineDueDate: Date;\n+ TestMethodName: Text[30];\n+ Step: Integer;\n+ TestVSTF257960A: Label 'VSTF257960A';\n \n [Test]\n [Scope('OnPrem')]\n@@ -758,6 +769,105 @@ codeunit 134381 \"ERM Dimension Priority\"\n Assert.IsFalse(ProdOrderLine.\"Shortcut Dimension 1 Code\" = ProdOrderComponent.\"Shortcut Dimension 1 Code\", 'Dimensions are equal.');\n end;\n \n+ [Test]\n+ [HandlerFunctions('DueDateBeforeWorkDateMsgHandler')]\n+ procedure AvailWarningAssemblyOrdersConsideringDueDates()\n+ var\n+ AsmHeader: Record \"Assembly Header\";\n+ AsmHeader2: Record \"Assembly Header\";\n+ AsmLine: Record \"Assembly Line\";\n+ AssemblySetup: Record \"Assembly Setup\";\n+ BOMComponent: Record \"BOM Component\";\n+ ComponentItem: Record Item;\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ Location: Record Location;\n+ ManufacturingSetup: Record \"Manufacturing Setup\";\n+ MyNotifications: Record \"My Notifications\";\n+ ProductItem: Record Item;\n+ Newworkdate: Date;\n+ begin\n+ // [SCENARIO 565695] Avail. Warning on Assembly Orders are now considering Demand for the Component only for selected Assembly Order.\n+ Initialize();\n+\n+ // [GIVEN] Set Item Avaibility Is Low Notification Enabled.\n+ SetMyNotificationsSetup(MyNotifications);\n+\n+ // [GIVEN] Create New Location.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Validate \"Default Location for Orders\" in Assembly Setup for New Created Location.\n+ AssemblySetup.Get();\n+ AssemblySetup.Validate(\"Default Location for Orders\", Location.Code);\n+ AssemblySetup.Modify(true);\n+\n+ // [GIVEN] Validate \"Components at Location\" in Manufacturing Setup for New Created Location.\n+ ManufacturingSetup.Get();\n+ ManufacturingSetup.Validate(\"Components at Location\", Location.Code);\n+ ManufacturingSetup.Modify(true);\n+\n+ // [GIVEN] Created Component Item\n+ LibraryInventory.CreateItem(ComponentItem);\n+\n+ // [GIVEN] Created Master Item and Assembly Component for Master Item\n+ LibraryInventory.CreateItem(ProductItem);\n+ ProductItem.Validate(\"Replenishment System\", ProductItem.\"Replenishment System\"::Purchase);\n+ ProductItem.Validate(\"Manufacturing Policy\", ProductItem.\"Manufacturing Policy\"::\"Make-to-Stock\");\n+ ProductItem.Modify(true);\n+ LibraryAssembly.CreateAssemblyListComponent(BOMComponent.Type::Item, ComponentItem.\"No.\", ProductItem.\"No.\", '', 0, 2, true);\n+\n+ // [GIVEN] Created 1st Assembly Order\n+ MakeAsmOrder(AsmHeader, ProductItem, 1, WorkDate(), Location.Code);\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity \n+ AsmLine.Get(AsmHeader.\"Document Type\", AsmHeader.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 1st Check \"Avail. Warning\" on Assemblyline for 1st Assembly Order\n+ Assert.IsTrue(AsmLine.\"Avail. Warning\", AvailWarningYesMsg);\n+\n+\n+ // [GIVEN] Created and Post Item Journal for Component Item\n+ LibraryInventory.CreateItemJournalLineInItemTemplate(ItemJournalLine, ComponentItem.\"No.\", Location.Code, '', 2);\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity for 1st Assembly Order\n+ AsmLine.Get(AsmHeader.\"Document Type\", AsmHeader.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 2nd Check \"Avail. Warning\" on Assemblyline for 1st Assembly Order\n+ Assert.IsFalse(AsmLine.\"Avail. Warning\", AvailWarningNoMsg);\n+\n+ // [GIVEN] Recall All Notifications\n+ NotificationLifecycleMgt.RecallAllNotifications();\n+\n+ // [GIVEN] Set 2nd New Work Date.\n+ Newworkdate := CalcDate('<1W>', WorkDate());\n+ WorkDate(Newworkdate);\n+\n+ // [GIVEN] Make 2nd Assembly Order \n+ MakeAsmOrder(AsmHeader2, ProductItem, 3, Newworkdate, Location.Code);\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity for 2nd Assembly Order\n+ AsmLine.Get(AsmHeader2.\"Document Type\", AsmHeader2.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 1st Check \"Avail. Warning\" on Assemblyline for 2nd Assembly Order\n+ Assert.IsTrue(AsmLine.\"Avail. Warning\", AvailWarningYesMsg);\n+\n+ // [WHEN] Get Assemblyline and Validate Quantity for 1st Assembly Order\n+ AsmLine.Get(AsmHeader.\"Document Type\", AsmHeader.\"No.\", 10000);\n+ AsmLine.ShowAvailabilityWarning();\n+ AsmLine.Validate(Quantity, AsmLine.Quantity);\n+\n+ // [THEN] 3rd Check \"Avail. Warning\" on Assemblyline for 1st Assembly Order\n+ Assert.IsFalse(AsmLine.\"Avail. Warning\", AvailWarningNoMsg);\n+\n+ NotificationLifecycleMgt.RecallAllNotifications();\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -1312,6 +1422,27 @@ codeunit 134381 \"ERM Dimension Priority\"\n CreateDefaultDimensionPriority(SourceCode, DATABASE::\"G/L Account\", 2);\n end;\n \n+ local procedure SetMyNotificationsSetup(var MyNotifications: Record \"My Notifications\")\n+ begin\n+ if MyNotifications.Get(UserId, ItemAvaibilityIsLowNotificationIdTxt) then begin\n+ MyNotifications.Validate(Enabled, true);\n+ MyNotifications.Modify(true);\n+ end else\n+ MyNotifications.InsertDefault(ItemAvaibilityIsLowNotificationIdTxt, '', '', true);\n+ end;\n+\n+ local procedure MakeAsmOrder(var AsmHeader: Record \"Assembly Header\"; ParentItem: Record Item; Qty: Decimal; DueDate: Date; LocationCode: Code[10])\n+ begin\n+ Clear(AsmHeader);\n+ AsmHeader.\"Document Type\" := AsmHeader.\"Document Type\"::Order;\n+ AsmHeader.Insert(true);\n+ AsmHeader.Validate(\"Due Date\", DueDate);\n+ AsmHeader.Validate(\"Location Code\", LocationCode);\n+ AsmHeader.Validate(\"Item No.\", ParentItem.\"No.\");\n+ AsmHeader.Validate(Quantity, Qty);\n+ AsmHeader.Modify(true);\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text)\n@@ -1541,5 +1672,36 @@ codeunit 134381 \"ERM Dimension Priority\"\n begin\n RequestPage.OK().Invoke();\n end;\n+\n+ [MessageHandler]\n+ procedure DueDateBeforeWorkDateMsgHandler(Msg: Text[1024])\n+ var\n+ MessageTextFromHeader: Text[1024];\n+ MessageTextFromLine: Text[1024];\n+ begin\n+ MessageTextFromHeader := StrSubstNo(DueDateBeforeWDFromHeaderMsg, NewLineDueDate, WorkDate());\n+ MessageTextFromLine := StrSubstNo(DueDateBeforeWDFromLineMsg, NewLineDueDate, WorkDate());\n+ case TestMethodName of\n+ TestVSTF257960A:\n+ case Step of\n+ 1, 9:\n+ begin\n+ Assert.IsTrue(\n+ StrPos(Msg, MessageTextFromHeader) > 0, StrSubstNo('Wrong message: %1 \\Expected: %2', Msg, MessageTextFromHeader));\n+ exit;\n+ end;\n+ 10:\n+ begin\n+ Assert.IsTrue(\n+ StrPos(Msg, MessageTextFromLine) > 0, StrSubstNo('Wrong message: %1 \\Expected: %2', Msg, MessageTextFromLine));\n+ exit;\n+ end;\n+ end;\n+ else\n+ exit; // for other test methods.\n+ end;\n+\n+ Assert.Fail(StrSubstNo('Message at Step %1 not expected.', Step));\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\nindex 62ba45edddc6..2f9a548804d4 100644\n--- a/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Assembly/Document/AssemblyLine.Table.al\n@@ -1575,10 +1575,13 @@ table 901 \"Assembly Line\"\n EarliestDate);\n \n if ExpectedInventory < \"Remaining Quantity (Base)\" then begin\n- if ExpectedInventory < 0 then\n- AbleToAssemble := 0\n- else\n- AbleToAssemble := Round(ExpectedInventory / \"Quantity per\", UOMMgt.QtyRndPrecision(), '<')\n+ if ExpectedInventory < 0 then begin\n+ AbleToAssemble := 0;\n+ if AvailableInventory >= \"Remaining Quantity (Base)\" then\n+ AbleToAssemble := AssemblyHeader.\"Remaining Quantity\";\n+ end else\n+ AbleToAssemble := Round(ExpectedInventory / \"Quantity per\", UOMMgt.QtyRndPrecision(), '<');\n+\n end else begin\n AbleToAssemble := AssemblyHeader.\"Remaining Quantity\";\n EarliestDate := 0D;\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al\nindex 26f5dfa5f2ae..710350355238 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Availability/ItemCheckAvail.Codeunit.al\n@@ -28,6 +28,7 @@ codeunit 311 \"Item-Check Avail.\"\n AvailableToPromise: Codeunit \"Available to Promise\";\n NotificationLifecycleMgt: Codeunit \"Notification Lifecycle Mgt.\";\n UOMMgt: Codeunit \"Unit of Measure Management\";\n+ AssemblyLineDueDateGlobal: Date;\n ItemNo: Code[20];\n UnitOfMeasureCode: Code[10];\n ItemLocationCode: Code[10];\n@@ -331,9 +332,8 @@ codeunit 311 \"Item-Check Avail.\"\n if IsHandled then\n exit;\n \n- AvailableToPromise.CalcQtyAvailabletoPromise(\n- Item, GrossReq, SchedRcpt, Item.GetRangeMax(\"Date Filter\"),\n- CompanyInfo.\"Check-Avail. Time Bucket\", CompanyInfo.\"Check-Avail. Period Calc.\");\n+ AvailableToPromise.CalcQtyAvailabletoPromise(Item, GrossReq, SchedRcpt, CheckAvailabilityDate(Item, AssemblyLineDueDateGlobal),\n+ CompanyInfo.\"Check-Avail. Time Bucket\", CompanyInfo.\"Check-Avail. Period Calc.\");\n InventoryQty := ConvertQty(AvailableToPromise.CalcAvailableInventory(Item) - OldItemNetResChange);\n GrossReq := ConvertQty(GrossReq);\n ReservedReq := ConvertQty(AvailableToPromise.CalcReservedRequirement(Item) + OldItemNetResChange);\n@@ -485,6 +485,7 @@ codeunit 311 \"Item-Check Avail.\"\n OldItemNetChange := 0;\n \n OldAssemblyLine := AssemblyLine;\n+ AssemblyLineDueDateGlobal := OldAssemblyLine.\"Due Date\";\n \n if OldAssemblyLine.Find() then begin // Find previous quantity\n ShouldCheckQty :=\n@@ -767,6 +768,14 @@ codeunit 311 \"Item-Check Avail.\"\n UseOrderPromise := NewUseOrderPromise;\n end;\n \n+ local procedure CheckAvailabilityDate(var Item: Record Item; AssemblyLineDueDate: Date): Date\n+ begin\n+ if AssemblyLineDueDate = 0D then\n+ exit(Item.GetRangeMax(\"Date Filter\"))\n+ else\n+ exit(0D);\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAfterCalculate(var Item: Record Item; var InitialQtyAvailable: Decimal; OldItemNetChange: Decimal; QtyPerUnitOfMeasure: Decimal; var ContextInfo: Dictionary of [Text, Text])\n begin\n"} +{"metadata": {"area": "finance", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-185792", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-06-07", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136305, "functionName": ["ProjectAmountUpdatedWhenAmountLCYIsInserted"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\nindex faf365eeaa53..f2ff7c96db82 100644\n--- a/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobJournal.Codeunit.al\n@@ -41,6 +41,7 @@ codeunit 136305 \"Job Journal\"\n AmountErr: Label 'Amount must be right';\n CurrencyDateConfirmTxt: Label 'The currency dates on all planning lines will be updated based on the invoice posting date because there is a difference in currency exchange rates. Recalculations will be based on the Exch. Calculation setup for the Cost and Price values for the project. Do you want to continue?';\n ControlNotFoundErr: Label 'Expected control not found on the page';\n+ ProjectTotalCostErr: Label 'Project Total Cost(LCY) must be updated.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2886,6 +2887,58 @@ codeunit 136305 \"Job Journal\"\n Assert.RecordCount(JobPlanningLine, 1);\n end;\n \n+ [Test]\n+ procedure ProjectAmountUpdatedWhenAmountLCYIsInserted()\n+ var\n+ JobTask: Record \"Job Task\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ GLAccount: Record \"G/L Account\";\n+ BankAccount: Record \"Bank Account\";\n+ Currency: Record Currency;\n+ PreviousProjectTotalCostLCY: Decimal;\n+ begin\n+ // [SCENARIO 537315] The Project G/L Ledgers line after changing the \"Amount (LCY)\" value changes Project Total Cost(LCY).\n+ Initialize();\n+\n+ // [GIVEN] Create a Job and job Task.\n+ CreateJobWithJobTask(JobTask);\n+\n+ // [GIVEN] Create a Job Journal Batch.\n+ CreateAndUpdateJobJournalBatch(GenJournalBatch);\n+\n+ // [GIVEN] Create a GL Account.\n+ LibraryERM.CreateGLAccount(GLAccount);\n+\n+ // [GIVEN] Create a Bank Account.\n+ LibraryERM.CreateBankAccount(BankAccount);\n+\n+ // [GIVEN] Get any existing Currency.\n+ LibraryERM.FindCurrency(Currency);\n+\n+ // [GIVEN] Create General Journal Line.\n+ LibraryERM.CreateGeneralJnlLine(\n+ GenJournalLine, GenJournalBatch.\"Journal Template Name\", GenJournalBatch.Name, GenJournalLine.\"Document Type\"::Invoice,\n+ GenJournalLine.\"Account Type\"::\"G/L Account\", GLAccount.\"No.\", LibraryRandom.RandDec(100, 2));\n+\n+ //[GIVEN] Validate Balancing Accounts.\n+ GenJournalLine.Validate(\"Bal. Account Type\", GenJournalLine.\"Bal. Account Type\"::\"Bank Account\");\n+ GenJournalLine.Validate(\"Bal. Account No.\", BankAccount.\"No.\");\n+ GenJournalLine.Validate(\"Currency Code\", Currency.Code);\n+ GenJournalLine.Validate(\"Job Line Type\", GenJournalLine.\"Job Line Type\"::\"Both Budget and Billable\");\n+ GenJournalLine.Validate(\"Job No.\", JobTask.\"Job No.\");\n+ GenJournalLine.Validate(\"Job Task No.\", JobTask.\"Job Task No.\");\n+ GenJournalLine.Validate(\"Job Quantity\", LibraryRandom.RandDec(10, 2));\n+\n+ // [GIVEN] Store Project Total Cost LCY and Validate Amount (LCY) to new Amount.\n+ PreviousProjectTotalCostLCY := GenJournalLine.\"Job Total Cost (LCY)\";\n+ GenJournalLine.Validate(\"Amount (LCY)\", LibraryRandom.RandDec(12, 2));\n+ GenJournalLine.Modify(true);\n+\n+ // [THEN] Project Total Cost (LCY) must be updated.\n+ Assert.AreNotEqual(GenJournalLine.\"Job Total Cost (LCY)\", PreviousProjectTotalCostLCY, ProjectTotalCostErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\nindex 84ae0e69ac8e..3c462d43423f 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalLine.Table.al\n@@ -590,6 +590,11 @@ table 81 \"Gen. Journal Line\"\n Validate(\"Bal. VAT %\");\n UpdateLineBalance();\n end;\n+\n+ if JobTaskIsSet() then begin\n+ CreateTempJobJnlLine();\n+ UpdatePricesFromJobJnlLine();\n+ end;\n end;\n }\n field(17; \"Balance (LCY)\"; Decimal)\n"} +{"metadata": {"area": "workflow", "image_count": 5}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-185488", "base_commit": "41efbd81ba3146b79667f1b9ce1194697dda34c6", "created_at": "2024-06-03", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\Workflow"], "FAIL_TO_PASS": [{"codeunitID": 134184, "functionName": ["CanRequestApprovalPurchaseQuoteWithNotifySender"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al b/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al\nindex eec702f0b7ed..c683ab7e3d58 100644\n--- a/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al\n+++ b/App/Layers/W1/Tests/Workflow/WFDemoPurchQuoteApprovals.Codeunit.al\n@@ -169,6 +169,48 @@ codeunit 134184 \"WF Demo Purch Quote Approvals\"\n Assert.ExpectedError(StrSubstNo(RecordIsRestrictedErr, Format(PurchaseHeader.RecordId, 0, 1)));\n end;\n \n+ [Test]\n+ procedure CanRequestApprovalPurchaseQuoteWithNotifySender()\n+ var\n+ PurchaseHeader: Record \"Purchase Header\";\n+ WorkflowStepInstance: Record \"Workflow Step Instance\";\n+ WorkflowStepArgument: Record \"Workflow Step Argument\";\n+ ApprovalEntry: Record \"Approval Entry\";\n+ WorkflowResponseHandling: Codeunit \"Workflow Response Handling\";\n+ Variant: Variant;\n+ begin\n+ // [SCENARIO] When ExecuteResponse is called with a purchase header as argument and setup to Create a notification entry code, no error is thrown.\n+ // [GIVEN] The approval workflow for purchase quotes is enabled.\n+ // [WHEN] The user wants to Release the purchase quote.\n+ // [THEN] The user will get an error that he cannot release the purchase quote that is not approved.\n+\n+ // Setup\n+ Initialize();\n+\n+ // [GIVEN] A purchase quote that should be approved\n+ CreatePurchaseQuote(PurchaseHeader);\n+\n+ // [GIVEN] An approval for the purchase quote\n+ if ApprovalEntry.FindLast() then;\n+ ApprovalEntry.\"Entry No.\" += 1;\n+ ApprovalEntry.\"Record ID to Approve\" := PurchaseHeader.RecordId;\n+ ApprovalEntry.Insert();\n+\n+ // [GIVEN] A workflow step for sending a notification\n+ WorkflowStepArgument.ID := CreateGuid();\n+ WorkflowStepArgument.\"Notify Sender\" := true;\n+ WorkflowStepArgument.Insert();\n+\n+ WorkflowStepInstance.ID := CreateGuid();\n+ WorkflowStepInstance.Argument := WorkflowStepArgument.ID;\n+ WorkflowStepInstance.\"Function Name\" := WorkflowResponseHandling.CreateNotificationEntryCode();\n+ WorkflowStepInstance.Insert();\n+\n+ // [WHEN] Executing the notification step\n+ // [THEN] No error is thrown\n+ WorkflowResponseHandling.ExecuteResponse(Variant, WorkflowStepInstance, PurchaseHeader);\n+ end;\n+\n [Test]\n [HandlerFunctions('MessageHandler')]\n [Scope('OnPrem')]\n", "patch": "diff --git a/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al b/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al\nindex bcd82095b12b..b00fddb95709 100644\n--- a/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/System/Workflow/WorkflowResponseHandling.Codeunit.al\n@@ -86,7 +86,7 @@ codeunit 1521 \"Workflow Response Handling\"\n ApplyNewValuesTxt: Label 'Apply the new values.';\n DiscardNewValuesTxt: Label 'Discard the new values.';\n EnableJobQueueEntryResponseDescTxt: Label 'Enable the job queue entry.';\n-\n+ UnknownRecordErr: Label 'Unknown record type.';\n // Telemetry strings\n WorkflowResponseStartTelemetryTxt: Label 'Workflow response: Start Scope', Locked = true;\n WorkflowResponseEndTelemetryTxt: Label 'Workflow response: End Scope', Locked = true;\n@@ -108,8 +108,8 @@ codeunit 1521 \"Workflow Response Handling\"\n AddResponseToLibrary(PostDocumentCode(), 0, PostDocumentTxt, 'GROUP 0');\n AddResponseToLibrary(PostDocumentAsyncCode(), 0, BackgroundDocumentPostTxt, 'GROUP 0');\n \n- AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocAsyncCode(), DATABASE::\"Purch. Inv. Header\", CreatePmtLineAsyncTxt, 'GROUP 1');\n- AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocCode(), DATABASE::\"Purch. Inv. Header\", CreatePmtLineTxt, 'GROUP 1');\n+ AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocAsyncCode(), Database::\"Purch. Inv. Header\", CreatePmtLineAsyncTxt, 'GROUP 1');\n+ AddResponseToLibrary(CreatePmtLineForPostedPurchaseDocCode(), Database::\"Purch. Inv. Header\", CreatePmtLineTxt, 'GROUP 1');\n \n AddResponseToLibrary(CreateOverdueNotificationCode(), 0, CreateOverdueNotifTxt, 'GROUP 2');\n AddResponseToLibrary(CheckCustomerCreditLimitCode(), 0, CheckCustomerCreditLimitTxt, 'GROUP 0');\n@@ -624,22 +624,45 @@ codeunit 1521 \"Workflow Response Handling\"\n begin\n end;\n \n- local procedure CreateNotificationEntry(WorkflowStepInstance: Record \"Workflow Step Instance\"; ApprovalEntry: Record \"Approval Entry\")\n+ local procedure CreateNotificationEntry(WorkflowStepInstance: Record \"Workflow Step Instance\"; var Variant: Variant)\n var\n+ ApprovalEntry: Record \"Approval Entry\";\n WorkflowStepArgument: Record \"Workflow Step Argument\";\n NotificationEntry: Record \"Notification Entry\";\n+ RecRef: RecordRef;\n IsHandled: Boolean;\n begin\n- IsHandled := false;\n- OnBeforeCreateNotificationEntry(WorkflowStepInstance, ApprovalEntry, IsHandled);\n- if IsHandled then\n- exit;\n+ RecRef.GetTable(Variant);\n+ case RecRef.Number of\n+ Database::\"Approval Entry\":\n+ begin\n+ ApprovalEntry := Variant;\n+ IsHandled := false;\n+ OnBeforeCreateNotificationEntry(WorkflowStepInstance, ApprovalEntry, IsHandled);\n+ if IsHandled then\n+ exit;\n \n- if WorkflowStepArgument.Get(WorkflowStepInstance.Argument) then\n- NotificationEntry.CreateNotificationEntry(\n- WorkflowStepArgument.\"Notification Entry Type\",\n- WorkflowStepArgument.GetNotificationUserID(ApprovalEntry), ApprovalEntry, WorkflowStepArgument.\"Link Target Page\",\n- WorkflowStepArgument.\"Custom Link\", UserID);\n+ if WorkflowStepArgument.Get(WorkflowStepInstance.Argument) then\n+ NotificationEntry.CreateNotificationEntry(WorkflowStepArgument.\"Notification Entry Type\", WorkflowStepArgument.GetNotificationUserID(ApprovalEntry), ApprovalEntry, WorkflowStepArgument.\"Link Target Page\", WorkflowStepArgument.\"Custom Link\", CopyStr(UserId(), 1, 50));\n+ end;\n+ Database::\"Incoming Document\",\n+ Database::\"Gen. Journal Line\",\n+ Database::\"Purchase Header\",\n+ Database::\"Purch. Inv. Header\":\n+ if WorkflowStepArgument.Get(WorkflowStepInstance.Argument) then\n+ if WorkflowStepArgument.\"Notify Sender\" then\n+ NotificationEntry.CreateNotificationEntry(WorkflowStepArgument.\"Notification Entry Type\", CopyStr(UserId(), 1, 50), Variant, WorkflowStepArgument.\"Link Target Page\", WorkflowStepArgument.\"Custom Link\", CopyStr(UserId(), 1, 50))\n+ else\n+ NotificationEntry.CreateNotificationEntry(WorkflowStepArgument.\"Notification Entry Type\", WorkflowStepArgument.\"Notification User ID\", Variant, WorkflowStepArgument.\"Link Target Page\", WorkflowStepArgument.\"Custom Link\", CopyStr(UserId(), 1, 50));\n+ else begin\n+ ApprovalEntry.SetRange(\"Record ID to Approve\", RecRef.RecordId);\n+ if ApprovalEntry.FindFirst() then begin\n+ Variant := ApprovalEntry;\n+ CreateNotificationEntry(WorkflowStepInstance, Variant);\n+ end else\n+ Error(UnknownRecordErr);\n+ end;\n+ end;\n end;\n \n local procedure ReleaseDocument(var Variant: Variant)\n@@ -657,25 +680,25 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n TargetRecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n Variant := TargetRecRef;\n ReleaseDocument(Variant);\n end;\n- DATABASE::\"Workflow Webhook Entry\":\n+ Database::\"Workflow Webhook Entry\":\n begin\n WorkflowWebhookEntry := Variant;\n TargetRecRef.Get(WorkflowWebhookEntry.\"Record ID\");\n Variant := TargetRecRef;\n ReleaseDocument(Variant);\n end;\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n ReleasePurchaseDocument.PerformManualCheckAndRelease(Variant);\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n ReleaseSalesDocument.PerformManualCheckAndRelease(Variant);\n- DATABASE::\"Incoming Document\":\n+ Database::\"Incoming Document\":\n ReleaseIncomingDocument.PerformManualRelease(Variant);\n else begin\n OnReleaseDocument(RecRef, Handled);\n@@ -699,25 +722,25 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n TargetRecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n Variant := TargetRecRef;\n OpenDocument(Variant);\n end;\n- DATABASE::\"Workflow Webhook Entry\":\n+ Database::\"Workflow Webhook Entry\":\n begin\n WorkflowWebhookEntry := Variant;\n TargetRecRef.Get(WorkflowWebhookEntry.\"Record ID\");\n Variant := TargetRecRef;\n OpenDocument(Variant);\n end;\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n ReleasePurchaseDocument.Reopen(Variant);\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n ReleaseSalesDocument.Reopen(Variant);\n- DATABASE::\"Incoming Document\":\n+ Database::\"Incoming Document\":\n ReleaseIncomingDocument.Reopen(Variant);\n else begin\n OnOpenDocument(RecRef, Handled);\n@@ -782,7 +805,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n ApprovalsMgmt.SendApprovalRequestFromApprovalEntry(Variant, WorkflowStepInstance);\n else\n ApprovalsMgmt.SendApprovalRequestFromRecord(RecRef, WorkflowStepInstance);\n@@ -798,7 +821,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n@@ -818,7 +841,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n@@ -838,7 +861,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := Variant;\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n@@ -859,13 +882,13 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n begin\n PurchaseHeader := Variant;\n PurchaseHeader.TestField(Status, PurchaseHeader.Status::Released);\n JobQueueEntry.ScheduleJobQueueEntry(CODEUNIT::\"Purchase Post via Job Queue\", PurchaseHeader.RecordId);\n end;\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n begin\n SalesHeader := Variant;\n SalesHeader.TestField(Status, SalesHeader.Status::Released);\n@@ -884,9 +907,9 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Purchase Header\":\n+ Database::\"Purchase Header\":\n CODEUNIT.Run(CODEUNIT::\"Purch.-Post\", Variant);\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n CODEUNIT.Run(CODEUNIT::\"Sales-Post\", Variant);\n else begin\n IsHandled := false;\n@@ -923,7 +946,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n begin\n SalesHeader := Variant;\n SalesHeader.CheckAvailableCreditLimit();\n@@ -939,7 +962,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Gen. Journal Batch\":\n+ Database::\"Gen. Journal Batch\":\n begin\n GenJournalBatch := Variant;\n GenJournalBatch.CheckBalance();\n@@ -955,9 +978,9 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Sales Header\":\n+ Database::\"Sales Header\":\n ApprovalsMgmt.CreateAndAutomaticallyApproveRequest(RecRef, WorkflowStepInstance);\n- DATABASE::Customer:\n+ Database::Customer:\n ApprovalsMgmt.CreateAndAutomaticallyApproveRequest(RecRef, WorkflowStepInstance);\n end;\n end;\n@@ -997,30 +1020,30 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(Variant);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n RecordRestrictionMgt.AllowRecordUsage(Variant);\n RecRef.SetTable(ApprovalEntry);\n RecRef.Get(ApprovalEntry.\"Record ID to Approve\");\n AllowRecordUsage(RecRef);\n end;\n- DATABASE::\"Workflow Webhook Entry\":\n+ Database::\"Workflow Webhook Entry\":\n begin\n RecRef.SetTable(WorkflowWebhookEntry);\n RecRef.Get(WorkflowWebhookEntry.\"Record ID\");\n AllowRecordUsage(RecRef);\n end;\n- DATABASE::\"Gen. Journal Batch\":\n+ Database::\"Gen. Journal Batch\":\n begin\n RecRef.SetTable(GenJournalBatch);\n RecordRestrictionMgt.AllowGenJournalBatchUsage(GenJournalBatch);\n end;\n- DATABASE::\"Item Journal Batch\":\n+ Database::\"Item Journal Batch\":\n begin\n RecRef.SetTable(ItemJournalBatch);\n RecordRestrictionMgt.AllowItemJournalBatchUsage(ItemJournalBatch);\n end;\n- DATABASE::\"FA Journal Batch\":\n+ Database::\"FA Journal Batch\":\n begin\n RecRef.SetTable(FAJournalBatch);\n RecordRestrictionMgt.AllowFAJournalBatchUsage(FAJournalBatch);\n@@ -1306,7 +1329,7 @@ codeunit 1521 \"Workflow Response Handling\"\n RecRef.GetTable(VariantRecord);\n \n case RecRef.Number of\n- DATABASE::\"Approval Entry\":\n+ Database::\"Approval Entry\":\n begin\n ApprovalEntry := VariantRecord;\n RecRef := ApprovalEntry.\"Record ID to Approve\".GetRecord();\n"} +{"metadata": {"area": "purchases", "image_count": 6}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-192565", "base_commit": "2c4e6d219aac9b612e09224312d199d48212cead", "created_at": "2024-08-27", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134282, "functionName": ["ChangingDirectUnitCostToZeroChangesNonDeductibleVAT"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\nindex 355bce76f10f..b8424b6d859b 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleUT.Codeunit.al\n@@ -179,6 +179,34 @@ codeunit 134282 \"Non-Deductible UT\"\n Assert.ExpectedError(StrSubstNo(DifferentNonDedVATRatesSameVATIdentifierErr, VATPostingSetup.\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\"));\n end;\n \n+ [Test]\n+ procedure ChangingDirectUnitCostToZeroChangesNonDeductibleVAT()\n+ var\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ // [SCENARIO 546032] Changeing the direct unit cost to zero also changes the Non-Deductible VAT of the purchase document\n+\n+ Initialize();\n+ // [GIVEN] VAT Posting Setup with \"VAT Identifier\" = \"X\", \"Allow Non-Deductible VAT\" is enabled and \"Non-Deductible VAT %\" is specified\n+ LibraryNonDeductibleVAT.CreateNonDeductibleNormalVATPostingSetup(VATPostingSetup);\n+ // [GIVEN] Purchase invoice with Non-Deductible VAT posting setup and a single line with direct unit cost\n+ LibraryPurchase.CreatePurchHeader(\n+ PurchaseHeader, PurchaseHeader.\"Document Type\"::Invoice,\n+ LibraryPurchase.CreateVendorWithVATBusPostingGroup(VATPostingSetup.\"VAT Bus. Posting Group\"));\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item,\n+ LibraryInventory.CreateItemWithVATProdPostingGroup(VATPostingSetup.\"VAT Prod. Posting Group\"), LibraryRandom.RandInt(100));\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandDec(100, 2));\n+\n+ // [WHEN] Change \"Direct Unit Cost\" to 0 in the purchase line\n+ PurchaseLine.Validate(\"Direct Unit Cost\", 0);\n+ // [THEN] \"Non-Deductible VAT Base\" and \"Non-Deductible VAT Amount\" are 0 in the purchase line\n+ PurchaseLine.TestField(\"Non-Deductible VAT Base\", 0);\n+ PurchaseLine.TestField(\"Non-Deductible VAT Amount\", 0);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Non-Deductible UT\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al b/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al\nindex fb45dbcf51a0..09b9b67c9b09 100644\n--- a/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al\n@@ -5365,6 +5365,7 @@ table 39 \"Purchase Line\"\n Amount := 0;\n \"VAT Base Amount\" := 0;\n \"Amount Including VAT\" := 0;\n+ NonDeductibleVAT.ClearNonDeductibleVAT(Rec);\n OnUpdateVATAmountsOnBeforePurchLineModify(Rec, PurchLine2);\n if (Quantity = 0) and (xRec.Quantity <> 0) and (xRec.Amount <> 0) then begin\n if \"Line No.\" <> 0 then\n"} +{"metadata": {"area": "workflow", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-181900", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-04-21", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\General Journal"], "FAIL_TO_PASS": [{"codeunitID": 134321, "functionName": ["ShowImposedRestrictionBatchStatusForWorkflowUserGroupIfFirstApprovalEntryIsApproved"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al b/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al\nindex 686a4b745e40..7b4a1c13b2e5 100644\n--- a/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al\n+++ b/App/Layers/W1/Tests/General Journal/GeneralJournalBatchApproval.Codeunit.al\n@@ -935,7 +935,7 @@ codeunit 134321 \"General Journal Batch Approval\"\n \n // [THEN] Verify error message\n Assert.ExpectedError(PreventModifyRecordWithOpenApprovalEntryMsg);\n- end; \n+ end;\n \n [Test]\n procedure ShowImposedRestrictionBatchStatusIfUserModifyGenJournalLineForApprovedApprovalRequest()\n@@ -976,6 +976,41 @@ codeunit 134321 \"General Journal Batch Approval\"\n Assert.AreEqual(ImposedRestrictionLbl, GeneralJournal.GenJnlBatchApprovalStatus.Value(), 'Imposed restriction is not shown');\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ procedure ShowImposedRestrictionBatchStatusForWorkflowUserGroupIfFirstApprovalEntryIsApproved()\n+ var\n+ Workflow: Record Workflow;\n+ CurrentUserSetup: Record \"User Setup\";\n+ IntermediateApproverUserSetup: Record \"User Setup\";\n+ FinalApproverUserSetup: Record \"User Setup\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ GenJournalBatch: Record \"Gen. Journal Batch\";\n+ GeneralJournal: TestPage \"General Journal\";\n+ begin\n+ // [SCENARIO 526988] Show Imposed restriction batch status for Workflow User Group if first approval entry is auto approved\n+ Initialize();\n+\n+ // [GIVEN] Copy Workflow Template\n+ LibraryWorkflow.CopyWorkflowTemplate(Workflow, WorkflowSetup.GeneralJournalBatchApprovalWorkflowCode());\n+\n+ // [GIVEN] Setup - Create 3 user setups, create workflow user group and set the group for the workflow\n+ LibraryDocumentApprovals.CreateUserSetupsAndGroupOfApproversForWorkflow(\n+ Workflow, CurrentUserSetup, IntermediateApproverUserSetup, FinalApproverUserSetup);\n+ LibraryWorkflow.EnableWorkflow(Workflow);\n+\n+ // [GIVEN] Non-empty Gen. Journal Batch\n+ CreateGeneralJournalBatchWithOneJournalLine(GenJournalBatch, GenJournalLine);\n+\n+ // [WHEN] Approval request has been sent for Gen. Journal Batch\n+ SendApprovalRequestBatch(GenJournalBatch.Name);\n+\n+ // [THEN] Verify result\n+ GeneralJournal.OpenView();\n+ GeneralJournal.CurrentJnlBatchName.SetValue(GenJournalBatch.Name);\n+ Assert.AreEqual(ImposedRestrictionLbl, GeneralJournal.GenJnlBatchApprovalStatus.Value(), 'Imposed restriction is not shown');\n+ end;\n+\n local procedure Initialize()\n var\n Workflow: Record Workflow;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al b/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al\nindex 42799bec2311..8cd1a961d386 100644\n--- a/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/OtherCapabilities/Approvals/ApprovalsMgmt.Codeunit.al\n@@ -463,8 +463,17 @@ codeunit 1535 \"Approvals Mgmt.\"\n exit(ApprovalEntry.FindFirst());\n end;\n \n+ procedure FindLastApprovalEntryForCurrUser(var ApprovalEntry: Record \"Approval Entry\"; RecordID: RecordID): Boolean\n+ begin\n+ ApprovalEntry.SetRange(\"Table ID\", RecordID.TableNo);\n+ ApprovalEntry.SetRange(\"Record ID to Approve\", RecordID);\n+ ApprovalEntry.SetRange(\"Approver ID\", UserId);\n+ exit(ApprovalEntry.FindLast());\n+ end;\n+\n procedure FindApprovalEntryByRecordId(var ApprovalEntry: Record \"Approval Entry\"; RecordID: RecordID): Boolean\n begin\n+ ApprovalEntry.Reset();\n ApprovalEntry.SetRange(\"Table ID\", RecordID.TableNo);\n ApprovalEntry.SetRange(\"Record ID to Approve\", RecordID);\n exit(ApprovalEntry.FindLast());\n@@ -2483,8 +2492,11 @@ codeunit 1535 \"Approvals Mgmt.\"\n if not GenJournalBatch.Get(GenJournalLine.\"Journal Template Name\", GenJournalLine.\"Journal Batch Name\") then\n exit;\n \n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) then\n- GenJnlBatchApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalBatch);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalBatch.RecordId) then\n+ GenJnlBatchApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalBatch)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) then\n+ GenJnlBatchApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalBatch);\n end;\n \n procedure GetGenJnlLineApprovalStatus(GenJournalLine: Record \"Gen. Journal Line\"; var GenJnlLineApprovalStatus: Text[20]; EnabledGenJnlLineWorkflowsExist: Boolean)\n@@ -2495,8 +2507,11 @@ codeunit 1535 \"Approvals Mgmt.\"\n if not EnabledGenJnlLineWorkflowsExist then\n exit;\n \n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) then\n- GenJnlLineApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalLine);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalLine.RecordId) then\n+ GenJnlLineApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalLine)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) then\n+ GenJnlLineApprovalStatus := GetApprovalStatusFromApprovalEntry(ApprovalEntry, GenJournalLine);\n end;\n \n local procedure GetApprovalStatusFromApprovalEntry(var ApprovalEntry: Record \"Approval Entry\"; GenJournalBatch: Record \"Gen. Journal Batch\"): Text[20]\n@@ -2572,12 +2587,18 @@ codeunit 1535 \"Approvals Mgmt.\"\n begin\n if GenJournalBatch.Get(GenJournalLine.\"Journal Template Name\", GenJournalLine.\"Journal Batch Name\") then\n if IsGeneralJournalBatchApprovalsWorkflowEnabled(GenJournalBatch) then\n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n- GenJnlBatchApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalBatch.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlBatchApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalBatch.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlBatchApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n \n if IsGeneralJournalLineApprovalsWorkflowEnabled(GenJournalLine) then\n- if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n- GenJnlLineApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n+ if FindLastApprovalEntryForCurrUser(ApprovalEntry, GenJournalLine.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlLineApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20)\n+ else\n+ if FindApprovalEntryByRecordId(ApprovalEntry, GenJournalLine.RecordId) and (ApprovalEntry.Status = ApprovalEntry.Status::Approved) then\n+ GenJnlLineApprovalStatus := CopyStr(ImposedRestrictionLbl, 1, 20);\n end;\n \n local procedure FindOpenApprovalEntryForSequenceNo(RecRef: RecordRef; WorkflowStepInstance: Record \"Workflow Step Instance\"; SequenceNo: Integer): Boolean\n"} +{"metadata": {"area": "finance", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-182354", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-04-26", "environment_setup_version": "24.2", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134924, "functionName": ["TotalOverdueLCYInFinanceCue"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al\nindex 12edc29d5fd3..8f0836e38d21 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCues.Codeunit.al\n@@ -13,8 +13,6 @@ codeunit 134924 \"ERM Cues\"\n Assert: Codeunit Assert;\n LibraryTimeSheet: Codeunit \"Library - Time Sheet\";\n LibraryService: Codeunit \"Library - Service\";\n- WrongValueErr: Label 'Wrong value of the field %1 in table %2.';\n- AverageDaysDelayedErr: Label 'Average Days Delayed is calculated incorrectly.';\n LibraryUtility: Codeunit \"Library - Utility\";\n LibraryRandom: Codeunit \"Library - Random\";\n LibraryTestInitialize: Codeunit \"Library - Test Initialize\";\n@@ -24,6 +22,8 @@ codeunit 134924 \"ERM Cues\"\n ShipStatus: Option Full,Partial,\"Not Shipped\";\n WrongNumberOfDelayedOrdersErr: Label 'Wrong number of delayed Sales Orders.';\n RedundantSalesOnListErr: Label 'List of delayed Sales Order contains redundant documents.';\n+ WrongValueErr: Label 'Wrong value of the field %1 in table %2.', Comment = '%1 = Field name, %2 = Table name';\n+ AverageDaysDelayedErr: Label 'Average Days Delayed is calculated incorrectly.';\n IsInitialized: Boolean;\n \n [Test]\n@@ -699,6 +699,49 @@ codeunit 134924 \"ERM Cues\"\n Assert.IsFalse(SalesOrderList.Previous(), '');\n end;\n \n+ [Test]\n+ procedure TotalOverdueLCYInFinanceCue()\n+ var\n+ DetailedCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n+ CustomerLedgerEntries: TestPage \"Customer Ledger Entries\";\n+ AccountReceivablesKPIs: TestPage \"Account Receivables KPIs\";\n+ TotalOverDueLCYErr: Label 'The total overdue LCY amount is not calculated correctly.', Locked = true;\n+ DateFilterTxt: Label '<=%1', Locked = true, Comment = '%1 = Date';\n+ begin\n+ // [FEATURE] [Finance Cue] [Accounts Receivables Overview]\n+ // [SCENARIO 506725] Total overdue LCY cue in Finance Cue displays the amount of open overdue cust. ledger entries where due date filter is today\n+ Initialize();\n+\n+ // [GIVEN] Create customer ledger entries and detailed customer ledger entries\n+ // [GIVEN] Cust. ledger entry 1, due date = today - 10days, open = true, amount (LCY) = 100.34, remaining amount (LCY) = 50.17 (detailed cust. ledger entry 1 amount (LCY) = 100.34, detailed cust. ledger entry 2 amount (LCY) = 50.17)\n+ // [GIVEN] Cust. ledger entry 2, due date = today, open = false, amount (LCY) = 120.23, remaining amount (LCY) = 0 (detailed cust. ledger entry 1 amount (LCY) = 120.23, detailed cust. ledger entry 2 amount (LCY) = 120.23)\n+ // [GIVEN] Cust. ledger entry 3, due date = today + 20days, open = true, amount (LCY) = 150.82, remaining amount (LCY) = 150.82 (detailed cust. ledger entry 1 amount (LCY) = 150.82, detailed cust. ledger entry 2 amount (LCY) = 150.82)\n+ CreateCustomerLedgerEntry(CalcDate('<-10D>', Today), true, 100.34, 50.17);\n+ CreateCustomerLedgerEntry(Today, false, 120.23, 120.23);\n+ CreateCustomerLedgerEntry(CalcDate('<+20D>', Today), true, 150.82, 0);\n+\n+ // [WHEN] Open Account Receivables KPIs page with overdue date filter\n+ AccountReceivablesKPIs.OpenView();\n+ AccountReceivablesKPIs.Filter.SetFilter(\"Overdue Date Filter\", StrSubstNo(DateFilterTxt, Today()));\n+\n+ // [WHEN] Calculate total overdue LCY amount\n+ DetailedCustLedgEntry.SetFilter(\"Initial Entry Due Date\", '<=%1', Today());\n+ DetailedCustLedgEntry.CalcSums(\"Amount (LCY)\");\n+\n+ // [THEN] Verify the total overdue amount is correct\n+ Assert.AreEqual(Format(DetailedCustLedgEntry.\"Amount (LCY)\"), AccountReceivablesKPIs.\"Sales - Total Overdue (LCY)\".Value, TotalOverDueLCYErr);\n+\n+ // [WHEN] DrillDown to \"Sales - Total Overdue (LCY)\" cue\n+ CustomerLedgerEntries.Trap();\n+ AccountReceivablesKPIs.\"Sales - Total Overdue (LCY)\".Drilldown();\n+\n+ // [THEN] Only Cust. ledger entry 1 is shown on Cust. ledger entries page\n+ CustomerLedgerEntries.First();\n+ Assert.AreEqual(Format(CustomerLedgerEntries.\"Remaining Amt. (LCY)\"), AccountReceivablesKPIs.\"Sales - Total Overdue (LCY)\".Value, TotalOverDueLCYErr);\n+ Assert.IsFalse(CustomerLedgerEntries.Next(), '');\n+ CustomerLedgerEntries.Close();\n+ end;\n+\n local procedure Initialize()\n var\n SalesHeader: Record \"Sales Header\";\n@@ -711,6 +754,8 @@ codeunit 134924 \"ERM Cues\"\n ServiceContractLine: Record \"Service Contract Line\";\n PostedWhseShipmentHeader: Record \"Posted Whse. Shipment Header\";\n VendorLedgerEntry: Record \"Vendor Ledger Entry\";\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ DetailedCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n SalesCue: Record \"Sales Cue\";\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"ERM Cues\");\n@@ -724,6 +769,9 @@ codeunit 134924 \"ERM Cues\"\n ServiceContractLine.DeleteAll();\n PostedWhseShipmentHeader.DeleteAll();\n VendorLedgerEntry.DeleteAll();\n+ CustLedgerEntry.DeleteAll();\n+ DetailedCustLedgEntry.DeleteAll();\n+\n if SalesCue.Get() then begin\n SalesCue.\"Avg. Days Delayed Updated On\" := 0DT;\n SalesCue.Modify();\n@@ -924,6 +972,35 @@ codeunit 134924 \"ERM Cues\"\n SalesLine.Modify(true);\n end;\n \n+ local procedure CreateCustomerLedgerEntry(DueDate: Date; Open: Boolean; Amount1: Decimal; Amount2: Decimal)\n+ var\n+ CustLedgerEntry: Record \"Cust. Ledger Entry\";\n+ begin\n+ CustLedgerEntry.\"Entry No.\" := CustLedgerEntry.GetLastEntryNo() + 1;\n+ CustLedgerEntry.\"Document Type\" := CustLedgerEntry.\"Document Type\"::Invoice;\n+ CustLedgerEntry.\"Due Date\" := DueDate;\n+ CustLedgerEntry.Open := Open;\n+ CustLedgerEntry.Insert();\n+\n+ CreateDetailedCustLedgEntry(CustLedgerEntry.\"Entry No.\", DueDate, Amount1, CustLedgerEntry.\"Document Type\", true);\n+ CreateDetailedCustLedgEntry(CustLedgerEntry.\"Entry No.\", DueDate, -Amount2, CustLedgerEntry.\"Document Type\", false);\n+ end;\n+\n+ local procedure CreateDetailedCustLedgEntry(CustEntryNo: Integer; PostingDate: Date; AmountLCY: Decimal; DocumentType: Enum \"Gen. Journal Document Type\"; LedgerEntryAmount: Boolean)\n+ var\n+ DetailedCustLedgEntry: Record \"Detailed Cust. Ledg. Entry\";\n+ begin\n+ DetailedCustLedgEntry.\"Entry No.\" := DetailedCustLedgEntry.GetLastEntryNo() + 1;\n+ DetailedCustLedgEntry.\"Cust. Ledger Entry No.\" := CustEntryNo;\n+ DetailedCustLedgEntry.\"Posting Date\" := PostingDate;\n+ DetailedCustLedgEntry.\"Amount (LCY)\" := AmountLCY;\n+ DetailedCustLedgEntry.\"Document Type\" := DocumentType;\n+ DetailedCustLedgEntry.\"Initial Document Type\" := DocumentType;\n+ DetailedCustLedgEntry.\"Initial Entry Due Date\" := PostingDate;\n+ DetailedCustLedgEntry.\"Ledger Entry Amount\" := LedgerEntryAmount;\n+ DetailedCustLedgEntry.Insert();\n+ end;\n+\n local procedure VerifySalesCueFlowFields()\n var\n SalesCue: Record \"Sales Cue\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al b/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al\nindex 737182d0ac93..f685f4977ef3 100644\n--- a/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al\n+++ b/App/Layers/W1/BaseApp/RoleCenters/AccountReceivablesKPIs.Page.al\n@@ -27,8 +27,7 @@ page 1318 \"Account Receivables KPIs\"\n CustomerLedgerEntries: Page \"Customer Ledger Entries\";\n begin\n CustLedgerEntry.SetRange(Open, true);\n- CustLedgerEntry.SetFilter(\"Remaining Amount\", '>%1', 0);\n- CustLedgerEntry.SetFilter(\"Due Date\", '<=%1', WorkDate());\n+ CustLedgerEntry.SetFilter(\"Due Date\", '<=%1', Today());\n CustomerLedgerEntries.SetTableView(CustLedgerEntry);\n CustomerLedgerEntries.Run();\n end;\n@@ -43,7 +42,6 @@ page 1318 \"Account Receivables KPIs\"\n CustomerLedgerEntries: Page \"Customer Ledger Entries\";\n begin\n CustLedgerEntry.SetRange(Open, true);\n- CustLedgerEntry.SetFilter(\"Remaining Amount\", '>%1', 0);\n CustomerLedgerEntries.SetTableView(CustLedgerEntry);\n CustomerLedgerEntries.Run();\n end;\n@@ -93,12 +91,12 @@ page 1318 \"Account Receivables KPIs\"\n SalesInvoicesDueNextWeekStyleExpr: Text;\n AverageCollectionDays: Decimal;\n \n- trigger OnInit()\n+ trigger OnOpenPage()\n var\n CuesAndKPIs: Codeunit \"Cues And KPIs\";\n SalesInvoicesDueNextWeekStyle: Enum \"Cues And KPIs Style\";\n begin\n- Rec.SetRange(\"Overdue Date Filter\", 0D, WorkDate());\n+ Rec.SetRange(\"Overdue Date Filter\", 0D, Today());\n if not Rec.Get() then begin\n Clear(Rec);\n Rec.Insert();\n@@ -113,11 +111,7 @@ page 1318 \"Account Receivables KPIs\"\n CuesAndKPIs.SetCueStyle(Database::\"Activities Cue\", ActivitiesCue.FieldNo(\"Sales Invoices Due Next Week\"), ActivitiesCue.\"Sales Invoices Due Next Week\", SalesInvoicesDueNextWeekStyle);\n SalesInvoicesDueNextWeekStyleExpr := Format(SalesInvoicesDueNextWeekStyle);\n Rec.\"AR Accounts Balance\" := ActivitiesMgt.CalcARAccountsBalances();\n- Rec.Modify();\n- end;\n \n- trigger OnOpenPage()\n- begin\n AverageCollectionDays := ActivitiesMgt.CalcAverageCollectionDays();\n end;\n }\n\\ No newline at end of file\n"} +{"metadata": {"area": "finance", "image_count": 11}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-205825", "base_commit": "8a2cfe76e431fe32a28a3d7026b394fe107da284", "created_at": "2025-01-29", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134237, "functionName": ["ShipToCodeConnectionAltCustVATSetupOfBillToCustomer"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al b/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al\nindex 87257d5a7940..d1f8ce9750a8 100644\n--- a/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/AltCustVATDocTests.Codeunit.al\n@@ -768,6 +768,44 @@ codeunit 134237 \"Alt. Cust. VAT. Doc. Tests\"\n LibraryLowerPermissions.SetOutsideO365Scope();\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandler,MessageHandler,NoNotificationOtherThanShipToAddressSendNotificationHandler')]\n+ procedure ShipToCodeConnectionAltCustVATSetupOfBillToCustomer()\n+ var\n+ ShipToAddress: Record \"Ship-to Address\";\n+ AltCustVATReg: Record \"Alt. Cust. VAT Reg.\";\n+ SalesHeader: Record \"Sales Header\";\n+ Customer, BillToCustomer : Record Customer;\n+ begin\n+ // [SCENARIO 563939] VAT Registration data is copied to the sales header from the Alternative Customer VAT Registration setup\n+ // [SCENARIO 563939] when ship-to address connected to the Alternative Customer VAT Registration setup for the Bill-To Customer\n+\n+ Initialize();\n+ // [GIVEN] Sell-To Customer with country \"X\", \"VAT Registration No.\" = \"X1234567890\", \"Gen. Bus. Posting Group\" = \"CUSTBUS\", \"VAT Bus. Posting Group\" = \"CUSTVAT\"\n+ LibrarySales.CreateCustomerWithCountryCodeAndVATRegNo(Customer);\n+ // [GIVEN] Bill-To Customer with country \"Z\", \"VAT Registration No.\" = \"Z1234567890\", \"Gen. Bus. Posting Group\" = \"BILLCUSTBUS\", \"VAT Bus. Posting Group\" = \"BILLCUSTVAT\"\n+ LibrarySales.CreateCustomerWithCountryCodeAndVATRegNo(BillToCustomer);\n+ // [GIVEN] Ship-To Address with country \"Y\"\n+ LibrarySales.CreateShipToAddressWithRandomCountryCode(ShipToAddress, Customer.\"No.\");\n+ // [GIVEN] Bill-To Customer and Ship-To Code are assigned to the Sell-To Customer\n+ Customer.Validate(\"Bill-to Customer No.\", BillToCustomer.\"No.\");\n+ Customer.Validate(\"Ship-to Code\", ShipToAddress.Code);\n+ Customer.Modify(true);\n+ LibraryLowerPermissions.SetO365Setup();\n+ LibraryLowerPermissions.AddSalesDocsCreate();\n+ // [GIVEN] Alternative Customer VAT Reg. for Bill-To Customer with country \"Y\", \"VAT Registration No.\" = \"Y1234567890\", \"Gen. Bus. Posting Group\" = \"SHIPTOBUS\", \"VAT Bus. Posting Group\" = \"SHIPTOVAT\"\n+ LibraryAltCustVATReg.CreateAlternativeCustVATReg(AltCustVATReg, BillToCustomer.\"No.\", ShipToAddress.\"Country/Region Code\");\n+ // [WHEN] Create sales order for Sell-To Customer (Bill-To Customer and Ship-To Code are taken from the card)\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ // [THEN] Sales order has \"VAT Registration No.\" = \"Y1234567890\", \"Gen. Bus. Posting Group\" = \"SHIPTOBUS\", \"VAT Bus. Posting Group\" = \"SHIPTOVAT\", \"Country/Region Code\" = \"Y\"\n+ VerifyVATRegDataInSalesHeader(SalesHeader, AltCustVATReg.\"VAT Bus. Posting Group\", AltCustVATReg.\"Gen. Bus. Posting Group\", AltCustVATReg.\"VAT Registration No.\", AltCustVATReg.\"VAT Country/Region Code\");\n+ // [THEN] Sales order has \"Alt. VAT Registration No.\", \"Alt. Gen. Bus Posting Group\", \"Alt. VAT Bus Posting Group\" options\n+ LibraryAltCustVATReg.VerifySalesDocAltVATReg(SalesHeader, true);\n+ LibraryVariableStorage.AssertEmpty();\n+\n+ LibraryLowerPermissions.SetOutsideO365Scope();\n+ end;\n+\n local procedure Initialize()\n begin\n LibrarySetupStorage.Restore();\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al\nindex 9b4af6be278e..d41581d178d2 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Registration/AltCustVATRegDocImpl.Codeunit.al\n@@ -124,6 +124,7 @@ codeunit 205 \"Alt. Cust. VAT Reg. Doc. Impl.\" implements \"Alt. Cust. VAT Reg. Do\n procedure UpdateSetupOnBillToCustomerChangeInSalesHeader(var SalesHeader: Record \"Sales Header\"; xSalesHeader: Record \"Sales Header\"; BillToCustomer: Record Customer)\n var\n GLSetup: Record \"General Ledger Setup\";\n+ AltCustVATReg: Record \"Alt. Cust. VAT Reg.\";\n begin\n GLSetup.Get();\n if GLSetup.\"Bill-to/Sell-to VAT Calc.\" <> GLSetup.\"Bill-to/Sell-to VAT Calc.\"::\"Bill-to/Pay-to No.\" then\n@@ -135,6 +136,10 @@ codeunit 205 \"Alt. Cust. VAT Reg. Doc. Impl.\" implements \"Alt. Cust. VAT Reg. Do\n CopyFromCustomer(SalesHeader, xSalesHeader, BillToCustomer);\n exit;\n end;\n+ if AltCustVATRegFacade.GetAlternativeCustVATReg(AltCustVATReg, BillToCustomer.\"No.\", SalesHeader.\"Ship-to Country/Region Code\") then begin\n+ SalesHeader.Validate(\"VAT Country/Region Code\", AltCustVATReg.\"VAT Country/Region Code\");\n+ exit;\n+ end;\n if (SalesHeader.\"VAT Bus. Posting Group\" <> '') and (SalesHeader.\"VAT Bus. Posting Group\" <> BillToCustomer.\"VAT Bus. Posting Group\") then\n SalesHeader.Validate(\"VAT Bus. Posting Group\", BillToCustomer.\"VAT Bus. Posting Group\")\n else\n"} +{"metadata": {"area": "pricing", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-185696", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-06-06", "environment_setup_version": "24.2", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134123, "functionName": ["VariantCodeMustBeBlankWhenInsertNewRecord"]}], "PASS_TO_PASS": [{"codeunitID": 134123, "functionName": ["VerifyProductNoIsNotDeletedOnCreatingNewPriceLineFromItemWithVariant"]}], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al b/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al\nindex eebac8020258..77237aa5fd31 100644\n--- a/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/PriceListLineUT.Codeunit.al\n@@ -44,6 +44,7 @@ codeunit 134123 \"Price List Line UT\"\n AssignToNoErr: Label 'Invalid Assign-to No.';\n VATProdPostingGroupErr: Label 'VAT Product Posting Group are not equal.';\n AmountTypeNotAllowedForSourceTypeErr: Label '%1 is not allowed for %2.', Comment = '%1 - Price or Discount, %2 - Source Type';\n+ VariantCodeErr: Label 'Variant Code must be empty when new record is inserted.';\n \n [Test]\n [HandlerFunctions('ItemUOMModalHandler')]\n@@ -3337,12 +3338,9 @@ codeunit 134123 \"Price List Line UT\"\n SalesPriceList.Filter.SetFilter(Code, PriceListHeader.Code);\n CreateNewSalesPriceListLine(SalesPriceList, Item.\"No.\", ItemVariant.Code);\n \n- // [WHEN] Create new Price List line with same Item No.\n+ // [GIVEN] Create new Price List line with same Item No.\n CreateNewSalesPriceListLine(SalesPriceList, Item.\"No.\", '');\n \n- // [THEN] Verify Variant Code is automatically inserted in second line\n- SalesPriceList.Lines.\"Variant Code\".AssertEquals(ItemVariant.Code);\n-\n // [WHEN] Create New Price Line from Action \n CreateNewSalesPriceListLine(SalesPriceList, Item2.\"No.\", '');\n \n@@ -3716,6 +3714,53 @@ codeunit 134123 \"Price List Line UT\"\n PriceListHeader.\"Source Type\"));\n end;\n \n+ [Test]\n+ procedure VariantCodeMustBeBlankWhenInsertNewRecord()\n+ var\n+ Item: Record Item;\n+ ItemVariant: Record \"Item Variant\";\n+ PriceListHeader: Record \"Price List Header\";\n+ PriceListLine: Record \"Price List Line\";\n+ SalesPriceList: TestPage \"Sales Price List\";\n+ begin\n+ // [SCENARIO 537505] When creating a new price for variant items the variant code does not automatically display in the price list based on the previously created line.\n+ Initialize(true);\n+\n+ // [GIVEN] Create a Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create Item Variant.\n+ LibraryInventory.CreateItemVariant(ItemVariant, Item.\"No.\");\n+\n+ // [GIVEN] Create Sales Price Header with Price Type Sales and Source Type All Customers.\n+ LibraryPriceCalculation.CreatePriceHeader(\n+ PriceListHeader,\n+ PriceListHeader.\"Price Type\"::Sale,\n+ PriceListHeader.\"Source Type\"::\"All Customers\",\n+ '');\n+\n+ // [GIVEN] Create a Price Line.\n+ LibraryPriceCalculation.CreatePriceListLine(\n+ PriceListLine,\n+ PriceListHeader,\n+ \"Price Amount Type\"::Price,\n+ \"Price Asset Type\"::Item,\n+ Item.\"No.\");\n+\n+ // [GIVEN] Validate a Variant Code.\n+ PriceListLine.Validate(\"Variant Code\", ItemVariant.Code);\n+ PriceListLine.Modify();\n+\n+ // [GIVEN] Open Sales Price List Page and insert new Line.\n+ SalesPriceList.OpenEdit();\n+ SalesPriceList.GoToRecord(PriceListHeader);\n+ SalesPriceList.Lines.New();\n+ SalesPriceList.Lines.\"Product No.\".SetValue(Item.\"No.\");\n+\n+ // [THEN] The value of Variant Code in new line must be empty.\n+ Assert.AreEqual('', SalesPriceList.Lines.\"Variant Code\".Value(), VariantCodeErr);\n+ end;\n+\n local procedure Initialize()\n begin\n Initialize(false);\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al\nindex bb986d659922..878710ff4e3e 100644\n--- a/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al\n+++ b/App/Layers/W1/BaseApp/Pricing/PriceList/PriceListLines.Page.al\n@@ -303,6 +303,7 @@ page 7001 \"Price List Lines\"\n Rec.\"Currency Code\" := PriceListHeader.\"Currency Code\";\n end;\n Rec.\"Amount Type\" := ViewAmountType;\n+ Rec.SetNewRecord(true);\n Rec.Validate(\"Asset Type\", xRec.\"Asset Type\");\n UpdateSourceType();\n end;\ndiff --git a/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al b/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al\nindex 2ef8d1aedaac..f2e15e4b9634 100644\n--- a/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al\n+++ b/App/Layers/W1/BaseApp/Purchases/Pricing/PurchasePriceListLines.Page.al\n@@ -300,6 +300,7 @@ page 7011 \"Purchase Price List Lines\"\n Rec.\"Currency Code\" := PriceListHeader.\"Currency Code\";\n end;\n Rec.\"Amount Type\" := ViewAmountType;\n+ Rec.SetNewRecord(true);\n Rec.Validate(\"Asset Type\", xRec.\"Asset Type\");\n UpdateSourceType();\n end;\n"} +{"metadata": {"area": "inventory", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176426", "base_commit": "e66d3aeb3bbf39912d6108e40442d2cfbf77e983", "created_at": "2024-02-27", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137391, "functionName": ["RolledUpMaterialAndCapacityCostWithRoutingAndNoBOM"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al\nindex b8748ee00c6b..d226736c56e9 100644\n--- a/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMBOMCostSharesReport.Codeunit.al\n@@ -652,6 +652,45 @@ codeunit 137391 \"SCM - BOM Cost Shares Report\"\n BOMCostShares.Close();\n end;\n \n+ [Test]\n+ procedure RolledUpMaterialAndCapacityCostWithRoutingAndNoBOM()\n+ var\n+ FinalItem: Record Item;\n+ InterimItem: Record Item;\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ BOMBuffer: Record \"BOM Buffer\";\n+ BOMCostShares: TestPage \"BOM Cost Shares\";\n+ TotalLeafsRolledUpCapacityCost: Decimal;\n+ QtyPer: Decimal;\n+ begin\n+ // [FEATURE] [BOM Cost Share]\n+ // [SCENARIO 500356] Rolled-up Material Cost and Rolled-up Capacity Cost for a interim production item with no BOM.\n+ Initialize();\n+ QtyPer := LibraryRandom.RandIntInRange(5, 10);\n+\n+ LibraryAssembly.CreateItem(InterimItem, InterimItem.\"Costing Method\"::FIFO, InterimItem.\"Replenishment System\"::\"Prod. Order\", '', '');\n+ InterimItem.Validate(\"Unit Cost\", LibraryRandom.RandDecInRange(50, 100, 2));\n+ InterimItem.Modify(true);\n+ LibraryAssembly.CreateRouting(InterimItem, LibraryRandom.RandInt(2));\n+ UpdateRoutingCostValues(InterimItem.\"Routing No.\");\n+\n+ LibraryAssembly.CreateItem(FinalItem, FinalItem.\"Costing Method\"::FIFO, FinalItem.\"Replenishment System\"::\"Prod. Order\", '', '');\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, FinalItem.\"Base Unit of Measure\");\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader, ProductionBOMLine, '', ProductionBOMLine.Type::Item, InterimItem.\"No.\", QtyPer);\n+ LibraryManufacturing.UpdateProductionBOMStatus(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+ FinalItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ FinalItem.Modify(true);\n+\n+ BOMCostShares.Trap();\n+ RunBOMCostSharesPage(FinalItem);\n+ TotalLeafsRolledUpCapacityCost += GetRolledUpCapacityCostValue(BOMCostShares, BOMBuffer.Type::\"Machine Center\");\n+ TotalLeafsRolledUpCapacityCost += GetRolledUpCapacityCostValue(BOMCostShares, BOMBuffer.Type::\"Work Center\");\n+ VerifyParentItemMaterialAndCapacityCost(BOMCostShares, InterimItem.\"No.\", InterimItem.\"Unit Cost\" * QtyPer, TotalLeafsRolledUpCapacityCost);\n+ BOMCostShares.Close();\n+ end;\n+\n local procedure CreateRoutingWithWorkCenter(WorkCenterNo: Code[20]; SetupTime: Decimal; RunTime: Decimal; LotSize: Decimal): Code[20]\n var\n RoutingHeader: Record \"Routing Header\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al b/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al\nindex ab93f2c20bf4..c74223865e6f 100644\n--- a/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/BOM/BOMBuffer.Table.al\n@@ -872,6 +872,20 @@ table 5870 \"BOM Buffer\"\n OnAfterGetItemCosts(Rec, Item);\n end;\n \n+ procedure GetItemUnitCost()\n+ var\n+ Item: Record Item;\n+ begin\n+ TestField(Type, Type::Item);\n+ Item.Get(\"No.\");\n+\n+ \"Unit Cost\" := Item.\"Unit Cost\";\n+ \"Single-Level Material Cost\" :=\n+ RoundUnitAmt(Item.\"Unit Cost\", UOMMgt.GetQtyPerUnitOfMeasure(Item, \"Unit of Measure Code\") * \"Qty. per Top Item\");\n+ \"Rolled-up Material Cost\" :=\n+ RoundUnitAmt(Item.\"Unit Cost\", UOMMgt.GetQtyPerUnitOfMeasure(Item, \"Unit of Measure Code\") * \"Qty. per Top Item\");\n+ end;\n+\n procedure GetResCosts()\n var\n Res: Record Resource;\ndiff --git a/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al\nindex d639a56247c2..647d066cfea8 100644\n--- a/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/BOM/Tree/CalculateBOMTree.Codeunit.al\n@@ -714,9 +714,11 @@ codeunit 5870 \"Calculate BOM Tree\"\n end;\n BOMBuffer.RoundCosts(1 / LotSize);\n end else\n- if HasBomStructure(BOMBuffer.\"No.\") then begin\n+ if IsProductionOrAssemblyItem(BOMBuffer.\"No.\") then begin\n BOMBuffer.CalcOvhdCost();\n BOMBuffer.RoundCosts(1 / LotSize);\n+ if not HasBomStructure(BOMBuffer.\"No.\") then\n+ BOMBuffer.GetItemUnitCost();\n end else\n if BOMBuffer.Type = BOMBuffer.Type::Item then begin\n BOMBuffer.RoundCosts(1 / LotSize);\n@@ -998,6 +1000,16 @@ codeunit 5870 \"Calculate BOM Tree\"\n end;\n end;\n \n+ local procedure IsProductionOrAssemblyItem(ItemNo: Code[20]): Boolean\n+ var\n+ Item: Record Item;\n+ begin\n+ if not Item.Get(ItemNo) then\n+ exit(false);\n+\n+ exit(Item.IsMfgItem() or Item.IsAssemblyItem());\n+ end;\n+\n procedure SetItemFilter(var Item: Record Item)\n begin\n ItemFilter.CopyFilters(Item);\n"} +{"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-180484", "base_commit": "adb5a68cf897c6367b0a4e8dd4e53dbc18e2d199", "created_at": "2024-04-05", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Data Exchange"], "FAIL_TO_PASS": [{"codeunitID": 139154, "functionName": ["StatusRemainsCreatedIfHasLinkedDocWhenReopenIncomingDoc"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al b/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al\nindex 354a3c190d4e..b626696591a7 100644\n--- a/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al\n+++ b/App/Layers/W1/Tests/Data Exchange/IncomingDocToDataExchUT.Codeunit.al\n@@ -51,6 +51,9 @@ codeunit 139154 \"Incoming Doc. To Data Exch.UT\"\n NothingToReleaseErr: Label 'There is nothing to release for the incoming document';\n NoDocCreatedForChoiceErr: Label 'The given key was not present in the dictionary.';\n UnknownChoiceErr: Label 'Unknown choice %1.', Comment = '%1=Choice (number)';\n+ PEPPOLINVOICELbl: Label 'PEPPOLINVOICE';\n+ PEPPOLLbl: Label 'PEPPOL';\n+ StatusErr: Label '%1 must be %2 in %3';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1472,6 +1475,72 @@ codeunit 139154 \"Incoming Doc. To Data Exch.UT\"\n end;\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler')]\n+ [Scope('OnPrem')]\n+ procedure StatusRemainsCreatedIfHasLinkedDocWhenReopenIncomingDoc()\n+ var\n+ DataExchDef: Record \"Data Exch. Def\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesInvoiceHeader: Record \"Sales Invoice Header\";\n+ IncomingDocument: Record \"Incoming Document\";\n+ DataExchangeType: Record \"Data Exchange Type\";\n+ IncomingDocumentCard: TestPage \"Incoming Document\";\n+ XmlPath: Text;\n+ begin\n+ // [SCENARIO 487620] When Stan runs Reopen action on an Incoming Document hvaing Status as Created, then Status remains as Created if a document is linked to it.\n+ Initialize();\n+\n+ // [GIVEN] Create a Sales Invoice.\n+ SalesHeader.Get(\n+ SalesHeader.\"Document Type\"::Invoice,\n+ CreateSalesDocument(\n+ SalesHeader.\"Document Type\"::Invoice,\n+ false));\n+\n+ // [GIVEN] Post Sales Invoice.\n+ SalesInvoiceHeader.Get(LibrarySales.PostSalesDocument(SalesHeader, true, true));\n+\n+ // [GIVEN] Generate and save XmlPath of Sales Invoice.\n+ XmlPath := ExportPEPPOLInvoice(SalesInvoiceHeader);\n+\n+ // [GIVEN] Setup Company Information for Sales Invoice Import.\n+ SetupCompanyForInvoiceImport(SalesInvoiceHeader);\n+\n+ // [GIVEN] Find Data Exchange Def.\n+ DataExchDef.Get(PEPPOLINVOICELbl);\n+\n+ // [GIVEN] Create Data Exchange Type.\n+ CreateDataExchangeType(DataExchangeType, DataExchDef);\n+\n+ // [GIVEN] Create Incoming Document and Validate Data Exchange Type.\n+ LibraryIncomingDocuments.CreateNewIncomingDocument(IncomingDocument);\n+ IncomingDocument.\"Data Exchange Type\" := DataExchangeType.Code;\n+ IncomingDocument.Modify(true);\n+\n+ // [GIVEN] Import Incoming Document.\n+ ImportAttachToIncomingDoc(IncomingDocument, XmlPath);\n+\n+ // [GIVEN] Open Incoming Document Card page and run Create Document action.\n+ LibraryVariableStorage.Enqueue(DocCreatedMsg);\n+ IncomingDocumentCard.OpenView();\n+ IncomingDocumentCard.GotoRecord(IncomingDocument);\n+ IncomingDocumentCard.CreateDocument.Invoke();\n+\n+ // [WHEN] Run Reopen action.\n+ IncomingDocumentCard.Reopen.Invoke();\n+\n+ // [VERIFY] Status of Incoming Document remains as Created.\n+ Assert.AreEqual(\n+ Format(IncomingDocument.Status::Created),\n+ IncomingDocumentCard.StatusField.Value,\n+ StrSubstNo(\n+ StatusErr,\n+ IncomingDocumentCard.StatusField.Caption(),\n+ Format(IncomingDocument.Status::Created),\n+ IncomingDocument.TableCaption()));\n+ end;\n+\n local procedure CreateDataExchDefSalesInvoiceAndLinesWithNamespaces(var DataExchDef: Record \"Data Exch. Def\")\n var\n SalesHeaderDataExchLineDef: Record \"Data Exch. Line Def\";\n@@ -2788,6 +2857,19 @@ codeunit 139154 \"Incoming Doc. To Data Exch.UT\"\n IncomingDocumentsSetup.Insert();\n end;\n \n+ local procedure CreateDataExchangeType(var DataExchangeType: Record \"Data Exchange Type\"; DataExchDef: Record \"Data Exch. Def\")\n+ begin\n+ DataExchDef.SetLoadFields(Code);\n+\n+ DataExchangeType.SetLoadFields(Code, \"Data Exch. Def. Code\");\n+ DataExchangeType.SetRange(\"Data Exch. Def. Code\", DataExchDef.Code);\n+ if not DataExchangeType.FindFirst() then begin\n+ DataExchangeType.Code := PEPPOLLbl;\n+ DataExchangeType.\"Data Exch. Def. Code\" := DataExchDef.Code;\n+ DataExchangeType.Insert();\n+ end;\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Msg: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al b/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al\nindex 4e5ba08c9623..473de43b9844 100644\n--- a/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/eServices/EDocument/ReleaseIncomingDocument.Codeunit.al\n@@ -44,11 +44,15 @@ codeunit 132 \"Release Incoming Document\"\n #pragma warning restore AA0470\n \n procedure Reopen(var IncomingDocument: Record \"Incoming Document\")\n+ var\n+ RelatedRecord: Variant;\n begin\n if IncomingDocument.Status = IncomingDocument.Status::New then\n exit;\n ClearReleaseFields(IncomingDocument);\n- IncomingDocument.Status := IncomingDocument.Status::New;\n+\n+ if not ((IncomingDocument.Status = IncomingDocument.Status::Created) and (IncomingDocument.GetRecord(RelatedRecord))) then\n+ IncomingDocument.Status := IncomingDocument.Status::New;\n \n IncomingDocument.Modify(true);\n end;\n"} +{"metadata": {"area": "finance", "image_count": 2}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-183399", "base_commit": "c4993b11717cb45174b98a323daccad1a2c1dece", "created_at": "2024-05-09", "environment_setup_version": "24.2", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134918, "functionName": ["DocumentAmountInPurchJnlAcceptsMaxThreeDecimalPlacesValue"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al\nindex a7905ad0b622..1c700b31886a 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesPurchaseApplication.Codeunit.al\n@@ -1359,6 +1359,42 @@ codeunit 134918 \"ERM Sales/Purchase Application\"\n VerifyCustomerLedgerEntry(Customer.\"No.\");\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure DocumentAmountInPurchJnlAcceptsMaxThreeDecimalPlacesValue()\n+ var\n+ Vendor: Record Vendor;\n+ PurchaseJournal: TestPage \"Purchase Journal\";\n+ DocumentAmount: Decimal;\n+ begin\n+ // [SCENARIO 534464] Document Amount field in Purchase Journal accepts a value of maximum 3 decimal places.\n+ Initialize();\n+\n+ // [GIVEN] Create a Vendor.\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ // [GIVEN] Open Purchase Journal.\n+ PurchaseJournal.OpenView();\n+ PurchaseJournal.New();\n+ PurchaseJournal.\"Account Type\".SetValue(\"Gen. Journal Account Type\"::Vendor);\n+ PurchaseJournal.\"Account No.\".SetValue(Vendor.\"No.\");\n+\n+ // [GIVEN] Generate and save Document Amount in a Variable.\n+ DocumentAmount := LibraryRandom.RandDecInRange(1, 4, 3);\n+\n+ // [WHEN] Set value of 3 decimal places in Document Amount field in Purchase Journal.\n+ PurchaseJournal.DocumentAmount.SetValue(DocumentAmount);\n+\n+ // [THEN] Document Amount in Purchase Journal has a value of 3 decimal places.\n+ Assert.AreEqual(\n+ DocumentAmount,\n+ PurchaseJournal.DocumentAmount.AsDecimal(),\n+ StrSubstNo(\n+ DocumentAmountLogicErr,\n+ DocumentAmount,\n+ PurchaseJournal.DocumentAmount.AsDecimal()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\nindex 553ae9c0726d..bf8ed7e92221 100644\n--- a/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n+++ b/App/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/PurchaseJournal.Page.al\n@@ -255,6 +255,7 @@ page 254 \"Purchase Journal\"\n {\n ApplicationArea = Basic, Suite;\n AutoFormatExpression = Rec.\"Currency Code\";\n+ DecimalPlaces = 0 : 3;\n Caption = 'Document Amount';\n ToolTip = 'Specifies the total amount (including VAT) that the journal line consists of.';\n \n"} +{"metadata": {"area": "sales", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-174794", "base_commit": "756f85a4eec20b0b7b28b0c7fe0d63d8b08659a1", "created_at": "2024-02-12", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134911, "functionName": ["IssueFinChargeMemoCreatesGLEntryOfAltCustPostingGrpIfAllowMultiPostingGrps"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al\nindex 95a8024d1290..07fdee93db4b 100644\n--- a/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMCreateFinanceChargeMemo.Codeunit.al\n@@ -28,6 +28,7 @@ codeunit 134911 \"ERM Create Finance Charge Memo\"\n PrintDocRef: Option \" \",Print,Email;\n EmailTxt: Label 'abc@microsoft.com', Locked = true;\n ProceedOnIssuingWithInvRoundingQst: Label 'The invoice rounding amount will be added to the finance charge memo when it is posted according to invoice rounding setup.\\Do you want to continue?';\n+ GLEntryMustNotBeEmpty: Label 'GL Entry must not be empty.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -465,6 +466,71 @@ codeunit 134911 \"ERM Create Finance Charge Memo\"\n \n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ procedure IssueFinChargeMemoCreatesGLEntryOfAltCustPostingGrpIfAllowMultiPostingGrps()\n+ var\n+ Customer: Record Customer;\n+ CustomerPostingGroup: Record \"Customer Posting Group\";\n+ CustomerPostingGroup2: Record \"Customer Posting Group\";\n+ FinanceChargeMemoHeader: Record \"Finance Charge Memo Header\";\n+ FinanceChargeMemoLine: Record \"Finance Charge Memo Line\";\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ IssueFinChargeMemoHeader: Record \"Issued Fin. Charge Memo Header\";\n+ GLEntry: Record \"G/L Entry\";\n+ FinChargeTermsCode: Code[10];\n+ begin\n+ // [SCENARIO 498604] When stan Issue a Finance Charge Memo having Alternate Customer Posting Group of Customer having Allow Multiple Posting Groups as true then it creates GL Entry of Alternate Customer Posting Group's Receivables Account.\n+ Initialize();\n+\n+ // [GIVEN] Validate Allow Multiple Posting Groups in Sales & Receivables Setup.\n+ SalesReceivablesSetup.Get();\n+ SalesReceivablesSetup.Validate(\"Allow Multiple Posting Groups\", true);\n+ SalesReceivablesSetup.Modify(true);\n+\n+ // [GIVEN] Create Finance Charge Terms.\n+ FinChargeTermsCode := CreateFinanceChargeTerms(LibraryRandom.RandInt(0));\n+\n+ // [GIVEN] Create Customer Posting Group.\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup2);\n+\n+ // [GIVEN] Create Customer Posting group 2.\n+ LibrarySales.CreateCustomerPostingGroup(CustomerPostingGroup);\n+\n+ // [GIVEN] Create Alternate Customer Posting Group.\n+ LibrarySales.CreateAltCustomerPostingGroup(CustomerPostingGroup.Code, CustomerPostingGroup2.Code);\n+\n+ // [GIVEN] Create Customer and Validate Customer Posting Group,\n+ // Allow Multiple Posting Groups and Fin. Charge Terms Code.\n+ LibrarySales.CreateCustomer(Customer);\n+ Customer.Validate(\"Customer Posting Group\", CustomerPostingGroup.Code);\n+ Customer.Validate(\"Allow Multiple Posting Groups\", true);\n+ Customer.Validate(\"Fin. Charge Terms Code\", FinChargeTermsCode);\n+ Customer.Modify(true);\n+\n+ // [GIVEN] Create Finance Charge Memo Header and Validate Customer Posting Group.\n+ LibraryERM.CreateFinanceChargeMemoHeader(FinanceChargeMemoHeader, Customer.\"No.\");\n+ FinanceChargeMemoHeader.Validate(\"Customer Posting Group\", CustomerPostingGroup2.Code);\n+ FinanceChargeMemoHeader.Modify(true);\n+\n+ // [GIVEN] Create Finance Charge Memo Line.\n+ CreateFinChargeMemoLineForInvRounding(FinanceChargeMemoLine, FinanceChargeMemoHeader, LibraryRandom.RandInt(0));\n+\n+ // [GIVEN] Issue Finance Charge Memo.\n+ LibraryERM.IssueFinanceChargeMemo(FinanceChargeMemoHeader);\n+\n+ // [GIVEN] Find Issued Fin. Charge Memo Header.\n+ IssueFinChargeMemoHeader.SetRange(\"Customer No.\", Customer.\"No.\");\n+ IssueFinChargeMemoHeader.FindFirst();\n+\n+ // [WHEN] Find GL Entry.\n+ GLEntry.SetRange(\"Document No.\", IssueFinChargeMemoHeader.\"No.\");\n+ GLEntry.SetRange(\"G/L Account No.\", CustomerPostingGroup2.\"Receivables Account\");\n+\n+ // [VERIFY] GL Entry has Receivables Account of Customer Posting Group 2 in GL Account No. \n+ Assert.IsFalse(GLEntry.IsEmpty(), GLEntryMustNotBeEmpty);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al b/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al\nindex b941d50ca23b..952f98211c5e 100644\n--- a/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Sales/FinanceCharge/FinChrgMemoIssue.Codeunit.al\n@@ -278,6 +278,7 @@ codeunit 395 \"FinChrgMemo-Issue\"\n TempGenJnlLine.\"Account Type\" := AccType;\n TempGenJnlLine.\"Account No.\" := AccNo;\n TempGenJnlLine.Validate(\"Account No.\");\n+ TempGenJnlLine.\"Posting Group\" := FinChrgMemoHeader.\"Customer Posting Group\";\n if TempGenJnlLine.\"Account Type\" = TempGenJnlLine.\"Account Type\"::\"G/L Account\" then begin\n TempGenJnlLine.\"Gen. Posting Type\" := TempGenJnlLine.\"Gen. Posting Type\"::Sale;\n TempGenJnlLine.\"Gen. Bus. Posting Group\" := FinChrgMemoHeader.\"Gen. Bus. Posting Group\";\n"} +{"metadata": {"area": "finance", "image_count": 4}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-203923", "base_commit": "8a2cfe76e431fe32a28a3d7026b394fe107da284", "created_at": "2025-01-06", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134288, "functionName": ["NonDeductibleVATShouldShowAsNonDeductibleOnDoingFullVAT"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al\nindex 32fd94753bc2..e741895af851 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleVATJournal.Codeunit.al\n@@ -20,6 +20,7 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n IsInitialized: Boolean;\n ReverseEntriesQst: Label 'Do you want to reverse the entries';\n EntriesReversedLbl: Label 'The entries were successfully reversed';\n+ NonDeductiableVATAmountMustBeEqualErr: Label 'Non-Deductable VAT Amount must be %1 in VAT Entries', Comment = '%1 = Expected Non-Deductible VAT Amount';\n \n [Test]\n [Scope('OnPrem')]\n@@ -177,7 +178,7 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n GLEntry.SetRange(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n GLEntry.FindFirst();\n // [THEN] \"Non-Deductible VAT Amount\" is zero in all non-VAT G/L entries\n-\t\t// Bug 523795: Bal. Non-Deductible VAT amount is not correct \n+ // Bug 523795: Bal. Non-Deductible VAT amount is not correct \n GLEntry.TestField(\"Non-Deductible VAT Amount\", Round(GenJournalLine.\"Bal. VAT Amount\" * VATPostingSetup.\"Non-Deductible VAT %\" / 100));\n GLEntry.SetRange(\"VAT Bus. Posting Group\", '');\n GLEntry.SetRange(\"VAT Prod. Posting Group\", '');\n@@ -215,6 +216,44 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n GenJournalLine.TestField(\"Bal. Non-Ded. VAT %\", VATPostingSetup.\"Non-Deductible VAT %\");\n end;\n \n+ [Test]\n+ procedure NonDeductibleVATShouldShowAsNonDeductibleOnDoingFullVAT()\n+ var\n+ GLAccount: Record \"G/L Account\";\n+ GenJournalLine: Record \"Gen. Journal Line\";\n+ VATEntry: Record \"VAT Entry\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ NonDeductableVATAmount: Decimal;\n+ begin\n+ // [SCENARIO 537128] On posting Non-Deductible full VAT amount should be display in Non-Deductable VAT field of VAT Entry. \n+ Initialize();\n+\n+ // [GIVEN] Create Non-Deductible VAT Posting Setup with \"Non-Deductible VAT %\" = 100.\n+ LibraryNonDeductibleVAT.CreatVATPostingSetupAllowedForNonDeductibleVAT(VATPostingSetup, VATPostingSetup.\"VAT Calculation Type\"::\"Full VAT\", 100);\n+ VATPostingSetup.Validate(\"Purchase VAT Account\", LibraryERM.CreateGLAccountWithVATPostingSetup(VATPostingSetup, GLAccount.\"Gen. Posting Type\"::Purchase));\n+ VATPostingSetup.Validate(\"Non-Deductible VAT %\", 100);\n+ VATPostingSetup.Modify(true);\n+\n+ // [GIVEN] General Journal Line with Non-Deductible VAT Posting Setup and \"Account No\" = VATPostingSetup.\"Purchase VAT Account\".\n+ LibraryJournals.CreateGenJournalLineWithBatch(\n+ GenJournalLine, GenJournalLine.\"Document Type\"::\" \", GenJournalLine.\"Account Type\"::\"G/L Account\",\n+ VATPostingSetup.\"Purchase VAT Account\", LibraryRandom.RandDec(100, 2));\n+ GenJournalLine.Validate(\"Bal. Account No.\", LibraryERM.CreateGLAccountNo());\n+\n+ // [GIVEN] Validate VAT Bus. & Prod. Posting Group fields.\n+ GenJournalLine.Validate(\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ GenJournalLine.Validate(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n+ GenJournalLine.Modify(true);\n+ NonDeductableVATAmount := GenJournalLine.Amount;\n+\n+ // [WHEN] Post the General Journal.\n+ LibraryERM.PostGeneralJnlLine(GenJournalLine);\n+\n+ // [THEN] Verify that \"Non-Deductible VAT Amount\" field must have the value in VAT Entry.\n+ FindVATEntryByVATPostingSetup(VATEntry, VATPostingSetup);\n+ Assert.AreEqual(NonDeductableVATAmount, VATEntry.\"Non-Deductible VAT Amount\", StrSubstNo(NonDeductiableVATAmountMustBeEqualErr, NonDeductableVATAmount));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -244,6 +283,13 @@ codeunit 134288 \"Non-Deductible VAT Journal\"\n VATEntry.Testfield(\"Non-Deductible VAT Amount\", NDAmount);\n end;\n \n+ local procedure FindVATEntryByVATPostingSetup(var VATENtry: Record \"VAT Entry\"; VATPostingSetup: Record \"VAT Posting Setup\")\n+ begin\n+ VATEntry.SetRange(\"VAT Bus. Posting Group\", VATPostingSetup.\"VAT Bus. Posting Group\");\n+ VATEntry.SetRange(\"VAT Prod. Posting Group\", VATPostingSetup.\"VAT Prod. Posting Group\");\n+ VATEntry.FindLast();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex a4336dd72bcc..795e790c227f 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -95,7 +95,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n NonDeductibleVAT.OnBeforeGetNonDeductibleVATPct(NonDeductibleVATPct, VATPostingSetup, GeneralPostingType, IsHandled);\n if IsHandled then\n exit(NonDeductibleVATPct);\n- if not (VATPostingSetup.\"VAT Calculation Type\" in [VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\", VATPostingSetup.\"VAT Calculation Type\"::\"Reverse Charge VAT\"]) then\n+ if not (VATPostingSetup.\"VAT Calculation Type\" in [VATPostingSetup.\"VAT Calculation Type\"::\"Normal VAT\", VATPostingSetup.\"VAT Calculation Type\"::\"Reverse Charge VAT\", VATPostingSetup.\"VAT Calculation Type\"::\"Full VAT\"]) then\n exit(0);\n if (VATPostingSetup.\"Allow Non-Deductible VAT\" = VATPostingSetup.\"Allow Non-Deductible VAT\"::\"Do not allow\") or (GeneralPostingType <> GeneralPostingType::Purchase) then\n exit(0);\n@@ -720,7 +720,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n NonDeductibleVAT.OnBeforeCalcNonDedAmountsInGenJnlLine(GenJournalLine, Currency, IsHandled);\n if IsHandled then\n exit;\n- if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\"]) then\n+ if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Full VAT\"]) then\n exit;\n if not VATPostingSetup.Get(GenJournalLine.\"VAT Bus. Posting Group\", GenJournalLine.\"VAT Prod. Posting Group\") then\n exit;\n@@ -1078,7 +1078,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n NonDeductibleVAT.OnBeforeGetNonDedVATPctForGenJnlLine(NonDeductibleVATPct, GenJournalLine, IsHandled);\n if IsHandled then\n exit(NonDeductibleVATPct);\n- if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\"]) then\n+ if not (GenJournalLine.\"VAT Calculation Type\" in [GenJournalLine.\"VAT Calculation Type\"::\"Normal VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Reverse Charge VAT\", GenJournalLine.\"VAT Calculation Type\"::\"Full VAT\"]) then\n exit(0);\n if not VATPostingSetup.Get(GenJournalLine.\"VAT Bus. Posting Group\", GenJournalLine.\"VAT Prod. Posting Group\") then\n exit(0);\n"} +{"metadata": {"area": "finance", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-204450", "base_commit": "8a2cfe76e431fe32a28a3d7026b394fe107da284", "created_at": "2025-01-13", "environment_setup_version": "25.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\VAT"], "FAIL_TO_PASS": [{"codeunitID": 134287, "functionName": ["PurchaseInvoiceInCurrencyIsPostedWhenChangeVATAmountOnStatisticIfNDVATPctIs100"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al b/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al\nindex 9780fc9969b7..4060fd099d20 100644\n--- a/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al\n+++ b/App/Layers/W1/Tests/VAT/NonDeductibleVATStatistics.Codeunit.al\n@@ -16,8 +16,11 @@ codeunit 134287 \"Non-Deductible VAT Statistics\"\n LibraryPurchase: Codeunit \"Library - Purchase\";\n LibraryInventory: Codeunit \"Library - Inventory\";\n LibraryRandom: Codeunit \"Library - Random\";\n+ LibraryUtility: Codeunit \"Library - Utility\";\n+ LibraryERM: Codeunit \"Library - ERM\";\n Assert: Codeunit Assert;\n isInitialized: Boolean;\n+ GLEntryConsistentErr: Label 'G/L Entry is inconsistent';\n \n [Test]\n [HandlerFunctions('PurchaseStatisticsChangeVATAmountModalPageHandler')]\n@@ -640,6 +643,60 @@ codeunit 134287 \"Non-Deductible VAT Statistics\"\n LibraryVariableStorage.AssertEmpty();\n end;\n \n+ [Test]\n+ [HandlerFunctions('PurchaseStatisticsChangeVATAmountModalPageHandler')]\n+ procedure PurchaseInvoiceInCurrencyIsPostedWhenChangeVATAmountOnStatisticIfNDVATPctIs100()\n+ var\n+ Currency: Record Currency;\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchInvHeader: Record \"Purch. Inv. Header\";\n+ VATPostingSetup: Record \"VAT Posting Setup\";\n+ PurchaseInvoicePage: TestPage \"Purchase Invoice\";\n+ GenPostingType: Enum \"General Posting Type\";\n+ GLAccountNo: Code[20];\n+ ChangeVATAmount: Decimal;\n+ begin\n+ // [SCENARIO 560355] Purchase Invoice with currency code gets posted when Non-Deductible VAT is 100 Percent\n+ // And Non-Deductible VAT and the VAT Amount was previously modified in the Statistics.\n+ Initialize();\n+\n+ // [GIVEN] \"Allow VAT Difference\" is enabled in Purchases Setup.\n+ LibraryPurchase.SetAllowVATDifference(true);\n+\n+ // [GIVEN] Create Currency with Exchange Rate.\n+ CreateCurrencyWithExchangeRate(Currency);\n+\n+ // [GIVEN] Set \"Max. VAT Difference Allowed\" in Currency.\n+ SetMaxVATDifferenceAllowInCurrency(LibraryRandom.RandIntInRange(1000, 1000), Currency);\n+\n+ // [GIVEN] Generate VAT Amount to Change.\n+ ChangeVATAmount := LibraryRandom.RandIntInRange(150, 150);\n+\n+ // [GIVEN] Create Normal VAT Posting Setup with \"VAT %\" = 20 and Non-Deductible VAT %\" = 100. \n+ LibraryNonDeductibleVAT.CreateVATPostingSetupWithNonDeductibleDetail(VATPostingSetup, 20, 100);\n+\n+ // [GIVEN] Create a G/L Account.\n+ GLAccountNo := LibraryERM.CreateGLAccountWithVATPostingSetup(VATPostingSetup, GenPostingType::Purchase);\n+\n+ // [GIVEN] Create a Purchase Invoice.\n+ CreatePurchaseInvoiceWithCurrencyCode(PurchaseHeader, VATPostingSetup.\"VAT Bus. Posting Group\", Currency.Code, GLAccountNo);\n+ LibraryVariableStorage.Enqueue(ChangeVATAmount);\n+ LibraryVariableStorage.Enqueue(ChangeVATAmount);\n+\n+ // [GIVEN] Open Purchase Invoice page.\n+ PurchaseInvoicePage.OpenEdit();\n+ PurchaseInvoicePage.Filter.SetFilter(\"No.\", PurchaseHeader.\"No.\");\n+\n+ // [GIVEN] Open statistics of the invoice.\n+ PurchaseInvoicePage.Statistics.Invoke();\n+\n+ // [WHEN] Purchase Invoice is Posted.\n+ PurchInvHeader.Get(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true));\n+\n+ // [THEN] Verify G/L Entry is Consistent.\n+ VerifyGLEntryByDocumentNo(PurchInvHeader.\"No.\", 0);\n+ end;\n+\n local procedure SetAllowVATDifference(MaxVATDifference: Decimal)\n var\n PurchasesSetup: Record \"Purchases & Payables Setup\";\n@@ -672,6 +729,61 @@ codeunit 134287 \"Non-Deductible VAT Statistics\"\n GLEntry.TestField(Amount, ExpectedAmount);\n end;\n \n+ local procedure CreateCurrencyWithExchangeRate(var Currency: Record Currency)\n+ var\n+ CurrencyExchangeRate: Record \"Currency Exchange Rate\";\n+ begin\n+ Currency.Get(LibraryERM.CreateCurrencyWithGLAccountSetup());\n+\n+ LibraryERM.CreateExchRate(CurrencyExchangeRate, Currency.Code, WorkDate());\n+ CurrencyExchangeRate.Validate(\"Exchange Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Adjustment Exch. Rate Amount\", LibraryRandom.RandInt(0));\n+ CurrencyExchangeRate.Validate(\"Relational Exch. Rate Amount\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Validate(\"Relational Adjmt Exch Rate Amt\", LibraryRandom.RandDecInDecimalRange(0.6458, 0.6458, 4));\n+ CurrencyExchangeRate.Modify(true);\n+ end;\n+\n+ local procedure SetMaxVATDifferenceAllowInCurrency(MaxVATDifference: Decimal; Currency: Record Currency)\n+ begin\n+ Currency.Validate(\"Max. VAT Difference Allowed\", MaxVATDifference);\n+ Currency.Modify(true);\n+ end;\n+\n+ local procedure CreatePurchaseInvoiceWithCurrencyCode(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ VATBusPostingGroup: Code[20];\n+ CurrencyCode: Code[20];\n+ GLAccountNo: Code[20])\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ LibraryPurchase.CreatePurchHeader(\n+ PurchaseHeader,\n+ PurchaseHeader.\"Document Type\"::Invoice,\n+ LibraryPurchase.CreateVendorWithVATBusPostingGroup(VATBusPostingGroup));\n+ PurchaseHeader.Validate(\"Vendor Invoice No.\", LibraryUtility.GenerateGUID());\n+ PurchaseHeader.Validate(\"Currency Code\", CurrencyCode);\n+ PurchaseHeader.Modify(true);\n+\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::\"G/L Account\",\n+ GLAccountNo,\n+ LibraryRandom.RandInt(0));\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandIntInRange(1000, 1000));\n+ PurchaseLine.Modify(true);\n+ end;\n+\n+ local procedure VerifyGLEntryByDocumentNo(DocumentNo: Code[20]; ExpectedAmount: Decimal)\n+ var\n+ GLEntry: Record \"G/L Entry\";\n+ begin\n+ GLEntry.SetRange(\"Document No.\", DocumentNo);\n+ GLEntry.CalcSums(Amount);\n+ Assert.AreEqual(ExpectedAmount, GLEntry.Amount, GLEntryConsistentErr);\n+ end;\n+\n [ModalPageHandler]\n procedure PurchaseStatisticsChangeVATAmountModalPageHandler(var PurchaseStatisticsPage: TestPage \"Purchase Statistics\")\n var\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\nindex 795e790c227f..bab527724d87 100644\n--- a/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Finance/VAT/Calculation/NonDedVATImpl.Codeunit.al\n@@ -648,7 +648,7 @@ codeunit 6201 \"Non-Ded. VAT Impl.\"\n \n if PurchaseLine.\"Non-Deductible VAT %\" = 100 then begin\n PurchaseLine.\"Non-Deductible VAT Base\" := PurchaseLine.\"VAT Base Amount\";\n- PurchaseLine.\"Non-Deductible VAT Amount\" := PurchaseLine.\"Amount Including VAT\" - PurchaseLine.\"VAT Base Amount\" - PurchaseLine.\"VAT Difference\";\n+ PurchaseLine.\"Non-Deductible VAT Amount\" := PurchaseLine.\"Amount Including VAT\" - PurchaseLine.\"VAT Base Amount\";\n exit;\n end;\n PurchaseLine.\"Non-Deductible VAT Base\" :=\n"} +{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-175577", "base_commit": "aebdede0933c2e90c7d60098c88186f48bb3c278", "created_at": "2024-02-19", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136323, "functionName": ["OneSalesInvoiceIsCreatedForJobTasksWithMultipleCustomersBillingMethodAndSameCustomerAndCurrencyData"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\nindex cbe0b59640ef..75d9d5805088 100644\n--- a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n@@ -1236,6 +1236,67 @@ codeunit 136323 \"Jobs - Multiple Customers\"\n LibrarySales.PostSalesDocument(SalesHeaders[2], true, true);\n end;\n \n+ [Test]\n+ [HandlerFunctions('JobCreateSalesInvoiceHandler,MessageHandler')]\n+ procedure OneSalesInvoiceIsCreatedForJobTasksWithMultipleCustomersBillingMethodAndSameCustomerAndCurrencyData()\n+ var\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ JobTasks: array[2] of Record \"Job Task\";\n+ Customers: array[2] of Record Customer;\n+ SalesHeaders: array[4] of Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ JobCreateSalesInvoice: Report \"Job Create Sales Invoice\";\n+ Qty: Decimal;\n+ OneInvoicesAreCreatedMsg: Label '1 invoice is created.';\n+ begin\n+ // [SCENARIO 501468] One Sales Invoice is Created for Job Tasks with Multiple Customers Billing Method and Same Customer and Currency Data\n+ Initialize();\n+\n+ // [GIVEN] Set Multiple Customers on Project Setup\n+ SetMultiupleCustomersOnProjectSetup();\n+\n+ // [GIVEN] Create Customers\n+ LibrarySales.CreateCustomer(Customers[1]);\n+ LibrarySales.CreateCustomer(Customers[2]);\n+\n+ // [GIVEN] Create new Project\n+ LibraryJob.CreateJob(Job, Customers[1].\"No.\");\n+\n+ // [GIVEN] Create Project Task 1 with Customer 1 and Bill-to Customer 2\n+ LibraryJob.CreateJobTask(Job, JobTasks[1]);\n+ JobTasks[1].Validate(\"Bill-to Customer No.\", Customers[2].\"No.\");\n+ JobTasks[1].Modify(true);\n+\n+ // [GIVEN] Create Project Task 2 with Customer 1 and Bill-to Customer 2\n+ LibraryJob.CreateJobTask(Job, JobTasks[2]);\n+ JobTasks[2].Validate(\"Bill-to Customer No.\", Customers[2].\"No.\");\n+ JobTasks[2].Modify(true);\n+\n+ // [GIVEN] Create Job Planning Line with Qty to Transfer to Invoice\n+ Qty := LibraryRandom.RandInt(10);\n+ CreateJobPlanningLineWithQtyToTransferToInvoice(JobPlanningLine, JobTasks[1], Qty, Qty);\n+ CreateJobPlanningLineWithQtyToTransferToInvoice(JobPlanningLine, JobTasks[2], Qty, Qty);\n+\n+ // [GIVEN] Enqueue data\n+ LibraryVariableStorage.Enqueue(OneInvoicesAreCreatedMsg);\n+\n+ // [WHEN] Run batch job \"Create Job Sales Invoice\" for Job Tasks\n+ Commit(); // Commit required for batch report.\n+ JobTask.SetFilter(\"Job No.\", '%1', Job.\"No.\");\n+ JobCreateSalesInvoice.SetTableView(JobTask);\n+ JobCreateSalesInvoice.Run();\n+\n+ // [GIVEN] Find Sales Invoice\n+ FindSalesHeader(SalesHeaders[1], Customers[1].\"No.\", Customers[2].\"No.\", SalesHeaders[1].\"Document Type\"::Invoice);\n+ SalesLine.SetRange(\"Document Type\", SalesHeaders[1].\"Document Type\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeaders[1].\"No.\");\n+\n+ // [THEN] Verify results\n+ Assert.RecordCount(SalesLine, 2);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Jobs - Multiple Customers\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al\nindex 1e465e1669af..77ad8ede08e5 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobCreateInvoice.Codeunit.al\n@@ -15,6 +15,7 @@ using Microsoft.Sales.Document;\n using Microsoft.Sales.History;\n using Microsoft.Sales.Setup;\n using System.Reflection;\n+using System.Text;\n \n codeunit 1002 \"Job Create-Invoice\"\n {\n@@ -29,6 +30,7 @@ codeunit 1002 \"Job Create-Invoice\"\n SalesHeader2: Record \"Sales Header\";\n SalesLine: Record \"Sales Line\";\n TempJobPlanningLine: Record \"Job Planning Line\" temporary;\n+ TempJobPlanningLine2: Record \"Job Planning Line\" temporary;\n TransferExtendedText: Codeunit \"Transfer Extended Text\";\n JobInvCurrency: Boolean;\n UpdateExchangeRates: Boolean;\n@@ -320,9 +322,11 @@ codeunit 1002 \"Job Create-Invoice\"\n if CreateNewInvoice(JobTask, InvoicePerTask, OldJobNo, OldJobTaskNo, LastJobTask) then begin\n Job.Get(TempJobPlanningLine.\"Job No.\");\n Cust.Get(ReturnBillToCustomerNoDependingOnTaskBillingMethod(Job, JobTask2));\n- NoOfInvoices := NoOfInvoices + 1;\n SalesHeader2.\"Document Type\" := SalesHeader2.\"Document Type\"::Invoice;\n- CreateSalesHeader(Job, PostingDate, DocumentDate, TempJobPlanningLine);\n+ if not SalesInvoiceExistForMultipleCustomerBillingMethod(Job) then begin\n+ CreateSalesHeader(Job, PostingDate, DocumentDate, TempJobPlanningLine);\n+ NoOfInvoices := NoOfInvoices + 1;\n+ end;\n OnCreateSalesInvoiceJobTaskOnBeforeTempJobPlanningLineFind(JobTask, SalesHeader, InvoicePerTask, TempJobPlanningLine);\n if TempJobPlanningLine.Find('-') then\n repeat\n@@ -378,6 +382,11 @@ codeunit 1002 \"Job Create-Invoice\"\n if TransferLine(JobPlanningLine) then begin\n TempJobPlanningLine := JobPlanningLine;\n TempJobPlanningLine.Insert();\n+\n+ if Job.\"Task Billing Method\" = Job.\"Task Billing Method\"::\"Multiple customers\" then begin\n+ TempJobPlanningLine2 := JobPlanningLine;\n+ TempJobPlanningLine2.Insert();\n+ end;\n end;\n until JobPlanningLine.Next() = 0;\n end;\n@@ -483,6 +492,44 @@ codeunit 1002 \"Job Create-Invoice\"\n SalesHeader.Modify(true);\n end;\n \n+ local procedure SalesInvoiceExistForMultipleCustomerBillingMethod(Job: Record Job): Boolean\n+ var\n+ JobTask: Record \"Job Task\";\n+ JobTask2: Record \"Job Task\";\n+ JobPlanningLineInvoice: Record \"Job Planning Line Invoice\";\n+ TempJobPlanningLine3: Record \"Job Planning Line\" temporary;\n+ SelectionFilterMgt: Codeunit SelectionFilterManagement;\n+ RecRef: RecordRef;\n+ JobTaskFilter: Text;\n+ begin\n+ if Job.\"Task Billing Method\" = Job.\"Task Billing Method\"::\"One customer\" then\n+ exit;\n+\n+ TempJobPlanningLine3.Copy(TempJobPlanningLine2, true);\n+ TempJobPlanningLine3.Reset();\n+ TempJobPlanningLine3.SetFilter(\"Job Contract Entry No.\", '<>%1', TempJobPlanningLine.\"Job Contract Entry No.\");\n+ RecRef.GetTable(TempJobPlanningLine3);\n+ JobTaskFilter := SelectionFilterMgt.GetSelectionFilter(RecRef, TempJobPlanningLine3.FieldNo(\"Job Task No.\"));\n+ if JobTaskFilter = '' then\n+ exit;\n+\n+ if JobTask.Get(TempJobPlanningLine.\"Job No.\", TempJobPlanningLine.\"Job Task No.\") then begin\n+ JobTask2.SetRange(\"Job No.\", Job.\"No.\");\n+ JobTask2.SetFilter(\"Job Task No.\", JobTaskFilter);\n+ JobTask2.SetRange(\"Sell-to Customer No.\", JobTask.\"Sell-to Customer No.\");\n+ JobTask2.SetRange(\"Bill-to Customer No.\", JobTask.\"Bill-to Customer No.\");\n+ JobTask2.SetRange(\"Invoice Currency Code\", JobTask.\"Invoice Currency Code\");\n+ if JobTask2.FindFirst() then begin\n+ JobPlanningLineInvoice.SetRange(\"Job No.\", Job.\"No.\");\n+ JobPlanningLineInvoice.SetRange(\"Job Task No.\", JobTask2.\"Job Task No.\");\n+ if JobPlanningLineInvoice.FindFirst() then begin\n+ SalesHeader.Get(SalesHeader.\"Document Type\"::Invoice, JobPlanningLineInvoice.\"Document No.\");\n+ exit(true);\n+ end;\n+ end;\n+ end;\n+ end;\n+\n local procedure GetCustomerNo(Job: Record Job; JobPlanningLine: Record \"Job Planning Line\"; SellToCustomerNo: Boolean): Code[20]\n var\n JobTask: Record \"Job Task\";\n"} +{"metadata": {"area": "manufacturing", "image_count": 3}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176150", "base_commit": "85238b294e452f1fc0e21a94a5d0e8feec6bcc46", "created_at": "2024-02-23", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137072, "functionName": ["PreviewPostingOfProductionJournalPostsCorrectConsumptionILE"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al\nindex 4369f0c8683d..6ca685e45568 100644\n--- a/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMProductionOrdersII.Codeunit.al\n@@ -67,6 +67,7 @@ codeunit 137072 \"SCM Production Orders II\"\n TimeShiftedOnParentLineMsg: Label 'The production starting date-time of the end item has been moved forward because a subassembly is taking longer than planned.';\n DateConflictInReservErr: Label 'The change leads to a date conflict with existing reservations.';\n QuantityErr: Label '%1 must be %2 in %3', Comment = '%1: Quantity, %2: Consumption Quantity Value, %3: Item Ledger Entry';\n+ ILENoOfRecordsMustNotBeZeroErr: Label 'Item Ledger Entry No. of Records must not be zero.';\n \n [Test]\n [Scope('OnPrem')]\n@@ -4312,6 +4313,59 @@ codeunit 137072 \"SCM Production Orders II\"\n ItemLedgerEntry.TableCaption()));\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('ProductionJournalPageHandler,GLPostingPreviewPageHandler')]\n+ procedure PreviewPostingOfProductionJournalPostsCorrectConsumptionILE()\n+ var\n+ Item, Item2 : Record Item;\n+ ProductionOrder, ProductionOrder2 : Record \"Production Order\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ReleasedProdOrder: TestPage \"Released Production Order\";\n+ begin\n+ // [SCENARIO 501883] When Preview Post or Post Production Journal From a Released Production Order, it creates correct Item Ledger Entries even if there is a Consumption Journal Line of completely different Production Order No. in Consumption Journal.\n+ Initialize();\n+\n+ // [GIVEN] Create Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProductionOrder(\n+ ProductionOrder,\n+ ProductionOrder.Status::Released,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10),\n+ '',\n+ '');\n+\n+ // [GIVEN] Create Item 2.\n+ LibraryInventory.CreateItem(Item2);\n+\n+ // [GIVEN] Create and Refresh Production Order 2.\n+ CreateAndRefreshProductionOrder(\n+ ProductionOrder2,\n+ ProductionOrder2.Status::Released,\n+ Item2.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10),\n+ '',\n+ '');\n+\n+ // [GIVEN] Create Consumption Journal Line for Production Order 2.\n+ CreateConsumptionJournalLine(\n+ ItemJournalLine,\n+ ProductionOrder2.\"No.\",\n+ Item2.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ // [WHEN] Open Released Production Order page and run Production Journal action.\n+ ReleasedProdOrder.OpenEdit();\n+ ReleasedProdOrder.GoToRecord(ProductionOrder);\n+ ReleasedProdOrder.ProdOrderLines.ProductionJournal.Invoke();\n+\n+ // [VERIFY] Item Ledger Entry No. of Records in Posting Preview is not zero.\n+ Assert.AreNotEqual(0, LibraryVariableStorage.DequeueInteger(), ILENoOfRecordsMustNotBeZeroErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -6045,6 +6099,43 @@ codeunit 137072 \"SCM Production Orders II\"\n LibraryManufacturing.UpdateRoutingStatus(RoutingHeader, RoutingHeader.Status::Certified);\n end;\n \n+ local procedure CreateConsumptionJournalLine(\n+ var ItemJournalLine: Record \"Item Journal Line\";\n+ ProdOrderNo: Code[20];\n+ ItemNo: Code[20];\n+ Qty: Decimal)\n+ var\n+ ItemJnlTemplate: Record \"Item Journal Template\";\n+ ItemJnlBatch: Record \"Item Journal Batch\";\n+ begin\n+ InitItemJournalBatch(ItemJnlBatch, ItemJnlBatch.\"Template Type\"::Consumption);\n+ ItemJournalLine.Init();\n+ ItemJournalLine.\"Entry Type\" := ItemJournalLine.\"Entry Type\"::Consumption;\n+\n+ ItemJnlTemplate.Get(ItemJnlBatch.\"Journal Template Name\");\n+ LibraryInventory.CreateItemJnlLineWithNoItem(\n+ ItemJournalLine,\n+ ItemJnlBatch,\n+ ItemJnlTemplate.Name,\n+ ItemJnlBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::Consumption);\n+\n+ ItemJournalLine.Validate(\"Order Type\", ItemJournalLine.\"Order Type\"::Production);\n+ ItemJournalLine.Validate(\"Order No.\", ProdOrderNo);\n+ ItemJournalLine.Validate(\"Item No.\", ItemNo);\n+ ItemJournalLine.Validate(Quantity, Qty);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n+ local procedure InitItemJournalBatch(var ItemJnlBatch: Record \"Item Journal Batch\"; TemplateType: Enum \"Item Journal Template Type\")\n+ var\n+ ItemJnlTemplate: Record \"Item Journal Template\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJnlTemplate, TemplateType);\n+ LibraryInventory.SelectItemJournalBatchName(ItemJnlBatch, TemplateType, ItemJnlTemplate.Name);\n+ LibraryInventory.ClearItemJournal(ItemJnlTemplate, ItemJnlBatch);\n+ end;\n+\n [ModalPageHandler]\n procedure ProductionJournalModalPageHandler(var ProductionJournal: TestPage \"Production Journal\")\n begin\n@@ -6143,6 +6234,21 @@ codeunit 137072 \"SCM Production Orders II\"\n ProductionJournal.Post.Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandler(var ProductionJournal: TestPage \"Production Journal\")\n+ begin\n+ ProductionJournal.PreviewPosting.Invoke();\n+ end;\n+\n+ [PageHandler]\n+ [Scope('OnPrem')]\n+ procedure GLPostingPreviewPageHandler(var ShowAllEntries: TestPage \"G/L Posting Preview\")\n+ begin\n+ ShowAllEntries.Filter.SetFilter(\"Table Name\", 'Item Ledger Entry');\n+ LibraryVariableStorage.Enqueue(ShowAllEntries.\"No. of Records\".AsInteger());\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al b/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al\nindex 55d3fbadd560..3b65f2ca204f 100644\n--- a/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al\n+++ b/App/Layers/W1/BaseApp/Manufacturing/Journal/ProductionJournal.Page.al\n@@ -1015,7 +1015,7 @@ page 5510 \"Production Journal\"\n \n protected procedure MarkRelevantRec(var ItemJournalLine: Record \"Item Journal Line\")\n begin\n- ItemJournalLine := Rec;\n+ ItemJournalLine.CopyFilters(Rec);\n if ItemJournalLine.FindSet() then begin\n repeat\n case ItemJournalLine.\"Entry Type\" of\n"} +{"metadata": {"area": "inventory", "image_count": 1}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-175765", "base_commit": "367956511110141ab18a506a72cf2f7c3255bcbf", "created_at": "2024-02-20", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137038, "functionName": ["AdjustCostOfUndoneTransferShipment"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\nindex ade329a726ce..e0b3ba5f0bf7 100644\n--- a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n@@ -3595,6 +3595,66 @@\n PostedTranferReceipt.Close();\n end;\n \n+ [Test]\n+ [HandlerFunctions('ConfirmHandlerYes')]\n+ [Scope('OnPrem')]\n+ procedure AdjustCostOfUndoneTransferShipment()\n+ var\n+ Item: Record Item;\n+ InTransitLocation: Record Location;\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ ItemLedgerEntryNo: Integer;\n+ LocationFromCode, LocationTOCode : Code[10];\n+ OldCost, NewCost : Decimal;\n+ begin\n+ // [FEATURE] [Transfer] [Undo Shipment] [Costing] [Adjust Cost - Item Entries]\n+ // [SCENARIO 496575] Item ledger entry for undone transfer shipment is adjusted with the correct cost.\n+ Initialize();\n+ OldCost := LibraryRandom.RandDec(100, 2);\n+ NewCost := LibraryRandom.RandDecInDecimalRange(101, 200, 2);\n+\n+ // [GIVEN] Item \"I\".\n+ // [GIVEN] Locations \"From\" and \"To\".\n+ LibraryInventory.CreateItem(Item);\n+ CreateLocations(LocationFromCode, LocationToCode);\n+ LibraryWarehouse.CreateInTransitLocation(InTransitLocation);\n+\n+ // [GIVEN] Post inventory adjustment of \"I\" to location \"From\". Unit Cost = 10.\n+ CreateAndPostItemJnlWithCostLocationVariant(\n+ \"Item Ledger Entry Type\"::\"Positive Adjmt.\", Item.\"No.\", 1, OldCost, LocationFromCode, '');\n+ ItemLedgerEntryNo := FindLastILENo(Item.\"No.\");\n+\n+ // [GIVEN] Create transfer order from \"From\" to \"To\".\n+ // [GIVEN] Ship the transfer order.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, LocationFromCode, LocationToCode, InTransitLocation.Code);\n+ LibraryInventory.CreateTransferLine(TransferHeader, TransferLine, Item.\"No.\", 1);\n+ LibraryInventory.PostTransferHeader(TransferHeader, true, false);\n+\n+ // [GIVEN] Revaluate the item entry for the inventory adjustment, new cost = 12.\n+ CreateAndPostRevaluationJournal(Item.\"No.\", ItemLedgerEntryNo, 1, NewCost);\n+\n+ // [GIVEN] Adjust cost.\n+ LibraryCosting.AdjustCostItemEntries(Item.\"No.\", '');\n+\n+ // [WHEN] Undo the transfer shipment and run the cost adjustment.\n+ LibraryInventory.UndoTransferShipments(TransferHeader.\"No.\");\n+ LibraryCosting.AdjustCostItemEntries(Item.\"No.\", '');\n+\n+ // [THEN] Unit cost of \"I\" = 12.\n+ Item.Find();\n+ Item.TestField(\"Unit Cost\", NewCost);\n+\n+ // [THEN] Item ledger entry for the undone transfer shipment is adjusted. Unit Cost = 12.\n+ ItemLedgerEntry.Get(FindLastILENo(Item.\"No.\"));\n+ ItemLedgerEntry.TestField(\"Entry Type\", ItemLedgerEntry.\"Entry Type\"::Transfer);\n+ ItemLedgerEntry.TestField(\"Location Code\", LocationFromCode);\n+ ItemLedgerEntry.TestField(Positive, true);\n+ ItemLedgerEntry.CalcFields(\"Cost Amount (Actual)\");\n+ ItemLedgerEntry.TestField(\"Cost Amount (Actual)\", NewCost);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -3708,6 +3768,26 @@\n UpdateLocation(LocationCode[5], true, HandlingTime2, HandlingTime2);\n end;\n \n+ local procedure CreateAndPostRevaluationJournal(ItemNo: Code[20]; AppliesToEntry: Integer; InventoryValueRevalued: Decimal; UnitCostRevalued: Decimal)\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ LibraryInventory.SelectItemJournalTemplateName(ItemJournalTemplate, ItemJournalTemplate.Type::Revaluation);\n+ LibraryInventory.CreateItemJournalBatch(ItemJournalBatch, ItemJournalTemplate.Name);\n+ ItemJournalLine.Validate(\"Journal Template Name\", ItemJournalBatch.\"Journal Template Name\");\n+ ItemJournalLine.Validate(\"Journal Batch Name\", ItemJournalBatch.Name);\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine, ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name, ItemJournalLine.\"Entry Type\"::\" \", ItemNo, 0);\n+ ItemJournalLine.Validate(\"Value Entry Type\", ItemJournalLine.\"Value Entry Type\"::Revaluation);\n+ ItemJournalLine.Validate(\"Applies-to Entry\", AppliesToEntry);\n+ ItemJournalLine.Validate(\"Inventory Value (Revalued)\", InventoryValueRevalued);\n+ ItemJournalLine.Validate(\"Unit Cost (Revalued)\", UnitCostRevalued);\n+ ItemJournalLine.Modify(true);\n+ LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n+ end;\n+\n local procedure PostTransferShipmentPartiallyWithBlockedItem(DirectTransfer: Boolean)\n var\n Location: array[3] of Record Location;\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\nindex 7eff49508788..7e739c297201 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n@@ -7182,6 +7182,19 @@ codeunit 22 \"Item Jnl.-Post Line\"\n Error(Text027);\n end;\n \n+ procedure MarkAppliedInboundItemEntriesForAdjustment(OutboundItemLedgerEntryNo: Integer)\n+ var\n+ InboundItemLedgerEntry: Record \"Item Ledger Entry\";\n+ ItemApplicationEntry: Record \"Item Application Entry\";\n+ begin\n+ if ItemApplicationEntry.GetInboundEntriesTheOutbndEntryAppliedTo(OutboundItemLedgerEntryNo) then\n+ repeat\n+ InboundItemLedgerEntry.SetLoadFields(\"Applied Entry to Adjust\");\n+ InboundItemLedgerEntry.Get(ItemApplicationEntry.\"Inbound Item Entry No.\");\n+ InboundItemLedgerEntry.SetAppliedEntryToAdjust(true);\n+ until ItemApplicationEntry.Next() = 0;\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnVerifyInvoicedQtyOnAfterGetSalesShipmentHeader(ItemLedgEntry2: Record \"Item Ledger Entry\"; var IsHandled: Boolean)\n begin\ndiff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al\nindex b47fc326b34d..14b98317476f 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/UndoTransferShipment.Codeunit.al\n@@ -332,13 +332,18 @@ codeunit 9030 \"Undo Transfer Shipment\"\n until TempItemEntryRelation.Next() = 0;\n end;\n \n- local procedure GetShptEntries(TransShptLine: Record \"Transfer Shipment Line\"; var ItemLedgEntry: Record \"Item Ledger Entry\"): Boolean\n+ local procedure GetShptEntries(TransShptLine: Record \"Transfer Shipment Line\"; var ItemLedgEntry: Record \"Item Ledger Entry\") Found: Boolean\n begin\n ItemLedgEntry.SetCurrentKey(\"Document No.\", \"Document Type\", \"Document Line No.\");\n ItemLedgEntry.SetRange(\"Document Type\", ItemLedgEntry.\"Document Type\"::\"Transfer Shipment\");\n ItemLedgEntry.SetRange(\"Document No.\", TransShptLine.\"Document No.\");\n ItemLedgEntry.SetRange(\"Document Line No.\", TransShptLine.\"Line No.\");\n- exit(ItemLedgEntry.FindSet());\n+ Found := ItemLedgEntry.FindSet();\n+\n+ if Found then\n+ repeat\n+ ItemJnlPostLine.MarkAppliedInboundItemEntriesForAdjustment(ItemLedgEntry.\"Entry No.\");\n+ until ItemLedgEntry.Next() = 0;\n end;\n \n local procedure MakeInventoryAdjustment()\n"} +{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-179733", "base_commit": "e5aa32e995fb795e9ee046e61b8f7ca8574be337", "created_at": "2024-03-26", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136323, "functionName": ["CopyTotalsProjectTasksTypeIntoProjectsWithMultipleCustomerBillingOption"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\nindex bf797dc801c0..b0c36dc1d842 100644\n--- a/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobsMultipleCustomers.Codeunit.al\n@@ -1520,6 +1520,53 @@ codeunit 136323 \"Jobs - Multiple Customers\"\n SalesLine.TestField(\"Document No.\", SalesHeader.\"No.\");\n end;\n \n+ [Test]\n+ procedure CopyTotalsProjectTasksTypeIntoProjectsWithMultipleCustomerBillingOption()\n+ var\n+ JobTasks: array[3] of Record \"Job Task\";\n+ Jobs: array[2] of Record Job;\n+ Customers: array[2] of Record Customer;\n+ CopyJob: Codeunit \"Copy Job\";\n+ begin\n+ // [SCENARIO 522645] Copy Totals Project Tasks Type into Projects with Multiple Customer Billing Option\n+ Initialize();\n+\n+ // [GIVEN] Set One Customer Billing option on Project Setup\n+ SetOneCustomerBillingMethodOnProjectSetup();\n+\n+ // [GIVEN] Create Customer\n+ LibrarySales.CreateCustomer(Customers[1]);\n+\n+ // [GIVEN] Create new Project\n+ LibraryJob.CreateJob(Jobs[1], Customers[1].\"No.\");\n+\n+ // [GIVEN] Create new Project Task of Type Begin Total\n+ LibraryJob.CreateJobTask(Jobs[1], JobTasks[1]);\n+ JobTasks[1].\"Job Task Type\" := JobTasks[1].\"Job Task Type\"::\"Begin-Total\";\n+ JobTasks[1].Modify(true);\n+\n+ // [GIVEN] Create new Project Task\n+ LibraryJob.CreateJobTask(Jobs[1], JobTasks[2]);\n+\n+ // [GIVEN] Set Multiple Customers on Project Setup\n+ SetMultiupleCustomersOnProjectSetup();\n+\n+ // [GIVEN] Create new Project\n+ LibraryJob.CreateJob(Jobs[2], Customers[1].\"No.\");\n+\n+ // [WHEN] Copy Project Tasks\n+ CopyJob.CopyJobTasks(Jobs[1], Jobs[2]);\n+\n+ // [THEN] Verify results\n+ JobTasks[3].Get(Jobs[2].\"No.\", JobTasks[1].\"Job Task No.\");\n+ JobTasks[3].TestField(\"Sell-to Customer No.\", '');\n+ JobTasks[3].TestField(\"Bill-to Customer No.\", '');\n+\n+ JobTasks[3].Get(Jobs[2].\"No.\", JobTasks[2].\"Job Task No.\");\n+ JobTasks[3].TestField(\"Sell-to Customer No.\", Jobs[2].\"Sell-to Customer No.\");\n+ JobTasks[3].TestField(\"Bill-to Customer No.\", Jobs[2].\"Bill-to Customer No.\");\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Jobs - Multiple Customers\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al b/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al\nindex ca6d73fa1a86..31cb529bc5b3 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Job/JobTask.Table.al\n@@ -1223,9 +1223,13 @@ table 1001 \"Job Task\"\n begin\n if not Job.Get(\"Job No.\") then\n exit;\n+\n if Job.\"Task Billing Method\" = Job.\"Task Billing Method\"::\"One customer\" then\n exit;\n \n+ if \"Job Task Type\" <> \"Job Task Type\"::Posting then\n+ exit;\n+\n SetHideValidationDialog(true);\n if Job.\"Sell-to Customer No.\" <> '' then\n Validate(\"Sell-to Customer No.\", Job.\"Sell-to Customer No.\");\n"} +{"metadata": {"area": "purchases", "image_count": 9}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176194", "base_commit": "fd0cc7aae1b3276f00096391f042fdbe73a7b5fd", "created_at": "2024-02-25", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\ERM"], "FAIL_TO_PASS": [{"codeunitID": 134329, "functionName": ["GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToReceiveIsBlankInPurchPayablesSetup"]}, {"codeunitID": 134387, "functionName": ["GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToShipIsBlankInSalesReceiSetup"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al\nindex 75cffb82321a..4b0d9d056234 100644\n--- a/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMPurchaseReturnOrder.Codeunit.al\n@@ -48,6 +48,8 @@ codeunit 134329 \"ERM Purchase Return Order\"\n ContactShouldBeEditableErr: Label 'Contact should be editable when vendorr is selected.';\n FunctionMustNotBeCalledErr: Label 'Function %1 must not be called.', Comment = '%1 - function name';\n BatchPostingErrrorNotificationMsg: Label 'An error or warning occured during operation Batch processing of Purchase Header records.';\n+ ReturnQtyToShipMustBeZeroErr: Label ' Return Qty. to Ship must be zero.';\n+ QtyToAssignErr: Label '%1 must be %2 in %3', Comment = '%1 = Qty. to Assign, %2 = Quantity, %3 = Purchase Return Order Subform';\n \n [Test]\n [Scope('OnPrem')]\n@@ -1376,6 +1378,83 @@ codeunit 134329 \"ERM Purchase Return Order\"\n PurchaseLine.TableCaption));\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('SuggestItemChargeAssignmentPageHandler,PostedPurchDocumentLinesPageHandler')]\n+ procedure GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToReceiveIsBlankInPurchPayablesSetup()\n+ var\n+ Item: Record Item;\n+ ItemCharge: Record \"Item Charge\";\n+ PurchasePayablesSetup: Record \"Purchases & Payables Setup\";\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseHeader2: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ Quantity: Decimal;\n+ PurchaseReturnOrder: TestPage \"Purchase Return Order\";\n+ PurchaseReturnOrderSubform: TestPage \"Purchase Return Order Subform\";\n+ begin\n+ // [SCENARIO 500596] Get Posted Document Lines to Reverse action on Purchase Return Order copies Purchase Invoice Lines of Type Item Charge Even when Default Qty to Receive on Purchase & Payables Setup is set to Blank.\n+ Initialize();\n+\n+ // [GIVEN] Validate Default Qty. to Receive in Purchase & Payables Setup.\n+ PurchasePayablesSetup.Get();\n+ PurchasePayablesSetup.Validate(\"Default Qty. to Receive\", PurchasePayablesSetup.\"Default Qty. to Receive\"::Blank);\n+ PurchasePayablesSetup.Modify(true);\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create an Item Charge.\n+ LibraryInventory.CreateItemCharge(ItemCharge);\n+\n+ // [GIVEN] Generate and Save Quantity in a Variable.\n+ Quantity := LibraryRandom.RandIntInRange(25, 25);\n+\n+ // [GIVEN] Create a Purchase Order with Item Charge.\n+ CreatePurchaseOrderWithItemCharge(PurchaseHeader, ItemCharge.\"No.\", Item.\"No.\", Quantity);\n+\n+ // [GIVEN] Set Purchase Order Lines Qty. to Receive.\n+ SetPurchaseLinesQtyToReceive(PurchaseHeader, Quantity);\n+\n+ // [GIVEN] Update Qty. to Assign on Item Charge Assignment.\n+ UpdateQtyToAssignOnItemChargeAssignment(PurchaseHeader);\n+\n+ // [GIVEN] Post Purchase Order.\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true);\n+\n+ // [GIVEN] Create a Purchase Return Order.\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader2, PurchaseHeader2.\"Document Type\"::\"Return Order\", PurchaseHeader.\"Buy-from Vendor No.\");\n+\n+ // [GIVEN] Open Purchase Return Order page and run Get Posted Document Lines to Reverse action.\n+ PurchaseReturnOrder.OpenEdit();\n+ PurchaseReturnOrder.GoToRecord(PurchaseHeader2);\n+ LibraryVariableStorage.Enqueue(ItemCharge.\"No.\");\n+ PurchaseReturnOrder.GetPostedDocumentLinesToReverse.Invoke();\n+\n+ // [WHEN] Find Purchase Line of Purchase Return Order.\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseLine.\"Document Type\"::\"Return Order\");\n+ PurchaseLine.SetRange(\"Document No.\", PurchaseHeader2.\"No.\");\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::\"Charge (Item)\");\n+ PurchaseLine.FindFirst();\n+\n+ // [VERIFY] Return Qty. to Receive in Purchase Line is 0.\n+ Assert.AreEqual(0, PurchaseLine.\"Return Qty. to Ship\", ReturnQtyToShipMustBeZeroErr);\n+\n+ // [WHEN] Open Purchase Return Order Subform page.\n+ PurchaseReturnOrderSubform.OpenEdit();\n+ PurchaseReturnOrderSubform.GoToRecord(PurchaseLine);\n+\n+ // [VERIFY] Quantity and Qty. to Assign in Purchase Line are same.\n+ Assert.AreEqual(\n+ Quantity,\n+ PurchaseReturnOrderSubform.\"Qty. to Assign\".AsDecimal(),\n+ StrSubstNo(\n+ QtyToAssignErr,\n+ PurchaseReturnOrderSubform.\"Qty. to Assign\".Caption(),\n+ Quantity,\n+ PurchaseReturnOrderSubform.Caption()));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -2062,6 +2141,64 @@ codeunit 134329 \"ERM Purchase Return Order\"\n if Confirm(StrSubstNo(ExpectedMessage)) then;\n end;\n \n+ local procedure CreatePurchaseOrderWithItemCharge(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ ItemChargeNo: Code[20];\n+ ItemNo: Code[20];\n+ Quantity: Decimal)\n+ var\n+ PurchaseLineItemCharge: Record \"Purchase Line\";\n+ PurchaseLineItem: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ begin\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLineItem,\n+ PurchaseHeader,\n+ PurchaseLineItem.Type::Item,\n+ ItemNo,\n+ Quantity);\n+\n+ PurchaseLineItem.Validate(\"Direct Unit Cost\", LibraryRandom.RandDec(100, 2));\n+ PurchaseLineItem.Modify(true);\n+\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLineItemCharge,\n+ PurchaseHeader,\n+ PurchaseLineItemCharge.Type::\"Charge (Item)\",\n+ ItemChargeNo,\n+ Quantity);\n+\n+ PurchaseLineItemCharge.Validate(\"Direct Unit Cost\", LibraryRandom.RandDec(100, 2));\n+ PurchaseLineItemCharge.Modify(true);\n+ end;\n+\n+ local procedure SetPurchaseLinesQtyToReceive(var PurchaseHeader: Record \"Purchase Header\"; Quantity: Decimal)\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseHeader.\"Document Type\");\n+ PurchaseLine.SetRange(\"Document No.\", PurchaseHeader.\"No.\");\n+ PurchaseLine.FindSet();\n+ repeat\n+ PurchaseLine.Validate(\"Qty. to Receive\", Quantity);\n+ PurchaseLine.Modify(true);\n+ until PurchaseLine.Next() = 0;\n+ end;\n+\n+ local procedure UpdateQtyToAssignOnItemChargeAssignment(PurchaseHeader: Record \"Purchase Header\")\n+ var\n+ PurchaseLine: Record \"Purchase Line\";\n+ begin\n+ PurchaseLine.SetRange(\"Document Type\", PurchaseHeader.\"Document Type\");\n+ PurchaseLine.SetRange(\"Document No.\", PurchaseHeader.\"No.\");\n+ PurchaseLine.SetRange(Type, PurchaseLine.Type::\"Charge (Item)\");\n+ PurchaseLine.FindFirst();\n+ PurchaseLine.ShowItemChargeAssgnt();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n@@ -2162,6 +2299,21 @@ codeunit 134329 \"ERM Purchase Return Order\"\n GetReturnShipmentLines.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedPurchDocumentLinesPageHandler(var PostedPurchaseDocumentLines: TestPage \"Posted Purchase Document Lines\")\n+ begin\n+ PostedPurchaseDocumentLines.PostedInvoices.Filter.SetFilter(\"No.\", LibraryVariableStorage.DequeueText());\n+ PostedPurchaseDocumentLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure SuggestItemChargeAssignmentPageHandler(var ItemChargeAssignmentPurch: TestPage \"Item Charge Assignment (Purch)\")\n+ begin\n+ ItemChargeAssignmentPurch.SuggestItemChargeAssignment.Invoke();\n+ end;\n+\n [SendNotificationHandler]\n [Scope('OnPrem')]\n procedure SendNotificationHandler(var Notification: Notification): Boolean\ndiff --git a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al\nindex 3f3d49bb821b..bc9ebbd1cdfb 100644\n--- a/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al\n+++ b/App/Layers/W1/Tests/ERM/ERMSalesDocumentsIII.Codeunit.al\n@@ -80,6 +80,8 @@ codeunit 134387 \"ERM Sales Documents III\"\n PackageTrackingNoErr: Label 'Package Tracking No does not exist.';\n CannotAllowInvDiscountErr: Label 'The value of the Allow Invoice Disc. field is not valid when the VAT Calculation Type field is set to \"Full VAT\".';\n PostingPreviewNoTok: Label '***', Locked = true;\n+ ReturnQtyToReceiveMustBeZeroErr: Label ' Return Qty. to Receive must be zero.';\n+ QtyToAssignErr: Label '%1 must be %2 in %3', Comment = '%1 = Qty. to Assign, %2 = Quantity, %3 = Sales Return Order Subform';\n \n [Test]\n [Scope('OnPrem')]\n@@ -5943,6 +5945,83 @@ codeunit 134387 \"ERM Sales Documents III\"\n Assert.AreNotEqual(Customer.\"Country/Region Code\", SalesHeader.\"Rcvd.-from Count./Region Code\", 'Received-from Country Code is set just as it is on customer');\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('SuggestItemChargeAssignmentPageHandler,PostedSalesDocumentLinesPageHandler')]\n+ procedure GetPostedDocumentLinesToReverseCopiesLinesWhenDefaultQtyToShipIsBlankInSalesReceiSetup()\n+ var\n+ Item: Record Item;\n+ ItemCharge: Record \"Item Charge\";\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n+ SalesHeader: Record \"Sales Header\";\n+ SalesHeader2: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ Quantity: Decimal;\n+ SalesReturnOrder: TestPage \"Sales Return Order\";\n+ SalesReturnOrderSubform: TestPage \"Sales Return Order Subform\";\n+ begin\n+ // [SCENARIO 500596] Get Posted Document Lines to Reverse action on Sales Return Order copies Sales Invoice Lines of Type Item Charge Even when Default Qty to Ship on Sales & Receivables Setup is set to Blank.\n+ Initialize();\n+\n+ // [GIVEN] Validate Default Quantity to Ship in Sales & Receivables Setup.\n+ SalesReceivablesSetup.Get();\n+ SalesReceivablesSetup.Validate(\"Default Quantity to Ship\", SalesReceivablesSetup.\"Default Quantity to Ship\"::Blank);\n+ SalesReceivablesSetup.Modify(true);\n+\n+ // [GIVEN] Create an Item.\n+ LibraryInventory.CreateItem(Item);\n+\n+ // [GIVEN] Create an Item Charge.\n+ LibraryInventory.CreateItemCharge(ItemCharge);\n+\n+ // [GIVEN] Generate and Save Quantity in a Variable.\n+ Quantity := LibraryRandom.RandIntInRange(25, 25);\n+\n+ // [GIVEN] Create a Sales Order with Item Charge.\n+ CreateSalesOrderWithItemCharge(SalesHeader, ItemCharge.\"No.\", Item.\"No.\", Quantity);\n+\n+ // [GIVEN] Set Sales Order Lines Qty. to Ship.\n+ SetSalesLinesQtyToShip(SalesHeader, Quantity);\n+\n+ // [GIVEN] Update Qty. to Assign on Item Charge Assignment.\n+ UpdateQtyToAssignOnItemChargeAssignment(SalesHeader);\n+\n+ // [GIVEN] Post Sales Order.\n+ LibrarySales.PostSalesDocument(SalesHeader, true, true);\n+\n+ // [GIVEN] Create a Sales Return Order.\n+ LibrarySales.CreateSalesHeader(SalesHeader2, SalesHeader2.\"Document Type\"::\"Return Order\", SalesHeader.\"Sell-to Customer No.\");\n+\n+ // [GIVEN] Open Sales Return Order page and run Get Posted Document Lines to Reverse action.\n+ SalesReturnOrder.OpenEdit();\n+ SalesReturnOrder.GoToRecord(SalesHeader2);\n+ LibraryVariableStorage.Enqueue(ItemCharge.\"No.\");\n+ SalesReturnOrder.GetPostedDocumentLinesToReverse.Invoke();\n+\n+ // [WHEN] Find Sales Line of Sales Return Order.\n+ SalesLine.SetRange(\"Document Type\", SalesLine.\"Document Type\"::\"Return Order\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeader2.\"No.\");\n+ SalesLine.SetRange(Type, SalesLine.Type::\"Charge (Item)\");\n+ SalesLine.FindFirst();\n+\n+ // [VERIFY] Return Qty. to Receive in Sales Line is 0.\n+ Assert.AreEqual(0, SalesLine.\"Return Qty. to Receive\", ReturnQtyToReceiveMustBeZeroErr);\n+\n+ // [WHEN] Open Sales Return Order Subform page.\n+ SalesReturnOrderSubform.OpenEdit();\n+ SalesReturnOrderSubform.GoToRecord(SalesLine);\n+\n+ // [VERIFY] Quantity and Qty. to Assign in Sales Line are same.\n+ Assert.AreEqual(\n+ Quantity,\n+ SalesReturnOrderSubform.\"Qty. to Assign\".AsDecimal(),\n+ StrSubstNo(\n+ QtyToAssignErr,\n+ SalesReturnOrderSubform.\"Qty. to Assign\".Caption(),\n+ Quantity,\n+ SalesReturnOrderSubform.Caption()));\n+ end;\n+\n local procedure Initialize()\n var\n ReportSelections: Record \"Report Selections\";\n@@ -7148,6 +7227,64 @@ codeunit 134387 \"ERM Sales Documents III\"\n SalesReceivablesSetup.Modify();\n end;\n \n+ local procedure CreateSalesOrderWithItemCharge(\n+ var SalesHeader: Record \"Sales Header\";\n+ ItemChargeNo: Code[20];\n+ ItemNo: Code[20];\n+ Quantity: Decimal)\n+ var\n+ SalesLineItemCharge: Record \"Sales Line\";\n+ SalesLineItem: Record \"Sales Line\";\n+ Customer: Record Customer;\n+ begin\n+ LibrarySales.CreateCustomer(Customer);\n+\n+ LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader.\"Document Type\"::Order, Customer.\"No.\");\n+ LibrarySales.CreateSalesLine(\n+ SalesLineItem,\n+ SalesHeader,\n+ SalesLineItem.Type::Item,\n+ ItemNo,\n+ Quantity);\n+\n+ SalesLineItem.Validate(\"Unit Price\", LibraryRandom.RandDec(100, 2));\n+ SalesLineItem.Modify(true);\n+\n+ LibrarySales.CreateSalesLine(\n+ SalesLineItemCharge,\n+ SalesHeader,\n+ SalesLineItemCharge.Type::\"Charge (Item)\",\n+ ItemChargeNo,\n+ Quantity);\n+\n+ SalesLineItemCharge.Validate(\"Unit Price\", LibraryRandom.RandDec(100, 2));\n+ SalesLineItemCharge.Modify(true);\n+ end;\n+\n+ local procedure SetSalesLinesQtyToShip(var SalesHeader: Record \"Sales Header\"; Quantity: Decimal)\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ SalesLine.SetRange(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeader.\"No.\");\n+ SalesLine.FindSet();\n+ repeat\n+ SalesLine.Validate(\"Qty. to Ship\", Quantity);\n+ SalesLine.Modify(true);\n+ until SalesLine.Next() = 0;\n+ end;\n+\n+ local procedure UpdateQtyToAssignOnItemChargeAssignment(SalesHeader: Record \"Sales Header\")\n+ var\n+ SalesLine: Record \"Sales Line\";\n+ begin\n+ SalesLine.SetRange(\"Document Type\", SalesHeader.\"Document Type\");\n+ SalesLine.SetRange(\"Document No.\", SalesHeader.\"No.\");\n+ SalesLine.SetRange(Type, SalesLine.Type::\"Charge (Item)\");\n+ SalesLine.FindFirst();\n+ SalesLine.ShowItemChargeAssgnt();\n+ end;\n+\n [ConfirmHandler]\n [Scope('OnPrem')]\n procedure CreateEmptyPostedInvConfirmHandler(Question: Text[1024]; var Reply: Boolean)\n@@ -7426,5 +7563,20 @@ codeunit 134387 \"ERM Sales Documents III\"\n Assert.AreEqual(LibraryVariableStorage.DequeueText(), ChangeLogEntries.\"New Value\".Value(), ChangeLogEntries.\"New Value\".Caption());\n ChangeLogEntries.OK().Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedSalesDocumentLinesPageHandler(var PostedSalesDocumentLines: TestPage \"Posted Sales Document Lines\")\n+ begin\n+ PostedSalesDocumentLines.PostedInvoices.Filter.SetFilter(\"No.\", LibraryVariableStorage.DequeueText());\n+ PostedSalesDocumentLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure SuggestItemChargeAssignmentPageHandler(var ItemChargeAssignmentSales: TestPage \"Item Charge Assignment (Sales)\")\n+ begin\n+ ItemChargeAssignmentSales.SuggestItemChargeAssignment.Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al b/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al\nindex 09f417117839..64796fbd73b1 100644\n--- a/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al\n+++ b/App/Layers/W1/BaseApp/Purchases/Document/ItemChargeAssignmentPurch.Table.al\n@@ -4,6 +4,7 @@ using Microsoft.Finance.Currency;\n using Microsoft.Inventory.Item;\n \n using Microsoft.Purchases.History;\n+using Microsoft.Purchases.Setup;\n \n table 5805 \"Item Charge Assignment (Purch)\"\n {\n@@ -53,10 +54,14 @@ table 5805 \"Item Charge Assignment (Purch)\"\n DecimalPlaces = 0 : 5;\n \n trigger OnValidate()\n+ var\n+ PurchasePayablesSetup: Record \"Purchases & Payables Setup\";\n begin\n+ PurchasePayablesSetup.Get();\n PurchLine.Get(\"Document Type\", \"Document No.\", \"Document Line No.\");\n if Rec.\"Qty. to Assign\" <> xRec.\"Qty. to Assign\" then\n- PurchLine.TestField(\"Qty. to Invoice\");\n+ if PurchasePayablesSetup.\"Default Qty. to Receive\" <> PurchasePayablesSetup.\"Default Qty. to Receive\"::Blank then\n+ PurchLine.TestField(\"Qty. to Invoice\");\n \n TestField(\"Applies-to Doc. Line No.\");\n if (\"Qty. to Assign\" <> 0) and (\"Applies-to Doc. Type\" = \"Document Type\") then\ndiff --git a/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al b/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al\nindex 7cd86681ca3b..403ca020426c 100644\n--- a/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al\n+++ b/App/Layers/W1/BaseApp/Sales/Document/ItemChargeAssignmentSales.Table.al\n@@ -7,6 +7,7 @@ namespace Microsoft.Sales.Document;\n using Microsoft.Finance.Currency;\n using Microsoft.Inventory.Item;\n using Microsoft.Sales.History;\n+using Microsoft.Sales.Setup;\n \n table 5809 \"Item Charge Assignment (Sales)\"\n {\n@@ -56,10 +57,15 @@ table 5809 \"Item Charge Assignment (Sales)\"\n DecimalPlaces = 0 : 5;\n \n trigger OnValidate()\n+ var\n+ SalesReceivablesSetup: Record \"Sales & Receivables Setup\";\n begin\n+ SalesReceivablesSetup.Get();\n SalesLine.Get(\"Document Type\", \"Document No.\", \"Document Line No.\");\n if Rec.\"Qty. to Assign\" <> xRec.\"Qty. to Assign\" then\n- SalesLine.TestField(\"Qty. to Invoice\");\n+ if SalesReceivablesSetup.\"Default Quantity to Ship\" <> SalesReceivablesSetup.\"Default Quantity to Ship\"::Blank then\n+ SalesLine.TestField(\"Qty. to Invoice\");\n+\n TestField(\"Applies-to Doc. Line No.\");\n if (\"Qty. to Assign\" <> 0) and (\"Applies-to Doc. Type\" = \"Document Type\") then\n if SalesLineInvoiced() then\n"} +{"metadata": {"area": "inventory", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-177493", "base_commit": "362fb524a9eb8dfd0de588e1dc5537e7df74f725", "created_at": "2024-03-06", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137023, "functionName": ["ItemWithReserveNeverNotInReservationWorksheet"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al\nindex 6c7fecaffcd2..fa163b5a789b 100644\n--- a/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMReservationWorksheet.Codeunit.al\n@@ -13,6 +13,7 @@ codeunit 137023 \"SCM Reservation Worksheet\"\n LibraryInventory: Codeunit \"Library - Inventory\";\n LibrarySales: Codeunit \"Library - Sales\";\n LibraryWarehouse: Codeunit \"Library - Warehouse\";\n+ LibraryAssembly: Codeunit \"Library - Assembly\";\n LibrarySetupStorage: Codeunit \"Library - Setup Storage\";\n LibraryVariableStorage: Codeunit \"Library - Variable Storage\";\n Assert: Codeunit Assert;\n@@ -943,6 +944,60 @@ codeunit 137023 \"SCM Reservation Worksheet\"\n VerifyQtyToReserveOnReservWkshLine(ReservationWkshLine, SalesOrderList.Get(3), GetOutstandingQtyOnSalesLine(SalesOrderList.Get(3)));\n end;\n \n+ [Test]\n+ [HandlerFunctions('GetDemandToReserveRequestPageHandler')]\n+ procedure ItemWithReserveNeverNotInReservationWorksheet()\n+ var\n+ Item: Record Item;\n+ Location: Record Location;\n+ SalesHeader: Record \"Sales Header\";\n+ SalesLine: Record \"Sales Line\";\n+ AssemblyHeader: Record \"Assembly Header\";\n+ AssemblyLine: Record \"Assembly Line\";\n+ ReservationWkshBatch: Record \"Reservation Wksh. Batch\";\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ ReservationWkshLine: Record \"Reservation Wksh. Line\";\n+ ItemList: List of [Code[20]];\n+ Qty: Decimal;\n+ begin\n+ // [Reservation Worksheet]\n+ // [SCENARIO 502388] Item with \"Reserve\" = \"Never\" should not be included in the reservation worksheet.\n+ Initialize();\n+\n+ // [GIVEN] Item \"X\" with \"Reserve\" = \"Never\".\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Reserve\", Item.\"Reserve\"::Never);\n+ Item.Modify(true);\n+ ItemList.Add(Item.\"No.\");\n+\n+ // [GIVEN] New location\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Item \"X\" available in the inventory.\n+ Qty := Random(100);\n+ LibraryInventory.CreateItemJournalLineInItemTemplate(ItemJournalLine, Item.\"No.\", Location.Code, '', Qty);\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+\n+ // [GIVEN] Sales order for the item \"X\" with \"Reserve\" = \"Never\".\n+ LibrarySales.CreateSalesDocumentWithItem(SalesHeader, SalesLine, SalesHeader.\"Document Type\"::Order, '', Item.\"No.\", Qty / 2, Location.Code, WorkDate());\n+ SalesLine.TestField(Reserve, SalesLine.Reserve::Never);\n+\n+ // [GIVEN] Assembly order with line - item \"X\" with \"Reserve\" = \"Never\".\n+ LibraryAssembly.CreateAssemblyHeader(AssemblyHeader, WorkDate(), LibraryInventory.CreateItemNo(), Location.Code, Qty / 2, '');\n+ LibraryAssembly.CreateAssemblyLine(AssemblyHeader, AssemblyLine, \"BOM Component Type\"::Item, Item.\"No.\", '', 1, 1, '');\n+ AssemblyLine.TestField(Reserve, AssemblyLine.Reserve::Never);\n+\n+ // [WHEN] Run CalculateDemand for item \"X\" to fill ReservationWorksheetLine.\n+ LibraryVariableStorage.Enqueue(Item.\"No.\");\n+ ReservationWkshBatch.FindFirst();\n+ GetDemand(ReservationWkshBatch.Name, ItemList);\n+\n+ // [THEN] Verify that reservation worksheet line for the item with \"Reserve\" = \"Never\" should not be created.\n+ ReservationWkshLine.SetRange(\"Journal Batch Name\", ReservationWkshBatch.Name);\n+ ReservationWkshLine.SetRange(\"Item No.\", Item.\"No.\");\n+ Assert.IsTrue(ReservationWkshLine.IsEmpty, 'Reservation Worksheet line for the item with \"Reserve\" = \"Never\" should not be created.');\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(CODEUNIT::\"SCM Reservation Worksheet\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al b/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al\nindex bb47904dc9a1..2eaf8a1433bf 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Tracking/GetDemandToReserve.Report.al\n@@ -40,6 +40,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Shipment Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', SalesOrderLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n@@ -140,6 +141,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Needed by Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', ServiceOrderLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n@@ -190,6 +192,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Planning Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', JobPlanningLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n@@ -241,6 +244,7 @@ report 302 \"Get Demand To Reserve\"\n SetFilter(\"Variant Code\", FilterItem.GetFilter(\"Variant Filter\"));\n SetFilter(\"Location Code\", FilterItem.GetFilter(\"Location Filter\"));\n SetFilter(\"Due Date\", FilterItem.GetFilter(\"Date Filter\"));\n+ SetFilter(Reserve, '<>%1', AssemblyLine.Reserve::Never);\n \n FilterGroup(2);\n if DateFilter <> '' then\n"} +{"metadata": {"area": "project", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-177750", "base_commit": "e47ecd850386e5039c5c4b737d8cd6cdc753ee66", "created_at": "2024-03-08", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Job"], "FAIL_TO_PASS": [{"codeunitID": 136322, "functionName": ["PostInventoryPickForAssemblyItemRelatedToJobPlanningLineWithBin"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al b/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al\nindex c18ad56092d7..2f27a020e6f5 100644\n--- a/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al\n+++ b/App/Layers/W1/Tests/Job/JobsAssembleToOrder.Codeunit.al\n@@ -692,6 +692,66 @@ codeunit 136322 \"Jobs - Assemble-to Order\"\n AssemblyHeader.TestField(\"Bin Code\", Bin[2].Code);\n end;\n \n+ [Test]\n+ [HandlerFunctions('MessageHandler,ConfirmHandlerTrue')]\n+ procedure PostInventoryPickForAssemblyItemRelatedToJobPlanningLineWithBin()\n+ var\n+ ParentItem, CompItem1, CompItem2 : Record Item;\n+ Job: Record Job;\n+ JobTask: Record \"Job Task\";\n+ JobPlanningLine: Record \"Job Planning Line\";\n+ Location: Record Location;\n+ Bin: Record Bin;\n+ WarehouseActivityHeader: Record \"Warehouse Activity Header\";\n+ PostedATOLink: Record \"Posted Assemble-to-Order Link\";\n+ InventoryPickPage: TestPage \"Inventory Pick\";\n+ begin\n+ // [SCENARIO 504561] Verify post inventory pick for assembly item related to job planning line with bin\n+ Initialize();\n+\n+ // [GIVEN] Create an assembly item with 2 components.\n+ CreateAssemblyItemWithBOM(ParentItem, CompItem1, CompItem2);\n+\n+ // [GIVEN] Create Location with required pick\n+ LibraryWarehouse.CreateLocationWMS(Location, true, false, true, false, false);\n+\n+ // [GIVEN] Create Bin in Location\n+ LibraryWarehouse.CreateBin(Bin, Location.Code, LibraryUtility.GenerateGUID(), '', '');\n+\n+ // [GIVEN] Create Warehouse Employee with default location\n+ CreateDefaultWarehouseEmployee(Location);\n+\n+ // [GIVEN] Add components to inventory\n+ CreateAndPostInvtAdjustmentWithUnitCost(CompItem1.\"No.\", Location.Code, Bin.Code, LibraryRandom.RandInt(100), LibraryRandom.RandDec(10, 2));\n+ CreateAndPostInvtAdjustmentWithUnitCost(CompItem2.\"No.\", Location.Code, Bin.Code, LibraryRandom.RandInt(100), LibraryRandom.RandDec(10, 2));\n+\n+ // [GIVEN] Create Job and Job Task\n+ CreateJobAndJobTask(Job, JobTask);\n+\n+ // [GIVEN] Create Job Planning Line\n+ CreateJobPlanningLineWithData(JobPlanningLine, JobTask, \"Job Planning Line Line Type\"::Budget, JobPlanningLine.Type::Item,\n+ ParentItem.\"No.\", Location.Code, Bin.Code, LibraryRandom.RandInt(10));\n+\n+ // [GIVEN] Create Inventory Pick for the Job\n+ LibraryWarehouse.CreateInvtPutPickMovement(\"Warehouse Request Source Document\"::\"Job Usage\", Job.\"No.\", false, true, false);\n+\n+ // [GIVEN] Find Warehouse Activity Header \n+ WarehouseActivityHeader.SetRange(\"Source Document\", WarehouseActivityHeader.\"Source Document\"::\"Job Usage\");\n+ WarehouseActivityHeader.SetRange(\"Source No.\", Job.\"No.\");\n+ WarehouseActivityHeader.SetRange(\"Location Code\", Location.Code);\n+ WarehouseActivityHeader.FindFirst();\n+\n+ // [WHEN] Inventory Pick is posted\n+ InventoryPickPage.OpenEdit();\n+ InventoryPickPage.GoToRecord(WarehouseActivityHeader);\n+ InventoryPickPage.AutofillQtyToHandle.Invoke();\n+ InventoryPickPage.\"P&ost\".Invoke();\n+\n+ // [THEN] Verify results\n+ SetFiltersToPostedATOLink(JobTask, JobPlanningLine, PostedATOLink);\n+ Assert.RecordIsNotEmpty(PostedATOLink);\n+ end;\n+\n local procedure Initialize()\n begin\n LibraryTestInitialize.OnTestInitialize(Codeunit::\"Jobs - Assemble-to Order\");\n", "patch": "diff --git a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al\nindex a1e3fedb7c27..c31bfe73d2a6 100644\n--- a/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al\n+++ b/App/Layers/W1/BaseApp/Projects/Project/Planning/JobPlanningLine.Table.al\n@@ -3187,6 +3187,21 @@ table 1003 \"Job Planning Line\"\n until Item.Next() = 0;\n end;\n \n+ procedure GetATOBin(Location: Record Location; var BinCode: Code[20]) Result: Boolean\n+ var\n+ AsmHeader: Record \"Assembly Header\";\n+ begin\n+ if not Location.\"Require Shipment\" then\n+ BinCode := Location.\"Asm.-to-Order Shpt. Bin Code\";\n+ if BinCode <> '' then\n+ exit(true);\n+\n+ if AsmHeader.GetFromAssemblyBin(Location, BinCode) then\n+ exit(true);\n+\n+ exit(false);\n+ end;\n+\n local procedure AddItem(var NewJobPlanningLine: Record \"Job Planning Line\"; ItemNo: Code[20])\n begin\n NewJobPlanningLine.\"Line No.\" += 10000;\ndiff --git a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\nindex 320720d71b39..436a633588b0 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Activity/CreateInventoryPickMovement.Codeunit.al\n@@ -2155,6 +2155,8 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n procedure CreateATOPickLine(NewWarehouseActivityLine: Record \"Warehouse Activity Line\"; BinCode: Code[20]; var RemQtyToPickBase: Decimal)\n var\n ATOSalesLine: Record \"Sales Line\";\n+ ATOJobPlanningLine: Record \"Job Planning Line\";\n+ ATOLink: Record \"Assemble-to-Order Link\";\n AssemblyHeader: Record \"Assembly Header\";\n AssemblySetup: Record \"Assembly Setup\";\n ReservationEntry: Record \"Reservation Entry\";\n@@ -2164,13 +2166,26 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n QtyToPickBase: Decimal;\n begin\n if (not IsInvtMovement) and\n- WMSManagement.GetATOSalesLine(NewWarehouseActivityLine.\"Source Type\",\n+ (WMSManagement.GetATOSalesLine(NewWarehouseActivityLine.\"Source Type\",\n NewWarehouseActivityLine.\"Source Subtype\",\n NewWarehouseActivityLine.\"Source No.\",\n NewWarehouseActivityLine.\"Source Line No.\",\n- ATOSalesLine)\n+ ATOSalesLine) or\n+ WMSManagement.GetATOJobPlanningLine(\n+ NewWarehouseActivityLine.\"Source Type\",\n+ NewWarehouseActivityLine.\"Source No.\",\n+ NewWarehouseActivityLine.\"Source Line No.\",\n+ NewWarehouseActivityLine.\"Source Subline No.\",\n+ ATOJobPlanningLine))\n then begin\n- ATOSalesLine.AsmToOrderExists(AssemblyHeader);\n+ if ATOLink.AsmExistsForSalesLine(ATOSalesLine) then\n+ ATOSalesLine.AsmToOrderExists(AssemblyHeader)\n+ else\n+ if ATOLink.AsmExistsForJobPlanningLine(ATOJobPlanningLine) then begin\n+ ATOJobPlanningLine.AsmToOrderExists(AssemblyHeader);\n+ AssemblyHeader.PerformManualRelease();\n+ end;\n+\n if NewWarehouseActivityLine.TrackingExists() then begin\n AssemblyHeader.SetReservationFilters(ReservationEntry);\n ReservationEntry.SetTrackingFilterFromWhseActivityLine(NewWarehouseActivityLine);\n@@ -2178,14 +2193,26 @@ codeunit 7322 \"Create Inventory Pick/Movement\"\n if ItemTrackingManagement.SumUpItemTracking(ReservationEntry, TempTrackingSpecification1, true, true) then\n QtyToAsmBase := Abs(TempTrackingSpecification1.\"Qty. to Handle (Base)\");\n end else\n- QtyToAsmBase := ATOSalesLine.QtyToAsmBaseOnATO();\n+ if ATOLink.Type = ATOLink.Type::Sale then\n+ QtyToAsmBase := ATOSalesLine.QtyToAsmBaseOnATO()\n+ else\n+ if ATOLink.Type = ATOLink.Type::Job then\n+ QtyToAsmBase := ATOJobPlanningLine.QtyToAsmBaseOnATO();\n WhseItemTrackingSetup.CopyTrackingFromWhseActivityLine(NewWarehouseActivityLine);\n- QtyToPickBase := QtyToAsmBase - WMSManagement.CalcQtyBaseOnATOInvtPick(ATOSalesLine, WhseItemTrackingSetup);\n+ if ATOLink.Type = ATOLink.Type::Sale then\n+ QtyToPickBase := QtyToAsmBase - WMSManagement.CalcQtyBaseOnATOInvtPick(ATOSalesLine, WhseItemTrackingSetup)\n+ else\n+ if ATOLink.Type = ATOLink.Type::Job then\n+ QtyToPickBase := QtyToAsmBase - WMSManagement.CalcQtyBaseOnATOInvtPick(ATOJobPlanningLine, WhseItemTrackingSetup);\n OnCreateATOPickLineOnAfterCalcQtyToPickBase(RemQtyToPickBase, QtyToPickBase, ATOSalesLine);\n if QtyToPickBase > 0 then begin\n MakeWarehouseActivityHeader();\n if CurrLocation.\"Bin Mandatory\" and (BinCode = '') then\n- ATOSalesLine.GetATOBin(CurrLocation, BinCode);\n+ if ATOLink.Type = ATOLink.Type::Sale then\n+ ATOSalesLine.GetATOBin(CurrLocation, BinCode)\n+ else\n+ if ATOLink.Type = ATOLink.Type::Job then\n+ ATOJobPlanningLine.GetATOBin(CurrLocation, BinCode);\n NewWarehouseActivityLine.\"Assemble to Order\" := true;\n MakeWarehouseActivityLine(NewWarehouseActivityLine, BinCode, QtyToPickBase, RemQtyToPickBase);\n \ndiff --git a/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al b/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al\nindex dda50b4d3256..1efcbbfc2855 100644\n--- a/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Warehouse/Journal/WMSManagement.Codeunit.al\n@@ -1738,6 +1738,15 @@ codeunit 7302 \"WMS Management\"\n WarehouseActivityLine.SetTrackingFilterIfNotEmpty();\n end;\n \n+ local procedure SetFiltersOnATOInvtPick(JobPlanningLine: Record \"Job Planning Line\"; var WarehouseActivityLine: Record \"Warehouse Activity Line\")\n+ begin\n+ WarehouseActivityLine.SetRange(WarehouseActivityLine.\"Activity Type\", WarehouseActivityLine.\"Activity Type\"::\"Invt. Pick\");\n+ WarehouseActivityLine.SetSourceFilter(\n+ Database::\"Job\", 0, JobPlanningLine.\"Document No.\", JobPlanningLine.\"Job Contract Entry No.\", JobPlanningLine.\"Line No.\", false);\n+ WarehouseActivityLine.SetRange(WarehouseActivityLine.\"Assemble to Order\", true);\n+ WarehouseActivityLine.SetTrackingFilterIfNotEmpty();\n+ end;\n+\n procedure ATOInvtPickExists(SalesLine: Record \"Sales Line\"): Boolean\n var\n WarehouseActivityLine: Record \"Warehouse Activity Line\";\n@@ -1758,6 +1767,18 @@ codeunit 7302 \"WMS Management\"\n until WarehouseActivityLine.Next() = 0;\n end;\n \n+ procedure CalcQtyBaseOnATOInvtPick(JobPlanningLine: Record \"Job Planning Line\"; WhseItemTrackingSetup: Record \"Item Tracking Setup\") QtyBase: Decimal\n+ var\n+ WarehouseActivityLine: Record \"Warehouse Activity Line\";\n+ begin\n+ WarehouseActivityLine.CopyTrackingFromItemTrackingSetup(WhseItemTrackingSetup);\n+ SetFiltersOnATOInvtPick(JobPlanningLine, WarehouseActivityLine);\n+ if WarehouseActivityLine.FindSet() then\n+ repeat\n+ QtyBase += WarehouseActivityLine.\"Qty. Outstanding (Base)\";\n+ until WarehouseActivityLine.Next() = 0;\n+ end;\n+\n procedure CheckOutboundBlockedBin(LocationCode: Code[10]; BinCode: Code[20]; ItemNo: Code[20]; VariantCode: Code[10]; UnitOfMeasureCode: Code[10])\n begin\n CheckBlockedBin(LocationCode, BinCode, ItemNo, VariantCode, UnitOfMeasureCode, false);\n"} +{"metadata": {"area": "inventory", "image_count": 0}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-178045", "base_commit": "22d8978231eb8792d03f150d61431d485d3c92a9", "created_at": "2024-03-11", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137404, "functionName": ["ConsumptionIsPostedForMultipleILEsOfSameLotNo"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\nindex 9467380d9f9b..e1036e0420d9 100644\n--- a/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMManufacturing.Codeunit.al\n@@ -47,6 +47,7 @@ codeunit 137404 \"SCM Manufacturing\"\n Capacity2: Decimal;\n GLB_ItemTrackingQty: Integer;\n GLB_SerialNo: Code[50];\n+ ItemTrackingMode: Option \" \",\"Assign Lot No.\",\"Select Entries\",\"Update Quantity\",\"Manual Lot No.\"; \n DocumentNoDoesNotExistErr: Label 'Document No. %1 does not exist.', Comment = '%1: Document number (Code)';\n ExpectedQuantityErr: Label 'Quantity must be %1.', Comment = '%1: Quantity (decimal value)';\n ModifyRtngErr: Label 'You cannot modify Routing No. %1 because there is at least one %2 associated with it.';\n@@ -80,6 +81,7 @@ codeunit 137404 \"SCM Manufacturing\"\n DidntExpectWhsePickMsg: Label 'Did not expect a Warehouse Pick Request associated with the Production Order Component Line, since the line doesn''t have a postitive remaining quantity';\n ProdOrderNoHandlerErr: Label 'Prod. Order No. must be %1, actual value is %2.', Comment = '%1: Expected Prod. Order No. Value; %2: Actual Prod. Order No. Value.';\n ProdOrderStatusHandlerErr: Label 'Prod. Order Status must be %1, actual value is %2.', Comment = '%1: Expected Prod. Order Status Value; %2: Actual Prod. Order Status Value.';\n+ ItemLedgerEntryMustBeFoundErr: Label 'Item Ledger Entry must be found.';\n \n [Test]\n [HandlerFunctions('ConfirmHandlerTrue,OutputJournalItemtrackingPageHandler,MessageHandler')]\n@@ -4149,6 +4151,104 @@ codeunit 137404 \"SCM Manufacturing\"\n LibraryInventory.PostItemJournalLine(ItemJournalBatch.\"Journal Template Name\", ItemJournalBatch.Name);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('ItemTrackingAssignLotNoPageHandler,ProductionJournalPageHandlerOnlyConsumption,ConfirmHandlerTrue,MessageHandler')]\n+ procedure ConsumptionIsPostedForMultipleILEsOfSameLotNo()\n+ var\n+ CompItem, ProdItem : Record Item;\n+ Location: Record Location;\n+ UnitOfMeasure: Record \"Unit of Measure\";\n+ ItemUnitOfMeasure: Record \"Item Unit of Measure\";\n+ ItemTrackingCode: Record \"Item Tracking Code\";\n+ ProductionBOMHeader: Record \"Production BOM Header\";\n+ ProductionBOMLine: Record \"Production BOM Line\";\n+ ProductionOrder: Record \"Production Order\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ LotNo: Code[10];\n+ Quantity: Decimal;\n+ ReleasedProdOrder: TestPage \"Released Production Order\";\n+ begin\n+ // [SCENARIO 501830] Consumption is posted against multiple Item Ledger Entries of same Lot No. when you post Production Journal from a Released Production Order.\n+ Initialize();\n+\n+ // [GIVEN] Create Item Tracking Code.\n+ LibraryItemTracking.CreateItemTrackingCode(ItemTrackingCode, false, true);\n+\n+ // [GIVEN] Create Unit of Measure.\n+ LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure);\n+\n+ // [GIVEN] Create Component Item with Unit of Measure.\n+ CreateItemWithUOM(CompItem, UnitOfMeasure, ItemUnitOfMeasure);\n+ CompItem.Validate(\"Replenishment System\", CompItem.\"Replenishment System\"::Purchase);\n+ CompItem.Validate(Reserve, CompItem.Reserve::Always);\n+ CompItem.Validate(\"Flushing Method\", CompItem.\"Flushing Method\"::Manual);\n+ CompItem.Validate(\"Item Tracking Code\", ItemTrackingCode.Code);\n+ CompItem.Modify(true);\n+\n+ // [GIVEN] Create Location with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+\n+ // [GIVEN] Create Production Item with Unit of Measure.\n+ CreateItemWithUOM(ProdItem, UnitOfMeasure, ItemUnitOfMeasure);\n+\n+ // [GIVEN] Generate and save Lot No. and Quantity in two different Variable.\n+ LotNo := Format(LibraryRandom.RandText(4));\n+ Quantity := LibraryRandom.RandIntInRange(35, 35);\n+\n+ // [GIVEN] Create and Post three Item Journal Lines with same Lot No.\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(5, 5), LotNo, '', Location.Code, true);\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(10, 10), LotNo, '', Location.Code, true);\n+ CreateAndPostItemJournalLineWithLotNo(CompItem.\"No.\", LibraryRandom.RandIntInRange(20, 20), LotNo, '', Location.Code, true);\n+\n+ // [GIVEN] Create a production BOM for the Production Item.\n+ LibraryManufacturing.CreateProductionBOMHeader(ProductionBOMHeader, ItemUnitOfMeasure.Code);\n+ LibraryManufacturing.CreateProductionBOMLine(\n+ ProductionBOMHeader,\n+ ProductionBOMLine,\n+ '',\n+ ProductionBOMLine.Type::Item,\n+ CompItem.\"No.\",\n+ LibraryRandom.RandIntInRange(1, 1));\n+\n+ // [GIVEN] Validate Unit of Measure in Production BOM.\n+ ProductionBOMLine.Validate(\"Unit of Measure Code\", ItemUnitOfMeasure.Code);\n+ ProductionBOMLine.Modify(true);\n+\n+ // [GIVEN] Change Status of Production BOM.\n+ LibraryManufacturing.UpdateProductionBOMStatus(ProductionBOMHeader, ProductionBOMHeader.Status::Certified);\n+\n+ // [GIVEN] Validate Replenishment System and Production BOM No. in Production Item.\n+ ProdItem.Validate(\"Replenishment System\", ProdItem.\"Replenishment System\"::\"Prod. Order\");\n+ ProdItem.Validate(\"Production BOM No.\", ProductionBOMHeader.\"No.\");\n+ ProdItem.Modify(true);\n+\n+ // [GIVEN] Create and Refresh Production Order.\n+ CreateAndRefreshProdOrder(\n+ ProductionOrder,\n+ ProductionOrder.Status::Released,\n+ ProdItem.\"No.\",\n+ Quantity,\n+ Location.Code,\n+ '');\n+\n+ // [GIVEN] Open Released Production Order page and run Production Journal action.\n+ ReleasedProdOrder.OpenEdit();\n+ ReleasedProdOrder.GoToRecord(ProductionOrder);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ LibraryVariableStorage.Enqueue(ItemTrackingMode::\"Assign Lot No.\");\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ ReleasedProdOrder.ProdOrderLines.ProductionJournal.Invoke();\n+\n+ // [WHEN] Find Item Ledger Entry.\n+ ItemLedgerEntry.SetRange(\"Item No.\", CompItem.\"No.\");\n+ ItemLedgerEntry.SetRange(Quantity, -Quantity);\n+\n+ // [VERIFY] Item Ledger Entry is found.\n+ Assert.IsFalse(ItemLedgerEntry.IsEmpty(), ItemLedgerEntryMustBeFoundErr);\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -6772,6 +6872,39 @@ codeunit 137404 \"SCM Manufacturing\"\n ReservationPage.OK().Invoke();\n end;\n \n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ItemTrackingAssignLotNoPageHandler(var ItemTrackingLines: TestPage \"Item Tracking Lines\")\n+ var\n+ DequeueVariable: Variant;\n+ begin\n+ LibraryVariableStorage.Dequeue(DequeueVariable);\n+ ItemTrackingMode := DequeueVariable;\n+ case ItemTrackingMode of\n+ ItemTrackingMode::\"Assign Lot No.\":\n+ begin\n+ ItemTrackingLines.\"Lot No.\".SetValue(LibraryVariableStorage.DequeueText());\n+ LibraryVariableStorage.Dequeue(DequeueVariable);\n+ ItemTrackingLines.\"Quantity (Base)\".SetValue(DequeueVariable);\n+ end;\n+ end;\n+ ItemTrackingLines.OK().Invoke();\n+ end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure ProductionJournalPageHandlerOnlyConsumption(var ProductionJournal: TestPage \"Production Journal\")\n+ var\n+ EntryType: Enum \"Item Ledger Entry Type\";\n+ begin\n+ Assert.IsTrue(ProductionJournal.FindFirstField(ProductionJournal.\"Entry Type\", EntryType::Output), '');\n+ ProductionJournal.\"Output Quantity\".SetValue(0);\n+ Assert.IsTrue(ProductionJournal.FindFirstField(ProductionJournal.\"Entry Type\", EntryType::Consumption), '');\n+ ProductionJournal.Quantity.SetValue(LibraryVariableStorage.DequeueDecimal());\n+ ProductionJournal.ItemTrackingLines.Invoke();\n+ ProductionJournal.Post.Invoke();\n+ end;\n+\n [PageHandler]\n procedure BOMStructurePageHandler(var BOMStructure: TestPage \"BOM Structure\")\n begin\n@@ -6840,5 +6973,74 @@ codeunit 137404 \"SCM Manufacturing\"\n DT2Time(ExpStartDateTime), DT2Time(ProdOrderLine.\"Starting Date-Time\"), StrSubstNo(WrongDateTimeErr, ProdOrderLine.FieldCaption(\"Starting Time\")));\n until ProdOrderLine.Next() = 0;\n end;\n+\n+ local procedure CreateItemWithUOM(\n+ var Item: Record Item;\n+ var UnitOfMeasure: Record \"Unit of Measure\";\n+ var ItemUnitOfMeasure: Record \"Item Unit of Measure\")\n+ begin\n+ LibraryInventory.CreateItem(Item);\n+\n+ LibraryInventory.CreateItemUnitOfMeasure(\n+ ItemUnitOfMeasure,\n+ Item.\"No.\",\n+ UnitOfMeasure.Code,\n+ LibraryRandom.RandInt(0));\n+\n+ Item.Validate(\"Base Unit of Measure\", UnitOfMeasure.Code);\n+ Item.Modify(true);\n+ end;\n+\n+ local procedure CreateAndPostItemJournalLineWithLotNo(\n+ ItemNo: Code[20];\n+ Quantity: Decimal;\n+ LotNo: Code[50];\n+ BinCode: Code[20];\n+ LocationCode: Code[10];\n+ Tracking: Boolean)\n+ var\n+ ItemJournalLine: Record \"Item Journal Line\";\n+ begin\n+ CreateItemJournalLine(ItemJournalLine, ItemNo, Quantity, BinCode, LocationCode);\n+ if Tracking then begin\n+ LibraryVariableStorage.Enqueue(ItemTrackingMode::\"Assign Lot No.\");\n+ LibraryVariableStorage.Enqueue(LotNo);\n+ LibraryVariableStorage.Enqueue(Quantity);\n+ ItemJournalLine.OpenItemTrackingLines(false);\n+ end;\n+ LibraryInventory.PostItemJournalLine(ItemJournalLine.\"Journal Template Name\", ItemJournalLine.\"Journal Batch Name\");\n+ end;\n+\n+ local procedure CreateItemJournalLine(var ItemJournalLine: Record \"Item Journal Line\"; ItemNo: Code[20]; Quantity: Decimal; BinCode: Code[20]; LocationCode: Code[10])\n+ var\n+ ItemJournalTemplate: Record \"Item Journal Template\";\n+ ItemJournalBatch: Record \"Item Journal Batch\";\n+ begin\n+ LibraryInventory.ClearItemJournal(ItemJournalTemplate, ItemJournalBatch);\n+ LibraryInventory.CreateItemJournalTemplate(ItemJournalTemplate);\n+ LibraryInventory.CreateItemJournalBatch(ItemJournalBatch, ItemJournalTemplate.Name);\n+ LibraryInventory.CreateItemJournalLine(\n+ ItemJournalLine,\n+ ItemJournalBatch.\"Journal Template Name\",\n+ ItemJournalBatch.Name,\n+ ItemJournalLine.\"Entry Type\"::\"Positive Adjmt.\",\n+ ItemNo,\n+ Quantity);\n+\n+ ItemJournalLine.Validate(\"Unit Cost\", LibraryRandom.RandDec(10, 2));\n+ ItemJournalLine.Validate(\"Location Code\", LocationCode);\n+ ItemJournalLine.Validate(\"Bin Code\", BinCode);\n+ ItemJournalLine.Modify(true);\n+ end;\n+\n+ local procedure CreateAndRefreshProdOrder(var ProductionOrder: Record \"Production Order\"; Status: Enum \"Production Order Status\"; SourceNo: Code[20]; Quantity: Decimal; LocationCode: Code[10]; BinCode: Code[20])\n+ begin\n+ LibraryManufacturing.CreateProductionOrder(ProductionOrder, Status, ProductionOrder.\"Source Type\"::Item, SourceNo, Quantity);\n+ ProductionOrder.Validate(\"Location Code\", LocationCode);\n+ ProductionOrder.Validate(\"Bin Code\", BinCode);\n+ ProductionOrder.Modify(true);\n+\n+ LibraryManufacturing.RefreshProdOrder(ProductionOrder, false, true, true, true, false);\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\nindex 7e739c297201..ffe0b880ce8d 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Posting/ItemJnlPostLine.Codeunit.al\n@@ -1946,8 +1946,11 @@ codeunit 22 \"Item Jnl.-Post Line\"\n Abs(ItemLedgEntry.\"Remaining Quantity\" - ItemLedgEntry.\"Reserved Quantity\")\n then\n AppliedQty := ItemLedgEntry.\"Remaining Quantity\" - ItemLedgEntry.\"Reserved Quantity\"\n- else\n+ else begin\n AppliedQty := -(OldItemLedgEntry.\"Remaining Quantity\" - OldItemLedgEntry.\"Reserved Quantity\");\n+ if AppliedQty = 0 then\n+ AppliedQty := UpdateAppliedQtyIfConsumptionEntry(ItemLedgEntry, OldItemLedgEntry);\n+ end;\n \n OnApplyItemLedgEntryOnAfterCalcAppliedQty(OldItemLedgEntry, ItemLedgEntry, AppliedQty);\n \n@@ -5908,6 +5911,17 @@ codeunit 22 \"Item Jnl.-Post Line\"\n (ItemJournalLine.\"Applies-to Entry\" <> 0)));\n end;\n \n+ local procedure UpdateAppliedQtyIfConsumptionEntry(ItemLedgerEntry: Record \"Item Ledger Entry\"; OldItemLedgerEntry: Record \"Item Ledger Entry\"): Decimal\n+ begin\n+ if ItemLedgerEntry.\"Entry Type\" <> ItemLedgerEntry.\"Entry Type\"::Consumption then\n+ exit(0);\n+\n+ if (ItemLedgerEntry.\"Remaining Quantity\" + OldItemLedgerEntry.\"Remaining Quantity\") > 0 then\n+ exit(0);\n+\n+ exit(-Abs(OldItemLedgerEntry.\"Reserved Quantity\"));\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnBeforeAllowProdApplication(OldItemLedgerEntry: Record \"Item Ledger Entry\"; ItemLedgerEntry: Record \"Item Ledger Entry\"; var AllowApplication: Boolean)\n begin\n"} +{"metadata": {"area": "inventory", "image_count": 7}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-176082", "base_commit": "cb30d50fe1ed2c716c6349370fdc31c6bd0ce956", "created_at": "2024-02-23", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\SCM"], "FAIL_TO_PASS": [{"codeunitID": 137038, "functionName": ["GetReceiptLinesShowListOfPostedPurchRcptsHavingTransferFromCodeInLocationCodeOfPurchRcptLines"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\nindex e0b3ba5f0bf7..ffa98cfbb351 100644\n--- a/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n+++ b/App/Layers/W1/Tests/SCM/SCMTransfers.Codeunit.al\n@@ -48,6 +48,7 @@\n UndoneTransLineQtyErr: Label 'Expected Quantity to be 0 after Transfer Shipment was undone';\n DerivedTransLineErr: Label 'Expected no Derived Transfer Line i.e. line with \"Derived From Line No.\" equal to original transfer line.';\n IncorrectSNUndoneErr: Label 'The Serial No. of the item on the transfer shipment line that was undone was different from the SN on the corresponding transfer line.';\n+ ApplToItemEntryErr: Label '%1 must be %2 in %3.', Comment = '%1 is Appl-to Item Entry, %2 is Item Ledger Entry No. and %3 is Transfer Line';\n \n [Test]\n [HandlerFunctions('MessageHandler')]\n@@ -3655,6 +3656,99 @@\n ItemLedgerEntry.TestField(\"Cost Amount (Actual)\", NewCost);\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('PostedPurchaseReceiptsModalPageHandler,PostedPurchRcptLinesModalPageHandler')]\n+ procedure GetReceiptLinesShowListOfPostedPurchRcptsHavingTransferFromCodeInLocationCodeOfPurchRcptLines()\n+ var\n+ Item: Record Item;\n+ Vendor: Record Vendor;\n+ Location: Record Location;\n+ Location2: Record Location;\n+ Location3: Record Location;\n+ PurchaseHeader: Record \"Purchase Header\";\n+ PurchaseHeader2: Record \"Purchase Header\";\n+ PurchaseHeader3: Record \"Purchase Header\";\n+ PurchaseLine: Record \"Purchase Line\";\n+ PurchaseLine2: Record \"Purchase Line\";\n+ PurchaseLine3: Record \"Purchase Line\";\n+ ItemLedgerEntry: Record \"Item Ledger Entry\";\n+ TransferHeader: Record \"Transfer Header\";\n+ TransferLine: Record \"Transfer Line\";\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ ItemLedgerEntryNo: Integer;\n+ PurchaseReceiptNo: Code[20];\n+ TransferOrder: TestPage \"Transfer Order\";\n+ begin\n+ // [SCENARIO 500597] Get Receipt Lines action on Transfer Order shows list of Posted Purchase Receipts having Transfer-from Code in Location Code of Purch Rcpt Lines and after selecting it populates Appl-to Item Entry field in Transfer Lines.\n+ Initialize();\n+\n+ // [GIVEN] Create an Item and Validate Costing Method.\n+ LibraryInventory.CreateItem(Item);\n+ Item.Validate(\"Costing Method\", Item.\"Costing Method\"::FIFO);\n+ Item.Modify(true);\n+\n+ // [GIVEN] Create two Locations with Inventory Posting Setup.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location2);\n+\n+ // [GIVEN] Create another Location with Inventory Posting Setup \n+ // And Validate Use As In-Transit.\n+ LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location3);\n+ Location3.Validate(\"Use As In-Transit\", true);\n+ Location3.Modify(true);\n+\n+ // [GIVEN] Create a Vendor.\n+ LibraryPurchase.CreateVendor(Vendor);\n+\n+ // [GIVEN] Create and Post Purchase Receipt with Location Code on Header.\n+ CreateAndPostPurchRcptWithLocationCodeInPurchHeader(PurchaseHeader, PurchaseLine, Vendor, Item, Location);\n+\n+ // [GIVEN] Create and Post Purchase Receipt 2 with Location Code on Header.\n+ CreateAndPostPurchRcptWithLocationCodeInPurchHeader(PurchaseHeader2, PurchaseLine2, Vendor, Item, Location);\n+\n+ // [GIVEN] Create and Post Purchase Receipt 3 with Location Code on Line.\n+ PurchaseReceiptNo := CreateAndPostPurchRcptWithLocationCodeInPurchLine(\n+ PurchaseHeader3,\n+ PurchaseLine3,\n+ Vendor,\n+ Item,\n+ Location);\n+\n+ // [GIVEN] Find and save Item Ledger Entry No. in a Variable.\n+ ItemLedgerEntry.SetRange(\"Document No.\", PurchaseReceiptNo);\n+ ItemLedgerEntry.FindFirst();\n+ ItemLedgerEntryNo := ItemLedgerEntry.\"Entry No.\";\n+\n+ // [GIVEN] Find Purch. Rcpt Line.\n+ FindRandomReceiptLine(PurchaseReceiptNo, PurchRcptLine);\n+\n+ // [GIVEN] Create Transfer Header.\n+ LibraryInventory.CreateTransferHeader(TransferHeader, Location.Code, Location2.Code, Location3.Code);\n+\n+ // [GIVEN] Open Transfer Order page and run Get Receipt Line action.\n+ TransferOrder.OpenEdit();\n+ TransferOrder.GoToRecord(TransferHeader);\n+ LibraryVariableStorage.Enqueue(PurchaseReceiptNo);\n+ LibraryVariableStorage.Enqueue(PurchaseReceiptNo);\n+ LibraryVariableStorage.Enqueue(PurchRcptLine.\"No.\");\n+ TransferOrder.GetReceiptLines.Invoke();\n+\n+ // [WHEN] Find Transfer Line.\n+ TransferLine.SetRange(\"Document No.\", TransferHeader.\"No.\");\n+ TransferLine.FindFirst();\n+\n+ // [VERIFY] Appl-to Item Entry and Item Ledger Entry No. are same.\n+ Assert.AreEqual(\n+ ItemLedgerEntryNo,\n+ TransferLine.\"Appl.-to Item Entry\",\n+ StrSubstNo(\n+ ApplToItemEntryErr,\n+ TransferLine.FieldCaption(\"Appl.-to Item Entry\"),\n+ ItemLedgerEntryNo,\n+ TransferLine.TableCaption));\n+ end;\n+\n local procedure Initialize()\n var\n LibraryERMCountryData: Codeunit \"Library - ERM Country Data\";\n@@ -5168,6 +5262,52 @@\n Assert.AreEqual(LineCount, TransferReceiptLine.Count(), '');\n end;\n \n+ local procedure CreateAndPostPurchRcptWithLocationCodeInPurchHeader(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ var PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ Item: Record Item;\n+ Location: Record Location)\n+ begin\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ PurchaseHeader.Validate(\"Location Code\", Location.Code);\n+ PurchaseHeader.Modify(true);\n+\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::Item,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandInt(15000));\n+ PurchaseLine.Modify(true);\n+\n+ LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false);\n+ end;\n+\n+ local procedure CreateAndPostPurchRcptWithLocationCodeInPurchLine(\n+ var PurchaseHeader: Record \"Purchase Header\";\n+ var PurchaseLine: Record \"Purchase Line\";\n+ Vendor: Record Vendor;\n+ Item: Record Item;\n+ Location: Record Location): Code[20]\n+ begin\n+ LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader.\"Document Type\"::Order, Vendor.\"No.\");\n+ LibraryPurchase.CreatePurchaseLine(\n+ PurchaseLine,\n+ PurchaseHeader,\n+ PurchaseLine.Type::Item,\n+ Item.\"No.\",\n+ LibraryRandom.RandIntInRange(10, 10));\n+\n+ PurchaseLine.Validate(\"Location Code\", Location.Code);\n+ PurchaseLine.Validate(\"Direct Unit Cost\", LibraryRandom.RandInt(15000));\n+ PurchaseLine.Modify(true);\n+\n+ exit(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false));\n+ end;\n+\n [MessageHandler]\n [Scope('OnPrem')]\n procedure MessageHandler(Message: Text[1024])\n@@ -5394,5 +5534,19 @@\n // 0 = Item.Type::Inventory\n Assert.AreEqual('0', ItemList.Filter.GetFilter(\"Type\"), 'Item List contains non-inventory items.');\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure PostedPurchRcptLinesModalPageHandler(var PostedPurchaseReceiptLines: Page \"Posted Purchase Receipt Lines\"; var Response: Action)\n+ var\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ begin\n+ PurchRcptLine.SetRange(\"Document No.\", LibraryVariableStorage.DequeueText());\n+ PurchRcptLine.SetRange(\"No.\", LibraryVariableStorage.DequeueText());\n+ PurchRcptLine.FindFirst();\n+ PostedPurchaseReceiptLines.SetRecord(PurchRcptLine);\n+\n+ Response := ACTION::LookupOK;\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\nindex 5fe44b4568d1..c16ab8669925 100644\n--- a/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\n+++ b/App/Layers/W1/BaseApp/Inventory/Transfer/TransferHeader.Table.al\n@@ -1304,7 +1304,7 @@ table 5740 \"Transfer Header\"\n TempPurchRcptHeader: Record \"Purch. Rcpt. Header\" temporary;\n PostedPurchaseReceipts: Page \"Posted Purchase Receipts\";\n begin\n- PurchRcptHeader.SetRange(\"Location Code\", \"Transfer-from Code\");\n+ FindPurchRcptHeader(PurchRcptHeader);\n PostedPurchaseReceipts.SetTableView(PurchRcptHeader);\n PostedPurchaseReceipts.LookupMode := true;\n if PostedPurchaseReceipts.RunModal() = ACTION::LookupOK then begin\n@@ -1376,6 +1376,8 @@ table 5740 \"Transfer Header\"\n PurchRcptLine.FilterPstdDocLnItemLedgEntries(ItemLedgerEntry);\n ItemTrackingDocMgt.CopyItemLedgerEntriesToTemp(TempItemLedgerEntry, ItemLedgerEntry);\n ItemTrackingMgt.CopyItemLedgEntryTrkgToTransferLine(TempItemLedgerEntry, TransferLine);\n+ TransferLine.\"Appl.-to Item Entry\" := ItemLedgerEntry.\"Entry No.\";\n+ TransferLine.Modify(true);\n \n OnAfterAddTransferLineFromReceiptLine(TransferLine, PurchRcptLine, TempItemLedgerEntry, Rec);\n end;\n@@ -1546,6 +1548,31 @@ table 5740 \"Transfer Header\"\n end;\n end;\n \n+ local procedure FindPurchRcptHeader(var PurchRcptHeader: Record \"Purch. Rcpt. Header\")\n+ var\n+ PurchRcptLine: Record \"Purch. Rcpt. Line\";\n+ DocumentNo: Code[20];\n+ begin\n+ PurchRcptLine.SetLoadFields(\"Document No.\", \"Location Code\");\n+ PurchRcptLine.SetCurrentKey(\"Document No.\");\n+ PurchRcptLine.SetRange(\"Location Code\", \"Transfer-from Code\");\n+ if PurchRcptLine.FindSet() then\n+ repeat\n+ GetPurchRcptHeader(PurchRcptHeader, PurchRcptLine, DocumentNo);\n+ until PurchRcptLine.Next() = 0;\n+ PurchRcptHeader.MarkedOnly(true);\n+ end;\n+\n+ local procedure GetPurchRcptHeader(var PurchRcptHeader: Record \"Purch. Rcpt. Header\"; PurchRcptLine: Record \"Purch. Rcpt. Line\"; var DocumentNo: Code[20])\n+ begin\n+ if PurchRcptLine.\"Document No.\" = DocumentNo then\n+ exit;\n+\n+ PurchRcptHeader.Get(PurchRcptLine.\"Document No.\");\n+ PurchRcptHeader.Mark(true);\n+ DocumentNo := PurchRcptLine.\"Document No.\";\n+ end;\n+\n [IntegrationEvent(false, false)]\n local procedure OnAddTransferLineFromReceiptLineOnBeforeTransferLineInsert(var TransferLine: Record \"Transfer Line\"; PurchRcptLine: Record \"Purch. Rcpt. Line\"; var TransferHeader: Record \"Transfer Header\")\n begin\n"} +{"metadata": {"area": "crm", "image_count": 8}, "repo": "microsoftInternal/NAV", "instance_id": "microsoftInternal__NAV-174087", "base_commit": "74a0b7c175da3f9a272745bd34453a4712b73e7b", "created_at": "2024-02-02", "environment_setup_version": "24.0", "project_paths": ["App\\Layers\\W1\\BaseApp", "App\\Layers\\W1\\Tests\\TestLibraries", "App\\Layers\\W1\\Tests\\Marketing"], "FAIL_TO_PASS": [{"codeunitID": 136208, "functionName": ["PopulateEvaluationFieldInInteractionLogEntry"]}], "PASS_TO_PASS": [], "test_patch": "diff --git a/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al b/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\nindex 4c4c73700d2a..59fff6e2be93 100644\n--- a/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\n+++ b/App/Layers/W1/Tests/Marketing/MarketingInteraction.Codeunit.al\n@@ -45,6 +45,7 @@ codeunit 136208 \"Marketing Interaction\"\n LoggedSegemntEntriesCreateMsg: Label 'Logged Segment entry was created';\n AttachmentFileShouldNotBeBlankErr: Label 'Attachment File should not be blank.';\n TxtFileExt: Label 'txt';\n+ EvaluationErr: Label '%1 must be %2 in %3', Comment = '%1 = Evaluation, %2 = Positive, %3 = Interaction Log Entry';\n \n [Test]\n [Scope('OnPrem')]\n@@ -2998,6 +2999,50 @@ codeunit 136208 \"Marketing Interaction\"\n VerifyAttachmentFileIsNotBlankOnInteractionLogEntry(Contact.\"No.\");\n end;\n \n+ [Test]\n+ [Scope('OnPrem')]\n+ [HandlerFunctions('CreateInteractionFromContactPageHandler')]\n+ procedure PopulateEvaluationFieldInInteractionLogEntry()\n+ var\n+ Contact: Record Contact;\n+ InteractionTemplate: Record \"Interaction Template\";\n+ InteractionLogEntry: Record \"Interaction Log Entry\";\n+ ContactCard: TestPage \"Contact Card\";\n+ InteractionEvaluation: Enum \"Interaction Evaluation\";\n+ begin\n+ // [SCENARIO 498395] When stan creates an Interaction using Create Interaction action from Contact, Evaluation field should be populated in Interaction Log Entry.\n+ Initialize();\n+\n+ // [GIVEN] Create a Contact.\n+ LibraryMarketing.CreateCompanyContact(Contact);\n+\n+ // [GIVEN] Create an Interaction Template and Validate Information Flow.\n+ LibraryMarketing.CreateInteractionTemplate(InteractionTemplate);\n+ InteractionTemplate.Validate(\"Information Flow\", InteractionTemplate.\"Information Flow\"::Outbound);\n+ InteractionTemplate.Modify(true);\n+\n+ // [GIVEN] Open Contact Card and Create Interaction.\n+ ContactCard.OpenEdit();\n+ ContactCard.GoToRecord(Contact);\n+ LibraryVariableStorage.Enqueue(InteractionTemplate.Code);\n+ LibraryVariableStorage.Enqueue(Format(InteractionEvaluation::Positive));\n+ ContactCard.\"Create &Interaction\".Invoke();\n+\n+ // [WHEN] Find Interaction Log Entry.\n+ InteractionLogEntry.SetRange(\"Contact No.\", Contact.\"No.\");\n+ InteractionLogEntry.FindFirst();\n+\n+ // [VERIFY] Interaction Log Entry has Evaluation field populated as Positive.\n+ Assert.AreEqual(\n+ InteractionEvaluation::Positive,\n+ InteractionLogEntry.Evaluation,\n+ StrSubstNo(\n+ EvaluationErr,\n+ InteractionLogEntry.FieldCaption(Evaluation),\n+ InteractionEvaluation::Positive,\n+ InteractionLogEntry.TableCaption));\n+ end;\n+\n local procedure Initialize()\n var\n LibrarySales: Codeunit \"Library - Sales\";\n@@ -4309,5 +4354,16 @@ CopyStr(StorageLocation, 1, MaxStrLen(MarketingSetup.\"Attachment Storage Locatio\n CreateInteraction.NextInteraction.Invoke();\n CreateInteraction.Finish.Invoke();\n end;\n+\n+ [ModalPageHandler]\n+ [Scope('OnPrem')]\n+ procedure CreateInteractionFromContactPageHandler(var CreateInteraction: TestPage \"Create Interaction\")\n+ begin\n+ CreateInteraction.\"Interaction Template Code\".SetValue(LibraryVariableStorage.DequeueText());\n+ CreateInteraction.NextInteraction.Invoke();\n+ CreateInteraction.NextInteraction.Invoke();\n+ CreateInteraction.Evaluation.SetValue(LibraryVariableStorage.DequeueText());\n+ CreateInteraction.FinishInteraction.Invoke();\n+ end;\n }\n \n", "patch": "diff --git a/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al b/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\nindex ff43f4ff6a7b..05a21a6196bf 100644\n--- a/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\n+++ b/App/Layers/W1/BaseApp/CRM/Segment/CreateInteraction.Page.al\n@@ -694,6 +694,7 @@ page 5077 \"Create Interaction\"\n end;\n Step::\"Step 4\":\n begin\n+ InteractionLogEntry.CopyFromSegment(Rec);\n InteractionLogEntry.Modify();\n CurrPage.Close();\n end;\n"}