Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
55fca09
Update Expense VAT Specification Source
Alexander-Ya Aug 17, 2026
f69c885
Update test
Alexander-Ya Aug 17, 2026
c941d85
Add Approve All action
Alexander-Ya Aug 17, 2026
f4daed4
Fix warnings
Alexander-Ya Aug 18, 2026
68792b7
Update VAT posting and rounding in different scenarios
Alexander-Ya Aug 18, 2026
8a3b45f
Add upgrade codeunit for VAT Specs
Alexander-Ya Aug 18, 2026
fe1b3e7
Resolve review comments
Alexander-Ya Aug 18, 2026
dc420b6
Fix more review comments
Alexander-Ya Aug 18, 2026
2b09003
Merge branch 'main' into bugs/Update-Expense-VAT-Specification-Source
Alexander-Ya Aug 18, 2026
c033dc9
Fix new warnings
Alexander-Ya Aug 18, 2026
e645da6
Merge branch 'bugs/Update-Expense-VAT-Specification-Source' of https:…
Alexander-Ya Aug 18, 2026
619d07c
Disable incorrect warnings
Alexander-Ya Aug 19, 2026
ccab0bb
Remove remaining warnings in tests
Alexander-Ya Aug 19, 2026
e4cde25
Add obsolete statement
Alexander-Ya Aug 19, 2026
87c3e47
Resolve more review comments
Alexander-Ya Aug 19, 2026
48eb7b9
Another round of review comments
Alexander-Ya Aug 19, 2026
0fa58a4
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 19, 2026
122ee6c
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 20, 2026
cc3def8
Fix VAT Non Deductible tests
Alexander-Ya Aug 20, 2026
2b91b9d
Fix ND VAT tests for BE IT NO
Alexander-Ya Aug 20, 2026
d3a0c69
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 20, 2026
ce0aaa0
Next round of code review comments
Alexander-Ya Aug 21, 2026
9a52657
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 21, 2026
d81ea1f
Improve upgrade
Alexander-Ya Aug 21, 2026
2ac54a7
Allow local agent VAT specification inserts
claudiuciumedean Aug 21, 2026
0b80dda
Update for code review
Alexander-Ya Aug 24, 2026
6362152
Temporarily disable new API test
Alexander-Ya Aug 25, 2026
cdee40b
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 25, 2026
cca9f21
Update for code review comments
Alexander-Ya Aug 25, 2026
c30f9ac
Eliminate dependency on enable Non Ded VAT feature
Alexander-Ya Aug 25, 2026
da45652
Resolve comments
Alexander-Ya Aug 25, 2026
0e2d6e4
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 26, 2026
9984cab
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 28, 2026
abfe68e
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 28, 2026
1daa890
Update obsolete tags to 30.0
Alexander-Ya Aug 28, 2026
4eba336
Fix obsolete tag
Alexander-Ya Aug 28, 2026
fd32555
Merge branch 'main' of https://github.com/microsoft/BCApps into bugs/…
Alexander-Ya Aug 28, 2026
4866ade
Fix remaining review comments
Alexander-Ya Aug 28, 2026
0c1756b
Revert breaking change in enum
Alexander-Ya Aug 29, 2026
5f2e958
Fix tests
Alexander-Ya Aug 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/Apps/W1/ExpenseAgent/app/src/APIs/ExpenseVATSpecAPI.Page.al
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ page 7085 "Expense VAT Spec. API"
ODataKeyFields = SystemId;
SourceTable = "Expense VAT Specification";
AboutText = 'Provides access to data from the Expense VAT Specification table';
ModifyAllowed = false;
Comment thread
Alexander-Ya marked this conversation as resolved.
DeleteAllowed = false;
AutoSplitKey = true;

