[Bug]: Warehouse Journal Line.CalcReservEntryQuantity uses uninitialized global WhseJnlLine instead of Rec for tracking filter (regression since BC18)

Abierto Apto para principiantes
#13,635 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
64/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Área
backend

Línea de trabajo

Lee src/Layers/W1/BaseApp/Warehouse/Journal/WarehouseJournalLine.Table.al e inspecciona CalcReservEntryQuantity, especialmente la llamada al filtro de seguimiento. Confirma que el registro actual proporciona el filtro de seguimiento y luego revisa las pruebas pertinentes de líneas de diario de almacén o añade una comprobación de regresión para una reserva con un lote diferente. La tarea está terminada cuando la búsqueda de reservas usa el seguimiento de la línea actual y funciona el escenario de envío de transferencia informado.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Team: SCM
Describe the issue

Table 7311 "Warehouse Journal Line", procedure CalcReservEntryQuantity(), filters the Reservation Entry on an uninitialized global variable instead of the current record:

ReservEntry.SetTrackingFilterFromWhseJnlLine(WhseJnlLine);

WhseJnlLine is the table's protected global variable, not Rec. It is not initialized when CalcReservEntryQuantity is called from codeunit 7302 "WMS Management".CheckWhseJnlLineTracking, so the Reservation Entry is always filtered on Serial No. = '' and Lot No. = '' instead of the journal line's tracking.

This is a regression from the BC18 refactoring that moved the procedure from codeunit 7302 to table 7311.

BC17 – codeunit 7302 "WMS Management" (correct): the line is passed as a parameter named WhseJnlLine.

local procedure CalcReservEntryQuantity(WhseJnlLine: Record "Warehouse Journal Line"): Decimal
var
    ReservEntry: Record "Reservation Entry";
begin
    with WhseJnlLine do begin
        if "Source Type" = DATABASE::"Prod. Order Component" then begin
            ReservEntry.SetSourceFilter("Source Type", "Source Subtype", "Journal Template Name", "Source Subline No.", true);
            ReservEntry.SetSourceFilter("Journal Batch Name", "Source Line No.");
        end else begin
            ReservEntry.SetSourceFilter("Source Type", "Source Subtype", "Journal Template Name", "Source Line No.", true);
            ReservEntry.SetSourceFilter("Journal Batch Name", 0);
        end;
        ReservEntry.SetTrackingFilterFromWhseJnlLine(WhseJnlLine); // <- WhseJnlLine = the parameter (the actual line)
        if ReservEntry.FindFirst then
            exit(ReservEntry."Quantity (Base)");
        exit("Qty. (Base)");
    end;
end;

Called as:

CheckLotNo(
  "Item No.", "Variant Code", "Location Code", "From Bin Code",
  "Unit of Measure Code", "Lot No.", CalcReservEntryQuantity(WhseJnlLine));

BC18 to current main – table 7311 "Warehouse Journal Line" (wrong): the parameter was removed, but the reference was not changed to Rec. The name now resolves to the table's global variable WhseJnlLine.

procedure CalcReservEntryQuantity(): Decimal
var
    ReservEntry: Record "Reservation Entry";
begin
    if "Source Type" = ProdOrderComponentSourceID() then begin
        ReservEntry.SetSourceFilter("Source Type", "Source Subtype", "Journal Template Name", "Source Subline No.", true);
        ReservEntry.SetSourceFilter("Journal Batch Name", "Source Line No.");
    end else begin
        ReservEntry.SetSourceFilter("Source Type", "Source Subtype", "Journal Template Name", "Source Line No.", true);
        ReservEntry.SetSourceFilter("Journal Batch Name", 0);
    end;
    ReservEntry.SetTrackingFilterFromWhseJnlLine(WhseJnlLine); // <- WhseJnlLine = uninitialized global, NOT Rec
    if ReservEntry.FindFirst() then
        exit(ReservEntry."Quantity (Base)");
    exit("Qty. (Base)");
end;
protected var
    Item: Record Item;
    WhseJnlLine: Record "Warehouse Journal Line";   // global used above
    PhysInvtEntered: Boolean;

Called from codeunit 7302 "WMS Management".CheckWhseJnlLineTracking:

