NAS Job Queue lanch a code unit have a UI interface

balhiniobalhinio Member Posts: 28
edited 2012-02-24 in NAV Three Tier
Hi All,

I have a job Queue tha execute a code unit. The code unit contain some variable of dialog user interface. when NAS try to execute the job it log the following error:

You cannot use C/AL variables of type DIALOG when running the Application Server for Microsoft Dynamics NAV Classic.
The code unit is a standard 5044076 PCF Engine

Haw can I excute this code unit from NAS?

Thanks for help.

Comments

  • bbrownbbrown Member Posts: 3,268
    See the command GUIALLOWED for your solution.
    There are no bugs - only undocumented features.
  • mohana_cse06mohana_cse06 Member Posts: 5,504
    You have to skip window/GUID/Input type of code using GUIALLOWED for NAS...

    <EDIT> Sorry bbrown..Did not see your post..
  • balhiniobalhinio Member Posts: 28
    The following is the code source of the code unit : (I have commented all code with DIALOG type)

    *************************************************************************
    POLARIS TT-30468
    Created
    22.03.2009
    RHJ
    *************************************************************************

    [Functions]

    Bool : ExecutePFC_COMMIT(PFCNo)
    Bool : ReservePFC_COMMIT(PFCNo)
    Bool : ReleasePFC_COMMIT(PFCNo)
    Bool : PostPFC_COMMIT(PFCNo)
    Bool : SetStatus_COMMIT(PFCNo, LineNo, Status)
    Bool : RetryPFCLine_COMMIT(PFCNo, PFCLineNo, UseDialog);
    Text[1024] : GetError()
    *************************************************************************
    POLARIS TT-33561
    08/12/2009
    Only Post PFC that are at least 1 minute old.
    MBH
    *************************************************************************
    POLARIS TT-33992
    16/12/2009
    Carriage Return in PFC description
    MBH
    *************************************************************************
    TB-ALG TT35971
    RTC adaptation

    //**************************************************************************
    // Project : TOPNET-Billing
    // Réf du FOB : Mis à jour du référentiel
    // Description :
    // Date de création : 12/04/2010
    // Auteur : z.gharsallaoui
    // Version : V1.0
    //**************************************************************************
    // Historique des modifications
    // ***********************
    // Date ! Par ! Ref FOB ! Objet de la modification
    //**************************************************************************
    // 11/11/2011 ! ZDE ! LOT0.LIV0 ! Scheduler(): désactiver l'affichage de Window.
    // 00/00/9999 ! ZDE ! LOT0.LIV0 !
    // 00/00/9999 ! ZDE ! LOT0.LIV0 !
    //
    //

    OnRun(VAR Rec : Record "Job Queue Entry")



    CLEAR(ErrorMsg);
    CLEARLASTERROR;

    CASE RunType OF
    RunType::Scheduler,
    RunType::Execute,
    RunType::SetStatus :
    BEGIN
    IF Setup."PFC Nos." = '' THEN
    Setup.GET();
    END;
    END;

    CASE RunType OF
    RunType::Scheduler : Scheduler();
    RunType::ReservePFC : ReservePFC();
    RunType::Execute : ExecutePFC();
    RunType::ExecuteLine : ExecutePFCLine();
    RunType::ExecuteAction : ExecuteAction();
    RunType::FinalisePFC : FinalisePFC();
    RunType::SetLineStatus : SetLineStatus();
    RunType::SetStatus : SetStatus();
    RunType::PostPFC : PostPFC();
    END;

    ExecutePFC_COMMIT(PFCNo : Code[20]) : Boolean
    //
    // Execute PFC
    //
    // After successfull execution, the PFC will be owned by either:
    // [Status] [Owned by]
    // Ready|Done Scheduler
    // Waiting Apropriate interface
    // Error GUI or other
    //

    CLEAR(ErrorMsg);
    CLEARLASTERROR;
    COMMIT;
    SELECTLATESTVERSION;

    ExecuteOK := TRUE;

    // Lock PFC by setting status to ::Executing
    PFCEngine._SetVars(RunType::ReservePFC, PFCNo, 0, PFCHeaderRec.ExecuteStatus::Executing, '');
    IF PFCEngine.RUN THEN BEGIN

    // Execute the PFC.
    PFCEngine._SetVars(RunType::Execute, PFCNo, 0, 0, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ExecuteOK := FALSE;
    ErrorMsg := PFCEngine.GetError();
    END;

    // New status is determined by the execute function but applied by Finalise function.
    PFCEngine._GetLastExecuteStatus(PFCExecuteStatus);

    // Finalise PFC, by setting control vars
    PFCEngine._SetVars(RunType::FinalisePFC, PFCNo, 0, PFCExecuteStatus, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ExecuteOK := FALSE;
    ErrorMsg := PFCEngine.GetError();
    END;
    END ELSE BEGIN
    ExecuteOK := FALSE;
    ErrorMsg := PFCEngine.GetError();
    END;

    COMMIT;

    EXIT(ExecuteOK);

    ReservePFC_COMMIT(PFCNo : Code[20]) : Boolean
    //
    // Reserve PFC
    //

    CLEAR(ErrorMsg);
    CLEARLASTERROR;
    COMMIT;
    SELECTLATESTVERSION;

    IF NOT PFCHeaderRec.GET(PFCNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, PFCNo);
    EXIT(FALSE);
    END;

    IF NOT (PFCHeaderRec.ExecuteStatus IN [PFCHeaderRec.ExecuteStatus::Waiting,
    PFCHeaderRec.ExecuteStatus::Error]) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_NotStatusWaitingErr);
    EXIT(FALSE);
    END;

    PFCEngine._SetVars(RunType::ReservePFC, PFCNo, 0, 0, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    EXIT(FALSE);
    END;

    EXIT(TRUE);

    ReleasePFC_COMMIT(PFCNo : Code[20]) : Boolean
    //
    // Release PFC
    //

    CLEAR(ErrorMsg);
    CLEARLASTERROR;
    COMMIT;
    SELECTLATESTVERSION;

    IF NOT PFCHeaderRec.GET(PFCNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, PFCNo);
    EXIT(FALSE);
    END;

    // If PFC is New, a Release means ready for execution
    IF PFCHeaderRec.ExecuteStatus = PFCHeaderRec.ExecuteStatus::New THEN
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;

    PFCEngine._SetVars(RunType::FinalisePFC, PFCNo, 0, PFCHeaderRec.ExecuteStatus, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    EXIT(FALSE);
    END;

    EXIT(TRUE);

    PostPFC_COMMIT(PFCNo : Code[20]) : Boolean
    CLEAR(ErrorMsg);
    CLEARLASTERROR;
    COMMIT;
    SELECTLATESTVERSION;

    PFCEngine._SetVars(RunType::PostPFC, PFCNo, 0, 0, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    EXIT(FALSE);
    END;

    EXIT(TRUE);

    SetStatus_COMMIT(PFCNo : Code[20];LineNo : Integer;Status : Text[250]) : Boolean

    CLEAR(ErrorMsg);
    CLEARLASTERROR;
    COMMIT;
    SELECTLATESTVERSION;

    PFCEngine._SetVars(RunType::SetStatus, PFCNo, LineNo, 0, Status);
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    EXIT(FALSE);
    END;

    COMMIT;
    EXIT(TRUE);

    RetryPFCLine_COMMIT(PFCHeaderNo : Code[20];PFCLineNo : Integer;UseDialog : Boolean) : Boolean
    CLEAR(ErrorMsg);
    CLEARLASTERROR;
    COMMIT;
    SELECTLATESTVERSION;

    PFCSetup.GET;

    IF NOT PFCLineRec.GET(PFCHeaderNo, PFCLineNo) THEN
    EXIT(FALSE);
    IF PFCLineRec.ExecuteStatus = PFCLineRec.ExecuteStatus::Error THEN BEGIN

    IF TransmissionRec.HasLineTransactions(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.") THEN BEGIN

    //HBR
    UseDialog:=FALSE;
    IF UseDialog THEN BEGIN
    TransmissionAction := STRMENU(TXT_HandleTransactions);
    IF (NOT TransmissionRec.HasErrorTransactions(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr."))
    AND (TransmissionAction = TransmissionAction::Resend) THEN
    ;
    //ERROR(ERR_NoErrorTransaction);
    IF TransmissionAction = TransmissionAction::None THEN
    ;
    // ERROR('');
    END ELSE
    TransmissionAction := TransmissionAction::Resend;

    END;

    IF UseDialog THEN BEGIN
    IF TransmissionAction <> TransmissionAction::Resend THEN
    ;
    // IF NOT CONFIRM(TXT_WarningInconsistence) THEN
    // ERROR('');
    END;

    IF NOT PFCEngine.ReservePFC_COMMIT(PFCHeaderNo) THEN
    IF UseDialog THEN
    ;
    // ERROR(PFCEngine.GetError())
    //ELSE
    //EXIT(FALSE);

    PFCHeaderRec.GET(PFCHeaderNo);

    IF TransmissionAction = TransmissionAction::Resend THEN BEGIN

    PFCLineRec.MODIFYWait();
    CLEAR(PFCHeaderRec."Status Description");
    PFCHeaderRec.VALIDATE(StatusCode, PFCSetup.WaitingStatus);
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Waiting;
    PFCHeaderRec.MODIFY();

    END ELSE BEGIN

    IF TransmissionAction = TransmissionAction::Retry THEN
    TransmissionRec.CancelTransactions(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.");

    PFCLineRec.MODIFYRetry(0DT);
    CLEAR(PFCHeaderRec."Status Description");
    PFCHeaderRec.VALIDATE(StatusCode, PFCSetup.ReadyStatus);
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;
    PFCHeaderRec.MODIFY();

    END;

    IF UseDialog THEN BEGIN

    { Window.OPEN(STRSUBSTNO(TXT_ExecutingPFC + '''%1''\#2##########################', PFCHeaderNo),
    PFCHeaderNo, PFCHeaderRec.Description); }

    IF NOT PFCEngine.ExecutePFC_COMMIT(PFCHeaderNo) THEN
    ;
    //ERROR(PFCEngine.GetError());
    //Window.CLOSE;

    END ELSE BEGIN
    PFCEngine.ReleasePFC_COMMIT(PFCHeaderNo);
    END;

    IF TransmissionAction = TransmissionAction::Resend THEN
    TransmissionRec.RetryErrors(PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.");

    EXIT(TRUE);

    END ELSE
    IF UseDialog THEN
    ;
    //ERROR(STRSUBSTNO(ERR_PFCLineNotInStatus, PFCLineRec.ExecuteStatus::Error));

    GetError() : Text[1024]
    IF ErrorMsg = '' THEN
    ErrorMsg := GETLASTERRORTEXT;

    //TT-33992 16/12/09 MBH >>>>
    CRLF := 13;
    SPACE := 32;
    ErrorMsg := CONVERTSTR(ErrorMsg,FORMAT(CRLF),FORMAT(SPACE));
    //TT-33992 16/12/09 MBH <<<<

    EXIT(ErrorMsg);

    -- Local Functions --()

    Scheduler()
    //message('%1',PFCHeaderRec."PFC Nr.");
    StartTime := Now();

    // Check for PFCs with Max Locktime exceeded.
    //
    CheckLockTimeout();
    COMMIT;

    // Check for Idle PFCs
    //
    CheckMaxIdle();
    COMMIT;

    // Execute ready PFCs.
    //
    PFCHeaderRec.RESET;
    PFCHeaderRec.SETCURRENTKEY(ExecuteStatus, ExecutePriority, "Next Execution DateTime");
    // ZDE OLD PFCHeaderRec.SETRANGE(ExecuteStatus, PFCHeaderRec.ExecuteStatus::Ready);
    PFCHeaderRec.SETRANGE(ExecuteStatus, PFCHeaderRec.ExecuteStatus::New,PFCHeaderRec.ExecuteStatus::Ready);
    PFCHeaderRec.SETFILTER("Next Execution DateTime", '..%1', StartTime);
    PFCHeaderRec.SETFILTER("Latest Execution", '..%1', StartTime);

    IF PFCHeaderRec.FINDFIRST() THEN BEGIN

    MaxCount := PFCHeaderRec.COUNT;
    {Progress.OPEN(TXT_ExecutingPFC + '\'+
    TXT_ExecTime + ' #1######\'+
    '#2#### '+TXT_Of+' #3######\'+
    '#4#####################\' +
    '@\',
    ExecTime, Counter, MaxCount, PFCHeaderRec.Description); }

    // Loop the ready PFCs, always keeping highest prio records first.
    WHILE PFCHeaderRec.FINDFIRST AND (NOT MaxTimeExceeded) DO BEGIN

    Counter += 1;
    TmpInt := Now() - StartTime;
    ExecTime := 000000T + TmpInt;
    //zde
    // Progress.UPDATE;
    //zde
    // Progress.UPDATE(5, (Counter/10000)*9999 DIV (MaxCount/10000));

    IF NOT ExecutePFC_COMMIT(PFCHeaderRec."PFC Nr.") THEN
    LastError := ErrorMsg;

    SELECTLATESTVERSION;

    // Check if we have been running too long
    MaxTimeExceeded := ( Setup.MaxRuntime > 0 )
    AND (Now() >= (StartTime + ( Setup.MaxRuntime * 60000 ) ));

    END;

    // Progress.CLOSE();
    END;

    IF MaxTimeExceeded THEN
    EXIT;

    COMMIT;

    // Post PFCs
    PFCHeaderRec.RESET;
    PFCHeaderRec.SETCURRENTKEY(ExecuteStatus, ExecutePriority, "Next Execution DateTime");
    PFCHeaderRec.SETRANGE(ExecuteStatus, PFCHeaderRec.ExecuteStatus::Done);
    PFCHeaderRec.SETFILTER(PFCHeaderRec."Latest Execution",'<%1|%2',CREATEDATETIME(TODAY,TIME - (60*1000)),0DT); //TT-33561
    IF PFCHeaderRec.FINDFIRST THEN BEGIN

    MaxCount := PFCHeaderRec.COUNT;
    CLEAR(Counter);

    { Progress.OPEN(TXT_PostingPFC + '\'+
    TXT_ExecTime + ' #1######\'+
    '#2#### '+TXT_Of+' #3######\'+
    '#4#####################\' +
    '@\',
    ExecTime, Counter, MaxCount, PFCHeaderRec.Description); }

    IF PFCHeaderRec.FINDSET(FALSE, FALSE) THEN REPEAT

    Counter += 1;
    TmpInt := Now() - StartTime;
    ExecTime := 000000T + TmpInt;
    //zde
    // Progress.UPDATE;
    //zde
    // Progress.UPDATE(5, (Counter/10000)*9999 DIV (MaxCount/10000));

    PFCEngine._SetVars(RunType::PostPFC, PFCHeaderRec."PFC Nr.", 0, 0, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    IF PFCHeaderRec2.GET(PFCHeaderRec."PFC Nr.") THEN BEGIN
    PFCHeaderRec2.VALIDATE(StatusCode, Setup.ErrorStatus);
    PFCHeaderRec2."Status Description" := DELSTR(TXT_PostingError + ':' + PFCFunctions.GetError(),
    MAXSTRLEN(PFCHeaderRec2."Status Description")+1);
    PFCHeaderRec2.MODIFY(FALSE);
    COMMIT;
    PFCEngine._SetVars(RunType::FinalisePFC, PFCHeaderRec."PFC Nr.", 0, PFCHeaderRec.ExecuteStatus::Error, '');
    IF NOT PFCEngine.RUN() THEN
    LastError := PFCEngine.GetError();
    END;
    END;

    // Check if we have been running too long
    MaxTimeExceeded := ( Setup.MaxRuntime > 0 )
    AND (Now() >= (StartTime + ( Setup.MaxRuntime * 60000 ) ));

    UNTIL MaxTimeExceeded
    OR (PFCHeaderRec.NEXT = 0);
    END;

    ReservePFC()
    //
    // Reserve PFC (for execution)
    //

    SELECTLATESTVERSION;

    ErrorMsg := STRSUBSTNO(ERR_UnableToLockPFC, _PFCNo);
    PFCHeaderRec.LOCKTABLE;
    IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
    //ERROR(ErrorMsg);
    END;

    IF NOT GetMySession(SessionRec) THEN
    ;
    // ERROR(ErrorMsg);

    // Exit if someone else has a lock on this.
    IF (PFCHeaderRec.LockUser <> '')
    OR (PFCHeaderRec.LockSession > 0) THEN BEGIN

    IF (PFCHeaderRec.LockUser <> UPPERCASE(USERID))
    OR (PFCHeaderRec.LockSession <> SessionRec."Connection ID") THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_LockedBy, _PFCNo, PFCHeaderRec.LockUser, PFCHeaderRec.LockSession);
    // ERROR(ErrorMsg);
    END;
    END;

    // Make sure we are the only ones executing it
    //IF _StatusOption <> 0 THEN //TB-ALG TT35971
    IF _Status <> 0 THEN
    PFCHeaderRec.ExecuteStatus := _Status;
    //PFCHeaderRec.ExecuteStatus := _StatusOption; //TB-ALG TT35971

    // Update lock information
    PFCHeaderRec.LockUser := USERID;
    PFCHeaderRec.LockSession := SessionRec."Connection ID";
    PFCHeaderRec.LockTime := Now();

    ErrorMsg := STRSUBSTNO(ERR_ModifyPFCFailed, _PFCNo);
    PFCHeaderRec.MODIFY(FALSE);
    COMMIT;
    CLEAR(ErrorMsg);

    FinalisePFC()
    //
    // Finalise PFC execution / Release PFC
    // Calculating priority, setting status etc.
    //

    SELECTLATESTVERSION;

    ErrorMsg := STRSUBSTNO(ERR_UnableToLockPFC, _PFCNo);
    PFCHeaderRec.LOCKTABLE;
    PFCHeaderRec.GET(_PFCNo);

    // Set executiondate to atleast NOW, to prevent race in the scheduler FINDFIRST()
    IF PFCHeaderRec."Next Execution DateTime" < Now() THEN
    PFCHeaderRec.VALIDATE("Next Execution DateTime", Now());

    // 0 signals a general update, we should not touch the status
    //IF _StatusOption > 0 THEN //TB-ALG TT35971
    // PFCHeaderRec.ExecuteStatus := _StatusOption; //TB-ALG TT35971
    IF _Status > 0 THEN
    PFCHeaderRec.ExecuteStatus := _Status;

    PFCHeaderRec."Latest Execution" := Now();
    PFCHeaderRec."Executed By" := USERID;

    CLEAR(PFCHeaderRec.LockUser);
    CLEAR(PFCHeaderRec.LockSession);
    CLEAR(PFCHeaderRec.LockTime);

    ErrorMsg := STRSUBSTNO(ERR_ModifyPFCFailed, _PFCNo);
    PFCHeaderRec.MODIFY(FALSE);
    COMMIT;

    CLEAR(ErrorMsg);

    ExecutePFC()
    //
    // Execute the PFC.
    //

    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
    Continue := TRUE;

    //
    // Execute Ready PFC lines
    //
    PFCLineRec.SETCURRENTKEY("PFC Nr.", "Line Nr.");
    PFCLineRec.SETRANGE("PFC Nr.", _PFCNo);
    PFCLineRec.SETRANGE("Line Nr.", 0, 999999998);
    PFCLineRec.SETFILTER(ExecuteStatus, '<>%1&<>%2', // all interesting lines.
    PFCLineRec.ExecuteStatus::Ok,
    PFCLineRec.ExecuteStatus::Skipped);
    WHILE PFCLineRec.FINDFIRST
    AND (Continue) DO BEGIN

    // Calculate line execution date
    IF PFCLineRec."Execution Date" = 0D THEN
    PFCLineRec."Execution Date" := WORKDATE;
    NextExecuteDate := CREATEDATETIME(PFCLineRec."Execution Date", PFCLineRec."Execution Time");

    Continue := PFCLineRec.ExecuteStatus = PFCLineRec.ExecuteStatus::New;
    Continue := Continue AND (NextExecuteDate <= Now());

    IF (Continue) THEN BEGIN

    PFCEngine._SetVars(RunType::ExecuteLine, PFCLineRec."PFC Nr.", PFCLineRec."Line Nr.", 0, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    IF ErrorMsg = '' THEN
    ErrorMsg := STRSUBSTNO(ERR_UnknownErrorExecutingLine, PFCLineRec."Line Nr.");
    Continue := FALSE;
    END;
    END;

    SELECTLATESTVERSION;
    END;

    IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
    // ERROR(ErrorMsg);
    END;

    IF ErrorMsg <> '' THEN BEGIN

    // If PFC is (or should be) in error, ErrorMsg is already set.
    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;

    END ELSE BEGIN

    // Else determine status of the PFC
    IF PFCLineRec.FINDFIRST THEN BEGIN

    IF PFCLineRec."Execution Date" = 0D THEN
    PFCLineRec."Execution Date" := WORKDATE;
    NextExecuteDate := CREATEDATETIME(PFCLineRec."Execution Date", PFCLineRec."Execution Time");

    CASE PFCLineRec.ExecuteStatus OF

    PFCLineRec.ExecuteStatus::New :
    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;

    PFCLineRec.ExecuteStatus::Waiting :
    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Waiting;

    // If the pfc and line was already in Error state
    // it is not executed and we should not overwrite the error message
    PFCLineRec.ExecuteStatus::Error :
    BEGIN
    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
    IF ErrorMsg = '' THEN
    // use previous error from header.
    ErrorMsg := PFCHeaderRec."Status Description";
    IF ErrorMsg = '' THEN
    // Undefined error
    ErrorMsg := STRSUBSTNO(ERR_UnknownErrorExecutingLine, PFCLineRec."Line Nr.");;
    END;

    PFCLineRec.ExecuteStatus::StopPFC :
    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Done;

    ELSE BEGIN
    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
    ErrorMsg := STRSUBSTNO(ERR_UnexpectedStatus,
    PFCLineRec.ExecuteStatus,
    PFCLineRec."Line Nr.");
    END;
    END;
    END ELSE BEGIN

    // No more lines to execute
    _ExecuteStatus := PFCHeaderRec.ExecuteStatus::Done;
    END;
    END;

    // Update Header status codes and description
    //
    // On Error, ErrorMsg always contains the error description (returned from Action OR scheduler functions)
    //
    IF _ExecuteStatus = PFCHeaderRec.ExecuteStatus::Error THEN BEGIN

    PFCHeaderRec.VALIDATE(StatusCode, Setup.ErrorStatus);
    PFCHeaderRec."Status Description" := DELSTR(ErrorMsg, MAXSTRLEN(PFCHeaderRec."Status Description")+1);

    END ELSE IF PFCHeaderRec.StatusCode = '' THEN BEGIN

    // No status set by return code, revert to default.
    CASE _ExecuteStatus OF
    PFCHeaderRec.ExecuteStatus::Waiting :
    PFCHeaderRec.VALIDATE(StatusCode, Setup.WaitingStatus);
    PFCHeaderRec.ExecuteStatus::Ready :
    PFCHeaderRec.VALIDATE(StatusCode, Setup.ReadyStatus);
    PFCHeaderRec.ExecuteStatus::Done :
    PFCHeaderRec.VALIDATE(StatusCode, Setup.DoneStatus);
    END;
    END;


    IF PFCHeaderRec."A-Number" = '' THEN
    PFCHeaderRec."A-Number" := PFCHeaderRec.ShowAnr;

    // Set general execution parms.
    PFCHeaderRec.VALIDATE("Next Execution DateTime", NextExecuteDate);
    IF PFCHeaderRec."Max Idle Time" > 0 THEN
    CalculateMaxIdle(PFCHeaderRec);
    PFCHeaderRec.MODIFY;

    COMMIT;

    CLEAR(ErrorMsg);

    ExecutePFCLine()
    //
    // Execute a single PFC Line.
    //

    CLEAR(ResultPFCLine);

    // set line = inprogress (and clear control vars)
    PFCEngine._SetVars(RunType::SetLineStatus, _PFCNo, _PFCLineNo, ResultPFCLine.ExecuteStatus::Initiated, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    // ERROR(ErrorMsg);
    END;

    // Reset header status code each time we execute a new line.
    ErrorMsg := STRSUBSTNO(ERR_UnableToLockPFC, _PFCNo);
    IF PFCHeaderRec.GET(_PFCNo) THEN BEGIN
    CLEAR(PFCHeaderRec.StatusCode);
    CLEAR(PFCHeaderRec."Status Description");
    ErrorMsg := STRSUBSTNO(ERR_ModifyPFCFailed, _PFCNo);
    PFCHeaderRec.MODIFY(FALSE);
    COMMIT;
    END ELSE BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
    //ERROR(ErrorMsg);
    END;
    CLEAR(ErrorMsg);


    // Execute Action
    //
    PFCEngine._SetVars(RunType::ExecuteAction, _PFCNo, _PFCLineNo, 0, '');
    IF NOT PFCEngine.RUN THEN BEGIN

    // Action codeunit reported back an error
    // (or function Crash)
    ErrorMsg := PFCEngine.GetError();
    ResultPFCLine.ExecuteStatus := ResultPFCLine.ExecuteStatus::Error;

    END ELSE BEGIN

    // Line OK or Return value set.

    // Query Line for current status
    SELECTLATESTVERSION;

    ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
    IF NOT ResultPFCLine.GET(_PFCNo, _PFCLineNo) THEN
    // ERROR(ErrorMsg);

    // If line still Inprogress, we should check the return code parameters
    IF ResultPFCLine.ExecuteStatus = ResultPFCLine.ExecuteStatus::Initiated THEN BEGIN

    IF ParseReturnCode(ResultPFCLine) THEN
    COMMIT;

    // No status reported by action (manual or return values)
    IF ResultPFCLine.ExecuteStatus = ResultPFCLine.ExecuteStatus::Initiated THEN
    ResultPFCLine.ExecuteStatus := ResultPFCLine.ExecuteStatus::Waiting;

    END;

    END;

    PFCEngine._SetVars(RunType::SetLineStatus, _PFCNo, _PFCLineNo, ResultPFCLine.ExecuteStatus, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    // ERROR(ErrorMsg);
    END;

    IF ResultPFCLine.ExecuteStatus IN [ResultPFCLine.ExecuteStatus::Error] THEN
    ;
    // ERROR(ErrorMsg);

    CLEAR(ErrorMsg);

    ExecuteAction()
    //
    // Execute PFC line Action.
    //

    ErrorMsg := STRSUBSTNO(ERR_ExecutingLine, _PFCLineNo);
    IF NOT PFCLineRec.GET(_PFCNo, _PFCLineNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
    // ERROR(ErrorMsg);
    END;
    IF NOT PFCActionRec.GET(PFCLineRec."Action ID") THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_ActionNotFound, PFCLineRec."PFC Nr.");
    // ERROR(ErrorMsg);
    END;
    CLEAR(ErrorMsg);

    CASE PFCActionRec.Type OF
    PFCActionRec.Type::"Function" : CODEUNIT.RUN(PFCActionRec."Object ID", PFCLineRec);
    PFCActionRec.Type::Report : REPORT.RUN(PFCActionRec."Object ID", FALSE, FALSE, PFCLineRec);
    PFCActionRec.Type::Dataport : IF NOT ISSERVICETIER THEN //TB-ALG TT35971
    DATAPORT.RUN(PFCActionRec."Object ID", FALSE, PFCLineRec);
    END;

    SetStatus()

    CLEAR(ErrorMsg);
    SELECTLATESTVERSION;

    IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
    // ERROR(ErrorMsg);
    END;

    IF NOT PFCLineRec.GET(_PFCNo, _PFCLineNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
    // ERROR(ErrorMsg);
    END;

    //
    // Inserting a return code is only allowed when the PFC is in Status::Waiting
    // OR
    // If the pfc is locked by the current process and in
    // Status::Executing (when called from action)
    // Status::Error (general update of the PFC error description)

    IF NOT ((PFCLineRec.ExecuteStatus IN [PFCLineRec.ExecuteStatus::Waiting,
    PFCLineRec.ExecuteStatus::Error])
    OR (PFCHeaderRec.ExecuteStatus = PFCHeaderRec.ExecuteStatus::Executing)) THEN BEGIN

    ErrorMsg := STRSUBSTNO(ERR_CantInsertRC, PFCLineRec.ExecuteStatus);
    //ERROR(ErrorMsg);
    END;

    // IF PFC not waiting, current process must be the owner.
    IF PFCHeaderRec.ExecuteStatus <> PFCHeaderRec.ExecuteStatus::Waiting THEN BEGIN

    IF NOT GetMySession(SessionRec) THEN
    ;
    // ERROR(ErrorMsg);

    IF (PFCHeaderRec.LockUser = '')
    OR (PFCHeaderRec.LockSession = 0) THEN BEGIN
    ErrorMsg := ERR_NotLocked;
    // ERROR(ErrorMsg);
    END;

    IF (PFCHeaderRec.LockUser <> UPPERCASE(USERID))
    OR (PFCHeaderRec.LockSession <> SessionRec."Connection ID") THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_LockedBy, _PFCNo, PFCHeaderRec.LockUser, PFCHeaderRec.LockSession);
    // ERROR(ErrorMsg);
    END;

    END ELSE BEGIN

    // Reserve the PFC before we do any modifications.
    IF NOT PFCEngine.ReservePFC_COMMIT(_PFCNo) THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    // ERROR(ErrorMsg);
    END;
    END;

    // Insert the status code on the PFC line
    PFCParameterRec."PFC Nr." := _PFCNo;
    PFCParameterRec."PFC Line Nr." := _PFCLineNo;
    PFCParameterRec."Entry Nr." := PFCParameterRec.GetNewEntryNr();
    PFCParameterRec.Parameter := 'STATUSCODE';
    PFCParameterRec.Value := DELSTR(_StatusValue, MAXSTRLEN(PFCParameterRec.Value)+1);
    PFCParameterRec.Modified := TRUE;
    PFCParameterRec.INSERT;

    COMMIT;

    // If PFC is currently executing,
    // We don't need to act on the status code yet (This will be done by ExecutePFCLine())
    IF PFCHeaderRec.ExecuteStatus = PFCHeaderRec.ExecuteStatus::Executing THEN
    EXIT;

    // Determine PFC line status.
    IF ParseReturnCode(PFCLineRec) THEN
    COMMIT;

    // Update PFC line
    PFCEngine._SetVars(RunType::SetLineStatus, _PFCNo, _PFCLineNo, PFCLineRec.ExecuteStatus, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    // ERROR(ErrorMsg);
    END;

    // Update PFC header
    CASE PFCLineRec.ExecuteStatus OF
    PFCLineRec.ExecuteStatus::Ok :
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Ready;
    PFCLineRec.ExecuteStatus::Waiting :
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Waiting;
    PFCLineRec.ExecuteStatus::StopPFC :
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Done;
    PFCLineRec.ExecuteStatus::Error :
    BEGIN
    PFCHeaderRec.VALIDATE(StatusCode, Setup.ErrorStatus);
    PFCHeaderRec."Status Description" := DELSTR(ErrorMsg, MAXSTRLEN(PFCHeaderRec."Status Description")+1);
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
    PFCHeaderRec.MODIFY();
    COMMIT;
    END;
    END;
    // Release the PFC
    PFCEngine._SetVars(RunType::FinalisePFC, _PFCNo, _PFCLineNo, PFCHeaderRec.ExecuteStatus, '');
    IF NOT PFCEngine.RUN THEN BEGIN
    ErrorMsg := PFCEngine.GetError();
    // ERROR(ErrorMsg);
    END;

    COMMIT;

    SetLineStatus()
    //
    // Sets the Status option of the line
    //

    SELECTLATESTVERSION;

    ErrorMsg := STRSUBSTNO(ERR_UnableToLockLine, _PFCLineNo);
    PFCLineRec.LOCKTABLE;
    IF NOT PFCLineRec.GET(_PFCNo, _PFCLineNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_LineNotFound, _PFCLineNo);
    // ERROR(ErrorMsg);
    END;

    ErrorMsg := STRSUBSTNO(ERR_LineStatusFailed, _PFCLineNo);

    CLEAR(PFCLineRec.ExecuteError);

    //PFCLineRec.ExecuteStatus := _StatusOption; //TB-ALG TT35971
    PFCLineRec.ExecuteStatus := _Status;
    PFCLineRec.MODIFY;
    COMMIT;

    CLEAR(ErrorMsg);

    ParseReturnCode(VAR PFCLineRec : Record "PFC Line") DataModified : Boolean
    //
    // Parses Return code values on the PFC line.
    //
    // Return DataModified = true if any data was modified in the db

    CLEAR(ErrorMsg);
    SELECTLATESTVERSION;

    PFCParameterRec.SETRANGE("PFC Nr.", PFCLineRec."PFC Nr.");
    PFCParameterRec.SETRANGE("PFC Line Nr.", PFCLineRec."Line Nr.");

    ReturnCodesRec.SETRANGE("PFC No.", PFCLineRec."PFC Nr.");
    ReturnCodesRec.SETRANGE("PFC Line No.", PFCLineRec."Line Nr.");
    IF ReturnCodesRec.ISEMPTY THEN BEGIN

    // No return codes specified, check for an error StatusCode.
    PFCParameterRec.SETRANGE(Parameter, 'STATUSCODE');
    IF PFCParameterRec.FINDLAST THEN BEGIN
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
    ErrorMsg := PFCParameterRec.Value;
    END ELSE
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Waiting;

    EXIT(DataModified);
    END;


    // 1. If a return code is mandatory, check if we have received one.
    ReturnCodesRec.SETRANGE("Value Requirement", ReturnCodesRec."Value Requirement"::Mandatory);
    //ReturnCodesRec.ASCENDING(TRUE);
    IF NOT ReturnCodesRec.ISEMPTY THEN BEGIN
    IF ReturnCodesRec.FINDSET(FALSE, FALSE) THEN REPEAT

    IF ReturnCodesRec."Return Value" <> '' THEN
    PFCParameterRec.SETRANGE(Value, ReturnCodesRec."Return Value");

    IF PFCParameterRec.FINDLAST THEN
    ReturnCodeFound := TRUE;

    UNTIL (ReturnCodesRec.NEXT = 0) OR ReturnCodeFound;
    END;

    // 2. do a general return code check
    IF NOT ReturnCodeFound THEN BEGIN

    ReturnCodesRec.SETRANGE("Value Requirement");
    PFCParameterRec.SETRANGE(Parameter); // ??
    PFCParameterRec.SETRANGE(Value); // ??

    // Find last inserted parameter.
    IF PFCParameterRec.FIND('+') THEN REPEAT

    // Check if parameter is a return code
    ReturnCodesRec.SETRANGE("Return Value");
    ReturnCodesRec.SETRANGE(Parameter, PFCParameterRec.Parameter);
    IF ReturnCodesRec.FINDFIRST THEN BEGIN

    // Return code match
    ReturnCodesRec.SETRANGE("Return Value", DELSTR(PFCParameterRec.Value, MAXSTRLEN(ReturnCodesRec."Return Value")+1));
    IF ReturnCodesRec.FINDFIRST THEN BEGIN

    // Exact match
    ReturnCodeFound := TRUE;

    END ELSE BEGIN

    // Generic match
    ReturnCodesRec.SETFILTER("Return Value", '''''');
    IF ReturnCodesRec.FINDFIRST THEN BEGIN
    ReturnCodeFound := TRUE;

    END ELSE BEGIN

    // Unknown - unknown values should be treated as error.
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
    ErrorMsg := PFCParameterRec.Value;
    EXIT(DataModified);

    END;
    END;
    END;

    UNTIL ReturnCodeFound
    OR (PFCParameterRec.NEXT(-1) = 0);
    END;

    IF NOT ReturnCodeFound THEN

    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Waiting

    ELSE BEGIN

    CASE ReturnCodesRec.LineExecuteStatus OF
    ReturnCodesRec.LineExecuteStatus::Ok :
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Ok;
    ReturnCodesRec.LineExecuteStatus::Error :
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
    ReturnCodesRec.LineExecuteStatus::Waiting :
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Waiting;
    END;

    // Only allow decisions when in OK state.
    IF (ReturnCodesRec.LineExecuteStatus = ReturnCodesRec.LineExecuteStatus::Ok)
    OR (ReturnCodesRec.Decision = ReturnCodesRec.Decision::"Create New PFC") THEN
    CASE ReturnCodesRec.Decision OF

    ReturnCodesRec.Decision::"Go to Step" :
    BEGIN
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;

    IF (NOT EVALUATE(SkipValue, ReturnCodesRec."Decision Value"))
    OR (SkipValue - 1 <= PFCLineRec."Line Nr.") THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_InvalidSkipValue, ReturnCodesRec."Decision Value");
    EXIT(DataModified);
    END;
    IF NOT PFCLineRecLoop.GET(PFCLineRec."PFC Nr.", SkipValue) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_SkipFailed, SkipValue);
    EXIT(DataModified);
    END;
    PFCLineRecLoop.SETRANGE("PFC Nr.", PFCLineRec."PFC Nr.");
    PFCLineRecLoop.SETRANGE("Line Nr.", PFCLineRec."Line Nr." + 1, SkipValue - 1);
    IF PFCLineRecLoop.FINDSET(TRUE, FALSE) THEN REPEAT
    IF PFCLineRecSkip.GET(PFCLineRecLoop."PFC Nr.", PFCLineRecLoop."Line Nr.") THEN BEGIN
    PFCLineRecSkip.ExecuteStatus := PFCLineRecSkip.ExecuteStatus::Skipped;
    PFCLineRecSkip.MODIFY;
    END;
    UNTIL PFCLineRecLoop.NEXT = 0;
    DataModified := TRUE;
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Ok;
    END;

    ReturnCodesRec.Decision::"Stop PFC" :
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::StopPFC;

    // Create a new PFC, and set ready to execute.
    ReturnCodesRec.Decision::"Stop PFC & Create New",
    ReturnCodesRec.Decision::"Create New PFC" :
    BEGIN
    IF NOT PFCHeaderRec.GET(PFCLineRec."PFC Nr.") THEN
    CLEAR(PFCHeaderRec);
    IF NOT PFCFunctions.GetParameter(DATABASE::"Wholesale Partner", 10, WP, PFCLineRec."PFC Nr.", 0) THEN
    CLEAR(WP);
    NewPFCNo := PFCFunctions.CreatePFC_COMMIT(ReturnCodesRec."Decision Value", PFCHeaderRec."Customer No.",
    PFCHeaderRec."Contract No.", DELSTR(WP, 21), FALSE);
    IF NewPFCNo <> '' THEN
    PFCEngine.ReleasePFC_COMMIT(NewPFCNo)
    ELSE BEGIN
    DataModified := TRUE;
    ErrorMsg := PFCFunctions.GetError();
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Error;
    EXIT(DataModified);
    END;
    IF ReturnCodesRec.Decision = ReturnCodesRec.Decision::"Stop PFC & Create New" THEN
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::StopPFC
    ELSE
    PFCLineRec.ExecuteStatus := PFCLineRec.ExecuteStatus::Ok;
    END;
    END;

    IF ReturnCodesRec."Change Header Status To" <> '' THEN
    IF PFCHeaderRec.GET(PFCLineRec."PFC Nr.") THEN BEGIN
    PFCHeaderRec.VALIDATE(StatusCode, ReturnCodesRec."Change Header Status To");
    IF PFCLineRec.ExecuteStatus = PFCLineRec.ExecuteStatus::Error THEN BEGIN
    IF ErrorMsg = '' THEN
    ErrorMsg := PFCParameterRec.Value;
    PFCHeaderRec."Status Description" := DELSTR(ErrorMsg, MAXSTRLEN(PFCHeaderRec."Status Description")+1);
    END;
    PFCHeaderRec.MODIFY(FALSE);
    DataModified := TRUE;
    END;

    END;

    EXIT(DataModified);

    PostPFC() : Boolean

    CLEAR(ErrorMsg);
    CLEARLASTERROR;
    SELECTLATESTVERSION;

    IF NOT PFCHeaderRec.GET(_PFCNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotFound, _PFCNo);
    // ERROR(ErrorMsg);
    END;

    IF PFCHeaderRec.ExecuteStatus <> PFCHeaderRec.ExecuteStatus::Done THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCNotReadyToPost, _PFCNo);
    // ERROR(ErrorMsg);
    END;

    IF TransmissionRec.HasOpenTransactions(_PFCNo) THEN BEGIN
    ErrorMsg := STRSUBSTNO(ERR_PFCHasTransactions, _PFCNo);
    //ERROR(ErrorMsg);
    END;

    CLEAR(PostedPFCRec);
    PostedPFCRec.TRANSFERFIELDS(PFCHeaderRec);
    IF PostedPFCRec."A-Number" = '' THEN
    PostedPFCRec."A-Number" := PFCHeaderRec.ShowAnr();
    PostedPFCRec.INSERT;

    PFCLineRec.SETRANGE("PFC Nr.", _PFCNo);
    PFCParameterRec.SETRANGE("PFC Nr.", _PFCNo);
    PFCRVRec.SETRANGE("PFC No.", _PFCNo);
    PFCFilterRec.SETRANGE("PFC Nr.", _PFCNo);

    IF PFCHeaderRec."Delete Details" = FALSE THEN BEGIN
    PFCLineRec.SETRANGE("Line Nr.", 0, 999999998);
    IF PFCLineRec.FINDSET(FALSE, FALSE) THEN REPEAT
    CLEAR(PostedLineRec);
    PostedLineRec.TRANSFERFIELDS(PFCLineRec);
    PostedLineRec.INSERT(FALSE);
    UNTIL PFCLineRec.NEXT = 0;

    PFCParameterRec.SETRANGE("PFC Line Nr.", 0, 999999998);
    IF PFCParameterRec.FINDSET(FALSE, FALSE) THEN REPEAT
    IF (PFCParameterRec.Value <> '') OR (PFCParameterRec.Modified) THEN BEGIN
    CLEAR(PostedParameterRec);
    PostedParameterRec.TRANSFERFIELDS(PFCParameterRec);
    PostedParameterRec.INSERT(FALSE);
    END;
    UNTIL PFCParameterRec.NEXT = 0;

    PFCLineRec.SETRANGE("Line Nr.");
    PFCParameterRec.SETRANGE("PFC Line Nr.");
    END;

    SimCardPoolRec.CleanUpSimPoolStatus(PFCHeaderRec."PFC Nr.", PFCHeaderRec."Customer No.");
    ANumberPoolRec.CleanUpANoPoolStatus(PFCHeaderRec."PFC Nr.", PFCHeaderRec."Customer No.");

    PFCLineRec.DELETEALL;
    PFCParameterRec.DELETEALL;

    PFCRVRec.DELETEALL;
    PFCFilterRec.DELETEALL;

    PFCHeaderRec.DELETE;

    COMMIT;

    GetMySession(VAR SessionRec : Record Session) : Boolean
    SessionRec.SETRANGE("My Session", TRUE);
    IF NOT SessionRec.FINDFIRST THEN BEGIN
    ;
    // ErrorMsg := ERR_SessionIDError;
    //EXIT(FALSE);
    END;

    EXIT(TRUE);

    CalculateMaxIdle(VAR PFCHeaderRec : Record "PFC Header")
    CLEAR(PFCHeaderRec.IdleAt);

    IF PFCHeaderRec."Max Idle Time" = 0 THEN
    EXIT;

    CASE PFCHeaderRec."Max Idle" OF
    PFCHeaderRec."Max Idle"::Days : Interval := 86400000;
    PFCHeaderRec."Max Idle"::Hours : Interval := 3600000;
    ELSE
    EXIT;
    END;

    Interval *= PFCHeaderRec."Max Idle Time";

    PFCHeaderRec.IdleAt := Now() + Interval;

    CheckLockTimeout()
    //
    // Check For PFCs in locked state for more than [Setup.LockTimeout] no. of minutes
    // And set them to Error state if lock retained too long.
    //

    IF Setup.LockTimeout = 0 THEN
    EXIT;

    PFCHeaderRec.SETCURRENTKEY(ExecuteStatus, LockTime);
    PFCHeaderRec.SETFILTER(ExecuteStatus, '<>%1', PFCHeaderRec.ExecuteStatus::Error);
    PFCHeaderRec.SETFILTER(LockTime, '>%1&<%2',
    CREATEDATETIME(0D, 0T),
    (CURRENTDATETIME - (60000 * Setup.LockTimeout)));
    IF PFCHeaderRec.FINDFIRST() THEN REPEAT
    IF PFCHeaderRec.GET(PFCHeaderRec."PFC Nr.") THEN BEGIN
    PFCHeaderRec.ExecuteStatus := PFCHeaderRec.ExecuteStatus::Error;
    PFCHeaderRec.VALIDATE(StatusCode, Setup.LockTimeoutStatus);
    // Preserve old status description.
    IF STRPOS(PFCHeaderRec."Status Description", ERR_LockTimeout) = 0 THEN // did we do this already?
    PFCHeaderRec."Status Description" := DELSTR(ERR_LockTimeout + ': ' + PFCHeaderRec."Status Description",
    MAXSTRLEN(PFCHeaderRec."Status Description")+1);
    PFCHeaderRec.MODIFY(FALSE);
    END;
    UNTIL PFCHeaderRec.NEXT = 0;

    CheckMaxIdle()
    //
    // Check For PFCs with IdlesAt time exceeded
    // And mark them as MaxIdle.
    //

    IF Setup.MaxIdleStatus = '' THEN
    EXIT;

    PFCHeaderRec.SETCURRENTKEY(IdleAt);
    PFCHeaderRec.SETFILTER(ExecuteStatus, '<>%1', PFCHeaderRec.ExecuteStatus::Error);
    PFCHeaderRec.SETFILTER(StatusCode, '<>%1', Setup.MaxIdleStatus);
    PFCHeaderRec.SETFILTER(IdleAt, '>%1&<=%2',
    CREATEDATETIME(0D, 0T),
    Now());
    IF PFCHeaderRec.FINDSET(FALSE, FALSE) THEN REPEAT
    PFCHeaderTmp."PFC Nr." := PFCHeaderRec."PFC Nr.";
    PFCHeaderTmp.INSERT;
    UNTIL PFCHeaderRec.NEXT = 0;

    IF PFCHeaderTmp.FIND('-') THEN REPEAT
    IF PFCEngine.ReservePFC_COMMIT(PFCHeaderTmp."PFC Nr.") THEN BEGIN
    IF PFCHeaderRec.GET(PFCHeaderTmp."PFC Nr.") THEN BEGIN
    PFCHeaderRec.VALIDATE(StatusCode, Setup.MaxIdleStatus);
    PFCHeaderRec.MODIFY(FALSE);
    END;
    PFCEngine.ReleasePFC_COMMIT(PFCHeaderTmp."PFC Nr.");
    END;
    UNTIL PFCHeaderTmp.NEXT = 0;

    Now() : DateTime
    EXIT(CREATEDATETIME(WORKDATE, TIME));

    _SetVars(NewRunType : Option;PFCNo : Code[20];LineNo : Integer;StatusOption : Option;Value : Text[250])
    RunType := NewRunType;
    _PFCNo := PFCNo;
    _PFCLineNo := LineNo;
    _StatusOption := StatusOption;
    _StatusValue := Value;

    _Status := StatusOption; //TB-ALG TT35971

    _GetLastExecuteStatus(VAR ExecuteStatus : Option)
    //
    // Return execute status from last PFC execution
    //

    ExecuteStatus := _ExecuteStatus;
    EXIT;
  • ssinglassingla Member Posts: 2,973
    Have you restarted the NAS service after updation of code?
    CA Sandeep Singla
    http://ssdynamics.co.in
Sign In or Register to comment.