/**
   * 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;
  }
 /**
  * Gets the next available batch item or null if no more are available
  *
  * @return the next available batch item
  * @throws IOException if an I/O error occurs while getting the next item from the batch file.
  */
 @Override
 public BatchItem getNextItem() throws IOException {
   if (curItem >= items.size()) {
     return null;
   } else {
     String line = items.get(curItem++);
     return new BatchItem(BatchFile.getFilename(line), BatchFile.getReference(line));
   }
 }
  /**
   * 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);
  }
  /**
   * Gets the set of lines from the file
   *
   * @param file the name of the file
   */
  private List<String> getBatchItems(String file) throws IOException {
    List<String> list = BatchFile.getLines(file, skip);

    if (totalBatches > 1) {
      int linesPerBatch = list.size() / totalBatches;
      if (linesPerBatch < 1) {
        linesPerBatch = 1;
      }
      if (whichBatch >= totalBatches) {
        whichBatch = totalBatches - 1;
      }
      int startLine = whichBatch * linesPerBatch;
      // last batch needs to get all remaining lines
      if (whichBatch == (totalBatches - 1)) {
        list = list.subList(startLine, list.size());
      } else {
        list = list.subList(startLine, startLine + linesPerBatch);
      }
    }
    return list;
  }