edu.ku.kuali.kra.timeandmoney.service.impl.TimeAndMoneyHistoryServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for edu.ku.kuali.kra.timeandmoney.service.impl.TimeAndMoneyHistoryServiceImpl.java

Source

/*
 * Copyright 2005-2013 The Kuali Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl1.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package edu.ku.kuali.kra.timeandmoney.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.kuali.coeus.sys.framework.service.KcServiceLocator;
import org.kuali.kra.award.home.Award;
import org.kuali.kra.award.home.AwardAmountInfo;
import org.kuali.kra.award.version.service.AwardVersionService;
import org.kuali.kra.timeandmoney.AwardAmountInfoHistory;
import org.kuali.kra.timeandmoney.TimeAndMoneyDocumentHistory;
import org.kuali.kra.timeandmoney.document.TimeAndMoneyDocument;
import org.kuali.kra.timeandmoney.history.TransactionDetail;
import org.kuali.kra.timeandmoney.history.TransactionDetailType;
import org.kuali.kra.timeandmoney.history.TransactionType;
import org.kuali.kra.timeandmoney.transactions.AwardAmountTransaction;
import org.kuali.rice.core.api.CoreApiServiceLocator;
import org.kuali.rice.kew.api.exception.WorkflowException;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.DocumentService;

import edu.ku.kuali.kra.timeandmoney.AwardVersionHistory;

public class TimeAndMoneyHistoryServiceImpl
        extends org.kuali.kra.timeandmoney.service.impl.TimeAndMoneyHistoryServiceImpl
        implements edu.ku.kuali.kra.timeandmoney.service.TimeAndMoneyHistoryService {

    private static final int NUMBER_30 = 30;
    BusinessObjectService businessObjectService;
    DocumentService documentService;
    AwardVersionService awardVersionService;

    @SuppressWarnings("unchecked")
    public void getTimeAndMoneyHistory(String awardNumber, Map<Object, Object> timeAndMoneyHistory,
            List<Integer> columnSpan) throws WorkflowException {
        Map<String, Object> fieldValues1 = new HashMap<String, Object>();
        Map<String, Object> fieldValues3 = new HashMap<String, Object>();
        Map<String, Object> fieldValues3a = new HashMap<String, Object>();
        Map<String, Object> fieldValues5 = new HashMap<String, Object>();

        Map<String, Object> fieldValues4 = new HashMap<String, Object>();

        AwardAmountTransaction awardAmountTransaction = null;
        timeAndMoneyHistory.clear();
        Award award = awardVersionService.getWorkingAwardVersion(awardNumber);
        List<TimeAndMoneyDocument> docs = null;
        int key = 150;
        int j = -1;

        award.refreshReferenceObject("awardDocument");
        // to get all docs, we must pass the root award number for the subject award.
        fieldValues1.put("rootAwardNumber", getRootAwardNumberForDocumentSearch(award.getAwardNumber()));
        docs = (List<TimeAndMoneyDocument>) businessObjectService.findMatching(TimeAndMoneyDocument.class,
                fieldValues1);
        Collections.sort(docs);
        timeAndMoneyHistory.put(buildForwardUrl(award.getAwardDocument().getDocumentNumber()),
                award.getAwardDescriptionLine());
        for (TimeAndMoneyDocument tempDoc : docs) {
            TimeAndMoneyDocument doc = (TimeAndMoneyDocument) documentService
                    .getByDocumentHeaderId(tempDoc.getDocumentNumber());
            List<AwardAmountTransaction> awardAmountTransactions = doc.getAwardAmountTransactions();
            // we don't want canceled docs in history.
            if (doc.getDocumentHeader().hasWorkflowDocument()) {
                if (!doc.getDocumentHeader().getWorkflowDocument().isCanceled()) {
                    // capture initial transaction
                    // we only want display this once.
                    for (AwardAmountInfo awardAmountInfo : award.getAwardAmountInfos()) {
                        if (!(awardAmountInfo.getTimeAndMoneyDocumentNumber() == null)) {
                            if (awardAmountInfo.getTimeAndMoneyDocumentNumber().equals(doc.getDocumentNumber())) {
                                if (StringUtils.equalsIgnoreCase(doc.getDocumentNumber(),
                                        awardAmountInfo.getTimeAndMoneyDocumentNumber())) {
                                    if (awardAmountTransactions.size() > 0) {
                                        awardAmountTransaction = awardAmountTransactions.get(0);
                                        timeAndMoneyHistory.put(buildForwardUrl(doc.getDocumentNumber()),
                                                award.getAwardDescriptionLine());
                                    }
                                    fieldValues5.put("destinationAwardNumber", awardAmountInfo.getAwardNumber());
                                    fieldValues5.put("transactionId", 0);
                                    fieldValues5.put("timeAndMoneyDocumentNumber",
                                            awardAmountInfo.getTimeAndMoneyDocumentNumber());
                                    fieldValues5.put("transactionDetailType",
                                            TransactionDetailType.PRIMARY.toString());
                                    List<TransactionDetail> transactionDetailsA = ((List<TransactionDetail>) businessObjectService
                                            .findMatchingOrderBy(TransactionDetail.class, fieldValues5,
                                                    "sourceAwardNumber", true));
                                    if (transactionDetailsA.size() > 0) {
                                        TransactionDetail transactionDetail = transactionDetailsA.get(0);
                                        timeAndMoneyHistory.put(0, awardAmountInfo);
                                        timeAndMoneyHistory.put(key, transactionDetail);
                                        key++;
                                        break;
                                    } else {
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    // capture money transactions
                    for (AwardAmountInfo awardAmountInfo : award.getAwardAmountInfos()) {
                        if (!(awardAmountInfo.getTimeAndMoneyDocumentNumber() == null)) {
                            if (awardAmountInfo.getTimeAndMoneyDocumentNumber().equals(doc.getDocumentNumber())) {
                                if (StringUtils.equalsIgnoreCase(doc.getDocumentNumber(),
                                        awardAmountInfo.getTimeAndMoneyDocumentNumber())) {
                                    if (awardAmountTransactions.size() > 0) {
                                        awardAmountTransaction = awardAmountTransactions.get(0);
                                        timeAndMoneyHistory.put(buildForwardUrl(doc.getDocumentNumber()),
                                                award.getAwardDescriptionLine());
                                    }
                                    List<TransactionDetail> transactionDetails = new ArrayList<TransactionDetail>();
                                    // get all Transaction Details for a node. It can be the source or a destination of the transaction.
                                    fieldValues3.put("sourceAwardNumber", awardAmountInfo.getAwardNumber());
                                    fieldValues3.put("transactionId", awardAmountInfo.getTransactionId());
                                    fieldValues3.put("timeAndMoneyDocumentNumber",
                                            awardAmountInfo.getTimeAndMoneyDocumentNumber());
                                    fieldValues5.put("transactionDetailType",
                                            TransactionDetailType.PRIMARY.toString());

                                    fieldValues3a.put("destinationAwardNumber", awardAmountInfo.getAwardNumber());
                                    fieldValues3a.put("transactionId", awardAmountInfo.getTransactionId());
                                    fieldValues3a.put("timeAndMoneyDocumentNumber",
                                            awardAmountInfo.getTimeAndMoneyDocumentNumber());
                                    fieldValues5.put("transactionDetailType",
                                            TransactionDetailType.PRIMARY.toString());

                                    // should only return one transaction detail because we are making transaction ID unique when we set
                                    // to Pending Transaction ID in ActivePendingTransactionService.
                                    List<TransactionDetail> transactionDetailsA = ((List<TransactionDetail>) businessObjectService
                                            .findMatchingOrderBy(TransactionDetail.class, fieldValues3,
                                                    "sourceAwardNumber", true));
                                    List<TransactionDetail> transactionDetailsB = ((List<TransactionDetail>) businessObjectService
                                            .findMatchingOrderBy(TransactionDetail.class, fieldValues3a,
                                                    "sourceAwardNumber", true));
                                    transactionDetails.addAll(transactionDetailsA);
                                    transactionDetails.addAll(transactionDetailsB);
                                    int i = 0;
                                    for (TransactionDetail transactionDetail : transactionDetails) {
                                        timeAndMoneyHistory.put(awardAmountInfo.getTransactionId(),
                                                awardAmountInfo);
                                        timeAndMoneyHistory.put(key, transactionDetail);
                                        key++;
                                        i++;
                                    }
                                    columnSpan.add(i);
                                }
                            }
                        }
                    }
                }
            }
            // capture date transactions
            for (AwardAmountInfo awardAmountInfo : award.getAwardAmountInfos()) {
                if (!(awardAmountInfo.getTimeAndMoneyDocumentNumber() == null)) {
                    if (awardAmountInfo.getTimeAndMoneyDocumentNumber().equals(doc.getDocumentNumber())) {
                        if (StringUtils.equalsIgnoreCase(doc.getDocumentNumber(),
                                awardAmountInfo.getTimeAndMoneyDocumentNumber())) {
                            if (awardAmountInfo.getTransactionId() == null) {
                                if (awardAmountTransactions.size() > 0) {
                                    awardAmountTransaction = awardAmountTransactions.get(0);
                                    timeAndMoneyHistory.put(buildForwardUrl(doc.getDocumentNumber()),
                                            award.getAwardDescriptionLine());
                                }
                                fieldValues4.put("sourceAwardNumber", awardAmountInfo.getAwardNumber());
                                fieldValues4.put("transactionId", "-1");
                                fieldValues4.put("timeAndMoneyDocumentNumber",
                                        awardAmountInfo.getTimeAndMoneyDocumentNumber());
                                fieldValues5.put("transactionDetailType", TransactionDetailType.PRIMARY.toString());

                                // Can return multiple transaction details because we are defaulting the transaction ID to -1
                                // in Date change transactions.
                                List<TransactionDetail> dateTransactionDetails = ((List<TransactionDetail>) businessObjectService
                                        .findMatchingOrderBy(TransactionDetail.class, fieldValues4,
                                                "sourceAwardNumber", true));
                                int i = 0;
                                for (TransactionDetail transactionDetail : dateTransactionDetails) {
                                    timeAndMoneyHistory.put(j, awardAmountInfo);// this is just for display only.
                                    timeAndMoneyHistory.put(key, transactionDetail);
                                    key++;
                                    i++;
                                    j--;// Map enforces unique key when adding to timeAndMoneyHistory. Must be negative so it does not conflict with
                                    // transaction ID of money transactions.
                                }
                                columnSpan.add(i);
                                break;
                            }
                        }
                    }
                }
            }

        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void buildTimeAndMoneyHistoryObjects(String awardNumber,
            List<AwardVersionHistory> awardVersionHistoryCollection, boolean doNothing) throws WorkflowException {
        List<Award> awardVersionList = (List<Award>) businessObjectService.findMatchingOrderBy(Award.class,
                getHashMapToFindActiveAward(awardNumber), "sequenceNumber", true);
        // we want the list in reverse chronological order.
        Collections.reverse(awardVersionList);
        List<TimeAndMoneyDocument> docs = null;
        Map<String, Object> fieldValues1 = new HashMap<String, Object>();
        // get the root award number.
        fieldValues1.put("rootAwardNumber",
                getRootAwardNumberForDocumentSearch(awardVersionList.get(0).getAwardNumber()));
        docs = (List<TimeAndMoneyDocument>) businessObjectService.findMatchingOrderBy(TimeAndMoneyDocument.class,
                fieldValues1, "documentNumber", true);
        // we don't want canceled docs to show in history.
        removeCanceledDocs(docs);
        for (Award award : awardVersionList) {
            AwardVersionHistory awardVersionHistory = new AwardVersionHistory(award);
            // BUKC-0023: Add History tab - Set Award number to display on the History tab
            awardVersionHistory.setAwardNumber(awardNumber);
            awardVersionHistory.setDocumentUrl(buildForwardUrl(award.getAwardDocument().getDocumentNumber()));
            awardVersionHistory.setAwardDescriptionLine(award.getAwardDescriptionLine());
            awardVersionHistory.setTimeAndMoneyDocumentHistoryList(
                    getDocHistoryAndValidInfosAssociatedWithAwardVersion(docs, award.getAwardAmountInfos(), award));

            awardVersionHistoryCollection.add(awardVersionHistory);
        }
    }

    public void buildTimeAndMoneyHistoryObjects(String awardNumber,
            List<org.kuali.kra.timeandmoney.AwardVersionHistory> awardVersionHistoryCollection)
            throws WorkflowException {
        List<Award> awardVersionList = (List<Award>) businessObjectService.findMatchingOrderBy(Award.class,
                getHashMapToFindActiveAward(awardNumber), "sequenceNumber", true);
        // we want the list in reverse chronological order.
        Collections.reverse(awardVersionList);
        List<TimeAndMoneyDocument> docs = null;
        Map<String, Object> fieldValues1 = new HashMap<String, Object>();
        // get the root award number.
        fieldValues1.put("rootAwardNumber",
                getRootAwardNumberForDocumentSearch(awardVersionList.get(0).getAwardNumber()));
        docs = (List<TimeAndMoneyDocument>) businessObjectService.findMatchingOrderBy(TimeAndMoneyDocument.class,
                fieldValues1, "documentNumber", true);
        // we don't want canceled docs to show in history.
        removeCanceledDocs(docs);
        for (Award award : awardVersionList) {
            org.kuali.kra.timeandmoney.AwardVersionHistory awardVersionHistory = new org.kuali.kra.timeandmoney.AwardVersionHistory(
                    award);
            awardVersionHistory.setDocumentUrl(buildForwardUrl(award.getAwardDocument().getDocumentNumber()));
            awardVersionHistory.setAwardDescriptionLine(award.getAwardDescriptionLine());
            awardVersionHistory.setTimeAndMoneyDocumentHistoryList(
                    getDocHistoryAndValidInfosAssociatedWithAwardVersion(docs, award.getAwardAmountInfos(), award));

            awardVersionHistoryCollection.add(awardVersionHistory);
        }
    }

    @Override
    protected List<AwardAmountInfoHistory> retrieveAwardAmountInfosFromPrimaryTransactions(TimeAndMoneyDocument doc,
            List<AwardAmountInfo> validInfos) {
        List<AwardAmountInfoHistory> primaryInfos = new ArrayList<AwardAmountInfoHistory>();
        primaryInfos.addAll(captureMoneyInfos(doc, validInfos));
        primaryInfos.addAll(captureDateInfos(doc, validInfos));
        primaryInfos.addAll(captureInitialTransactionInfo(doc, validInfos));
        return primaryInfos;
    }

    @SuppressWarnings("unchecked")
    protected List<AwardAmountInfoHistory> captureMoneyInfos(TimeAndMoneyDocument doc,
            List<AwardAmountInfo> validInfos) {
        List<AwardAmountInfoHistory> moneyInfoHistoryList = new ArrayList<AwardAmountInfoHistory>();
        Map<String, Object> fieldValues1 = new HashMap<String, Object>();
        Map<String, Object> fieldValues1a = new HashMap<String, Object>();
        Map<String, Object> fieldValues2 = new HashMap<String, Object>();
        Map<String, Object> fieldValues3 = new HashMap<String, Object>();

        for (AwardAmountInfo awardAmountInfo : validInfos) {
            if (!(awardAmountInfo.getTimeAndMoneyDocumentNumber() == null)) {
                if (StringUtils.equalsIgnoreCase(doc.getDocumentNumber(),
                        awardAmountInfo.getTimeAndMoneyDocumentNumber())) {
                    // get all Transaction Details for a node. It can be the source or a destination of the transaction.
                    fieldValues1.put("sourceAwardNumber", awardAmountInfo.getAwardNumber());
                    fieldValues1.put("transactionId", awardAmountInfo.getTransactionId());
                    fieldValues1.put("transactionDetailType", TransactionDetailType.PRIMARY.toString());
                    fieldValues1a.put("destinationAwardNumber", awardAmountInfo.getAwardNumber());
                    fieldValues1a.put("transactionId", awardAmountInfo.getTransactionId());
                    fieldValues1a.put("transactionDetailType", TransactionDetailType.PRIMARY.toString());
                    fieldValues2.put("transactionId", awardAmountInfo.getTransactionId());
                    fieldValues2.put("transactionDetailType", TransactionDetailType.INTERMEDIATE.toString());
                    List<TransactionDetail> transactionDetails = ((List<TransactionDetail>) businessObjectService
                            .findMatchingOrderBy(TransactionDetail.class, fieldValues1, "transactionDetailId",
                                    true));
                    List<TransactionDetail> transactionDetailsA = ((List<TransactionDetail>) businessObjectService
                            .findMatchingOrderBy(TransactionDetail.class, fieldValues1a, "transactionDetailId",
                                    true));

                    // BUKC-0067: Show T&M transaction details associated with the parent award when rollup occurs on award history and T&M history
                    // This is a core code bug where the transactions not shown when the destination on the history panel/pane
                    fieldValues3.put("destinationAwardNumber", awardAmountInfo.getAward().getParentNumber());
                    fieldValues3.put("transactionId", awardAmountInfo.getTransactionId());
                    List<TransactionDetail> transactionDetailsOnParent = ((List<TransactionDetail>) businessObjectService
                            .findMatchingOrderBy(TransactionDetail.class, fieldValues3, "transactionDetailId",
                                    true));
                    transactionDetails.addAll(transactionDetailsOnParent);

                    // we do a join on this list, but there can only be one possible since we are searching by Award Amount Info and there can only be
                    // one transaction associated.
                    transactionDetails.addAll(transactionDetailsA);
                    List<TransactionDetail> transactionDetailsB = ((List<TransactionDetail>) businessObjectService
                            .findMatchingOrderBy(TransactionDetail.class, fieldValues2, "transactionDetailId",
                                    true));
                    if (transactionDetails.size() > 0) {
                        AwardAmountInfoHistory awardAmountInfoHistory = new AwardAmountInfoHistory();
                        awardAmountInfoHistory.setAwardAmountInfo(awardAmountInfo);
                        awardAmountInfoHistory.setTransactionType(TransactionType.MONEY.toString());
                        awardAmountInfoHistory.setPrimaryDetail(transactionDetails.get(0));
                        awardAmountInfoHistory.setIntermediateDetails(transactionDetailsB);
                        moneyInfoHistoryList.add(awardAmountInfoHistory);
                    }
                }
            }
        }
        return moneyInfoHistoryList;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected List<AwardAmountInfoHistory> captureDateInfos(TimeAndMoneyDocument doc,
            List<AwardAmountInfo> validInfos) {
        List<AwardAmountInfoHistory> dateInfoHistoryList = new ArrayList<AwardAmountInfoHistory>();
        Map<String, Object> fieldValues = new HashMap<String, Object>();
        for (AwardAmountInfo awardAmountInfo : validInfos) {
            if (!(awardAmountInfo.getTimeAndMoneyDocumentNumber() == null)) {
                if (StringUtils.equalsIgnoreCase(doc.getDocumentNumber(),
                        awardAmountInfo.getTimeAndMoneyDocumentNumber())) {
                    if (awardAmountInfo.getTransactionId() == null) {
                        fieldValues.put("sourceAwardNumber", awardAmountInfo.getAwardNumber());
                        fieldValues.put("transactionId", "-1");
                        fieldValues.put("timeAndMoneyDocumentNumber",
                                awardAmountInfo.getTimeAndMoneyDocumentNumber());
                        List<TransactionDetail> dateTransactionDetails = ((List<TransactionDetail>) businessObjectService
                                .findMatchingOrderBy(TransactionDetail.class, fieldValues, "sourceAwardNumber",
                                        true));
                        if (dateTransactionDetails.size() > 0) {
                            AwardAmountInfoHistory awardAmountInfoHistory = new AwardAmountInfoHistory();
                            awardAmountInfoHistory.setAwardAmountInfo(awardAmountInfo);
                            awardAmountInfoHistory.setTransactionType(TransactionType.DATE.toString());
                            dateInfoHistoryList.add(awardAmountInfoHistory);
                        }
                    }
                }
            }
        }
        return dateInfoHistoryList;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected List<AwardAmountInfoHistory> captureInitialTransactionInfo(TimeAndMoneyDocument doc,
            List<AwardAmountInfo> validInfos) {
        List<AwardAmountInfoHistory> initialInfoHistoryList = new ArrayList<AwardAmountInfoHistory>();
        Map<String, Object> fieldValues = new HashMap<String, Object>();
        for (AwardAmountInfo awardAmountInfo : validInfos) {
            if (!(awardAmountInfo.getTimeAndMoneyDocumentNumber() == null)) {
                if (StringUtils.equalsIgnoreCase(doc.getDocumentNumber(),
                        awardAmountInfo.getTimeAndMoneyDocumentNumber())) {
                    fieldValues.put("destinationAwardNumber", awardAmountInfo.getAwardNumber());
                    fieldValues.put("transactionId", 0);
                    fieldValues.put("timeAndMoneyDocumentNumber", awardAmountInfo.getTimeAndMoneyDocumentNumber());
                    fieldValues.put("transactionDetailType", TransactionDetailType.PRIMARY.toString());
                    List<TransactionDetail> transactionDetailsA = ((List<TransactionDetail>) businessObjectService
                            .findMatchingOrderBy(TransactionDetail.class, fieldValues, "sourceAwardNumber", true));
                    if (transactionDetailsA.size() > 0) {
                        AwardAmountInfoHistory awardAmountInfoHistory = new AwardAmountInfoHistory();
                        awardAmountInfoHistory.setAwardAmountInfo(awardAmountInfo);
                        awardAmountInfoHistory.setTransactionType(TransactionType.INITIAL.toString());
                        initialInfoHistoryList.add(awardAmountInfoHistory);
                        break;
                    } else {
                        break;
                    }
                }
            }
        }
        return initialInfoHistoryList;
    }

    @SuppressWarnings("unchecked")
    public List<TimeAndMoneyDocument> buildTimeAndMoneyListForAwardDisplay(Award award) throws WorkflowException {
        Map<String, Object> fieldValues1 = new HashMap<String, Object>();
        // get the award number.
        fieldValues1.put("rootAwardNumber", award.getAwardNumber());
        List<TimeAndMoneyDocument> docs = (List<TimeAndMoneyDocument>) businessObjectService
                .findMatchingOrderBy(TimeAndMoneyDocument.class, fieldValues1, "documentNumber", true);
        // we don't want canceled docs to show in history.
        removeCanceledDocs(docs);
        return docs;
    }

    @Override
    protected String getUpdateTimeAndUser(TimeAndMoneyDocument doc) {
        String createDateStr = null;
        String updateUser = null;
        if (doc.getUpdateTimestamp() != null) {
            createDateStr = CoreApiServiceLocator.getDateTimeService().toString(doc.getUpdateTimestamp(),
                    "MM/dd/yy");
            updateUser = doc.getUpdateUser().length() > NUMBER_30 ? doc.getUpdateUser().substring(0, NUMBER_30)
                    : doc.getUpdateUser();
        }
        return createDateStr + " by " + updateUser;
    }

    @Override
    public List<TimeAndMoneyDocumentHistory> getDocHistoryAndValidInfosAssociatedWithAwardVersion(
            List<TimeAndMoneyDocument> docs, List<AwardAmountInfo> awardAmountInfos, Award award)
            throws WorkflowException {
        List<TimeAndMoneyDocumentHistory> timeAndMoneyDocumentHistoryList = new ArrayList<TimeAndMoneyDocumentHistory>();
        List<AwardAmountInfo> validInfos = getValidAwardAmountInfosAssociatedWithAwardVersion(awardAmountInfos,
                award);
        List<TimeAndMoneyDocument> awardVersionDocs = getValidDocumentsCreatedForAwardVersion(docs, validInfos);
        // we want the list in reverse chronological order.
        Collections.reverse(awardVersionDocs);
        for (TimeAndMoneyDocument doc : awardVersionDocs) {
            TimeAndMoneyDocumentHistory docHistory = new TimeAndMoneyDocumentHistory();
            docHistory.setTimeAndMoneyDocument(doc);
            docHistory.setDocumentUrl(buildForwardUrl(doc.getDocumentNumber()));
            docHistory.setTimeAndMoneyDocumentDescriptionLine(
                    buildNewTimeAndMoneyDescriptionLine(doc, awardAmountInfos));
            docHistory.setValidAwardAmountInfoHistoryList(
                    retrieveAwardAmountInfosFromPrimaryTransactions(doc, validInfos));
            timeAndMoneyDocumentHistoryList.add(docHistory);
        }

        return timeAndMoneyDocumentHistoryList;
    }

    protected String buildNewTimeAndMoneyDescriptionLine(TimeAndMoneyDocument doc,
            List<AwardAmountInfo> awardAmountInfos) {
        AwardAmountTransaction aat = doc.getAwardAmountTransactions().get(0);
        String noticeDate;
        String transactionTypeDescription;

        // BUKC-0066: BU's AAI data cleanup
        // add Award Number and Version Number to T&M Description on History to link the award to the T&M due to the AAI cleanup process
        String originatingAwardNumber = null;
        String originatingAwardVersion = "None";
        for (AwardAmountInfo awardAmountInfo : awardAmountInfos) {
            if (doc.getDocumentNumber().equals(awardAmountInfo.getTimeAndMoneyDocumentNumber())) {
                originatingAwardNumber = awardAmountInfo.getAwardNumber();
                originatingAwardVersion = awardAmountInfo.getOriginatingAwardVersion().toString();
                break;
            }
        }

        if (!(aat.getNoticeDate() == null)) {
            noticeDate = aat.getNoticeDate().toString();
        } else {
            noticeDate = "None";
        }
        if (!(aat.getAwardTransactionType() == null)) {
            transactionTypeDescription = aat.getAwardTransactionType().getDescription();
        } else {
            transactionTypeDescription = "None";
        }

        if (!(aat.getNoticeDate() == null)) {
            noticeDate = aat.getNoticeDate().toString();
        } else {
            noticeDate = "None";
        }
        return "Time And Money Document: " + transactionTypeDescription + ", Award Number : "
                + originatingAwardNumber + " - Award Version : " + originatingAwardVersion + ", notice date: "
                + noticeDate + ", updated " + getUpdateTimeAndUser(doc) + ". Comments: "
                + (aat.getComments() == null ? "None" : aat.getComments());
    }

    @Override
    protected List<AwardAmountInfo> getValidAwardAmountInfosAssociatedWithAwardVersion(
            List<AwardAmountInfo> awardAmountInfos, Award award) {
        List<AwardAmountInfo> validInfos = new ArrayList<AwardAmountInfo>();
        for (AwardAmountInfo awardAmountInfo : awardAmountInfos) {
            if (!(awardAmountInfo.getOriginatingAwardVersion() == null)) {
                // BUKC-0066: BU's AAI data cleanup
                // Don't match award version to the originating award version. This change is due to BU's AAI cleanup. all new
                // created records as in 5.2, the two fields should match and the check is not needed
                // the clean up was to remove all originating award version and nullify T&M document number on all but the last finalized version.
                // if(awardAmountInfo.getOriginatingAwardVersion().equals(award.getSequenceNumber())) {
                validInfos.add(awardAmountInfo);
                // }
            }
        }
        return validInfos;
    }

    @Override
    protected List<TimeAndMoneyDocument> getValidDocumentsCreatedForAwardVersion(List<TimeAndMoneyDocument> docs,
            List<AwardAmountInfo> validInfos) {
        List<TimeAndMoneyDocument> validDocs = new ArrayList<TimeAndMoneyDocument>();
        for (TimeAndMoneyDocument doc : docs) {
            if (isInValidInfosCollection(doc, validInfos)) {
                validDocs.add(doc);
            }
        }
        return validDocs;
    }

    @Override
    protected Boolean isInValidInfosCollection(TimeAndMoneyDocument doc, List<AwardAmountInfo> validInfos) {
        Boolean valid = false;
        for (AwardAmountInfo awardAmountInfo : validInfos) {
            if (!(awardAmountInfo.getTimeAndMoneyDocumentNumber() == null)) {
                if (awardAmountInfo.getTimeAndMoneyDocumentNumber().equals(doc.getDocumentNumber())) {
                    valid = true;
                    break;
                }
            }
        }
        return valid;
    }

    @Override
    protected void removeCanceledDocs(List<TimeAndMoneyDocument> docs) {
        List<TimeAndMoneyDocument> tempCanceledDocs = new ArrayList<TimeAndMoneyDocument>();
        for (TimeAndMoneyDocument doc : docs) {
            if (doc.getDocumentHeader().hasWorkflowDocument()) {
                if (doc.getDocumentHeader().getWorkflowDocument().isCanceled()) {
                    tempCanceledDocs.add(doc);
                }
            }
        }
        docs.removeAll(tempCanceledDocs);
    }

    @Override
    public AwardVersionService getAwardVersionService() {
        if (awardVersionService == null) {
            awardVersionService = KcServiceLocator.getService(AwardVersionService.class);
        }
        return awardVersionService;
    }

    @Override
    public void setAwardVersionService(AwardVersionService awardVersionService) {
        this.awardVersionService = awardVersionService;
    }

    /**
     * Gets the documentService attribute.
     *
     * @return Returns the documentService.
     */
    @Override
    public DocumentService getDocumentService() {
        return documentService;
    }

    /**
     * Sets the documentService attribute value.
     *
     * @param documentService
     *            The documentService to set.
     */
    @Override
    public void setDocumentService(DocumentService documentService) {
        this.documentService = documentService;
    }

    /**
     * Gets the businessObjectService attribute.
     *
     * @return Returns the businessObjectService.
     */
    @Override
    public BusinessObjectService getBusinessObjectService() {
        return businessObjectService;
    }

    /**
     * Sets the businessObjectService attribute value.
     *
     * @param businessObjectService
     *            The businessObjectService to set.
     */
    @Override
    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
        this.businessObjectService = businessObjectService;
    }

}