diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 287d9621f2..6045e77384 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -224,3 +224,5 @@ erpnext.patches.v6_4.email_digest_update execute:frappe.delete_doc_if_exists("DocType", "Applicable Territory") execute:frappe.delete_doc_if_exists("DocType", "Shopping Cart Price List") execute:frappe.delete_doc_if_exists("DocType", "Shopping Cart Taxes and Charges Master") +erpnext.patches.v6_4.set_user_in_contact +erpnext.patches.v6_4.make_image_thumbnail diff --git a/erpnext/patches/v6_4/make_image_thumbnail.py b/erpnext/patches/v6_4/make_image_thumbnail.py new file mode 100644 index 0000000000..1daaede0c3 --- /dev/null +++ b/erpnext/patches/v6_4/make_image_thumbnail.py @@ -0,0 +1,14 @@ +import frappe + +def execute(): + frappe.reload_doctype("File") + frappe.reload_doctype("Item") + for item in frappe.get_all("Item", fields=("name", "website_image")): + if item.website_image: + item_doc = frappe.get_doc("Item", item.name) + try: + item_doc.make_thumbnail() + if item_doc.thumbnail: + item_doc.db_set("thumbnail", item_doc.thumbnail, update_modified=False) + except Exception: + print "Unable to make thumbnail for {0}".format(item.website_image) diff --git a/erpnext/patches/v6_4/set_user_in_contact.py b/erpnext/patches/v6_4/set_user_in_contact.py new file mode 100644 index 0000000000..41f76af94d --- /dev/null +++ b/erpnext/patches/v6_4/set_user_in_contact.py @@ -0,0 +1,6 @@ +import frappe + +def execute(): + frappe.reload_doctype("Contact") + frappe.db.sql("""update tabContact, tabUser set tabContact.user = tabUser.name + where tabContact.email_id = tabUser.email""") diff --git a/erpnext/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js index 0c3049c7ce..d437d74e96 100644 --- a/erpnext/public/js/shopping_cart.js +++ b/erpnext/public/js/shopping_cart.js @@ -20,7 +20,6 @@ $.extend(shopping_cart, { if(!full_name || full_name==="Guest") { if(localStorage) { localStorage.setItem("last_visited", window.location.pathname); - localStorage.setItem("pending_add_to_cart", opts.item_code); } window.location.href = "/login"; } else { diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 5a98e084b9..b5520ff7fd 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -19,6 +19,8 @@ class Quotation(SellingController): self.validate_order_type() self.validate_uom_is_integer("stock_uom", "qty") self.validate_quotation_to() + if self.items: + self.with_items = 1 def has_sales_order(self): return frappe.db.get_value("Sales Order Item", {"prevdoc_docname": self.name, "docstatus": 1}) diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py index 279ff0a264..97367013d7 100644 --- a/erpnext/setup/doctype/item_group/item_group.py +++ b/erpnext/setup/doctype/item_group/item_group.py @@ -66,11 +66,12 @@ def get_product_list_for_group(product_group=None, start=0, limit=10): child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(product_group)]) # base query - query = """select name, item_name, page_name, website_image, item_group, + query = """select name, item_name, page_name, website_image, thumbnail, item_group, web_long_description as website_description, concat(parent_website_route, "/", page_name) as route from `tabItem` where show_in_website = 1 + and (variant_of = '' or variant_of is null) and (item_group in (%s) or name in (select parent from `tabWebsite Item Group` where item_group in (%s))) """ % (child_groups, child_groups) diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py index c4f3db0395..22f920faa6 100644 --- a/erpnext/shopping_cart/cart.py +++ b/erpnext/shopping_cart/cart.py @@ -143,7 +143,7 @@ def guess_territory(): def decorate_quotation_doc(doc): for d in doc.get("items", []): d.update(frappe.db.get_value("Item", d.item_code, - ["website_image", "description", "page_name"], as_dict=True)) + ["thumbnail", "website_image", "description", "page_name"], as_dict=True)) return doc diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index 4de617a5a3..7d314d2c81 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -1902,6 +1902,28 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "thumbnail", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Thumbnail", + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -2264,4 +2286,4 @@ "read_only_onload": 0, "search_fields": "item_name,description,item_group,customer_code", "title_field": "item_name" -} \ No newline at end of file +} diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 1ec4b52124..41329f3b4c 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import frappe +import json from frappe import msgprint, _ from frappe.utils import cstr, flt, cint, getdate, now_datetime, formatdate from frappe.website.website_generator import WebsiteGenerator @@ -65,6 +66,7 @@ class Item(WebsiteGenerator): self.validate_has_variants() self.validate_attributes() self.validate_variant_attributes() + self.make_thumbnail() if not self.get("__islocal"): self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group") @@ -78,13 +80,64 @@ class Item(WebsiteGenerator): self.update_item_price() self.update_variants() + def make_thumbnail(self): + """Make a thumbnail of `website_image`""" + if self.website_image and not self.thumbnail: + file_doc = frappe.get_doc("File", { + "file_url": self.website_image, + "attached_to_doctype": "Item", + "attached_to_name": self.name + }) + + if not file_doc: + file_doc = frappe.get_doc({ + "doctype": "File", + "file_url": self.website_image, + "attached_to_doctype": "Item", + "attached_to_name": self.name + }).insert() + + if file_doc: + self.thumbnail = file_doc.make_thumbnail() + def get_context(self, context): - context["parent_groups"] = get_parent_item_groups(self.item_group) + \ + context.parent_groups = get_parent_item_groups(self.item_group) + \ [{"name": self.name}] if self.slideshow: context.update(get_slideshow(self)) - context["parents"] = self.get_parents(context) + if self.has_variants: + attribute_values_available = {} + context.attribute_values = {} + + # load variants + context.variants = frappe.get_all("Item", + filters={"variant_of": self.name, "show_in_website": 1}) + + # load attributes + for v in context.variants: + v.attributes = frappe.get_all("Item Variant Attribute", + fields=["attribute", "attribute_value"], filters={"parent": v.name}) + + for attr in v.attributes: + values = attribute_values_available.setdefault(attr.attribute, []) + if attr.attribute_value not in values: + values.append(attr.attribute_value) + + # filter attributes, order based on attribute table + for attr in self.attributes: + values = context.attribute_values.setdefault(attr.attribute, []) + + # get list of values defined (for sequence) + for attr_value in frappe.db.get_all("Item Attribute Value", + fields=["attribute_value"], filters={"parent": attr.attribute}, order_by="idx asc"): + + if attr_value.attribute_value in attribute_values_available.get(attr.attribute, []): + values.append(attr_value.attribute_value) + + context.variant_info = json.dumps(context.variants) + + context.parents = self.get_parents(context) return context diff --git a/erpnext/templates/generators/item.html b/erpnext/templates/generators/item.html index af4a795c9f..f24b1a678b 100644 --- a/erpnext/templates/generators/item.html +++ b/erpnext/templates/generators/item.html @@ -30,6 +30,22 @@

+ {% if has_variants %} + {% for d in attributes %} +
+
{{ _(d.attribute) }}
+ +
+ {% endfor %} + {% endif %} +
@@ -76,13 +92,10 @@ {% endblock %} diff --git a/erpnext/templates/includes/product_in_grid.html b/erpnext/templates/includes/product_in_grid.html index d2c1c46ee6..ff39f1f8c2 100644 --- a/erpnext/templates/includes/product_in_grid.html +++ b/erpnext/templates/includes/product_in_grid.html @@ -2,7 +2,7 @@
- {{ product_image_square(website_image) }} + {{ product_image_square(thumbnail or website_image) }}
{{ item_name }}
diff --git a/erpnext/templates/includes/product_in_list.html b/erpnext/templates/includes/product_in_list.html index 2a6cbe1a75..8a4bdf6e16 100644 --- a/erpnext/templates/includes/product_in_list.html +++ b/erpnext/templates/includes/product_in_list.html @@ -3,7 +3,8 @@
{%- if website_image -%} - + {%- else -%}
{%- endif -%} diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js index 98331a4f20..7468ffeff9 100644 --- a/erpnext/templates/includes/product_page.js +++ b/erpnext/templates/includes/product_page.js @@ -2,7 +2,7 @@ // License: GNU General Public License v3. See license.txt frappe.ready(function() { - var item_code = $('[itemscope] [itemprop="productID"]').text().trim(); + window.item_code = $('[itemscope] [itemprop="productID"]').text().trim(); var qty = 0; frappe.call({ @@ -12,7 +12,6 @@ frappe.ready(function() { item_code: "{{ name }}" }, callback: function(r) { - console.log(r.message); $(".item-cart").toggleClass("hide", !!!r.message.price); if(r.message && r.message.price) { $(".item-price") @@ -38,7 +37,7 @@ frappe.ready(function() { $("#item-add-to-cart button").on("click", function() { shopping_cart.update_cart({ - item_code: item_code, + item_code: get_item_code(), qty: 1, callback: function(r) { if(!r.exc) { @@ -52,7 +51,7 @@ frappe.ready(function() { $("#item-update-cart button").on("click", function() { shopping_cart.update_cart({ - item_code: item_code, + item_code: get_item_code(), qty: $("#item-update-cart input").val(), btn: this, callback: function(r) { @@ -64,11 +63,6 @@ frappe.ready(function() { }, }); }); - - if(localStorage && localStorage.getItem("pending_add_to_cart") && full_name) { - localStorage.removeItem("pending_add_to_cart"); - $("#item-add-to-cart button").trigger("click"); - } }); var toggle_update_cart = function(qty) { @@ -77,3 +71,29 @@ var toggle_update_cart = function(qty) { .toggle(qty ? true : false) .find("input").val(qty); } + +function get_item_code() { + if(window.variant_info) { + attributes = {}; + $('[itemscope]').find(".item-view-attribute select").each(function() { + attributes[$(this).attr('data-attribute')] = $(this).val(); + }); + for(var i in variant_info) { + var variant = variant_info[i]; + var match = true; + for(var j in variant.attributes) { + if(attributes[variant.attributes[j].attribute] + != variant.attributes[j].attribute_value) { + match = false; + break; + } + } + if(match) { + return variant.name; + } + } + throw "Unable to match variant"; + } else { + return item_code; + } +} diff --git a/erpnext/templates/pages/product_search.py b/erpnext/templates/pages/product_search.py index f4c4534c12..897a199ec9 100644 --- a/erpnext/templates/pages/product_search.py +++ b/erpnext/templates/pages/product_search.py @@ -12,9 +12,9 @@ no_sitemap = 1 @frappe.whitelist(allow_guest=True) def get_product_list(search=None, start=0, limit=10): # base query - query = """select name, item_name, page_name, website_image, item_group, + query = """select name, item_name, page_name, website_image, thumbnail, item_group, web_long_description as website_description, parent_website_route - from `tabItem` where show_in_website = 1""" + from `tabItem` where show_in_website = 1 and (variant_of is null or variant_of = '')""" # search term condition if search: diff --git a/erpnext/utilities/doctype/contact/contact.js b/erpnext/utilities/doctype/contact/contact.js index e8aae144f7..7b64b760df 100644 --- a/erpnext/utilities/doctype/contact/contact.js +++ b/erpnext/utilities/doctype/contact/contact.js @@ -4,11 +4,28 @@ {% include 'controllers/js/contact_address_common.js' %}; cur_frm.email_field = "email_id"; -frappe.ui.form.on("Contact", "validate", function(frm) { - // clear linked customer / supplier / sales partner on saving... - $.each(["Customer", "Supplier", "Sales Partner"], function(i, doctype) { - var name = frm.doc[doctype.toLowerCase().replace(/ /g, "_")]; - if(name && locals[doctype] && locals[doctype][name]) - frappe.model.remove_from_locals(doctype, name); - }); +frappe.ui.form.on("Contact", { + refresh: function(frm) { + if(!frm.doc.user && !frm.is_new() && frm.perm[0].write) { + frm.add_custom_button(__("Invite as User"), function() { + frappe.call({ + method: "erpnext.utilities.doctype.contact.contact.invite_user", + args: { + contact: frm.doc.name + }, + callback: function(r) { + frm.set_value("user", r.message); + } + }); + }); + } + }, + validate: function(frm) { + // clear linked customer / supplier / sales partner on saving... + $.each(["Customer", "Supplier", "Sales Partner"], function(i, doctype) { + var name = frm.doc[doctype.toLowerCase().replace(/ /g, "_")]; + if(name && locals[doctype] && locals[doctype][name]) + frappe.model.remove_from_locals(doctype, name); + }); + } }); diff --git a/erpnext/utilities/doctype/contact/contact.json b/erpnext/utilities/doctype/contact/contact.json index 54b0107705..d50313fa23 100644 --- a/erpnext/utilities/doctype/contact/contact.json +++ b/erpnext/utilities/doctype/contact/contact.json @@ -1,724 +1,747 @@ { - "allow_copy": 0, - "allow_import": 1, - "allow_rename": 1, - "creation": "2013-01-10 16:34:32", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", + "allow_copy": 0, + "allow_import": 1, + "allow_rename": 1, + "creation": "2013-01-10 16:34:32", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Setup", "fields": [ { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "contact_section", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "", - "no_copy": 0, - "options": "icon-user", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "contact_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "", + "no_copy": 0, + "options": "icon-user", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "first_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "First Name", - "no_copy": 0, - "oldfieldname": "first_name", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "first_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "First Name", + "no_copy": 0, + "oldfieldname": "first_name", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "last_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Last Name", - "no_copy": 0, - "oldfieldname": "last_name", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "last_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Last Name", + "no_copy": 0, + "oldfieldname": "last_name", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "cb00", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "email_id", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Email Id", + "no_copy": 0, + "oldfieldname": "email_id", + "oldfieldtype": "Data", + "options": "Email", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 1, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "default": "Passive", - "fieldname": "status", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 1, - "label": "Status", - "length": 20, - "no_copy": 0, - "options": "Passive\nOpen\nReplied", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "cb00", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "email_id", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Email Id", - "no_copy": 0, - "oldfieldname": "email_id", - "oldfieldtype": "Data", - "options": "Email", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Passive", + "fieldname": "status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Status", + "length": 20, + "no_copy": 0, + "options": "Passive\nOpen\nReplied", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "phone", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Phone", - "no_copy": 0, - "oldfieldname": "contact_no", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "phone", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Phone", + "no_copy": 0, + "oldfieldname": "contact_no", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "contact_details", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Reference", - "no_copy": 0, - "options": "icon-pushpin", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "contact_details", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Reference", + "no_copy": 0, + "options": "icon-pushpin", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "", - "fieldname": "customer", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Customer", - "no_copy": 0, - "oldfieldname": "customer", - "oldfieldtype": "Link", - "options": "Customer", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "user", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "User Id", + "no_copy": 0, + "options": "User", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "", - "fieldname": "customer_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Customer Name", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "customer", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Customer", + "no_copy": 0, + "oldfieldname": "customer", + "oldfieldtype": "Link", + "options": "Customer", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "column_break1", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "no_copy": 0, - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "customer_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Customer Name", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break1", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0, "width": "50%" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "", - "fieldname": "supplier", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Supplier", - "no_copy": 0, - "options": "Supplier", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "supplier", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Supplier", + "no_copy": 0, + "options": "Supplier", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "", - "fieldname": "supplier_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Supplier Name", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "supplier_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Supplier Name", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "", - "fieldname": "sales_partner", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Sales Partner", - "no_copy": 0, - "options": "Sales Partner", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "sales_partner", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Sales Partner", + "no_copy": 0, + "options": "Sales Partner", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "default": "0", - "depends_on": "eval:(doc.customer || doc.supplier || doc.sales_partner)", - "fieldname": "is_primary_contact", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Is Primary Contact", - "no_copy": 0, - "oldfieldname": "is_primary_contact", - "oldfieldtype": "Select", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "0", + "depends_on": "eval:(doc.customer || doc.supplier || doc.sales_partner)", + "fieldname": "is_primary_contact", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Is Primary Contact", + "no_copy": 0, + "oldfieldname": "is_primary_contact", + "oldfieldtype": "Select", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "more_info", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "More Information", - "no_copy": 0, - "options": "icon-file-text", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "more_info", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "More Information", + "no_copy": 0, + "options": "icon-file-text", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "mobile_no", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Mobile No", - "no_copy": 0, - "oldfieldname": "mobile_no", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "mobile_no", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Mobile No", + "no_copy": 0, + "oldfieldname": "mobile_no", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "description": "Enter department to which this Contact belongs", - "fieldname": "department", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Department", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "Enter department to which this Contact belongs", + "fieldname": "department", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Department", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "description": "Enter designation of this Contact", - "fieldname": "designation", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Designation", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "Enter designation of this Contact", + "fieldname": "designation", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Designation", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "unsubscribed", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Unsubscribed", - "no_copy": 0, - "permlevel": 0, - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "unsubscribed", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Unsubscribed", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 } - ], - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "icon-user", - "idx": 1, - "in_create": 0, - "in_dialog": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "modified": "2015-10-02 07:38:42.365280", - "modified_by": "Administrator", - "module": "Utilities", - "name": "Contact", - "owner": "Administrator", + ], + "hide_heading": 0, + "hide_toolbar": 0, + "icon": "icon-user", + "idx": 1, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "modified": "2015-10-07 00:38:08.152183", + "modified_by": "Administrator", + "module": "Utilities", + "name": "Contact", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales Master Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales Master Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase Master Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase Master Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Maintenance Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Maintenance Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Maintenance User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Maintenance User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "apply_user_permissions": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "match": "", - "permlevel": 1, - "print": 0, - "read": 1, - "report": 1, - "role": "All", - "set_user_permissions": 0, - "share": 0, - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 0, + "export": 0, + "if_owner": 0, + "import": 0, + "match": "", + "permlevel": 1, + "print": 0, + "read": 1, + "report": 1, + "role": "All", + "set_user_permissions": 0, + "share": 0, + "submit": 0, "write": 0 } - ], - "read_only": 0, + ], + "read_only": 0, "read_only_onload": 0 -} \ No newline at end of file +} diff --git a/erpnext/utilities/doctype/contact/contact.py b/erpnext/utilities/doctype/contact/contact.py index 314014f518..bfab79f813 100644 --- a/erpnext/utilities/doctype/contact/contact.py +++ b/erpnext/utilities/doctype/contact/contact.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cstr, extract_email_id +from frappe.utils import cstr from erpnext.controllers.status_updater import StatusUpdater @@ -22,6 +22,11 @@ class Contact(StatusUpdater): def validate(self): self.set_status() self.validate_primary_contact() + self.set_user() + + def set_user(self): + if not self.user and self.email_id: + self.user = frappe.db.get_value("User", {"email": self.email_id}) def validate_primary_contact(self): if self.is_primary_contact == 1: @@ -53,6 +58,21 @@ class Contact(StatusUpdater): frappe.db.sql("""update `tabIssue` set contact='' where contact=%s""", self.name) +@frappe.whitelist() +def invite_user(contact): + contact = frappe.get_doc("Contact", contact) + if contact.has_permission("write"): + user = frappe.get_doc({ + "doctype": "User", + "first_name": contact.first_name, + "last_name": contact.last_name, + "email": contact.email_id, + "user_type": "Website User", + "send_welcome_email": 1 + }).insert(ignore_permissions = True) + + return user.name + @frappe.whitelist() def get_contact_details(contact): contact = frappe.get_doc("Contact", contact)