T_VLDUS - US Street-level Validation

**FREE
// Example Program: T_VLDUS
// Description:
//  This is a test program to illustrate how to call the ATI_ValidateStreet()
//  subproceure to validate a United States street address.
//
//  ATI_ValidateStreet() can validate an address when provided with the
//  following data:
//    - Street address (and optionally secondary info) and the ZIP Code
//    - Street address, city, and state (and optionally a ZIP Code)
//  For Puerto Rican addresses, the Urbanization value may also be required.
//
//  To achieve this, first generate a unique ID with ATI_GetUniqueID(), then
//  populate and write a record to ATIADRREQ that contains the address data
//  to be validated. Then, call ATI_ValidateStreet() by passing in your
//  unique ID and other parameters as shown.
//
//  ATI_ValidateStreet() will return *On if no error occurred, or *Off if
//  there an error was encountered. If an error occurred, you can review the
//  fields in the ErrorDS parameter data structure to retrieve information
//  about the error. Errors are also logged in the file ATIERRLOG.
//
//  Otherwise, you can retrieve the validation response data from the
//  ATIADRRSP and ATICANDS files.

Ctl-Opt ActGrp(*New) BndDir('ATIBND')
  Text('ATI US Street Address Validation Example');

/COPY QRPGLECPY,ATICB

Dcl-F ATIADRREQ Usage(*Input:*Output) Qualified Alias Keyed;
Dcl-Ds REQ LikeRec(ATIADRREQ.RATIADRREQ:*All);

Dcl-F ATIADRRSP Usage(*Input) Qualified Alias Keyed;
Dcl-F ATICANDS Usage(*Input) Qualified Alias Keyed;

Dcl-Ds RSP LikeRec(ATIADRRSP.RATIADRRSP:*All);
Dcl-Ds CAND LikeRec(ATICANDS.RATICANDS:*All);
Dcl-Ds CAND_Key LikeRec(ATICANDS.RATICANDS:*Key);

// This is included for demo output purposes.
Dcl-Pr WriteToJobLog Int(10) Extproc('Qp0zLprintf');
  pString Pointer Value Options(*String);
End-Pr;
Dcl-C NewLine x'15';

// This stores the unique ID for this API call
Dcl-S UniqueID Like(ATI_UniqueID_t);

// This holds any error information returned by the API call
Dcl-Ds ErrorDS LikeDS(ATI_ErrorDS_t);

// Modify this field to use your API key ID from the ATICFGKEY table
Dcl-S KeyID Like(ATI_ConfigId_t) Inz(ATI_DEFAULT);

// Each API call requires a unique ID
UniqueID = ATI_GetUniqueID();

// ATIADRREQ needs to be populated with the address data to be validated
clear REQ;
REQ.AddressID = UniqueID;
REQ.Street = '124 Walnut Street';
REQ.SecondaryInfo = 'Suite 310';
REQ.City = 'Mankato';
REQ.State = 'Minnesota';
REQ.ZipCode = '56002';
// We recommend setting this field to assist with later cleanup of the
//  transactional files
REQ.RequestTimestamp = %Timestamp();
write ATIADRREQ.RATIADRREQ REQ;

reset ErrorDS;

if not ATI_ValidateStreet( UniqueID : KeyID : ErrorDS );
  // If ATI_ValidateStreet() returns *Off then an error occured.

  // You should check ErrorDS subfields for info:
  //  ErrorDS.Subprocedure = Name of ATI subprocedure that threw error
  //  ErrorDS.MessageCode = Message code or ID of the error message
  //  ErrorDS.Message = Error message description
  //  ErrorDS.LogFile = Path to a log file created in the IFS that can
  //   be used for troubleshooting. Log files are generated automatically
  //   whenever an error occurs. You can also force log files to generate
  //   by modifying the value of the LOGALL field in ATICFGKEY for the
  //   provided Key ID.
  //  ErrorDS.Source =
  //    - ATI_ERROR_INTERNAL is a general product error.
  //      This could be due to issues with input data, or the
  //      inability to access physical files, etc.
  //
  //    - ATI_ERROR_EXTERNAL is an error message returned by the address
  //      validation service. This could be due to invalid request data,
  //      or invalid configuration information.
  WriteToJobLog( 'Error Message Code: ' + ErrorDS.MessageCode + NewLine );
  WriteToJobLog( 'Error Message: ' + ErrorDS.Message + NewLine );
  WriteToJobLog( 'Error Source: ' + ErrorDS.Source + NewLine );
  WriteToJobLog( 'Logfile: ' + ErrorDS.LogFile + NewLine );

  // All error information is also written to the file ATIERRLOG
else;
  // If ATI_ValidateStreet() returned *On the request was successful. You can
  //  access the results in the ATIADRRSP file using the same UniqueID that
  //  was used to create the request record in ATIADRREQ.

  chain UniqueID ATIADRRSP.RATIADRRSP RSP;
  if %Found(ATIADRRSP);
    // For this sample program, we're writing the response data to the job
    //  log, but generally you would extract the response data into your
    //  own data tables, or to otherwise use the validated address data.

    // The validation APIs return a summary of the credits used and
    //  remaining for this request
    WriteToJobLog( 'Credits used: ' + %Char(RSP.CREDITSUSED) + NewLine );
    WriteToJobLog( 'Credits remaining (block): '
                 + %Char(RSP.CURRENTBLOCKREMAINING) + NewLine );
    WriteToJobLog( 'Credits remaining (all): ' + %Char(RSP.ALLBLOCKSREMAINING)
                 + NewLine );

    // Checking if any candidate addresses were returned
    if RSP.CandidatesReturned <= 0;
      WriteToJobLog( 'No address candidates returned' );
    else;
      // There will be one or more candidate addresses in ATICANDS. For
      //  demonstration purposes, we'll display only the data returned
      //  in the first candidate.
      CAND_Key.AddressID = UniqueID;

      chain %Kds( CAND_Key : 1 ) ATICANDS.RATICANDS CAND;

      if %Found(ATICANDS);
        WriteToJobLog( 'Delivery line 1: ' + CAND.DeliveryLine1 + NewLine );
        WriteToJobLog( 'City: ' + CAND.CityName + NewLine );
        WriteToJobLog( 'State: ' + CAND.StateAbbreviation + NewLine );
        WriteToJobLog( 'ZIP Code: ' + CAND.ZIPCode + NewLine );
        WriteToJobLog( 'ZIP+4: ' + CAND.Plus4Code + NewLine );
        WriteToJobLog( 'DPV match code: ' + CAND.DPVMatchCode + NewLine );
        WriteToJobLog( 'DPV footnotes: ' + CAND.DPVFootnotes + NewLine );
      endif;
    endif;
  endif;
endif;

// Write unique ID to job log for easy reference
WriteToJobLog( 'T_VLDUS Unique ID: ' + %Char(UniqueId) + NewLine );

*INLR = *On;
return;