layout
Expand Down Expand Up @@ -90,6 +92,7 @@ page 7085 "Expense VAT Spec. API"
field(source; Rec.Source)
{
Caption = 'Source';
Editable = false;
}
field(confidence; Rec.Confidence)
{
Expand All @@ -105,4 +108,16 @@ page 7085 "Expense VAT Spec. API"
begin
ExpenseAgentAPIValidation.VerifyAgentAccess();
end;

trigger OnInsertRecord(BelowxRec: Boolean): Boolean
Comment thread
Alexander-Ya marked this conversation as resolved.
begin
InsertVATSpecification(Rec);
exit(false);
end;

internal procedure InsertVATSpecification(var ExpenseVATSpecification: Record "Expense VAT Specification")
Comment thread
Alexander-Ya marked this conversation as resolved.
Comment thread
Alexander-Ya marked this conversation as resolved.
begin
ExpenseVATSpecification.Source := ExpenseVATSpecification.Source::Agent;
Comment thread
Alexander-Ya marked this conversation as resolved.
ExpenseVATSpecification.Insert(true);
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@ page 7084 "Expense VAT Specification"
}
}
}

}
82 changes: 56 additions & 26 deletions src/Apps/W1/ExpenseAgent/app/src/Expense/Tables/Expense.Table.al
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,7 @@ table 6900 Expense
NonRefundableAmountCannotBeNegativeErr: Label '%1 cannot be in negative on Expense No. %2.', Comment = '%1 = Field Caption, %2 = Expense No.';
ExpenseUserMustBeLinkedToAnEmployeeErr: Label 'Expense User %1 must be linked to an Employee No.', Comment = '%1 = Expense User No.';
BillableCustomerAndProjectErr: Label 'You cannot use both %1 and %2 at the same time.', Comment = '%1 = Billable to Customer field caption, %2 = Project No. field caption';
ModifyOrDeleteErr: Label 'Modifications and delete are not allowed for records created by the Expense Agent API.';

Comment thread
t-prda marked this conversation as resolved.
procedure AssistEdit() Result: Boolean
begin
Expand Down Expand Up @@ -1321,6 +1322,7 @@ table 6900 Expense

internal procedure UpdateVATSpecification(ExpenseNo: Code[20])
var
ExpenseCategory: Record "Expense Category";
ExpenseItemization: Record "Expense Itemization";
ExpenseVATSpec: Record "Expense VAT Specification";
TempExpenseVATSpec: Record "Expense VAT Specification" temporary;
Expand All @@ -1330,33 +1332,61 @@ table 6900 Expense
if ExpenseAgentSetup."Default VAT Bus. Posting Group" = '' then
exit;

ExpenseItemization.SetRange("Expense No.", ExpenseNo);
if ExpenseItemization.IsEmpty() then
exit;
Comment thread
Alexander-Ya marked this conversation as resolved.
Comment thread
Alexander-Ya marked this conversation as resolved.

ExpenseVATSpec.SetRange("Expense No.", ExpenseNo);
ExpenseVATSpec.DeleteAll();

LineNo := 0;
ExpenseItemization.FindSet();
repeat
TempExpenseVATSpec.SetRange("Expense Category", ExpenseItemization."Expense Category Code");
TempExpenseVATSpec.SetRange("Expense Subcategory", ExpenseItemization."Expense Subcategory Code");
if TempExpenseVATSpec.FindFirst() then begin
TempExpenseVATSpec."Amount" += ExpenseItemization."Amount";
TempExpenseVATSpec.Modify();
end else begin
TempExpenseVATSpec.Init();
TempExpenseVATSpec."Expense No." := ExpenseNo;
LineNo += 1;
TempExpenseVATSpec."Line No." := LineNo;
TempExpenseVATSpec.Validate("Expense Category", ExpenseItemization."Expense Category Code");
TempExpenseVATSpec.Validate("Expense Subcategory", ExpenseItemization."Expense Subcategory Code");
TempExpenseVATSpec.Validate("VAT Bus. Posting Group", ExpenseAgentSetup."Default VAT Bus. Posting Group");
TempExpenseVATSpec.Validate("Amount", ExpenseItemization.Amount);
TempExpenseVATSpec.Insert();
end;
until ExpenseItemization.Next() = 0;
ExpenseVATSpec.SetRange(Source, ExpenseVATSpec.Source::Agent);
Comment thread
Alexander-Ya marked this conversation as resolved.
if not ExpenseVATSpec.IsEmpty() then
error(ModifyOrDeleteErr);

ExpenseCategory.Get("Expense Category");
case ExpenseCategory."Expense Detail Required" of
Comment thread
Alexander-Ya marked this conversation as resolved.
ExpenseCategory."Expense Detail Required"::Itemize:
begin
ExpenseItemization.SetRange("Expense No.", ExpenseNo);
if not ExpenseItemization.IsEmpty() then begin
ExpenseVATSpec.SetRange(Source);
ExpenseVATSpec.DeleteAll();

LineNo := 0;
ExpenseItemization.FindSet();
repeat
TempExpenseVATSpec.SetRange("Expense Category", ExpenseItemization."Expense Category Code");
TempExpenseVATSpec.SetRange("Expense Subcategory", ExpenseItemization."Expense Subcategory Code");
if TempExpenseVATSpec.FindFirst() then begin
TempExpenseVATSpec.Validate(Amount, TempExpenseVATSpec.Amount + ExpenseItemization.Amount);
TempExpenseVATSpec.Modify();
end else begin
TempExpenseVATSpec.Init();
TempExpenseVATSpec.Source := TempExpenseVATSpec.Source::Manual;
TempExpenseVATSpec."Expense No." := ExpenseNo;
LineNo += 1;
TempExpenseVATSpec."Line No." := LineNo;
TempExpenseVATSpec.Validate("Expense Category", ExpenseItemization."Expense Category Code");
TempExpenseVATSpec.Validate("Expense Subcategory", ExpenseItemization."Expense Subcategory Code");
TempExpenseVATSpec.Validate("VAT Bus. Posting Group", ExpenseAgentSetup."Default VAT Bus. Posting Group");
TempExpenseVATSpec.Validate("Amount", ExpenseItemization.Amount);
TempExpenseVATSpec.Insert();
end;
until ExpenseItemization.Next() = 0;
end;
end;
else
if ExpenseCategory."VAT Prod. Posting Group" <> '' then begin
Comment thread
Alexander-Ya marked this conversation as resolved.
ExpenseVATSpec.SetRange(Source);
ExpenseVATSpec.DeleteAll();

TempExpenseVATSpec.Init();
TempExpenseVATSpec.Source := TempExpenseVATSpec.Source::Manual;
TempExpenseVATSpec."Expense No." := ExpenseNo;
LineNo += 1;
TempExpenseVATSpec."Line No." := LineNo;
TempExpenseVATSpec.Validate("Expense Category", "Expense Category");
if "Expense Subcategory" <> '' then
TempExpenseVATSpec.Validate("Expense Subcategory", "Expense Subcategory");
TempExpenseVATSpec.Validate("VAT Bus. Posting Group", ExpenseAgentSetup."Default VAT Bus. Posting Group");
TempExpenseVATSpec.Validate("Amount", Amount);
Comment thread
Alexander-Ya marked this conversation as resolved.
TempExpenseVATSpec.Insert();
end;
end;

TempExpenseVATSpec.Reset();
if TempExpenseVATSpec.FindSet() then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ table 6918 "Expense VAT Specification"
trigger OnValidate()
begin
GetExpense();
if Expense."Expense Category" <> '' then
Validate("Expense Category", "Expense Category");
if Expense."Expense Subcategory" <> '' then
Validate("Expense Subcategory", "Expense Subcategory");
if Source <> Source::Agent then begin
Comment thread
Alexander-Ya marked this conversation as resolved.
if Expense."Expense Category" <> '' then
Validate("Expense Category", "Expense Category");
if Expense."Expense Subcategory" <> '' then
Validate("Expense Subcategory", "Expense Subcategory");
end;
end;
}
field(2; "Line No."; Integer)
Expand All @@ -57,12 +59,14 @@ table 6918 "Expense VAT Specification"

trigger OnValidate()
begin
InitializeCurrency();
"VAT Amount" := Round(Amount * "VAT %" / (100 + "VAT %"), Currency."Amount Rounding Precision", Currency.VATRoundingDirection());
"VAT Base Amount" := Round(Amount - "VAT Amount", Currency."Amount Rounding Precision");
"VAT Difference" := 0;
"VAT Amount (LCY)" := CalcVATAmountLCY();
"VAT Base Amount (LCY)" := "Amount (LCY)" - "VAT Amount (LCY)";
if Source <> Source::Agent then begin
InitializeCurrency();
"VAT Amount" := Round(Amount * "VAT %" / (100 + "VAT %"), Currency."Amount Rounding Precision", Currency.VATRoundingDirection());
"VAT Base Amount" := Round(Amount - "VAT Amount", Currency."Amount Rounding Precision");
"VAT Difference" := 0;
"VAT Amount (LCY)" := CalcVATAmountLCY();
"VAT Base Amount (LCY)" := "Amount (LCY)" - "VAT Amount (LCY)";
end;
end;
}
field(11; "VAT Base Amount"; Decimal)
Expand Down Expand Up @@ -91,7 +95,8 @@ table 6918 "Expense VAT Specification"

trigger OnValidate()
begin
ValidateAmount();
if Source <> Source::Agent then
ValidateAmount();
end;
}
/// <summary>
Expand Down Expand Up @@ -151,17 +156,18 @@ table 6918 "Expense VAT Specification"

trigger OnValidate()
begin
GetExpense();
if Expense."Currency Code" = '' then begin
Amount := "Amount (LCY)";
Validate(Amount);
end else begin
Comment thread
Alexander-Ya marked this conversation as resolved.
TestField("Amount (LCY)");
TestField(Amount);
Expense."Currency Factor" := Amount / "Amount (LCY)";
if Source <> Source::Agent then begin
GetExpense();
Comment thread
Alexander-Ya marked this conversation as resolved.
if Expense."Currency Code" = '' then begin
Amount := "Amount (LCY)";
Validate(Amount);
end else begin
TestField("Amount (LCY)");
TestField(Amount);
Expense."Currency Factor" := Amount / "Amount (LCY)";
end;
Validate("VAT %");
end;

Validate("VAT %");
end;
}
field(27; "Expense Category"; Code[20])
Expand All @@ -174,14 +180,16 @@ table 6918 "Expense VAT Specification"
var
ExpenseCategory: Record "Expense Category";
begin
if "Expense Category" = '' then
exit;
if "Expense Subcategory" <> '' then
exit;
if ExpenseCategory.Get("Expense Category") then begin
"VAT Prod. Posting Group" := ExpenseCategory."VAT Prod. Posting Group";
"VAT %" := ExpenseCategory."Default VAT %";
Validate("VAT %");
if Source <> Source::Agent then begin
if "Expense Category" = '' then
exit;
if "Expense Subcategory" <> '' then
exit;
if ExpenseCategory.Get("Expense Category") then begin
"VAT Prod. Posting Group" := ExpenseCategory."VAT Prod. Posting Group";
"VAT %" := ExpenseCategory."Default VAT %";
Validate("VAT %");
end;
end;
end;
}
Expand All @@ -196,6 +204,9 @@ table 6918 "Expense VAT Specification"
ExpenseSubcategory: Record "Expense Subcategory";
ExpenseCategory: Record "Expense Category";
begin
if Source = Source::Agent then
exit;

if "Expense Subcategory" <> '' then begin
if ExpenseSubcategory.Get("Expense Category", "Expense Subcategory") then begin
"VAT Prod. Posting Group" := ExpenseSubcategory."VAT Prod. Posting Group";
Expand All @@ -214,6 +225,8 @@ table 6918 "Expense VAT Specification"
field(40; Source; Enum "Expense VAT Spec Source")
{
Caption = 'Source';
Editable = false;
Comment thread
Alexander-Ya marked this conversation as resolved.
Comment thread
Alexander-Ya marked this conversation as resolved.
DataClassification = SystemMetadata;
ToolTip = 'Specifies how this VAT specification line was created, for example whether it was entered manually or extracted automatically from a receipt.';
}
field(41; Confidence; Decimal)
Expand Down Expand Up @@ -249,11 +262,26 @@ table 6918 "Expense VAT Specification"
end;
end;

trigger OnModify()
Comment thread
Alexander-Ya marked this conversation as resolved.
Comment thread
Alexander-Ya marked this conversation as resolved.
Comment thread
Alexander-Ya marked this conversation as resolved.
Comment thread
Alexander-Ya marked this conversation as resolved.
begin
TestStatusOpenOfExpense();
if Source = Source::Agent then
error(ModifyOrDeleteErr);
end;

trigger OnDelete()
begin
TestStatusOpenOfExpense();
if Source = Source::Agent then
error(ModifyOrDeleteErr);
end;
Comment thread
Alexander-Ya marked this conversation as resolved.

var
Currency: Record Currency;
CurrExchRate: Record "Currency Exchange Rate";
Expense: Record Expense;
ExpenseAgentSetup: Record "Expense Agent Setup";
ModifyOrDeleteErr: Label 'Modifications and delete are not allowed for records created by the Expense Agent API.';

local procedure CalcVATAmountLCY(): Decimal
var
Expand Down Expand Up @@ -356,4 +384,13 @@ table 6918 "Expense VAT Specification"
Rec.Reasoning.CreateInStream(InStream, TextEncoding::UTF8);
InStream.ReadText(Result);
end;

local procedure TestStatusOpenOfExpense()
var
ExpenseRecord: Record Expense;
begin
ExpenseRecord.SetLoadFields(Status);
ExpenseRecord.Get("Expense No.");
ExpenseRecord.TestStatusOpen();
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ codeunit 6983 "Create Expense Report"
ExpenseReportLine.Validate("Expense User No.", Expense."Expense User No.");
ExpenseReportLine.Validate("Expense Category", Expense."Expense Category");
ExpenseReportLine.Validate("Expense Subcategory Code", Expense."Expense Subcategory");
ExpenseReportLine.Validate("Expense Location", Expense."Expense Location");
ExpenseReportLine.Validate("Expense Location", CopyStr(Expense."Expense Location", 1, 20));
if Expense.Description <> '' then
ExpenseReportLine.Validate(Description, Expense.Description);
if ExpenseReportLine."Expense Subcategory Code" <> '' then
Expand Down Expand Up @@ -328,6 +328,8 @@ codeunit 6983 "Create Expense Report"
ExpenseReportLineVATSpec."VAT Amount" := ExpenseVATSpec."VAT Amount";
ExpenseReportLineVATSpec.Amount := ExpenseVATSpec.Amount;
ExpenseReportLineVATSpec."VAT Difference" := ExpenseVATSpec."VAT Difference";
ExpenseReportLineVATSpec."Currency Code" := Expense."Currency Code";
ExpenseReportLineVATSpec."Currency Factor" := Expense."Currency Factor";
ExpenseReportLineVATSpec."VAT Bus. Posting Group" := ExpenseVATSpec."VAT Bus. Posting Group";
ExpenseReportLineVATSpec."VAT Prod. Posting Group" := ExpenseVATSpec."VAT Prod. Posting Group";
ExpenseReportLineVATSpec."VAT Amount (LCY)" := ExpenseVATSpec."VAT Amount (LCY)";
Expand All @@ -341,6 +343,7 @@ codeunit 6983 "Create Expense Report"
else
if ExpenseCategory.Get(ExpenseVATSpec."Expense Category") then
ExpenseReportLineVATSpec.Validate("Reclaim %", ExpenseCategory."Default VAT Reclaim %");
ExpenseReportLineVATSpec.UpdateReimbursementAmounts();
ExpenseReportLineVATSpec.Insert();
until ExpenseVATSpec.Next() = 0;

Expand Down
Loading
Loading