diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 59a1e2b2b6..25444d9988 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -165,6 +165,9 @@ doc_events = {
"Address": {
"validate": "erpnext.shopping_cart.cart.set_customer_in_address"
},
+ "Communication":{
+ "after_insert":"erpnext.utilities.doctype.contact.match_email_to_contact"
+ },
# bubble transaction notification on master
('Opportunity', 'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
diff --git a/erpnext/public/js/templates/address_list.html b/erpnext/public/js/templates/address_list.html
index 6ee7d782bf..f9a317f173 100644
--- a/erpnext/public/js/templates/address_list.html
+++ b/erpnext/public/js/templates/address_list.html
@@ -2,7 +2,7 @@
{% for(var i=0, l=addr_list.length; i
- {%= i+1 %}. {%= addr_list[i].address_type %}
+ {%= i+1 %}. {%= addr_list[i].address_type!="Other" ? addr_list[i].address_type : addr_list[i].address_title %}
{% if(addr_list[i].is_primary_address) { %}
({%= __("Primary") %}){% } %}
{% if(addr_list[i].is_shipping_address) { %}
diff --git a/erpnext/public/js/templates/contact_list.html b/erpnext/public/js/templates/contact_list.html
index ddd3e5292d..765ddf802d 100644
--- a/erpnext/public/js/templates/contact_list.html
+++ b/erpnext/public/js/templates/contact_list.html
@@ -8,7 +8,9 @@
{% if(contact_list[i].is_primary_contact) { %}
({%= __("Primary") %})
{% } %}
-
+ {% if(contact_list[i].designation){ %}
+ – {%= contact_list[i].designation %}
+ {% } %}
{%= __("Edit") %}
diff --git a/erpnext/utilities/doctype/address/address.json b/erpnext/utilities/doctype/address/address.json
index 329e05f587..70564acd24 100644
--- a/erpnext/utilities/doctype/address/address.json
+++ b/erpnext/utilities/doctype/address/address.json
@@ -595,6 +595,35 @@
"set_only_once": 0,
"unique": 0
},
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "organisation",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Organisation",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Organisation",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
{
"allow_on_submit": 0,
"bold": 0,
@@ -750,7 +779,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-11-07 05:47:06.911933",
+ "modified": "2016-12-22 13:49:22.968498",
"modified_by": "Administrator",
"module": "Utilities",
"name": "Address",
diff --git a/erpnext/utilities/doctype/address/address.py b/erpnext/utilities/doctype/address/address.py
index 2952531f01..2c84a9df55 100644
--- a/erpnext/utilities/doctype/address/address.py
+++ b/erpnext/utilities/doctype/address/address.py
@@ -19,7 +19,7 @@ class Address(Document):
def autoname(self):
if not self.address_title:
self.address_title = self.customer \
- or self.supplier or self.sales_partner or self.lead
+ or self.supplier or self.sales_partner or self.lead or self.organisation
if self.address_title:
self.name = (cstr(self.address_title).strip() + "-" + cstr(self.address_type).strip())
@@ -30,7 +30,7 @@ class Address(Document):
throw(_("Address Title is mandatory."))
def validate(self):
- self.link_fields = ("customer", "supplier", "sales_partner", "lead")
+ self.link_fields = ("customer", "supplier", "sales_partner", "lead", "organisation")
self.link_address()
self.validate_primary_address()
self.validate_shipping_address()
@@ -83,7 +83,7 @@ class Address(Document):
frappe.throw(_("Remove reference of customer, supplier, sales partner and lead, as it is your company address"))
def _unset_other(self, is_address_type):
- for fieldname in ["customer", "supplier", "sales_partner", "lead"]:
+ for fieldname in ["customer", "supplier", "sales_partner", "lead", "organisation"]:
if self.get(fieldname):
frappe.db.sql("""update `tabAddress` set `%s`=0 where `%s`=%s and name!=%s""" %
(is_address_type, fieldname, "%s", "%s"), (self.get(fieldname), self.name))
diff --git a/erpnext/utilities/doctype/contact/__init__.py b/erpnext/utilities/doctype/contact/__init__.py
index baffc48825..e4075fda8e 100644
--- a/erpnext/utilities/doctype/contact/__init__.py
+++ b/erpnext/utilities/doctype/contact/__init__.py
@@ -1 +1,39 @@
from __future__ import unicode_literals
+import frappe
+
+def match_email_to_contact(doc,method=None):
+ if doc.communication_type == "Communication":
+ origin_contact = frappe.db.sql(
+ "select name, email_id, supplier, supplier_name, customer, customer_name, user, organisation from `tabContact` where email_id <>''",
+ as_dict=1)
+ for comm in origin_contact:
+ if comm.email_id:
+ if (doc.sender and doc.sent_or_received == "Received" and doc.sender.find(comm.email_id) > -1) or (
+ doc.recipients and doc.sent_or_received == "Sent" and doc.recipients.find(
+ comm.email_id) > -1):
+ if sum(1 for x in [comm.supplier, comm.customer, comm.user, comm.organisation] if x) > 1:
+ doc.db_set("timeline_doctype", "Contact")
+ doc.db_set("timeline_name", comm.name)
+ doc.db_set("timeline_label", doc.name)
+
+ elif comm.supplier:
+ doc.db_set("timeline_doctype", "Supplier")
+ doc.db_set("timeline_name", comm.supplier)
+ doc.db_set("timeline_label", comm.supplier_name)
+
+ elif comm.customer:
+ doc.db_set("timeline_doctype", "Customer")
+ doc.db_set("timeline_name", comm.customer)
+ doc.db_set("timeline_label", comm.customer_name)
+ elif comm.user:
+ doc.db_set("timeline_doctype", "User")
+ doc.db_set("timeline_name", comm.user)
+ doc.db_set("timeline_label", comm.user)
+ elif comm.organisation:
+ doc.db_set("timeline_doctype", "Organisation")
+ doc.db_set("timeline_name", comm.organisation)
+ doc.db_set("timeline_label", comm.organisation)
+ else:
+ doc.db_set("timeline_doctype", None)
+ doc.db_set("timeline_name", None)
+ doc.db_set("timeline_label", None)
diff --git a/erpnext/utilities/doctype/contact/contact.js b/erpnext/utilities/doctype/contact/contact.js
index 07d9d6f90b..db25e99dea 100644
--- a/erpnext/utilities/doctype/contact/contact.js
+++ b/erpnext/utilities/doctype/contact/contact.js
@@ -5,6 +5,21 @@
cur_frm.email_field = "email_id";
frappe.ui.form.on("Contact", {
+ onload:function(frm){
+ if(frappe.route_titles["update_contact"])
+ {
+ frappe.confirm("change email address from "+cur_frm.doc.email_id+ " to "+frappe.route_titles["update_contact"]["email_id"]
+ ,function(){
+ cur_frm.doc.email_id = frappe.route_titles["update_contact"]["email_id"];
+ cur_frm.refresh();
+ cur_frm.dirty();
+ delete frappe.route_titles["update_contact"];
+ },function(){
+ delete frappe.route_titles["update_contact"];
+ })
+
+ }
+ },
refresh: function(frm) {
if(!frm.doc.user && !frm.is_new() && frm.perm[0].write) {
frm.add_custom_button(__("Invite as User"), function() {
@@ -27,5 +42,24 @@ frappe.ui.form.on("Contact", {
if(name && locals[doctype] && locals[doctype][name])
frappe.model.remove_from_locals(doctype, name);
});
+ var fieldlist = ["supplier","customer","user","organisation"]
+ if(frappe.route_titles["create_contact"]==1&&!($.map(fieldlist,function(v){return frm.doc[v]?true:false}).indexOf(true)!=-1)){
+ $.each(fieldlist,function(i,v){
+ cur_frm.set_df_property(v,"reqd",1);
+ })
+
+ } else {
+ $.each(fieldlist,function(i,v){
+ cur_frm.set_df_property(v,"reqd",0);
+ })
+ }
+ },
+ after_save:function(frm){
+ if (frappe.route_titles["create_contact"])
+ {
+ delete frappe.route_titles["create_contact"]
+ frappe.set_route("email_inbox");
+ frappe.pages['email_inbox'].Inbox.run()
+ }
}
-});
+});
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/contact/contact.json b/erpnext/utilities/doctype/contact/contact.json
index 98061da23c..21046b7f57 100644
--- a/erpnext/utilities/doctype/contact/contact.json
+++ b/erpnext/utilities/doctype/contact/contact.json
@@ -469,6 +469,35 @@
"set_only_once": 0,
"unique": 0
},
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "organisation",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Organisation",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Organisation",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
{
"allow_on_submit": 0,
"bold": 0,
@@ -653,7 +682,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-11-07 05:30:56.576752",
+ "modified": "2016-12-22 13:46:02.655141",
"modified_by": "Administrator",
"module": "Utilities",
"name": "Contact",
diff --git a/erpnext/utilities/doctype/contact/contact.py b/erpnext/utilities/doctype/contact/contact.py
index be0f9858e9..03eb94cab1 100644
--- a/erpnext/utilities/doctype/contact/contact.py
+++ b/erpnext/utilities/doctype/contact/contact.py
@@ -15,7 +15,7 @@ class Contact(StatusUpdater):
[cstr(self.get(f)).strip() for f in ["first_name", "last_name"]]))
# concat party name if reqd
- for fieldname in ("customer", "supplier", "sales_partner"):
+ for fieldname in ("customer", "supplier", "sales_partner", "organisation"):
if self.get(fieldname):
self.name = self.name + "-" + cstr(self.get(fieldname)).strip()
break
@@ -26,6 +26,7 @@ class Contact(StatusUpdater):
self.set_user()
if self.email_id:
self.image = has_gravatar(self.email_id)
+ self.contact_update_communication_ref()
def set_user(self):
if not self.user and self.email_id:
@@ -61,6 +62,88 @@ class Contact(StatusUpdater):
frappe.db.sql("""update `tabIssue` set contact='' where contact=%s""",
self.name)
+ def contact_update_communication_ref(self):
+ origin_communication = frappe.db.sql("select name, sender,recipients,sent_or_received from `tabCommunication`",
+ as_dict=1)
+
+ if self.email_id:
+ self.email_id = self.email_id.lower()
+ comm = frappe._dict({"email_id": self.email_id,
+ "name": self.name,
+ "supplier": self.supplier,
+ "supplier_name": self.supplier_name,
+ "customer": self.customer,
+ "customer_name": self.customer_name,
+ "user": self.user,
+ "organisation": self.organisation
+ })
+ for communication in origin_communication:
+ sender = communication.sender
+ recipients = communication.recipients
+ if comm.email_id:
+ if (sender and communication.sent_or_received == "Received" and sender.find(
+ comm.email_id) > -1) or (
+ recipients and communication.sent_or_received == "Sent" and recipients.find(
+ comm.email_id) > -1):
+ if sum(1 for x in [comm.supplier, comm.customer, comm.user, comm.organisation] if x) > 1:
+ frappe.db.sql("""update `tabCommunication`
+ set timeline_doctype = %(timeline_doctype)s,
+ timeline_name = %(timeline_name)s,
+ timeline_label = %(timeline_label)s
+ where name = %(name)s""", {
+ "timeline_doctype": "Contact",
+ "timeline_name": comm.name,
+ "timeline_label": self.name,
+ "name": communication.name
+ })
+
+ elif comm.supplier:
+ frappe.db.sql("""update `tabCommunication`
+ set timeline_doctype = %(timeline_doctype)s,
+ timeline_name = %(timeline_name)s,
+ timeline_label = %(timeline_label)s
+ where name = %(name)s""", {
+ "timeline_doctype": "Supplier",
+ "timeline_name": comm.supplier,
+ "timeline_label": comm.supplier_name,
+ "name": communication.name
+ })
+
+ elif comm.customer:
+
+ frappe.db.sql("""update `tabCommunication`
+ set timeline_doctype = %(timeline_doctype)s,
+ timeline_name = %(timeline_name)s,
+ timeline_label = %(timeline_label)s
+ where name = %(name)s""", {
+ "timeline_doctype": "Customer",
+ "timeline_name": comm.customer,
+ "timeline_label": comm.customer_name,
+ "name": communication.name
+ })
+ elif comm.user:
+ frappe.db.sql("""update `tabCommunication`
+ set timeline_doctype = %(timeline_doctype)s,
+ timeline_name = %(timeline_name)s,
+ timeline_label = %(timeline_label)s
+ where name = %(name)s""", {
+ "timeline_doctype": "User",
+ "timeline_name": comm.user,
+ "timeline_label": comm.user,
+ "name": communication.name
+ })
+ elif comm.organisation:
+ frappe.db.sql("""update `tabCommunication`
+ set timeline_doctype = %(timeline_doctype)s,
+ timeline_name = %(timeline_name)s,
+ timeline_label = %(timeline_label)s
+ where name = %(name)s""", {
+ "timeline_doctype": "Organisation",
+ "timeline_name": comm.organisation,
+ "timeline_label": comm.organisation,
+ "name": communication.name
+ })
+
@frappe.whitelist()
def invite_user(contact):
contact = frappe.get_doc("Contact", contact)
diff --git a/erpnext/utilities/doctype/organisation/__init__.py b/erpnext/utilities/doctype/organisation/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/utilities/doctype/organisation/organisation.js b/erpnext/utilities/doctype/organisation/organisation.js
new file mode 100644
index 0000000000..2d3bb31bea
--- /dev/null
+++ b/erpnext/utilities/doctype/organisation/organisation.js
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Organisation', {
+ refresh: function(frm) {
+ frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
+
+ if(!frm.doc.__islocal) {
+ erpnext.utils.render_address_and_contact(frm);
+ } else {
+ erpnext.utils.clear_address_and_contact(frm);
+ }
+ }
+});
diff --git a/erpnext/utilities/doctype/organisation/organisation.json b/erpnext/utilities/doctype/organisation/organisation.json
new file mode 100644
index 0000000000..9cbcc90cf9
--- /dev/null
+++ b/erpnext/utilities/doctype/organisation/organisation.json
@@ -0,0 +1,199 @@
+{
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:organisation_name",
+ "beta": 0,
+ "creation": "2016-08-22 11:08:27.151412",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 0,
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "organisation_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "address_contacts",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Address and Contact",
+ "length": 0,
+ "no_copy": 0,
+ "options": "icon-map-marker",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "address_html",
+ "fieldtype": "HTML",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Address HTML",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 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,
+ "columns": 0,
+ "fieldname": "contact_html",
+ "fieldtype": "HTML",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Contact HTML",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "HTML",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2016-12-23 08:33:29.997375",
+ "modified_by": "Administrator",
+ "module": "Utilities",
+ "name": "Organisation",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 1,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Email User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/organisation/organisation.py b/erpnext/utilities/doctype/organisation/organisation.py
new file mode 100644
index 0000000000..d04f226ea1
--- /dev/null
+++ b/erpnext/utilities/doctype/organisation/organisation.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from erpnext.utilities.address_and_contact import load_address_and_contact
+
+class Organisation(Document):
+ def onload(self):
+ """Load address and contacts in `__onload`"""
+ load_address_and_contact(self, "organisation")
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/organisation/test_organisation.py b/erpnext/utilities/doctype/organisation/test_organisation.py
new file mode 100644
index 0000000000..499c63acbb
--- /dev/null
+++ b/erpnext/utilities/doctype/organisation/test_organisation.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+# test_records = frappe.get_test_records('Organisation')
+
+class TestOrganisation(unittest.TestCase):
+ pass