CheckLotNo(
  WarehouseJournalLine."Item No.", WarehouseJournalLine."Variant Code", WarehouseJournalLine."Location Code", WarehouseJournalLine."From Bin Code",
  WarehouseJournalLine."Unit of Measure Code", WarehouseJournalLine."Lot No.", WarehouseJournalLine.CalcReservEntryQuantity());

Impact: CheckLotNo / CheckSerialNo can receive the quantity of an unrelated, untracked reservation entry instead of the line's quantity, and posting fails with a false error such as:

Quantity (Base) must not be -2 in Bin Content Location Code='MK-MF',Bin Code='SCHEIA',Item No.='5615522',Variant Code='',Unit of Measure Code='BUC'.

even though the bin holds enough of the lot for the line being posted.

We hit this when posting / previewing a transfer order shipment on BC W1 29.0 (Platform 29.0.56814.0 + Application 29.0.54011.56829). In the debugger:

  • Effective Reservation Entry filters: Source Type = 5741, Source Subtype = 0, Source ID = '', Source Batch Name = '', Source Prod. Order Line = 0, Source Ref. No. = 40000, Serial No. = '', Lot No. = '', Package No. = ''
  • ReservEntry.FindFirst() = true, ReservEntry."Quantity (Base)" = -3 (an unrelated entry for another location)
  • Rec."Lot No." = the actual lot, Rec."Qty. (Base)" = 1
  • Bin content for the lot = 1, so the check computes 1 - 3 = -2 and raises the error.
Expected behavior

CalcReservEntryQuantity should filter the Reservation Entry on the tracking of the current record:

ReservEntry.SetTrackingFilterFromWhseJnlLine(Rec);

With this, the bin content check in CheckLotNo / CheckSerialNo uses the quantity of the line's own lot / serial number, and the transfer shipment in the scenario above posts successfully.

Steps to reproduce
  1. Create a location with Bin Mandatory = Yes and a bin B.
  2. Create an item with an item tracking code that has Lot Specific Tracking = Yes.
  3. Post 1 unit of lot L1 into bin B.
  4. Make sure a Reservation Entry exists with Source Type = 5741 (Transfer Line), Source Subtype = 0, Source ID = '', Source Batch Name = '', Source Ref. No. = 10000, Lot No. = '', Quantity (Base) = -3 (any item / location). In our case these were old orphaned entries; in a test it can be inserted directly.
  5. Create a transfer order from the location with one line (Line No. = 10000), Quantity = 1, lot L1, bin B.
  6. Post the transfer order (or Preview Posting) with option Ship.

Actual result: error "Quantity (Base) must not be -2 in Bin Content ...".

Expected result: the shipment posts. With Rec used in SetTrackingFilterFromWhseJnlLine, the filter includes Lot No. = L1, the unrelated entry does not match, and the procedure falls back to Rec."Qty. (Base)" (= 1), which the bin covers.

Additional context

Proposed fix (src/Layers/W1/BaseApp/Warehouse/Journal/WarehouseJournalLine.Table.al):

-        ReservEntry.SetTrackingFilterFromWhseJnlLine(WhseJnlLine);
+        ReservEntry.SetTrackingFilterFromWhseJnlLine(Rec);

Related observation (not part of the proposed fix): the source filter uses "Journal Template Name" / "Journal Batch Name" as Source ID / Source Batch Name:

ReservEntry.SetSourceFilter("Source Type", "Source Subtype", "Journal Template Name", "Source Line No.", true);
ReservEntry.SetSourceFilter("Journal Batch Name", 0);

This is correct for journal sources, but for document sources such as Transfer Line (set via WMSMgmt.SetTransferLine) both fields are blank. The filter then becomes Source ID = '' instead of the document number, and there is no Item No. / Location Code filter. This is why an unrelated entry could match at all. Changing it affects behavior more broadly, so we'd appreciate Microsoft's view on whether it should be handled separately.

Affected versions: BC18 through current main (verified in BC 23-29 and main).

I will provide a fix for a bug
  • I will provide a fix for a bug
Lenguaje dominante
AL
Estrellas
720
Forks
488
Merge medio
2 d 17 h
PR fusionados (30 d)
568

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de microsoft/BCApps

Todos los issues de microsoft/BCApps

Issues similares

Más issues de Backend & API Design

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.