2015-03-03 09:25:30 +00:00
|
|
|
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
2014-04-18 10:45:31 +00:00
|
|
|
// License: GNU General Public License v3. See license.txt
|
|
|
|
|
2015-09-11 13:19:59 +00:00
|
|
|
frappe.ready(function() {
|
2015-10-05 10:57:52 +00:00
|
|
|
window.item_code = $('[itemscope] [itemprop="productID"]').text().trim();
|
2014-04-18 10:45:31 +00:00
|
|
|
var qty = 0;
|
2015-09-11 13:19:59 +00:00
|
|
|
|
2014-04-18 10:45:31 +00:00
|
|
|
frappe.call({
|
|
|
|
type: "POST",
|
Hub (#10934)
* [WIP]Hub
* [listing] Show items, users and item_groups
* Show filters
* [start] cart, api for rfq and opp
* rfq working
* [wip] keys
* wip quotes
* [hub] register/unregister
* [hub] rename password to access_token, remove passed company field
* [hub] publishing cases, api call wrapper
* [hub] add and remove fields working
* [hub] fix flags, update on client save working
* [hub] new hub page, client item CUD at hub working
* listing, standard rate, local site hack
* item listing, item page, search, back to home
* [hub] implement hub company
* [hub] company filter
* [hub] basic rfq-ing, item page cleanup
* categories wip
* [hub] use get_doc_before_save()
* [hub] send opportunity message to hub, api to make locally
* [hub] enqueueing in hub api request wrapper
* cleanup
* [hub] refactor shopping cart's product.py to reuse
* sync dynamic item fields daily
* Scheduler heartbeat check
* [wip] hub categories
* [hub] wip enqueued callbacks
* [hub] outgoing messages, fixing callback loop
* [hub] bug: callback save after primary save
* [hub] pricing, stock, currency
* [hub] replace send_hub_request with make_and_enqueue
* add hub.less, refactor code
* Remove template html files, add styling for hub item cards
* fix paging
* add breadcrumb
* Add sidebar
* [hub] add company page, change country
* [hub] order_by filters
* [hub] make hub category a tree
* [hub] enqueue batched item enqueueing
* [hub] requested products page
* [minor]
* update hub url
* [fix] url
* [fix] more reform
* fix recursion
* [hub] data migration plans as jsons
* Hub register, create data connector, sync with run
* [add] user registration by session user
* Removed hub_message
* Remove sync code from hub_settings
* Remove hub methods from item.py
* Update Hub Sync plan
* Hub unregister
* Update Hub connector on reregister
* Dont delete Hub Connector on unregister
* Enable hub on success response
* Add new hub whitelisted methods
* [hub] list working
* Hub register from hub page
* [hub] Add hub logo in desk icon, link to page
* [hub] hide page head on empty state
* [hub] make rfq
* [hub] push opportunity doc, poll for opportunity docs
* add fields to item mapping
* update hub mappings
* Make RFQ
* [hub] item, home routing
* Make rfq and send opportunity refactor
* [hub][fix] remote lead data
* images passed as base64
* set default company on register
* Revert "images passed as base64"
This reverts commit 0b033a5fb7072b2d39a1b87a47dc41e7af707bb4.
* Add sync to hub page
* Prompt for publish items to hub
* add post process to hub document to lead
* Rename Hub document to Hub message, create opportunity in post process
2017-10-05 05:47:30 +00:00
|
|
|
method: "erpnext.shopping_cart.product_info.get_product_info_for_website",
|
2014-04-18 10:45:31 +00:00
|
|
|
args: {
|
2015-10-20 12:00:02 +00:00
|
|
|
item_code: get_item_code()
|
2014-04-18 10:45:31 +00:00
|
|
|
},
|
|
|
|
callback: function(r) {
|
2017-04-13 13:15:09 +00:00
|
|
|
$(".item-cart").toggleClass("hide", (!!!r.message.price || !!!r.message.in_stock));
|
2014-04-18 10:45:31 +00:00
|
|
|
if(r.message && r.message.price) {
|
|
|
|
$(".item-price")
|
2018-03-20 08:58:44 +00:00
|
|
|
.html(r.message.price.formatted_price_sales_uom + "<div style='font-size: small'>\
|
|
|
|
(" + r.message.price.formatted_price + " / " + r.message.uom + ")</div>");
|
2015-09-11 13:19:59 +00:00
|
|
|
|
2017-03-21 10:58:03 +00:00
|
|
|
if(r.message.in_stock==0) {
|
2017-06-20 07:21:32 +00:00
|
|
|
$(".item-stock").html("<div style='color: red'> <i class='fa fa-close'></i> {{ _("Not in stock") }}</div>");
|
2014-04-18 10:45:31 +00:00
|
|
|
}
|
2017-03-21 10:58:03 +00:00
|
|
|
else if(r.message.in_stock==1) {
|
2017-06-20 07:21:32 +00:00
|
|
|
var qty_display = "{{ _("In stock") }}";
|
2017-03-21 10:58:03 +00:00
|
|
|
if (r.message.show_stock_qty) {
|
2017-06-20 07:21:32 +00:00
|
|
|
qty_display += " ("+r.message.stock_qty+")";
|
2017-03-21 10:58:03 +00:00
|
|
|
}
|
2014-04-18 10:45:31 +00:00
|
|
|
$(".item-stock").html("<div style='color: green'>\
|
2017-06-20 07:21:32 +00:00
|
|
|
<i class='fa fa-check'></i> "+qty_display+"</div>");
|
2014-04-18 10:45:31 +00:00
|
|
|
}
|
2015-09-11 13:19:59 +00:00
|
|
|
|
2014-04-18 10:45:31 +00:00
|
|
|
if(r.message.qty) {
|
|
|
|
qty = r.message.qty;
|
2015-09-11 13:19:59 +00:00
|
|
|
toggle_update_cart(r.message.qty);
|
|
|
|
} else {
|
|
|
|
toggle_update_cart(0);
|
2014-04-18 10:45:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2015-09-11 13:19:59 +00:00
|
|
|
|
2014-04-18 10:45:31 +00:00
|
|
|
$("#item-add-to-cart button").on("click", function() {
|
2017-05-30 07:24:42 +00:00
|
|
|
frappe.provide('erpnext.shopping_cart');
|
|
|
|
|
|
|
|
erpnext.shopping_cart.update_cart({
|
2015-10-05 10:57:52 +00:00
|
|
|
item_code: get_item_code(),
|
2018-01-19 17:31:25 +00:00
|
|
|
qty: $("#item-spinner .cart-qty").val(),
|
2014-04-18 10:45:31 +00:00
|
|
|
callback: function(r) {
|
|
|
|
if(!r.exc) {
|
|
|
|
toggle_update_cart(1);
|
|
|
|
qty = 1;
|
|
|
|
}
|
|
|
|
},
|
2015-09-11 13:19:59 +00:00
|
|
|
btn: this,
|
2014-04-18 10:45:31 +00:00
|
|
|
});
|
|
|
|
});
|
2015-09-11 13:19:59 +00:00
|
|
|
|
2018-01-19 17:31:25 +00:00
|
|
|
$("#item-spinner").on('click', '.number-spinner button', function () {
|
|
|
|
var btn = $(this),
|
|
|
|
input = btn.closest('.number-spinner').find('input'),
|
|
|
|
oldValue = input.val().trim(),
|
|
|
|
newVal = 0;
|
|
|
|
|
|
|
|
if (btn.attr('data-dir') == 'up') {
|
|
|
|
newVal = parseInt(oldValue) + 1;
|
|
|
|
} else if (btn.attr('data-dir') == 'dwn') {
|
|
|
|
if (parseInt(oldValue) > 1) {
|
|
|
|
newVal = parseInt(oldValue) - 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
newVal = parseInt(oldValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
input.val(newVal);
|
|
|
|
});
|
|
|
|
|
2015-10-26 14:27:31 +00:00
|
|
|
$("[itemscope] .item-view-attribute .form-control").on("change", function() {
|
|
|
|
try {
|
|
|
|
var item_code = encodeURIComponent(get_item_code());
|
2015-10-29 07:50:07 +00:00
|
|
|
|
2015-10-26 14:27:31 +00:00
|
|
|
} catch(e) {
|
|
|
|
// unable to find variant
|
|
|
|
// then chose the closest available one
|
|
|
|
|
|
|
|
var attribute = $(this).attr("data-attribute");
|
2018-01-05 07:17:20 +00:00
|
|
|
var attribute_value = $(this).val();
|
2015-10-29 07:50:07 +00:00
|
|
|
var item_code = find_closest_match(attribute, attribute_value);
|
2015-10-26 14:27:31 +00:00
|
|
|
|
|
|
|
if (!item_code) {
|
2017-05-30 07:24:42 +00:00
|
|
|
frappe.msgprint(__("Cannot find a matching Item. Please select some other value for {0}.", [attribute]))
|
2015-10-26 14:27:31 +00:00
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-29 08:32:49 +00:00
|
|
|
if (window.location.search == ("?variant=" + item_code) || window.location.search.includes(item_code)) {
|
2015-10-20 12:00:02 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-01 11:53:12 +00:00
|
|
|
window.location.href = window.location.pathname + "?variant=" + item_code;
|
2015-10-20 12:00:02 +00:00
|
|
|
});
|
2014-04-18 10:45:31 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
var toggle_update_cart = function(qty) {
|
|
|
|
$("#item-add-to-cart").toggle(qty ? false : true);
|
|
|
|
$("#item-update-cart")
|
|
|
|
.toggle(qty ? true : false)
|
|
|
|
.find("input").val(qty);
|
2018-01-19 17:31:25 +00:00
|
|
|
$("#item-spinner").toggle(qty ? false : true);
|
2015-09-11 13:19:59 +00:00
|
|
|
}
|
2015-10-05 10:57:52 +00:00
|
|
|
|
|
|
|
function get_item_code() {
|
2017-05-30 07:24:42 +00:00
|
|
|
var variant_info = window.variant_info;
|
|
|
|
if(variant_info) {
|
2015-10-26 14:27:31 +00:00
|
|
|
var attributes = get_selected_attributes();
|
2015-10-29 07:50:07 +00:00
|
|
|
var no_of_attributes = Object.keys(attributes).length;
|
2015-10-26 14:27:31 +00:00
|
|
|
|
2015-10-05 10:57:52 +00:00
|
|
|
for(var i in variant_info) {
|
|
|
|
var variant = variant_info[i];
|
2015-10-29 07:50:07 +00:00
|
|
|
|
|
|
|
if (variant.attributes.length < no_of_attributes) {
|
|
|
|
// the case when variant has less attributes than template
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-10-05 10:57:52 +00:00
|
|
|
var match = true;
|
|
|
|
for(var j in variant.attributes) {
|
|
|
|
if(attributes[variant.attributes[j].attribute]
|
2017-05-30 07:24:42 +00:00
|
|
|
!= variant.attributes[j].attribute_value
|
|
|
|
) {
|
|
|
|
match = false;
|
|
|
|
break;
|
2015-10-05 10:57:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if(match) {
|
|
|
|
return variant.name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw "Unable to match variant";
|
|
|
|
} else {
|
2017-05-30 07:24:42 +00:00
|
|
|
return window.item_code;
|
2015-10-05 10:57:52 +00:00
|
|
|
}
|
|
|
|
}
|
2015-10-26 14:27:31 +00:00
|
|
|
|
2015-10-29 07:50:07 +00:00
|
|
|
function find_closest_match(selected_attribute, selected_attribute_value) {
|
2015-10-26 14:27:31 +00:00
|
|
|
// find the closest match keeping the selected attribute in focus and get the item code
|
|
|
|
|
|
|
|
var attributes = get_selected_attributes();
|
|
|
|
|
|
|
|
var previous_match_score = 0;
|
2015-10-29 07:50:07 +00:00
|
|
|
var previous_no_of_attributes = 0;
|
2015-10-26 14:27:31 +00:00
|
|
|
var matched;
|
2015-10-29 07:50:07 +00:00
|
|
|
|
2017-05-30 07:24:42 +00:00
|
|
|
var variant_info = window.variant_info;
|
2015-10-26 14:27:31 +00:00
|
|
|
for(var i in variant_info) {
|
|
|
|
var variant = variant_info[i];
|
|
|
|
var match_score = 0;
|
|
|
|
var has_selected_attribute = false;
|
|
|
|
|
|
|
|
for(var j in variant.attributes) {
|
|
|
|
if(attributes[variant.attributes[j].attribute]===variant.attributes[j].attribute_value) {
|
|
|
|
match_score = match_score + 1;
|
|
|
|
|
|
|
|
if (variant.attributes[j].attribute==selected_attribute && variant.attributes[j].attribute_value==selected_attribute_value) {
|
|
|
|
has_selected_attribute = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-29 07:50:07 +00:00
|
|
|
if (has_selected_attribute
|
|
|
|
&& ((match_score > previous_match_score) || (match_score==previous_match_score && previous_no_of_attributes < variant.attributes.length))) {
|
2015-10-26 14:27:31 +00:00
|
|
|
previous_match_score = match_score;
|
|
|
|
matched = variant;
|
2015-10-29 07:50:07 +00:00
|
|
|
previous_no_of_attributes = variant.attributes.length;
|
|
|
|
|
|
|
|
|
2015-10-26 14:27:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (matched) {
|
|
|
|
for (var j in matched.attributes) {
|
|
|
|
var attr = matched.attributes[j];
|
|
|
|
$('[itemscope]')
|
|
|
|
.find(repl('.item-view-attribute .form-control[data-attribute="%(attribute)s"]', attr))
|
|
|
|
.val(attr.attribute_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return matched.name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_selected_attributes() {
|
|
|
|
var attributes = {};
|
|
|
|
$('[itemscope]').find(".item-view-attribute .form-control").each(function() {
|
|
|
|
attributes[$(this).attr('data-attribute')] = $(this).val();
|
|
|
|
});
|
|
|
|
return attributes;
|
|
|
|
}
|