Answers.Body: <p>Just in case it's preferred by anyone else, here's a more compact and performant version of pretty much the same technique as Luke's answer:</p>
  <p><code>{% set inStock = product.variants|filter(v =&gt; v.hasStock())|length %}</code></p>
  <p>Less readable? Perhaps, but this way also saved me 14 queries compared to the accepted answer.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-10-24T09:48:48.047Z
Answers.Text: love your solution – great :-)
Answers.UserDisplayName: Matthias
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-09-01T19:19:33.323Z
Answers.LastActivityDate: 2020-09-01T19:19:33.323Z
Answers.UserDisplayName: James Smith
Answers.Body: <p>I managed do this with the following:</p>
  
  <pre><code>{% set variants = craft.commerce.variants({
      product: product,
      hasStock: true
  }) %}
  
  {% if variants|length &lt;= 0 %}
    Sold out
  {% else %}
    Add to basket
  {% endif %}
  </code></pre>
  
  <p>The <code>hasStock</code> criteria takes <code>unlimitedStock</code> into consideration.</p>
  
  <pre><code>if (isset($criteria-&gt;hasStock) &amp;&amp; $criteria-&gt;hasStock === true)
  {
    $hasStockCondition = ['or', '(variants.stock &gt; 0 AND variants.unlimitedStock != 1)', 'variants.unlimitedStock = 1'];
    $query-&gt;andWhere($hasStockCondition);
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-07T17:02:12.037Z
Answers.Text: Great! I had previously tried {% set variants = craft.commerce.products({hasVariants {hasStock: true )} %}... Cheers!
Answers.UserDisplayName: Anders
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-10T11:01:13.157Z
Answers.Text: According to https://craftcommerce.com/support/hiding-out-of-stock-products the query in your comment should work. I'm also having trouble with getting any results from this.
Answers.UserDisplayName: Clive Portman
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-14T03:57:38.117Z
Answers.Text: Should be `hasVariant` not `hasVariants`
Answers.UserDisplayName: Luke Holder
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-07T08:13:48.550Z
Answers.LastActivityDate: 2016-10-07T08:13:48.550Z
Answers.UserDisplayName: Luke Pearce
Body: <p>Basically, I'm trying to show "Out of stock" and disable a button for when none of the variants have stock, and unlimited stock is unchecked.</p>
  
  <p>I've tried this, which isn't working:</p>
  
  <pre><code>{% if product.variants.stock &lt;= 0 and product.variants.unlimitedStock == false %}
      {{ "Out of stock"|t }}
  {% else %}
      {{ "Add to cart"|t }}
  {% endif %}
  </code></pre>
  
Tags: <plugin-craftcommerce>
Title: How do I check if a product has stock in any of it's variants?
ThreadText: # How do I check if a product has stock in any of it's variants?
  
  (Asked by: username_0 on 2016-10-07)
  
  Basically, I'm trying to show "Out of stock" and disable a button for when none of the variants have stock, and unlimited stock is unchecked.
  
  I've tried this, which isn't working:
  
  ```
  {% if product.variants.stock <= 0 and product.variants.unlimitedStock == false %}
      {{ "Out of stock"|t }}
  {% else %}
      {{ "Add to cart"|t }}
  {% endif %}
  
  ```
  
  **Tags:** plugin-craftcommerce
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_3 on 2016-10-07. Score: 6 | Accepted answer
  
  I managed do this with the following:
  
  ```
  {% set variants = craft.commerce.variants({
      product: product,
      hasStock: true
  }) %}
  
  {% if variants|length <= 0 %}
    Sold out
  {% else %}
    Add to basket
  {% endif %}
  
  ```
  
  The `hasStock` criteria takes `unlimitedStock` into consideration.
  
  ```
  if (isset($criteria->hasStock) && $criteria->hasStock === true)
  {
    $hasStockCondition = ['or', '(variants.stock > 0 AND variants.unlimitedStock != 1)', 'variants.unlimitedStock = 1'];
    $query->andWhere($hasStockCondition);
  }
  
  ```
  
  > **Comments:**
  > **username_0**: Great! I had previously tried {% set variants = craft.commerce.products({hasVariants {hasStock: true )} %}... Cheers!  
  > **username_4**: According to https://craftcommerce.com/support/hiding-out-of-stock-products the query in your comment should work. I'm also having trouble with getting any results from this.  
  > **username_5**: Should be `hasVariant` not `hasVariants`  
  
  ---
  
  ### Answer by username_1 on 2020-09-01. Score: 5
  
  Just in case it's preferred by anyone else, here's a more compact and performant version of pretty much the same technique as username_3's answer:
  
  `{% set inStock = product.variants|filter(v => v.hasStock())|length %}`
  
  Less readable? Perhaps, but this way also saved me 14 queries compared to the accepted answer.
  
  > **Comments:**
  > **username_2**: love your solution – great :-)  
  
  ---
  
  