@Override
 @Transactional
 public void writeItems(List<Object> items) throws Exception {
   try (PrintWriter archive =
       new PrintWriter(
           new BufferedWriter(
               new FileWriter(
                   new File(
                       jobContext.getProperties().getProperty(ARCHIVE_DIRECTORY)
                           + "/archive_"
                           + jobContext.getJobName()
                           + "_"
                           + jobContext.getInstanceId()
                           + ".csv"),
                   true)))) {
     for (Object item : items) {
       HandlingEventRegistrationAttempt attempt = (HandlingEventRegistrationAttempt) item;
       applicationEvents.receivedHandlingEventRegistrationAttempt(attempt);
       archive.println(
           attempt.getRegistrationTime()
               + ","
               + attempt.getCompletionTime()
               + ","
               + attempt.getTrackingId()
               + ","
               + attempt.getVoyageNumber()
               + ","
               + attempt.getUnLocode()
               + ","
               + attempt.getType());
     }
   }
 }
  @POST
  @Path("/reports")
  @Consumes(MediaType.APPLICATION_JSON)
  // TODO Better exception handling.
  public void submitReport(@NotNull @Valid HandlingReport handlingReport) {
    try {
      Date completionTime =
          new SimpleDateFormat(ISO_8601_FORMAT).parse(handlingReport.getCompletionTime());
      VoyageNumber voyageNumber = null;

      if (handlingReport.getVoyageNumber() != null) {
        voyageNumber = new VoyageNumber(handlingReport.getVoyageNumber());
      }

      HandlingEvent.Type type = HandlingEvent.Type.valueOf(handlingReport.getEventType());
      UnLocode unLocode = new UnLocode(handlingReport.getUnLocode());

      TrackingId trackingId = new TrackingId(handlingReport.getTrackingId());

      Date registrationTime = new Date();
      HandlingEventRegistrationAttempt attempt =
          new HandlingEventRegistrationAttempt(
              registrationTime, completionTime, trackingId, voyageNumber, type, unLocode);

      applicationEvents.receivedHandlingEventRegistrationAttempt(attempt);
    } catch (ParseException ex) {
      throw new RuntimeException("Error parsing completion time", ex);
    }
  }