extend type Query {
  "List all tax codes supported by the current active tax service for the shop"
  taxCodes(
    "The shop to use for getting the list of active tax services"
    shopId: ID!
  ): [TaxCode]!

  "Get a full list of all tax services for the shop"
  taxServices(
    "The shop to use for getting the list of all tax services"
    shopId: ID!
  ): [TaxService]!
}

"A tax code that may be used on a product to indicate proper taxation category"
type TaxCode {
  "The code"
  code: String!

  "Short description of what types of products the code is for"
  label: String!
}

"A service registered by a tax plugin, that provides tax codes and calculations"
type TaxService {
  "Human-readable display name"
  displayName: String!

  "The tax service name. Any valid name that has been registered by a tax plugin."
  name: String!

  "Name of the plugin that added the tax service"
  pluginName: String!
}

extend type CatalogProductVariant {
  "Is sales tax charged on this item?"
  isTaxable: Boolean!

  "An optional code which, if understood by the active tax service for the shop, determines how this product should be taxed"
  taxCode: String

  "A description to use for the tax line item on an invoice"
  taxDescription: String
}

extend type Cart {
  """
  A summary of calculated taxes for this cart. Null means "not able to calculate",
  such as when no fulfillment method has been selected for some fulfillment groups.
  """
  taxSummary: TaxSummary
}

extend type OrderFulfillmentGroup {
  """
  A summary of calculated taxes for this group.
  """
  taxSummary: TaxSummary
}

extend type CartItem {
  "Is this a taxable item?"
  isTaxable: Boolean!

  "Total tax calculated for this item"
  tax: Money

  "The tax code for this item"
  taxCode: String

  "Amount of subtotal that is taxable"
  taxableAmount: Money

  "List of calculated taxes due for this item"
  taxes: [CalculatedTax]
}

extend type OrderItem {
  "Is this a taxable item?"
  isTaxable: Boolean!

  "Total tax calculated for this item"
  tax: Money!

  "The tax code for this item"
  taxCode: String

  "Amount of subtotal that is taxable"
  taxableAmount: Money!

  "List of calculated taxes due for this item"
  taxes: [CalculatedTax]!
}

"Tax sources"
enum TaxSource {
  "Tax is applied when the destination matches the tax jurisdiction"
  destination

  "Tax is applied when the origin matches the tax jurisdiction"
  origin
}

"A single calculated tax for a cart, order group, cart item, or order item"
type CalculatedTax {
  "Calculated tax ID"
  _id: ID!

  "Jurisdiction ID. It is up to the tax service to determine if and how to use this."
  jurisdictionId: String

  "Did this tax match due to the order origin or the order destination?"
  sourcing: TaxSource!

  "Amount of tax due"
  tax: Money!

  "A human-readable display name for showing this tax to operators and customers in the UI"
  taxName: String!

  "The tax rate used for this calculation"
  taxRate: Rate!

  "Amount that was used for calculating the tax due"
  taxableAmount: Money!
}

"A summary of tax-related calculations for a cart or order group"
type TaxSummary {
  "The time at which taxes were last calculated for the cart or order group"
  calculatedAt: DateTime!

  "The name of the tax service that last calculated taxes for the cart or order group"
  calculatedByTaxServiceName: String

  "A reference ID for the external system that calculated the taxes"
  referenceId: String

  "Total tax calculated by the active tax service"
  tax: Money!

  "Amount that was deemed subject to any taxes by the active tax service"
  taxableAmount: Money!

  "Full list of all taxes that were calculated by the active tax service for the cart or order group"
  taxes: [CalculatedTax]!
}

extend type ShopSettings {
  "The default value to use for `taxCode` property of a product"
  defaultTaxCode: String

  """
  The name of the tax service to fall back to if the primary tax service is down.
  This will match the `name` field of one of the services returned by the `taxServices`
  query.
  """
  fallbackTaxServiceName: String

  """
  The name of the tax service to use for calculating taxes on carts and orders.
  This will match the `name` field of one of the services returned by the `taxServices`
  query.
  """
  primaryTaxServiceName: String
}

extend type ProductVariant {
  "Whether this variant is taxable"
  isTaxable: Boolean

  "Tax code"
  taxCode: String

  "Tax description"
  taxDescription: String
}

extend input ShopSettingsUpdates {
  "The default value to use for `taxCode` property of a product"
  defaultTaxCode: String

  """
  Optionally, set the name of the tax service to fall back to if the primary tax service is down.
  This must match the `name` field of one of the services returned by the `taxServices` query.
  """
  fallbackTaxServiceName: String

  """
  Set the name of the tax service to use for calculating taxes on carts and orders.
  This will match the `name` field of one of the services returned by the `taxServices`
  query. There will be no taxes charged for any carts or orders if this is not set.
  """
  primaryTaxServiceName: String
}

extend input ProductVariantInput {
  "Whether this variant is taxable"
  isTaxable: Boolean

  "Tax code"
  taxCode: String

  "Tax description"
  taxDescription: String
}
