protected void writeLaborGLEntry(
      LaborOriginEntry laborOriginEntry,
      LaborLedgerUnitOfWork laborLedgerUnitOfWork,
      Date runDate,
      int lineNumber,
      Map<String, Integer> glEntryReportSummary) {
    LaborOriginEntry summarizedEntry =
        summarizeLaborGLEntries(
            laborOriginEntry, laborLedgerUnitOfWork, runDate, lineNumber, glEntryReportSummary);
    if (summarizedEntry == null) {
      return;
    }

    try {
      List<Message> errors = this.isPostableForLaborGLEntry(summarizedEntry);
      if (errors == null || errors.isEmpty()) {
        String operationType = laborGLLedgerEntryPoster.post(summarizedEntry, 0, runDate, null);
        updateReportSummary(
            glEntryReportSummary, laborGLLedgerEntryPoster.getDestinationName(), operationType);
      } else {
        updateReportSummary(glEntryReportSummary, ORIGN_ENTRY, KFSConstants.OperationType.BYPASS);
      }
    } catch (RuntimeException ioe) {
      // catch here again, it should be from postSingleEntryIntoLaborLedger
      LOG.error(
          "postLaborGLEntries stopped due to: "
              + ioe.getMessage()
              + " on line number : "
              + lineNumber,
          ioe);
      throw new RuntimeException(
          "Unable to execute: " + ioe.getMessage() + " on line number : " + lineNumber, ioe);
    }
  }
 // construct a poster report summary object
 protected void fillPosterReportWriter(
     int lineNumber,
     Map<String, Integer> reportSummary,
     Map<String, Integer> glEntryReportSummary) {
   reportWriterService.writeStatisticLine(
       "SEQUENTIAL RECORDS READ                    %,9d", lineNumber);
   reportWriterService.writeStatisticLine(
       "LLEN RECORDS INSERTED (LD_LDGR_ENTR_T)     %,9d",
       reportSummary.get(
           laborLedgerEntryPoster.getDestinationName() + "," + KFSConstants.OperationType.INSERT));
   reportWriterService.writeStatisticLine(
       "LLBL RECORDS INSERTED (LD_LDGR_BAL_T)      %,9d",
       reportSummary.get(
           laborLedgerBalancePoster.getDestinationName()
               + ","
               + KFSConstants.OperationType.INSERT));
   reportWriterService.writeStatisticLine(
       "LLBL RECORDS UPDATED  (LD_LDGR_BAL_T)      %,9d",
       reportSummary.get(
           laborLedgerBalancePoster.getDestinationName()
               + ","
               + KFSConstants.OperationType.UPDATE));
   reportWriterService.writeStatisticLine(
       "LLGL RECORDS INSERTED (LD_LBR_GL_ENTRY_T)  %,9d",
       glEntryReportSummary.get(
           laborGLLedgerEntryPoster.getDestinationName()
               + ","
               + KFSConstants.OperationType.INSERT));
   reportWriterService.writeStatisticLine(
       "WARNING RECORDS WRITTEN                    %,9d", numberOfErrorOriginEntry);
 }
  /**
   * post the given entry into the labor ledger tables if the entry is qualified; otherwise report
   * error
   *
   * @param originEntry the given origin entry, a transaction
   * @param reportSummary the report summary object that need to be update when a transaction is
   *     posted
   * @param runDate the data when the process is running
   * @return true if the given transaction is posted into ledger tables; otherwise, return false
   */
  protected boolean postSingleEntryIntoLaborLedger(
      LaborOriginEntry originEntry, Map<String, Integer> reportSummary, Date runDate, String line) {
    // reject the invalid entry so that it can be available for error correction
    List<Message> errors = new ArrayList<Message>();
    try {
      errors = this.validateEntry(originEntry);
    } catch (Exception e) {
      errors.add(new Message(e.toString() + " occurred for this record.", Message.TYPE_FATAL));
    }

    if (errors != null && !errors.isEmpty()) {
      reportWriterService.writeError(originEntry, errors);
      numberOfErrorOriginEntry += errors.size();
      writeErrorEntry(line);
      return false;
    }

    String operationOnLedgerEntry = postAsLedgerEntry(originEntry, runDate);
    updateReportSummary(
        reportSummary, laborLedgerEntryPoster.getDestinationName(), operationOnLedgerEntry);

    String operationOnLedgerBalance = updateLedgerBalance(originEntry, runDate);
    updateReportSummary(
        reportSummary, laborLedgerBalancePoster.getDestinationName(), operationOnLedgerBalance);

    return true;
  }
 // fill the poster report writer with the collected data
 protected Map<String, Integer> constructPosterReportSummary() {
   Map<String, Integer> reportSummary = new HashMap<String, Integer>();
   reportSummary.put(
       laborLedgerEntryPoster.getDestinationName() + "," + KFSConstants.OperationType.INSERT, 0);
   reportSummary.put(
       laborLedgerBalancePoster.getDestinationName() + "," + KFSConstants.OperationType.INSERT, 0);
   reportSummary.put(
       laborLedgerBalancePoster.getDestinationName() + "," + KFSConstants.OperationType.UPDATE, 0);
   reportSummary.put(
       laborGLLedgerEntryPoster.getDestinationName() + "," + KFSConstants.OperationType.INSERT, 0);
   return reportSummary;
 }
  // construct a gl entry report summary object
  protected Map<String, Integer> constructGlEntryReportSummary() {
    Map<String, Integer> glEntryReportSummary = new HashMap<String, Integer>();
    glEntryReportSummary.put(ORIGN_ENTRY + "," + KFSConstants.OperationType.READ, 0);
    glEntryReportSummary.put(ORIGN_ENTRY + "," + KFSConstants.OperationType.BYPASS, 0);
    glEntryReportSummary.put(ORIGN_ENTRY + "," + KFSConstants.OperationType.SELECT, 0);
    glEntryReportSummary.put(ORIGN_ENTRY + "," + KFSConstants.OperationType.REPORT_ERROR, 0);
    glEntryReportSummary.put(
        laborGLLedgerEntryPoster.getDestinationName() + "," + KFSConstants.OperationType.INSERT, 0);

    return glEntryReportSummary;
  }
 // fill the gl entry report writer with the collected data
 protected void fillGlEntryReportWriter(Map<String, Integer> glEntryReportSummary) {
   laborGlEntryStatisticsReportWriterService.writeStatisticLine(
       "NUMBER OF RECORDS READ              %,9d",
       glEntryReportSummary.get(ORIGN_ENTRY + "," + KFSConstants.OperationType.READ));
   laborGlEntryStatisticsReportWriterService.writeStatisticLine(
       "NUMBER OF RECORDS BYPASSED          %,9d",
       glEntryReportSummary.get(ORIGN_ENTRY + "," + KFSConstants.OperationType.BYPASS));
   laborGlEntryStatisticsReportWriterService.writeStatisticLine(
       "NUMBER OF RECORDS SELECTED          %,9d",
       glEntryReportSummary.get(ORIGN_ENTRY + "," + KFSConstants.OperationType.SELECT));
   laborGlEntryStatisticsReportWriterService.writeStatisticLine(
       "NUMBER OF RECORDS IN ERROR          %,9d",
       glEntryReportSummary.get(ORIGN_ENTRY + "," + KFSConstants.OperationType.REPORT_ERROR));
   laborGlEntryStatisticsReportWriterService.writeStatisticLine(
       "NUMBER OF RECORDS INSERTED          %,9d",
       glEntryReportSummary.get(
           laborGLLedgerEntryPoster.getDestinationName()
               + ","
               + KFSConstants.OperationType.INSERT));
 }
 /**
  * update the labor ledger balance for the given entry
  *
  * @param originEntry the given origin entry, a transaction
  * @param postDate the data when the transaction is processes return the operation type of the
  *     process
  */
 protected String updateLedgerBalance(LaborOriginEntry originEntry, Date postDate) {
   return laborLedgerBalancePoster.post(originEntry, 0, postDate, null);
 }
 /**
  * post the given entry to the labor entry table
  *
  * @param originEntry the given origin entry, a transaction
  * @param postDate the data when the transaction is processes return the operation type of the
  *     process
  */
 protected String postAsLedgerEntry(LaborOriginEntry originEntry, Date postDate) {
   return laborLedgerEntryPoster.post(originEntry, 0, postDate, null);
 }