T_VLDZIP - Validate Zipcode

**FREE
// Example Program: T_VLDZIP
// Description:
//  This is a test program to illustrate how to call the ATI_ValidateStreet()
//  subproceure to validate the ZIP Code for 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 ZIP Code 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 = '1109 9th';
REQ.City = 'Phoenix';
REQ.State = 'AZ';
// 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_SOURCE_INTERNAL is a general product error.
  //      This could be due to issues with input data, or the
  //      inability to access physical files, etc.
  //
  //    - ATI_SOURCE_TRANSMIT is a product error that specifically occurred
  //      during HTTPS communication with the address validation webservice.
  //      This could be due to issues with your network configuration, proxy
  //      setup, internet connection, etc.
  //
  //    - ATI_SOURCE_REMOTE is an error message returned by the address
  //      validation service.
  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. If the submitted
  //  address was able to be validated, one or more candidate address records
  //  will be found in the file ATICANDS.

  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. We'll
      //  read through the file in a loop to write each candidate to the
      //  job log.
      CAND_Key.AddressID = UniqueID;

      setll %Kds( CAND_Key : 1 ) ATICANDS.RATICANDS;

      if %Equal(ATICANDS);
        reade %Kds( CAND_Key : 1 ) ATICANDS.RATICANDS CAND;

        dow not %Eof(ATICANDS);
          WriteToJobLog( 'Candidate index: ' + %Char(CAND.CandidateIndex)
                       + NewLine );
          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 );
          WriteToJobLog( '--------------------' + NewLine );

          reade %Kds( CAND_Key : 1 ) ATICANDS.RATICANDS CAND;
        enddo;
      endif;
    endif;
  endif;
endif;

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

*INLR = *On;
return;