public CreditApplication save(FinalAssessmentDTO data) throws ServiceException {
    unMask(data);
    data.unmaskFAFields();
    // saved changed quote data first
    super.save(data);
    // now save the new DC1 data
    entity = capDAO.read(data.getId());
    entity.fromDTO(data);
    // associate applicant data
    entity = applicantDAO.associate(entity, data);
    // and save
    entity.setUpdatedBy(data.getUserLink().getUserName());
    entity.setUpdatedOn(DateUtils.now());
    entity = capDAO.save(entity);

    // update the bankaccount too
    updateMainBankAccount(data);

    // let descendants implement their own note saves
    if (!this.getClass().getSimpleName().equals(DAO)) return entity;
    Long pid = entity.getPid();
    // save exceptions
    saveExceptions(data.getErrors(), pid, data.getTid(), TASK);
    // save notes
    saveNotes(data.getNotes(), pid, data.getTid(), TASK);
    return entity;
  }
  @Override
  public FinalAssessmentDTO read(Long pid) throws ServiceException {

    entity = capDAO.find(CreditApplication.onPid, pid);

    // resolve selected lazies on the quote level

    if (entity.getQuote() != null) {
      Hibernate.initialize(entity.getQuote().getSettlements());
      Collections.sort(
          entity.getQuote().getSettlements(),
          new Comparator<Settlement>() {
            public int compare(Settlement s1, Settlement s2) {
              return s1.getRanking() > s2.getRanking()
                  ? 1
                  : s1.getRanking() < s2.getRanking() ? -1 : 0;
            }
          });
    }
    Hibernate.initialize(entity.getQuote().getOffers());
    for (Offer offer : entity.getQuote().getOffers()) {
      Hibernate.initialize(offer.getOfferRetailItems());
      Hibernate.initialize(offer.getOfferSIMItems());
    }

    Hibernate.initialize(entity.getDeposits());
    // AffordabilityV2 data
    if (!Hibernate.isInitialized(entity.getAffordabilityV2()))
      Hibernate.initialize(entity.getAffordabilityV2());
    if (entity.getAffordabilityV2() != null) {
      if (!Hibernate.isInitialized(entity.getAffordabilityV2().getBankStatementAdjustments()))
        Hibernate.initialize(entity.getAffordabilityV2().getBankStatementAdjustments());
      if (!Hibernate.isInitialized(entity.getAffordabilityV2().getPayslipDeductionLines()))
        Hibernate.initialize(entity.getAffordabilityV2().getPayslipDeductionLines());
      if (!Hibernate.isInitialized(entity.getAffordabilityV2().getPayslipIncomeLines()))
        Hibernate.initialize(entity.getAffordabilityV2().getPayslipIncomeLines());
      if (!Hibernate.isInitialized(entity.getAffordabilityV2().getPayslips()))
        Hibernate.initialize(entity.getAffordabilityV2().getPayslips());
      if (!Hibernate.isInitialized(entity.getAffordabilityV2().getAffordabilityV2Deposits()))
        Hibernate.initialize(entity.getAffordabilityV2().getAffordabilityV2Deposits());
    }
    if (entity.getQuote().getAffordabilityV2() != null) {
      if (!Hibernate.isInitialized(
          entity.getQuote().getAffordabilityV2().getBankStatementAdjustments()))
        Hibernate.initialize(entity.getQuote().getAffordabilityV2().getBankStatementAdjustments());
      if (!Hibernate.isInitialized(
          entity.getQuote().getAffordabilityV2().getPayslipDeductionLines()))
        Hibernate.initialize(entity.getQuote().getAffordabilityV2().getPayslipDeductionLines());
      if (!Hibernate.isInitialized(entity.getQuote().getAffordabilityV2().getPayslipIncomeLines()))
        Hibernate.initialize(entity.getQuote().getAffordabilityV2().getPayslipIncomeLines());
      if (!Hibernate.isInitialized(entity.getQuote().getAffordabilityV2().getPayslips()))
        Hibernate.initialize(entity.getQuote().getAffordabilityV2().getPayslips());
      if (!Hibernate.isInitialized(
          entity.getQuote().getAffordabilityV2().getAffordabilityV2Deposits()))
        Hibernate.initialize(entity.getQuote().getAffordabilityV2().getAffordabilityV2Deposits());
    }

    // load from base quote dto
    QuoteDTO quote = new QuoteDTO(entity.getQuote());

    // needs app info
    loadAppInfo(quote);

    FinalAssessmentDTO result = new FinalAssessmentDTO();
    result.toDTO(entity);
    result = copyDTO(quote, result);
    result.mapApplicant(entity);
    result.mapDeposits(entity);
    result.mapRecordings(entity);
    result.setId(entity.getId());
    result.setContractingMethod(entity.getContractingMethod());
    result.setContractingMsgDetail(entity.getContractingMsgDetail());
    result.setContractingMsgType(entity.getContractingMsgType());
    // sets the contract generated version number
    result.setContractVersionNumber(
        dataService
            .findDocumentVersionNumber(quote.getProcessBundleLogId(), "LON_PRE", false)
            .toString());
    result.initialiseReworkFields();
    result.setAffordabilityV2CA(entity.getAffordabilityV2());
    return result;
  }