/**
  * Part of a complete breakfast, it has everything you need to populate Key Personnel into a
  * <code>{@link ProposalDevelopmentDocument}</code>
  *
  * @param document
  */
 public void populateDocument(ProposalDevelopmentDocument document) {
   if (hasBeenRoutedOrCanceled(document)) {
     Collection<InvestigatorCreditType> availableCreditTypes = getAllInvestigatorCreditTypes();
     Set<InvestigatorCreditType> usedCreditTypes = new HashSet<InvestigatorCreditType>();
     for (ProposalPerson person : document.getDevelopmentProposal().getInvestigators()) {
       for (ProposalPersonCreditSplit creditSplit : person.getCreditSplits()) {
         for (InvestigatorCreditType currentCreditType : availableCreditTypes) {
           if (currentCreditType.getCode().equals(creditSplit.getInvCreditTypeCode())) {
             usedCreditTypes.add(currentCreditType);
           }
         }
       }
     }
     document.getDevelopmentProposal().setInvestigatorCreditTypes(usedCreditTypes);
   } else {
     document.getDevelopmentProposal().setInvestigatorCreditTypes(getInvestigatorCreditTypes());
   }
   if (document.getDevelopmentProposal().getInvestigators().isEmpty()
       && !document.getDevelopmentProposal().getProposalPersons().isEmpty()) {
     LOG.info("Need to repopulate investigator list");
     populateInvestigators(document);
     if (!(document.getDocumentHeader().getWorkflowDocument().getStatus().getCode().equals("R"))) {
       populateActiveCredittypesPerson(document);
     }
   }
   /* check for new certification questions */
   for (ProposalPerson person : document.getDevelopmentProposal().getProposalPersons()) {
     getYnqService().getPersonYNQ(person, document);
   }
 }
  /**
   * Initializes credit splits for new investigators
   *
   * @param person
   */
  protected void populateCreditTypes(ProposalPerson person) {
    if (!person.getCreditSplits().isEmpty()) {
      return;
    }

    for (InvestigatorCreditType creditType :
        (Collection<InvestigatorCreditType>) getInvestigatorCreditTypes()) {
      ProposalPersonCreditSplit creditSplit = new ProposalPersonCreditSplit();
      creditSplit.setProposalPerson(person);
      creditSplit.setInvCreditTypeCode(creditType.getCode());
      creditSplit.setCredit(new ScaleTwoDecimal(0));
      person.getCreditSplits().add(creditSplit);
    }
  }
  public boolean checkInstitutionalProposalPersonUnitCreditSplitTotals(
      InstitutionalProposalPersonUnitCreditSplitRuleEvent event) {
    int errorCount = 0;
    for (InvestigatorCreditType creditType : loadInvestigatorCreditTypes()) {
      if (creditType.addsToHundred()) {
        ScaleTwoDecimal value = event.getTotalsByCreditSplitType().get(creditType.getCode());
        if (value == null) {
          break; // value may not have been initialized yet, so we don't want to block save
        }
        if (!MAX_TOTAL_VALUE.subtract(value).isZero()) {
          InstitutionalProposalCreditSplitAuditError.addAuditError(
              PROPOSAL_PERSON_UNIT_CREDIT_SPLIT_ERROR_MSG_KEY, creditType.getDescription());
          errorCount++;
        }
      }
    }

    return errorCount == 0;
  }
  /**
   * Uses a <code>{@link Unit}</code> obtained from the <code>{@link Unit}</code> lookup to create a
   * <code>{@link ProposalPersonUnit}</code> instance.
   *
   * @param unitId
   * @return ProposalPersonUnit
   */
  public ProposalPersonUnit createProposalPersonUnit(String unitId, ProposalPerson person) {
    ProposalPersonUnit retval = new ProposalPersonUnit();
    Map valueMap = new HashMap();
    valueMap.put("unitNumber", unitId);
    Collection<Unit> units = getBusinessObjectService().findMatching(Unit.class, valueMap);

    for (Unit found : units) {
      retval.setUnitNumber(found.getUnitNumber());
      retval.setUnit(found);
    }

    for (InvestigatorCreditType creditType : getInvestigatorCreditTypes()) {
      ProposalUnitCreditSplit creditSplit = new ProposalUnitCreditSplit();
      creditSplit.setProposalPersonUnit(retval);
      creditSplit.setInvCreditTypeCode(creditType.getCode());
      creditSplit.setCredit(new ScaleTwoDecimal(0));
      retval.getCreditSplits().add(creditSplit);
    }

    return retval;
  }
 /**
  * It populates the Active credit type in the proposalpersoncreditsplit and unitcreditsplit
  *
  * @param document
  * @return true or false
  */
 public void populateActiveCredittypesPerson(ProposalDevelopmentDocument document) {
   Collection<InvestigatorCreditType> invcrdttype = getInvestigatorCreditTypes();
   for (ProposalPerson person : document.getDevelopmentProposal().getInvestigators()) {
     for (InvestigatorCreditType invcredtype : invcrdttype) {
       boolean creditTypeFound = false;
       for (ProposalPersonCreditSplit proposalpersoncrdt : person.getCreditSplits()) {
         if ((invcredtype.getCode().equals(proposalpersoncrdt.getInvCreditTypeCode()))) {
           creditTypeFound = true;
           break;
         }
       }
       if (!creditTypeFound) {
         ProposalPersonCreditSplit creditSplit = new ProposalPersonCreditSplit();
         creditSplit.setProposalPerson(person);
         creditSplit.setInvCreditTypeCode(invcredtype.getCode());
         creditSplit.setCredit(new ScaleTwoDecimal(0));
         person.getCreditSplits().add(creditSplit);
       }
     }
     for (ProposalPersonUnit unitsplit : person.getUnits()) {
       for (InvestigatorCreditType invcrdtype : invcrdttype) {
         boolean creditTypeFound = false;
         for (ProposalUnitCreditSplit unitcreditsplit : unitsplit.getCreditSplits()) {
           if ((invcrdtype.getCode().equals(unitcreditsplit.getInvCreditTypeCode()))) {
             creditTypeFound = true;
             break;
           }
         }
         if (!creditTypeFound) {
           ProposalUnitCreditSplit creditSplit = new ProposalUnitCreditSplit();
           creditSplit.setProposalPersonUnit(unitsplit);
           creditSplit.setInvCreditTypeCode(invcrdtype.getCode());
           creditSplit.setCredit(new ScaleTwoDecimal(0));
           unitsplit.getCreditSplits().add(creditSplit);
         }
       }
     }
   }
 }
  /**
   * Everytime something changes that will effect credit split values, this gets called to generate
   * a graph of the new data.
   *
   * @param document
   * @return Map
   */
  public Map calculateCreditSplitTotals(ProposalDevelopmentDocument document) {
    Map<String, Map<String, ScaleTwoDecimal>> retval =
        new HashMap<String, Map<String, ScaleTwoDecimal>>();

    // Initialize investigator credit types if there aren't any
    if (document.getDevelopmentProposal().getInvestigatorCreditTypes() == null
        || document.getDevelopmentProposal().getInvestigatorCreditTypes().size() == 0) {
      document.getDevelopmentProposal().setInvestigatorCreditTypes(getInvestigatorCreditTypes());
    }

    Collection<InvestigatorCreditType> creditTypes =
        document.getDevelopmentProposal().getInvestigatorCreditTypes();

    for (ProposalPerson investigator : document.getDevelopmentProposal().getInvestigators()) {
      Map<String, ScaleTwoDecimal> creditTypeTotals =
          retval.get(investigator.getProposalPersonNumber().toString());
      Map<String, ScaleTwoDecimal> investigatorCreditTypeTotals =
          retval.get(PROPOSAL_PERSON_INVESTIGATOR);

      if (creditTypeTotals == null) {
        creditTypeTotals = new HashMap<String, ScaleTwoDecimal>();
        retval.put(investigator.getProposalPersonNumber().toString(), creditTypeTotals);
      }
      if (investigatorCreditTypeTotals == null) {
        investigatorCreditTypeTotals = new HashMap<String, ScaleTwoDecimal>();
        retval.put(PROPOSAL_PERSON_INVESTIGATOR, investigatorCreditTypeTotals);
      }

      // Initialize everything to zero
      for (InvestigatorCreditType creditType : creditTypes) {
        ScaleTwoDecimal totalCredit = creditTypeTotals.get(creditType.getCode());

        if (totalCredit == null) {
          totalCredit = new ScaleTwoDecimal(0);
          creditTypeTotals.put(creditType.getCode(), totalCredit);
        }
        ScaleTwoDecimal investigatorTotalCredit =
            investigatorCreditTypeTotals.get(creditType.getCode());

        if (investigatorTotalCredit == null) {
          investigatorTotalCredit = new ScaleTwoDecimal(0);
          investigatorCreditTypeTotals.put(creditType.getCode(), investigatorTotalCredit);
        }
        // set investigator credit total
        for (CreditSplit creditSplit : investigator.getCreditSplits()) {
          if (creditSplit.getInvCreditTypeCode().equals(creditType.getCode())) {
            investigatorCreditTypeTotals.put(
                creditType.getCode(), investigatorTotalCredit.add(creditSplit.getCredit()));
          }
        }
      }

      for (ProposalPersonUnit unit : investigator.getUnits()) {
        for (CreditSplit creditSplit : unit.getCreditSplits()) {
          ScaleTwoDecimal totalCredit = creditTypeTotals.get(creditSplit.getInvCreditTypeCode());

          if (totalCredit == null) {
            totalCredit = new ScaleTwoDecimal(0);
            creditTypeTotals.put(creditSplit.getInvCreditTypeCode(), totalCredit);
          }
          creditTypeTotals.put(
              creditSplit.getInvCreditTypeCode(), totalCredit.add(creditSplit.getCredit()));
        }
      }
    }

    return retval;
  }