/**
   * Batch Fetch processor.
   *
   * <p>Fetches a Batch result
   *
   * <p>{@sample.xml ../../../doc/avalara-connector.xml.sample avalara:fetch-batch-file}
   *
   * @param batchId The numerical identifier of the BatchFile.
   * @return The {@link Map<String,BatchFileFetchResult>}
   * @throws AvalaraRuntimeException
   */
  @Processor
  public Map<String, BatchFileFetchResult> fetchBatchFile(String batchId) {
    // This Request is needed to retrieve the batch file ids. The actual content cannot be retrieved
    // at once.
    FetchRequest batchFetchRequest = new FetchRequest();
    batchFetchRequest.setFields("Files");
    batchFetchRequest.setFilters("BatchId=" + batchId);
    BatchFetchResult batchFetchResult =
        apiClient.sendBatchRequestToAvalara(BatchRequestType.BatchFetch, batchFetchRequest);
    Map<String, BatchFileFetchResult> resultHashMap = new HashMap<String, BatchFileFetchResult>();
    // This is in order to be able to return result and error file to the caller.
    for (BatchFile bf : batchFetchResult.getBatches().getBatch().get(0).getFiles().getBatchFile()) {
      if (bf.getName().equalsIgnoreCase("Result")) {
        FetchRequest fetchRequest = new FetchRequest();
        fetchRequest.setFields("*,Content");
        fetchRequest.setFilters("BatchFileId=" + bf.getBatchFileId());
        resultHashMap.put(
            "result",
            (BatchFileFetchResult)
                apiClient.sendBatchRequestToAvalara(BatchRequestType.BatchFileFetch, fetchRequest));
      } else if (bf.getName().equalsIgnoreCase("Error")) {
        FetchRequest fetchRequest = new FetchRequest();
        fetchRequest.setFields("*,Content");
        fetchRequest.setFilters("BatchFileId=" + bf.getBatchFileId());
        resultHashMap.put(
            "error",
            (BatchFileFetchResult)
                apiClient.sendBatchRequestToAvalara(BatchRequestType.BatchFileFetch, fetchRequest));
      }
    }

    return resultHashMap;
  }
  /**
   * Batch Save processor.
   *
   * <p>Saves a Batch. Note that you should pass-in your console credentials for this method,
   * instead of the API ones
   *
   * <p>{@sample.xml ../../../doc/avalara-connector.xml.sample avalara:save-batch}
   *
   * @param batchType The kind of records to be imported.
   * @param companyId The id of the company. (Need to be retrived from address bar in Avalara after
   *     hitting the Organization Tab)
   * @param content The content of this import, usually a csv file.
   * @param batchName The name of the batch.
   * @return The {@link BatchSaveResult}
   * @throws AvalaraRuntimeException
   */
  @Processor
  public BatchSaveResult saveBatch(
      BatchType batchType, int companyId, String content, @Optional String batchName) {

    final BatchFile batchFile = new BatchFile();
    batchFile.setContent(content.getBytes()); // cxf takes care of base64 encoding
    batchFile.setContentType("application/csv");
    batchFile.setName(
        batchName + ".csv"); // Must set extension, or Avalara will complain about missing ext
    final ArrayOfBatchFile arrayOfBatchFile = new ArrayOfBatchFile();
    arrayOfBatchFile.getBatchFile().add(batchFile);

    // Batch object to contain the file.
    // Have tested batchfile as well but all examples from Avalara is using this one.
    final Batch batch = new Batch();
    batch.setName(batchName);
    batch.setBatchTypeId(batchType.value());
    batch.setCompanyId(companyId);
    batch.setFiles(arrayOfBatchFile);
    return apiClient.sendBatchRequestToAvalara(BatchRequestType.BatchSave, batch);
  }