Why do you need this change?
Problem statement:
The standard check in CheckVATDateCZL for "Original Doc. VAT Date CZL" did not distinguish between posting a receipt only versus posting with invoicing on a Purchase Order. This caused the field to be incorrectly required already at receipt posting, blocking users from posting a goods receipt because of a field that is only relevant for invoicing. The fix restricts the check so it only fires when the document is actually invoiced (Document Type = Invoice, or Document Type = Order combined with Invoice = true). There is currently no integration event in VAT Date Handler CZL.CheckVATDateCZL allowing partners to adjust this condition without modifying standard code directly.
Alternatives evaluated:
No other alternative solution exists for this change.
Proposed publisher location:
Object: codeunit 11742 "VAT Date Handler CZL"
Procedure: CheckVATDateCZL
Placement rationale:
This is the only place in standard code where the decision "should this field be required" is made, so it's the natural extension point — anywhere else would mean duplicating this logic. The default value passed to the event matches current behavior (PurchaseHeader.Invoice), so existing installations are unaffected unless a subscriber overrides it.
Proposed code snippet (before -> after):
procedure CheckVATDateCZL(var PurchaseHeader: Record "Purchase Header")
var
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:BEGIN
CheckOriginalDocVATDateCZL: Boolean;
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:END
MustBeLessOrEqualErr: Label 'must be less or equal to %1', Comment = '%1 = fieldcaption of VAT Date';
begin
if not VATReportingDateMgt.IsVATDateEnabled() then begin
PurchaseHeader.TestField("VAT Reporting Date", PurchaseHeader."Posting Date");
exit;
end;
PurchaseHeader.TestField("VAT Reporting Date");
#if not CLEAN28
#pragma warning disable AL0432
if not ReplaceVATPeriodMgtCZL.IsEnabled() then
VATPeriodCZLCheck(PurchaseHeader."VAT Reporting Date");
#pragma warning restore AL0432
#endif
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:BEGIN
CheckOriginalDocVATDateCZL := PurchaseHeader.Invoice;
OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL(PurchaseHeader, CheckOriginalDocVATDateCZL);
if CheckOriginalDocVATDateCZL then
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:END
PurchaseHeader.TestField("Original Doc. VAT Date CZL");
if PurchaseHeader."Original Doc. VAT Date CZL" > PurchaseHeader."VAT Reporting Date" then
PurchaseHeader.FieldError("Original Doc. VAT Date CZL", StrSubstNo(MustBeLessOrEqualErr, PurchaseHeader.FieldCaption("VAT Reporting Date")));
end;
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:BEGIN
[IntegrationEvent(false, false)]
local procedure OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL(var PurchaseHeader: Record "Purchase Header"; var CheckOriginalDocVATDateCZL: Boolean)
begin
end;
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:END
Subscriber example (illustrative):
[EventSubscriber(ObjectType::Codeunit, Codeunit::"VAT Date Handler CZL", OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL, '', false, false)]
local procedure OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL(var PurchaseHeader: Record "Purchase Header"; var CheckOriginalDocVATDateCZL: Boolean)
begin
CheckOriginalDocVATDateCZL := (PurchaseHeader."Document Type" = PurchaseHeader."Document Type"::Invoice) or ((PurchaseHeader."Document Type" = PurchaseHeader."Document Type"::Order) and PurchaseHeader.Invoice);
end;
Performance & data considerations:
PurchaseHeader is passed as var (by reference) to avoid copying the full record, consistent with the other overloads of CheckVATDateCZL in this codeunit. The event is called once per document posting/check (not in a loop over lines), so the performance impact is negligible. The subscriber only reads header fields ("Document Type", Invoice) that the caller already has access to — no sensitive data is exposed beyond what CheckVATDateCZL already operates on.
Multi‑extension interaction:
Since multiple subscribers can handle this event, the last-run subscriber's assignment to CheckOriginalDocVATDateCZL wins and execution order across extensions is not guaranteed. Because the default value passed into the event (PurchaseHeader.Invoice) already reflects standard behavior, a subscriber that fully replaces the condition (as in this proposal) is a legitimate and expected pattern — it does not need to OR/AND with the incoming value, since doing so would simply collapse back to the original (narrower) standard condition and undo the fix. Extensions that need to add extra cases on top of another extension's override should combine with the incoming value instead of overwriting it outright.
Justification for using IsHandled over alternatives:
We simply need to replace the existing condition with a new one — no need to skip the rest of the procedure, so a plain var Boolean is sufficient.
Describe the request
procedure CheckVATDateCZL(var PurchaseHeader: Record "Purchase Header")
var
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:BEGIN
CheckOriginalDocVATDateCZL: Boolean;
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:END
MustBeLessOrEqualErr: Label 'must be less or equal to %1', Comment = '%1 = fieldcaption of VAT Date';
begin
if not VATReportingDateMgt.IsVATDateEnabled() then begin
PurchaseHeader.TestField("VAT Reporting Date", PurchaseHeader."Posting Date");
exit;
end;
PurchaseHeader.TestField("VAT Reporting Date");
#if not CLEAN28
#pragma warning disable AL0432
if not ReplaceVATPeriodMgtCZL.IsEnabled() then
VATPeriodCZLCheck(PurchaseHeader."VAT Reporting Date");
#pragma warning restore AL0432
#endif
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:BEGIN
CheckOriginalDocVATDateCZL := PurchaseHeader.Invoice;
OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL(PurchaseHeader, CheckOriginalDocVATDateCZL);
if CheckOriginalDocVATDateCZL then
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:END
PurchaseHeader.TestField("Original Doc. VAT Date CZL");
if PurchaseHeader."Original Doc. VAT Date CZL" > PurchaseHeader."VAT Reporting Date" then
PurchaseHeader.FieldError("Original Doc. VAT Date CZL", StrSubstNo(MustBeLessOrEqualErr, PurchaseHeader.FieldCaption("VAT Reporting Date")));
end;
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:BEGIN
[IntegrationEvent(false, false)]
local procedure OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL(var PurchaseHeader: Record "Purchase Header"; var CheckOriginalDocVATDateCZL: Boolean)
begin
end;
//------------------------------------------OnCheckVATDateCZLOnBeforeTestFieldOriginalDocVATDateCZL:END
Provide an implementation (optional)
Why do you need this change?
Problem statement:
The standard check in CheckVATDateCZL for "Original Doc. VAT Date CZL" did not distinguish between posting a receipt only versus posting with invoicing on a Purchase Order. This caused the field to be incorrectly required already at receipt posting, blocking users from posting a goods receipt because of a field that is only relevant for invoicing. The fix restricts the check so it only fires when the document is actually invoiced (Document Type = Invoice, or Document Type = Order combined with Invoice = true). There is currently no integration event in VAT Date Handler CZL.CheckVATDateCZL allowing partners to adjust this condition without modifying standard code directly.
Alternatives evaluated:
No other alternative solution exists for this change.
Proposed publisher location:
Object: codeunit 11742 "VAT Date Handler CZL"
Procedure: CheckVATDateCZL
Placement rationale:
This is the only place in standard code where the decision "should this field be required" is made, so it's the natural extension point — anywhere else would mean duplicating this logic. The default value passed to the event matches current behavior (PurchaseHeader.Invoice), so existing installations are unaffected unless a subscriber overrides it.
Proposed code snippet (before -> after):
Subscriber example (illustrative):
Performance & data considerations:
PurchaseHeader is passed as var (by reference) to avoid copying the full record, consistent with the other overloads of CheckVATDateCZL in this codeunit. The event is called once per document posting/check (not in a loop over lines), so the performance impact is negligible. The subscriber only reads header fields ("Document Type", Invoice) that the caller already has access to — no sensitive data is exposed beyond what CheckVATDateCZL already operates on.
Multi‑extension interaction:
Since multiple subscribers can handle this event, the last-run subscriber's assignment to CheckOriginalDocVATDateCZL wins and execution order across extensions is not guaranteed. Because the default value passed into the event (PurchaseHeader.Invoice) already reflects standard behavior, a subscriber that fully replaces the condition (as in this proposal) is a legitimate and expected pattern — it does not need to OR/AND with the incoming value, since doing so would simply collapse back to the original (narrower) standard condition and undo the fix. Extensions that need to add extra cases on top of another extension's override should combine with the incoming value instead of overwriting it outright.
Justification for using IsHandled over alternatives:
We simply need to replace the existing condition with a new one — no need to skip the rest of the procedure, so a plain var Boolean is sufficient.
Describe the request
Provide an implementation (optional)