Skip to content

Instantly share code, notes, and snippets.

@gterrill
Last active December 6, 2018 21:03
Show Gist options
  • Save gterrill/58062a6df4528bdde1992641e0faa4ae to your computer and use it in GitHub Desktop.
Save gterrill/58062a6df4528bdde1992641e0faa4ae to your computer and use it in GitHub Desktop.
Booking deposit using product tags
{% comment %}
======================
booking-deposit.liquid
======================
Iterates over each product in the cart and collects their deposit tags. Then for each
deposit tag, find a matching deposit variant and to the cart in the same quantity as the product.
For a simpler version that simply adds a deposit based on the number of rentable items in the cart
see this gist: https://gist.github.com/gterrill/d6e985ceeeb229c348c77949a05fb828
Installation
------------
1. Create a new 'booking-deposit' snippet and add this code.
2. In cart.liquid (template or section):
- Add {% include 'booking-deposit' %} to the bottom of the file.
- Find where it allows updating the quantity for the line item. Change it so that it is
read-only (this prevents users from removing the deposit item). Something like this:
{% if item.product.metafields.bookthatapp.config or item.product.handle == 'deposit' %}
{{ item.quantity }}
<input type="hidden" name="updates[]" id="updates_{{ item.id }}" value="{{ item.quantity }}">
{% else %}
// normal update input field here
{% endif %}
- Find where it allows removing a line item. Change it so that it ignores the deposit
product. Something like this:
{% unless item.product.handle == 'deposit' %}
<a href="/cart/change?line={{ forloop.index }}&quantity=0" class="remove">Remove</a>
{% endunless %}
Product Setup
-------------
1. Create a deposit product called 'Deposit'. Add variants for each class of deposit you will
apply to products - e.g. 'Class 1', 'Class 2'.
2. Go to each product that needs a deposit and add a tag of 'Deposit: ' + the class. It is case
sensitive so be careful.
Support
-------
Contact support@zetya.com if you need help with this.
{% endcomment %}
<script>
BookingDeposit = function() {
var _this = this;
_this.cart = {{ cart | json }};
_this.depositProduct = {{ all_products['deposit'] | json }};
_this.depositTags = [];
_this.depositItemUpdates = {}; // deposit variant id => quantity
_this.depositItemQuantities = {}; // deposit variant id => quantity
this.init = function() {
if (_this.depositProduct.error) {
alert('Product with handle "deposit" not found');
}
_this.initData();
_this.collectDepositUpdates();
if (!_this.depositItemsMatch()) {
_this.addDepositItemsToCart().done(function(cart) {
location.href = '/cart';
});
}
};
this.collectDepositUpdates = function() {
for (var i = 0; i < _this.depositTags.length; i++) {
var depositTag = _this.depositTags[i],
tag = depositTag.tag.substr(9), // remove 'Deposit: ' part
qty = depositTag.qty,
depositVariantId = _this.findDepositVariantFromTag(tag);
if (depositVariantId) {
_this.depositItemUpdates[depositVariantId] = _this.depositItemUpdates[depositVariantId] + qty;
}
}
};
this.findDepositVariantFromTag = function(tag) {
for (var i = 0; i < _this.depositProduct.variants.length; i++) {
var variant = _this.depositProduct.variants[i];
if (variant.title == tag) {
return variant.id;
}
}
};
this.depositItemsMatch = function() {
var result = true;
$.each(_this.depositItemUpdates, function(updateId, newQty) {
var found = false,
qtyMatch = false;
$.each(_this.depositItemQuantities, function(existingId, oldQty) {
if (updateId == existingId) {
found = true;
qtyMatch = newQty == oldQty;
return false; // found it
}
});
result = (found && qtyMatch) || (!found && newQty == 0);
return result; // quit iterating as soon as an item doesn't match
});
return result;
};
this.addDepositItemsToCart = function() {
return $.ajax({
type: 'POST',
url: '/cart/update.js', // will add if it doesn't exist yet
data: {updates: _this.depositItemUpdates},
dataType: 'json'
});
}
this.initData = function() {
// initialize deposit item update quantities
for (var x = 0; x < _this.depositProduct.variants.length; x++) {
_this.depositItemUpdates[_this.depositProduct.variants[x].id] = 0;
}
// find deposit tags and associated quantity
{% for item in cart.items %}
{%- if item.product.handle == 'deposit' -%}
_this.depositItemQuantities[{{ item.id }}] = {{ item.quantity }};
{%- else -%}
{%- for tag in item.product.tags -%}
{%- if tag contains 'Deposit: ' -%}
_this.depositTags.push({tag: '{{ tag }}', qty: {{ item.quantity }} }); // or simply qty: 1
{%- break -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{% endfor %}
}
this.init();
}
document.addEventListener("DOMContentLoaded", function(event) {
new BookingDeposit();
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment