Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
08c3cc0
Add synchronous E-Document message transport
Aug 20, 2026
31b4bb0
Add French collected and refused messages
Aug 20, 2026
dc09a12
Merge branch 'main' of https://github.com/microsoft/BCApps into featu…
Aug 20, 2026
31387e6
new
Aug 20, 2026
161edf4
new changes
Aug 20, 2026
53b2023
tests updated
Aug 20, 2026
bcef50b
ai test updates
Aug 20, 2026
54fcc33
PR comment changes
Aug 20, 2026
6cff425
new comments fixes
Aug 20, 2026
6a85318
new
Aug 21, 2026
19a729b
vat changes
Aug 21, 2026
7a454d7
reason code upd
Aug 21, 2026
dc578d2
Task 647421
Aug 21, 2026
c55c5d4
retry
Aug 21, 2026
70ca478
PPF context changes
Aug 21, 2026
80c8837
Added Validatior, asynh
Aug 21, 2026
67d718e
errors compile
Aug 21, 2026
05f4c34
tests fix
Aug 21, 2026
f5b8567
Merge branch 'main' into feature/fr-collected-refused-messages
Aug 23, 2026
62dd4e4
compile errors
Aug 24, 2026
ad98e96
tests update
Aug 24, 2026
bb53620
tests updated
Aug 24, 2026
2e6e4e3
Object ID changed
Aug 24, 2026
e3a91c8
Fix E-Document test object ID collision
Aug 25, 2026
372c19e
Merge branch 'main' into feature/fr-collected-refused-messages
Aug 25, 2026
b7a91c6
update
Aug 25, 2026
82f63eb
Merge branch 'main' into feature/fr-collected-refused-messages
Aug 28, 2026
991a431
Fix Factur-X test variable shadowing
Aug 28, 2026
e9d53e8
Merge branch 'main' into feature/fr-collected-refused-messages
Aug 28, 2026
4b51423
Merge branch 'main' into feature/fr-collected-refused-messages
Aug 29, 2026
24e1a2d
Added payload and external-reference cleanup
Aug 30, 2026
0352707
removed msg status and retry
Aug 30, 2026
7482b3e
upd
Aug 30, 2026
492e6bc
move tooltips
Aug 30, 2026
c338520
ResolveFrenchService condition
Aug 30, 2026
1043838
Pr comments changes
Aug 30, 2026
69f597a
object ID changed
Aug 31, 2026
23fe6c7
TASK 647421
Aug 31, 2026
18505a5
PR commnet changes
Aug 31, 2026
f050e29
test fix
Aug 31, 2026
2f40dd8
added try function and telemetry
Aug 31, 2026
df2aa42
Merge branch 'feature/fr-collected-refused-messages' of https://githu…
Aug 31, 2026
4a91f8d
Fix E-Document analyzer warnings
Aug 31, 2026
5c97aa7
Merge branch 'main' into feature/fr-collected-refused-messages
Aug 31, 2026
676e1ba
tests update
Aug 31, 2026
0e167f1
accept and refuse only for fr
Aug 31, 2026
964dfe6
backgroundjobs
Aug 31, 2026
272a916
new changes
Aug 31, 2026
26511fe
compile err
Aug 31, 2026
5342a13
test
Sep 1, 2026
11f4ddd
DataClassificationEvalData
Sep 1, 2026
e279968
removed code from install and upgrade cu
Sep 1, 2026
f2d4900
git merge
Sep 11, 2026
89eb7f8
object ID fix
Sep 12, 2026
71299e4
Export requested receipt dates in PEPPOL orders
Sep 12, 2026
357036c
Apply PEPPOL requested delivery dates to sales lines
Sep 12, 2026
405754d
Revert "Apply PEPPOL requested delivery dates to sales lines"
Sep 14, 2026
f3783b8
Revert "Export requested receipt dates in PEPPOL orders"
Sep 14, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.eServices.EDocument.Formats;

using Microsoft.eServices.EDocument;

permissionset 10988 "E-Reporting FR User"
{
Assignable = true;
Caption = 'E-Reporting FR - User';

IncludedPermissionSets = "E-Doc. Core - User";

Comment thread
djukicmilica marked this conversation as resolved.
Permissions =
Comment thread
djukicmilica marked this conversation as resolved.
table "FR E-Invoice Message" = X,
tabledata "FR E-Invoice Message" = R,
table "FR E-Invoice Message VAT" = X,
tabledata "FR E-Invoice Message VAT" = R,
codeunit "FR E-Invoice Message Mgt." = X,
codeunit "FR E-Invoice Message Builder" = X,
codeunit "FR E-Invoice Profile Validator" = X,
codeunit "FR E-Invoice Message API" = X,
page "FR E-Invoice Refusal Dialog" = X,
page "FR E-Invoice Messages" = X;
Comment thread
djukicmilica marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ codeunit 10978 "CII XML Builder"

AddSellerTradeParty(AgreementElement, CompanyInformation);
AddBuyerTradeParty(AgreementElement, SourceDocumentHeader);
AddInvoiceReferencedDocument(AgreementElement, SourceDocumentHeader);

// BT-13 Purchase order reference
if FREDocHelpers.FindFieldByName(SourceDocumentHeader, 'Order No.', FieldRefVar) then
Expand All @@ -177,6 +178,35 @@ codeunit 10978 "CII XML Builder"
TransactionElement.Add(AgreementElement);
end;

local procedure AddInvoiceReferencedDocument(var AgreementElement: XmlElement; var SourceDocumentHeader: RecordRef)
var
SalesInvoiceHeader: Record "Sales Invoice Header";
FREDocHelpers: Codeunit "EDoc. Helpers";
AppliesToDocumentNoFieldRef: FieldRef;
DateStringElement: XmlElement;
FormattedIssueDateElement: XmlElement;
InvoiceReferenceElement: XmlElement;
AppliesToDocumentNo: Code[20];
begin
if SourceDocumentHeader.Number() <> Database::"Sales Cr.Memo Header" then
exit;
if not FREDocHelpers.FindFieldByName(SourceDocumentHeader, 'Applies-to Doc. No.', AppliesToDocumentNoFieldRef) then
exit;

AppliesToDocumentNo := AppliesToDocumentNoFieldRef.Value();
if (AppliesToDocumentNo = '') or not SalesInvoiceHeader.Get(AppliesToDocumentNo) then
exit;
Comment thread
djukicmilica marked this conversation as resolved.

InvoiceReferenceElement := XmlElement.Create('InvoiceReferencedDocument', RamNamespaceTok);
InvoiceReferenceElement.Add(XmlElement.Create('IssuerAssignedID', RamNamespaceTok, AppliesToDocumentNo));
FormattedIssueDateElement := XmlElement.Create('FormattedIssueDateTime', RamNamespaceTok);
DateStringElement := XmlElement.Create('DateTimeString', QdtNamespaceTok, FormatDate(SalesInvoiceHeader."Document Date"));
DateStringElement.SetAttribute('format', '102');
FormattedIssueDateElement.Add(DateStringElement);
InvoiceReferenceElement.Add(FormattedIssueDateElement);
AgreementElement.Add(InvoiceReferenceElement);
end;

local procedure AddSellerTradeParty(var AgreementElement: XmlElement; CompanyInformation: Record "Company Information")
var
SellerElement: XmlElement;
Expand Down Expand Up @@ -270,6 +300,31 @@ codeunit 10978 "CII XML Builder"
AgreementElement.Add(BuyerElement);
end;

procedure TryGetBuyerElectronicAddress(Customer: Record Customer; var BuyerElectronicAddress: Text): Boolean
var
VATRegistrationNo: Text;
begin
if Customer."FR Electronic Address" <> '' then begin
BuyerElectronicAddress := Customer."FR Electronic Address";
exit(true);
end;

if Customer."Registration Number" <> '' then begin
BuyerElectronicAddress := CopyStr(Customer."Registration Number", 1, 14);
exit(true);
end;

VATRegistrationNo := UpperCase(DelChr(Customer."VAT Registration No.", '=', ' '));
if (StrLen(VATRegistrationNo) = 13) and (CopyStr(VATRegistrationNo, 1, 2) = 'FR') and
(DelChr(CopyStr(VATRegistrationNo, 3), '=', '0123456789') = '')
then begin
BuyerElectronicAddress := CopyStr(VATRegistrationNo, 5, 9);
exit(true);
end;

exit(false);
end;

local procedure GetHeaderFieldText(var SourceDocumentHeader: RecordRef; PrimaryFieldName: Text; FallbackFieldName: Text): Text
var
FREDocHelpers: Codeunit "EDoc. Helpers";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.eServices.EDocument.Formats;

using Microsoft.eServices.EDocument;

table 10970 "FR E-Invoice Message"
{
Access = Internal;
Caption = 'FR E-Invoice Message';
DataClassification = CustomerContent;
InherentEntitlements = X;
InherentPermissions = X;
Permissions = tabledata "FR E-Invoice Message VAT" = d;
ReplicateData = false;
Comment thread
djukicmilica marked this conversation as resolved.

fields
{
field(1; "Entry No."; Integer)
{
AutoIncrement = true;
Caption = 'Entry No.';
DataClassification = SystemMetadata;
}
field(2; "E-Document Entry No."; Integer)
{
Caption = 'E-Document Entry No.';
DataClassification = SystemMetadata;
TableRelation = "E-Document"."Entry No";
}
field(3; Type; Enum "FR E-Invoice Message Type")
{
Caption = 'Type';
DataClassification = SystemMetadata;
ToolTip = 'Specifies the French lifecycle status represented by this message.';
}
field(4; "Source Occurrence ID"; Guid)
{
Caption = 'Source Occurrence ID';
DataClassification = SystemMetadata;
ToolTip = 'Specifies the immutable source identifier used to prevent duplicate lifecycle messages.';
}
field(5; "Original Entry No."; Integer)
{
Caption = 'Original Entry No.';
DataClassification = SystemMetadata;
TableRelation = "FR E-Invoice Message"."Entry No.";
ToolTip = 'Specifies the original collected message reversed by a negative collected message.';
}
field(6; Amount; Decimal)
{
AutoFormatExpression = Rec."Currency Code";
AutoFormatType = 1;
Caption = 'Amount';
DataClassification = CustomerContent;
ToolTip = 'Specifies the payment amount reported by a collected or negative collected message.';
}
field(7; "Currency Code"; Code[10])
{
Caption = 'Currency Code';
DataClassification = CustomerContent;
ToolTip = 'Specifies the currency of the reported payment amount.';
}
field(8; "Event Date"; Date)
{
Caption = 'Event Date';
DataClassification = CustomerContent;
ToolTip = 'Specifies the business date on which the lifecycle event occurred.';
}
field(9; "Detailed Ledger Entry No."; Integer)
{
Caption = 'Detailed Ledger Entry No.';
DataClassification = SystemMetadata;
}
field(10; "Reason Code"; Code[20])
{
Caption = 'Reason Code';
DataClassification = CustomerContent;
ToolTip = 'Specifies the reason code supplied for the lifecycle status.';
}
field(11; "Reason Description"; Text[500])
{
Caption = 'Reason Description';
DataClassification = CustomerContent;
ToolTip = 'Specifies the reason description supplied for the lifecycle status.';
}
field(12; "E-Document Message Entry No."; Integer)
Comment thread
djukicmilica marked this conversation as resolved.
{
Caption = 'E-Document Message Entry No.';
DataClassification = SystemMetadata;
ToolTip = 'Specifies the related generic E-Document message entry.';
}
Comment thread
djukicmilica marked this conversation as resolved.
field(13; "Created At"; DateTime)
{
Caption = 'Created At';
DataClassification = SystemMetadata;
ToolTip = 'Specifies when the French lifecycle message was created.';
}
field(14; "External Message ID"; Text[250])
{
Caption = 'External Message ID';
DataClassification = CustomerContent;
ToolTip = 'Specifies the identifier assigned to an incoming lifecycle message by the external service.';
}
field(15; "Received At"; DateTime)
{
Caption = 'Received At';
DataClassification = SystemMetadata;
ToolTip = 'Specifies when the incoming lifecycle message was received.';
}
field(16; "Sender Platform ID"; Text[50])
{
Caption = 'Sender Platform ID';
DataClassification = OrganizationIdentifiableInformation;
ToolTip = 'Specifies the frozen identifier of the sender platform.';
}
field(17; "Sender Platform Scheme"; Code[4])
{
Caption = 'Sender Platform Scheme';
DataClassification = SystemMetadata;
ToolTip = 'Specifies the frozen identifier scheme of the sender platform.';
}
field(18; "Sender Platform Name"; Text[100])
{
Caption = 'Sender Platform Name';
DataClassification = OrganizationIdentifiableInformation;
ToolTip = 'Specifies the frozen name of the sender platform.';
}
field(19; "Invoice Issue Date"; Date)
{
Caption = 'Invoice Issue Date';
DataClassification = CustomerContent;
ToolTip = 'Specifies the frozen issue date of the invoice.';
}
field(20; "Invoice Receipt At"; DateTime)
{
Caption = 'Invoice Receipt At';
DataClassification = CustomerContent;
ToolTip = 'Specifies the frozen date and time when the sender platform received the invoice.';
}
field(21; "Invoice Issuer ID"; Text[50])
{
Caption = 'Invoice Issuer ID';
DataClassification = OrganizationIdentifiableInformation;
ToolTip = 'Specifies the frozen SIREN identifier of the invoice issuer.';
}
field(22; "Invoice Issuer Scheme"; Code[4])
{
Caption = 'Invoice Issuer Scheme';
DataClassification = SystemMetadata;
ToolTip = 'Specifies the frozen identifier scheme of the invoice issuer.';
}
field(23; "Invoice Issuer Name"; Text[100])
{
Caption = 'Invoice Issuer Name';
DataClassification = OrganizationIdentifiableInformation;
ToolTip = 'Specifies the frozen name of the invoice issuer.';
}
}

keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
key(Occurrence; "E-Document Entry No.", "Source Occurrence ID", Type)
Comment thread
djukicmilica marked this conversation as resolved.
{
Unique = true;
}
key(EDocumentType; "E-Document Entry No.", Type)
{
}
key(DetailedLedgerEntry; Type, "Detailed Ledger Entry No.")
{
}
key(EDocumentMessage; "E-Document Message Entry No.")
{
}
}

trigger OnDelete()
var
FREInvoiceMessageVAT: Record "FR E-Invoice Message VAT";
begin
FREInvoiceMessageVAT.SetRange("Message Entry No.", Rec."Entry No.");
FREInvoiceMessageVAT.DeleteAll(false);
end;
}
Loading
Loading