/**
   * @param permId instrument perm id
   * @param attributeEnum instrument attribute enumeration
   * @param effectiveFrom effective from
   * @param effectiveTo effective to
   * @return instrumentVO with the history of the required attribute within the specified period;
   *     return valid object with no attributes if no data found
   * @throws JSONException
   * @throws InvalidRawValueException
   * @throws InvalidServiceMethodCallException
   */
  public InstrumentVO getHistoryAttributeOfInstrumentByPermId(
      Long permId,
      InstrumentVO.AttributesEnum attributeEnum, //
      Date effectiveFrom,
      Date effectiveTo)
      throws JSONException, InvalidRawValueException, InvalidServiceMethodCallException {
    String entityVOStr =
        (String)
            Utils.callMethod( //
                this.getIQMNonTemporalAppModuleService(), //
                "getHistoryEntityVOJSONByAttributeNameAndDateRange", //
                new Object[] {
                  InstrumentVO.entityLevel,
                  permId.toString(),
                  attributeEnum.getEnumName(),
                  Utils.convertToString(effectiveFrom),
                  Utils.convertToString(effectiveTo)
                });

    InstrumentVO instrumentVO = (InstrumentVO) Utils.getEntityVOFromJSON(entityVOStr);
    if (instrumentVO != null) {
      instrumentVO.setIsNormalized(null);
      AttributeConverter.convertEntityVO(instrumentVO, false);
    }
    return instrumentVO;
  }
  /**
   * @param permId quote perm id
   * @param attributeEnum quote attribute enumeration
   * @return quoteVO with the full history of the required attribute; return valid object with no
   *     attributes if no data found
   * @throws JSONException
   * @throws InvalidRawValueException
   * @throws InvalidServiceMethodCallException
   */
  public QuoteVO getHistoryAttributeOfQuoteByPermId(
      Long permId, //
      QuoteVO.AttributesEnum attributeEnum)
      throws JSONException, InvalidRawValueException, InvalidServiceMethodCallException {
    String entityVOStr =
        (String)
            Utils.callMethod( //
                this.getIQMNonTemporalAppModuleService(), //
                "getHistoryEntityVOJSONByAttributeName", //
                new Object[] {QuoteVO.entityLevel, permId.toString(), attributeEnum.getEnumName()});

    QuoteVO quoteVO = (QuoteVO) Utils.getEntityVOFromJSON(entityVOStr);
    if (quoteVO != null) {
      quoteVO.setIsNormalized(null);
      AttributeConverter.convertEntityVO(quoteVO, false);
    }
    return quoteVO;
  }
  /**
   * @param permId quote perm id
   * @param effectiveFromDate effective from
   * @param effectiveToDate effective to
   * @return QuoteVO with all the info of the requested quote
   * @throws JSONException
   * @throws InvalidRawValueException
   * @throws InvalidServiceMethodCallException <br>
   *     Only its BASE_ASEET instrument will have full info provided, while other related issues (if
   *     any) will just have perm ids). <br>
   *     All attributes will have denormalized values instead of ids. <br>
   *     E.g. "Published" (TRCS name) will be provided for ADMIN_STATUS instead of 1010003 (TRCS
   *     perm id).
   */
  public QuoteVO getQuoteVOByPermId(Long permId, Date effectiveFromDate, Date effectiveToDate)
      throws JSONException, InvalidRawValueException, InvalidServiceMethodCallException {

    String entityVOStr =
        (String)
            Utils.callMethod(
                this.getIQMAppService(), //
                "getQuoteVOJSONByPermId", //
                new Object[] { //
                  permId.toString(), //
                  Utils.convertToString(effectiveFromDate), //
                  Utils.convertToString(effectiveToDate) //
                });

    QuoteVO entityVO = (QuoteVO) Utils.getEntityVOFromJSON(entityVOStr);
    if (entityVO != null) {
      entityVO.setIsNormalized(null);
      AttributeConverter.convertEntityVO(entityVO, false);
    }

    return entityVO;
  }
  /**
   * @param entityVO entityVO which holds the business changes
   * @return entity perm id
   * @throws InvalidEntityVOException
   * @throws JSONException
   * @throws InvalidRawValueException
   * @throws InvalidServiceMethodCallException <br>
   *     It calls entityMaintain to save the change to db. <br>
   *     If the db write succeeds, return quote perm id; else throw InvalidEntityVOException.
   */
  public Long saveEntityVO(EntityVO entityVO)
      throws InvalidEntityVOException, JSONException, InvalidRawValueException,
          InvalidServiceMethodCallException {
    ObjectMapper mapper = new ObjectMapper();
    String assetStr = null;
    if (entityVO == null) {
      return null;
    }

    EntityVO tmpEntityVO = AttributeConverter.convertEntityVO(entityVO, true);
    try {
      assetStr = mapper.writeValueAsString((Asset) (tmpEntityVO.getEntity()));

      //            // output for testing
      //            Utils.printTrace(false);
      //            Utils.printMessage(assetStr);
    } catch (IOException ex) {
      //            Utils.printTrace(ex);
      //            Utils.printMessage(ex);
      throw new InvalidEntityVOException(ex);
    }

    String entityMaintainStr =
        (String)
            Utils.callMethod( //
                this.getIQMAppService(), //
                "entityMaintain", //
                new Object[] {assetStr});

    DaoResult daoResult = Utils.fromJSON(entityMaintainStr);

    if (daoResult.isSucc()) {
      return Long.parseLong(daoResult.getKey_value());
    } else {
      throw new InvalidEntityVOException(daoResult.getMessage(), entityMaintainStr);
    }
  }