Skip to content

[W1][Report][840 ][Suggest Worksheet Lines] Add IsHandled in OnJobPlanningLineOnBeforeInsertCFLineForJobPlanningLine event #30374

Description

@MortegaITB

Why do you need this change?

We need to parametrize whether completed projects (Jobs with Status = Completed) should be taken into account when report 840 "Suggest Worksheet Lines" generates cash flow lines from Job Planning Line.

The dataitem "Job Planning Line" already has an event fired right before line generation:

trigger OnAfterGetRecord()
begin
    Window.Update(2, JobsMsg);
    Window.Update(3, "Job No.");

    if not ("Line Type" in ["Line Type"::Billable, "Line Type"::"Both Budget and Billable"]) then
        exit;

    OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine("Job Planning Line");
    InsertCFLineForJobPlanningLine();
end;

However, OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine has no IsHandled parameter — a subscriber can react to the record, but has no way to prevent the subsequent, unconditional call to InsertCFLineForJobPlanningLine(). So today there is no way to skip generating a cash flow line for a specific Job Planning Line (e.g. one belonging to a completed project) without a workaround.

Alternatives evaluated

  • Filtering "Job Planning Line" via SetFilter on "Job No." at OnPreDataItem (e.g. <>proj1&<>proj2&...): Rejected. In a dataset with, for example, 500 completed projects out of 10,000 total planning lines, the exclusion list would have to enumerate up to 500 project numbers in a single filter string. AL filter strings have a maximum length, so this approach fails or truncates once the excluded set grows past a relatively small number of values — it does not scale with real data volumes.
  • Post-processing and deleting already-inserted lines in Cash Flow Worksheet Line: Works around the filter-length limit, but does redundant work (lines are calculated and inserted, then removed) and risks temporary inconsistent state.
  • Duplicating the report's logic in a custom extension: Maintenance liability with every BC update. Rejected.
  • Adding a brand-new event publisher instead of extending the existing one: Considered, but rejected in favor of the option below — the existing OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine already fires at exactly the right point (right before InsertCFLineForJobPlanningLine()), so introducing a second, near-duplicate event would be redundant.
  • Adding var IsHandled: Boolean to the existing OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine publisher: Selected. This is a minimal signature change to an event that already exists and already fires at the correct point in the loop. Each of the 10,000 records is evaluated individually with an O(1) Job.Get("Job No.") lookup against its own Status field — there is no filter string involved, so the 500-completed/10,000-total scenario (or any larger scale) is unaffected by AL's filter length limitation.

Performance & data considerations

No new event and no additional recordset iteration are introduced — the existing event already fires once per "Job Planning Line" record being processed by the dataitem. A subscriber's per-record Job.Get() is a primary-key lookup, so cost scales linearly with the number of planning lines already being processed, not with the number of excluded projects, and no filter string is ever built or concatenated.

No additional sensitive or GDPR-relevant data is exposed; "Job Planning Line" is already present in the existing event signature.

Multi-extension interaction

The IsHandled pattern is standard BC behavior: if multiple subscribers evaluate the same record and any one of them sets IsHandled := true, the line is skipped for that record. Worst case, a line is skipped that another extension might have wanted included — no data corruption or inconsistent state results. Existing subscribers to this event that don't use IsHandled are unaffected, since it defaults to false and the existing call to InsertCFLineForJobPlanningLine() still executes exactly as before when no subscriber sets it.

Describe the request

Add var IsHandled: Boolean as a new parameter to the existing event publisher OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine in report 840 "Suggest Worksheet Lines", and use it in OnAfterGetRecord of the

Thank you for the review. Clarifying both points:

1. Event choice clarification

Yes — the existing event OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine(JobPlanningLine: Record "Job Planning Line") should be extended, not duplicated. This request is to add var IsHandled: Boolean to that existing publisher, not to introduce a new one. Updated signature:

[IntegrationEvent(false, false)]
local procedure OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine(JobPlanningLine: Record "Job Planning Line"; var IsHandled: Boolean)
begin
end;

Call site (OnAfterGetRecord of the "Job Planning Line" dataitem):

trigger OnAfterGetRecord()
var
    IsHandled: Boolean;
begin
    Window.Update(2, JobsMsg);
    Window.Update(3, "Job No.");

    if not ("Line Type" in ["Line Type"::Billable, "Line Type"::"Both Budget and Billable"]) then
        exit;

    IsHandled := false;
    OnJobPlanningLineOnAfterGetRecordOnBeforeInsertCFLineForJobPlanningLine("Job Planning Line", IsHandled);
    if IsHandled then
        exit;

    InsertCFLineForJobPlanningLine();
end;

2. Requested behavior clarification

Confirmed: the broader skip is intentional. When a subscriber sets IsHandled := true for a given Job Planning Line (e.g. because it belongs to a completed project), we want both:

  • the cash flow worksheet line generation (InsertCFLineForJobPlanningLine()) to be skipped, and
  • the side effect inside it that updates and persists the record itself (UpdatePlannedDueDate() / Modify() on "Job Planning Line") to be skipped as well.

This is intentional because a project we are choosing to exclude from the cash flow calculation (e.g. a completed project) should not have its planning line touched/updated as a side effect of a report run that is meant to ignore it. Placing the event in OnAfterGetRecord, before the call to InsertCFLineForJobPlanningLine(), is therefore the correct location — no change needed to move it further inside that procedure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    missing-infoThe issue misses information that prevents it from completion.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions