/**
   * Post Tax processor
   *
   * <p>{@sample.xml ../../../doc/avalara-connector.xml.sample avalara:post-tax}
   *
   * @param docId The original document's type, such as Sales Invoice or Purchase Invoice.
   * @param companyCode Client application company reference code. If docId is specified, this is
   *     not needed.
   * @param docType The document type specifies the category of the document and affects how the
   *     document is treated after a tax calculation; see {@link AvalaraDocumentType} for more
   *     information about the specific document types.
   * @param docCode The internal reference code used by the client application.
   * @param docDate The date on the invoice, purchase order, etc
   * @param totalAmount The total amount (not including tax) for the document. This is used for
   *     verification and reconciliation. This should be the <b>TotalAmount</b> returned by {@link
   *     GetTaxResult} when tax was calculated for this document; otherwise the web service will
   *     return an error. The string represents a {@link BigDecimal}
   * @param totalTax The total tax for the document. This is used for verification and
   *     reconciliation. This should be the <b>TotalTax</b> returned by {@link GetTaxResult} when
   *     tax was calculated for this document; otherwise the web service will return an error. The
   *     string represents a {@link BigDecimal}
   * @param commit The commit value. This has been defaulted to false. If this has been set to true
   *     AvaTax will commit the document on this call. Seller's system who wants to Post and Commit
   *     the document on one call should use this flag.
   * @param newDocCode The new document code value.
   * @return The {@link PostTaxResult}
   * @throws AvalaraRuntimeException
   */
  @Processor
  public PostTaxResult postTax(
      @Optional String docId,
      String companyCode,
      AvalaraDocumentType docType,
      @Optional String docCode,
      XMLGregorianCalendar docDate,
      String totalAmount,
      String totalTax,
      @Default("false") boolean commit,
      @Optional String newDocCode) {
    BigDecimal totalAmountDecimal = totalAmount == null ? null : new BigDecimal(totalAmount);
    BigDecimal totalTaxDecimal = totalTax == null ? null : new BigDecimal(totalTax);

    return (PostTaxResult)
        apiClient.sendTaxRequestToAvalara(
            TaxRequestType.PostTax,
            mom.unmap(
                new MapBuilder()
                    .with("docId", docId)
                    .with("companyCode", companyCode)
                    .with("docType", docType.toDocumentType())
                    .with("docCode", docCode)
                    .with("docDate", docDate)
                    .with("totalAmount", totalAmountDecimal)
                    .with("totalTax", totalTaxDecimal)
                    .with("commit", commit)
                    .with("newDocCode", newDocCode)
                    .build(),
                PostTaxRequest.class));
  }
 /**
  * Cancel tax, indicating the document that should be canceled and the reason for the operation.
  *
  * <p>{@sample.xml ../../../doc/avalara-connector.xml.sample avalara:cancel-tax}
  *
  * @param docId The original document's type, such as Sales Invoice or Purchase Invoice.
  * @param companyCode Client application company reference code. If docId is specified, this is
  *     not needed.
  * @param docType The document type specifies the category of the document and affects how the
  *     document is treated after a tax calculation; see {@link AvalaraDocumentType} for more
  *     information about the specific document types.
  * @param docCode The internal reference code used by the client application.
  * @param cancelCode A code indicating the reason the document is getting canceled.
  * @return The {@link CancelTaxResult}
  * @throws AvalaraRuntimeException
  */
 @Processor
 public CancelTaxResult cancelTax(
     @Optional String docId,
     String companyCode,
     AvalaraDocumentType docType,
     @Optional String docCode,
     CancelCodeType cancelCode) {
   return (CancelTaxResult)
       apiClient.sendTaxRequestToAvalara(
           TaxRequestType.CancelTax,
           mom.unmap(
               new MapBuilder()
                   .with("docId", docId)
                   .with("companyCode", companyCode)
                   .with("docType", docType.toDocumentType())
                   .with("docCode", docCode)
                   .with("cancelCode", cancelCode.toAvalaraCancelCode())
                   .build(),
               CancelTaxRequest.class));
 }
 /**
  * Get Tax History processor
  *
  * <p>{@sample.xml ../../../doc/avalara-connector.xml.sample avalara:get-tax-history}
  *
  * @param docId The original document's type, such as Sales Invoice or Purchase Invoice.
  * @param companyCode Client application company reference code. If docId is specified, this is
  *     not needed.
  * @param docType The document type specifies the category of the document and affects how the
  *     document is treated after a tax calculation; see {@link AvalaraDocumentType} for more
  *     information about the specific document types.
  * @param docCode The internal reference code used by the client application.
  * @param detailLevel Specifies the level of detail to return. See {@link DetailLevelType}.
  * @return The {@link GetTaxHistoryResult}
  * @throws AvalaraRuntimeException
  */
 @Processor
 public GetTaxHistoryResult getTaxHistory(
     @Optional String docId,
     String companyCode,
     AvalaraDocumentType docType,
     @Optional String docCode,
     DetailLevelType detailLevel) {
   return (GetTaxHistoryResult)
       apiClient.sendTaxRequestToAvalara(
           TaxRequestType.GetTaxHistory,
           mom.unmap(
               new MapBuilder()
                   .with("docId", docId)
                   .with("companyCode", companyCode)
                   .with("docType", docType.toDocumentType())
                   .with("docCode", docCode)
                   .with("detailLevel", detailLevel.toAvalaraDetailLevel())
                   .build(),
               GetTaxHistoryRequest.class));
 }
  /**
   * Adjust Tax processor.
   *
   * <p>The Get Tax operation calculates tax for one or more invoiced items and displays details
   * describing the calculation of tax for each line item.
   *
   * <p>{@sample.xml ../../../doc/avalara-connector.xml.sample avalara:adjust-tax}
   *
   * @param companyCode Client application company reference code
   * @param adjustmentReason The reason for this tax adjustment.
   * @param adjustmentDescription A description of a tax adjustment.
   * @param docType The document type specifies the category of the document and affects how the
   *     document is treated after a tax calculation; see {@link AvalaraDocumentType} for more
   *     information about the specific document types.
   * @param docCode The internal reference code used by the client application.
   * @param docDate Date of invoice, purchase order, etc.
   * @param salespersonCode The client application salesperson reference code.
   * @param customerCode Client application customer reference code
   * @param customerUsageType Client application customer or usage type. CustomerUsageType
   *     determines the exempt status of the transaction based on the exemption tax rules for the
   *     jurisdictions involved. CustomerUsageType may also be set at the line item level.
   *     <p>The standard values for the CustomerUsageType (A-L).<br>
   *     A Federal Government<br>
   *     B State/Local Govt.<br>
   *     C Tribal Government<br>
   *     D Foreign Diplomat<br>
   *     E Charitable Organization<br>
   *     F Religious/Education<br>
   *     G Resale<br>
   *     H Agricultural Production<br>
   *     I Industrial Prod/Mfg.<br>
   *     J Direct Pay Permit<br>
   *     K Direct Mail<br>
   *     L - Other
   * @param discount The discount amount to apply to the document. The string represents a {@link
   *     BigDecimal}.
   * @param purchaseOrderNo Purchase order identifier. PurchaseOrderNo is required for single use
   *     exemption certificates to match the order and invoice with the certificate.
   * @param exemptionNo Exemption number used for this transaction
   * @param originCode Code that refers one of the address of the baseAddress collection. It has to
   *     be the same code of one of the address's addressCode. It represents the origin address.
   * @param destinationCode Code that refers one of the address of the baseAddress collection. It
   *     has to be the same code of one of the address's addressCode. It represents the destination
   *     address.
   * @param baseAddresses Collection of physical addresses that will be referred to as the
   *     destination or origination of 1 or more invoice line entries
   * @param lines Collection of invoice lines requiring tax calculation
   * @param detailLevel Specifies the level of tax detail to return
   * @param referenceCode For returns (see {@link AvalaraDocumentType}), refers to the {@link
   *     AdjustTaxRequest} of the original invoice.
   * @param locationCode Location Code value. It is Also referred to as a Store Location, Outlet Id,
   *     or Outlet code is a number assigned by the State which identifies a Store location. Some
   *     state returns require taxes are broken out separately for Store Locations.
   * @param commit Commit flag. If Commit is set to true, tax for the transaction is saved, posted
   *     and committed as tax document.
   * @param batchCode The batchCode value.
   * @param taxOverride Indicates to apply tax override to the document.
   * @param currencyCode It is 3 character ISO 4217 currency code.
   * @param serviceMode This is only supported by AvaLocal servers. It provides the ability to
   *     controls whether tax is calculated locally or remotely when using an AvaLocal server. The
   *     default is Automatic which calculates locally unless remote is necessary for non-local
   *     addresses.
   * @param paymentDate The date on which payment was made.
   * @param exchangeRate The exchange rate value. The string represents a {@link BigDecimal}
   * @param exchangeRateEffDate The exchange rate effective date value.
   * @return The {@link AdjustTaxResult}
   * @throws AvalaraRuntimeException
   */
  @Processor
  public AdjustTaxResult adjustTax(
      int adjustmentReason,
      String adjustmentDescription,
      String companyCode,
      AvalaraDocumentType docType,
      @Optional String docCode,
      XMLGregorianCalendar docDate,
      @Optional String salespersonCode,
      String customerCode,
      @Optional String customerUsageType,
      String discount,
      @Optional String purchaseOrderNo,
      @Optional String exemptionNo,
      String originCode,
      String destinationCode,
      List<Map<String, Object>> baseAddresses,
      List<Map<String, Object>> lines,
      DetailLevelType detailLevel,
      @Optional String referenceCode,
      @Optional String locationCode,
      @Default("false") boolean commit,
      @Optional String batchCode,
      @Optional Map<String, Object> taxOverride,
      @Optional String currencyCode,
      @Default("AUTOMATIC") ServiceModeType serviceMode,
      XMLGregorianCalendar paymentDate,
      String exchangeRate,
      XMLGregorianCalendar exchangeRateEffDate) {
    BigDecimal discountDecimal = discount == null ? null : new BigDecimal(discount);
    BigDecimal exchangeRateDecimal = exchangeRate == null ? null : new BigDecimal(exchangeRate);

    Map<String, Object> addresses = null;
    if (baseAddresses != null && !baseAddresses.isEmpty()) {
      addresses = new HashMap<String, Object>();
      addresses.put("baseAddress", baseAddresses);
    }

    Map<String, Object> mapLines = null;
    if (lines != null && !lines.isEmpty()) {
      mapLines = new HashMap<String, Object>();
      mapLines.put("line", lines);
    }
    GetTaxRequest getTaxRequest =
        (GetTaxRequest)
            mom.unmap(
                new MapBuilder()
                    .with("companyCode", companyCode)
                    .with("docType", docType.toDocumentType())
                    .with("docCode", docCode)
                    .with("docDate", docDate)
                    .with("salespersonCode", salespersonCode)
                    .with("customerCode", customerCode)
                    .with("customerUsageType", customerUsageType)
                    .with("discount", discountDecimal)
                    .with("purchaseOrderNo", purchaseOrderNo)
                    .with("exemptionNo", exemptionNo)
                    .with("originCode", originCode)
                    .with("destinationCode", destinationCode)
                    .with("addresses", addresses)
                    .with("lines", mapLines)
                    .with("detailLevel", detailLevel.toAvalaraDetailLevel())
                    .with("referenceCode", referenceCode)
                    .with("locationCode", locationCode)
                    .with("commit", commit)
                    .with("batchCode", batchCode)
                    .with("taxOverride", taxOverride)
                    .with("currencyCode", currencyCode)
                    .with("serviceMode", serviceMode.toAvalaraServiceMode())
                    .with("paymentDate", paymentDate)
                    .with("exchangeRate", exchangeRateDecimal)
                    .with("exchangeRateEffDate", exchangeRateEffDate)
                    .build(),
                GetTaxRequest.class);

    return apiClient.sendTaxRequestToAvalara(
        TaxRequestType.AdjustTax,
        mom.unmap(
            new MapBuilder()
                .with("adjustmentReason", adjustmentReason)
                .with("adjustmentDescription", adjustmentDescription)
                .with("getTaxRequest", getTaxRequest)
                .build(),
            AdjustTaxRequest.class));
  }