Merge pull request #7571 from RicardoJohann/projectfilter
added project filter to gl and carry project filter from P&L
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 67d9a35..20f5e54 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
import frappe
-__version__ = '7.2.14'
+__version__ = '7.2.17'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index 720a1dc..c03ccc8 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -21,20 +21,12 @@
if(this.frm.get_field('shipping_address')) {
this.frm.set_query("shipping_address", function(){
if(me.frm.doc.customer){
- return{
- filters:{
- "customer": me.frm.doc.customer
- }
- }
- }
- else{
- return{
- filters:{
- "is_your_company_address": 1,
- "company": me.frm.doc.company
- }
- }
- }
+ return {
+ query: 'frappe.geo.doctype.address.address.address_query',
+ filters: { link_doctype: 'Customer', link_name: me.frm.doc.customer }
+ };
+ } else
+ return erpnext.queries.company_address_query(me.frm.doc)
});
}
},
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index ce6f451..7e5e045 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -26,11 +26,11 @@
if(frm.doc.__islocal){
hide_field(['address_html','contact_html']);
- erpnext.utils.clear_address_and_contact(frm);
+ frappe.geo.clear_address_and_contact(frm);
}
else {
unhide_field(['address_html','contact_html']);
- erpnext.utils.render_address_and_contact(frm);
+ frappe.geo.render_address_and_contact(frm);
// custom buttons
frm.add_custom_button(__('Accounting Ledger'), function() {
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index 9eaaad1..7f92767 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -6,7 +6,7 @@
import frappe.defaults
from frappe import msgprint, _
from frappe.model.naming import make_autoname
-from erpnext.utilities.address_and_contact import (load_address_and_contact,
+from frappe.geo.address_and_contact import (load_address_and_contact,
delete_contact_and_address)
from erpnext.utilities.transaction_base import TransactionBase
@@ -61,14 +61,6 @@
validate_party_accounts(self)
self.status = get_party_status(self)
- def get_contacts(self,nm):
- if nm:
- contact_details =frappe.db.convert_to_lists(frappe.db.sql("select name, CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,'')),contact_no,email_id from `tabContact` where supplier = %s", nm))
-
- return contact_details
- else:
- return ''
-
def on_trash(self):
delete_contact_and_address('Supplier', self.name)
diff --git a/erpnext/buying/report/supplier_addresses_and_contacts/__init__.py b/erpnext/buying/report/supplier_addresses_and_contacts/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/buying/report/supplier_addresses_and_contacts/__init__.py
+++ /dev/null
diff --git a/erpnext/buying/report/supplier_addresses_and_contacts/supplier_addresses_and_contacts.json b/erpnext/buying/report/supplier_addresses_and_contacts/supplier_addresses_and_contacts.json
deleted file mode 100644
index 128548f..0000000
--- a/erpnext/buying/report/supplier_addresses_and_contacts/supplier_addresses_and_contacts.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "apply_user_permissions": 1,
- "creation": "2013-10-09 10:38:40",
- "docstatus": 0,
- "doctype": "Report",
- "idx": 1,
- "is_standard": "Yes",
- "modified": "2014-09-11 08:53:17.358554",
- "modified_by": "Administrator",
- "module": "Buying",
- "name": "Supplier Addresses and Contacts",
- "owner": "Administrator",
- "query": "SELECT\n `tabSupplier`.name as \"Supplier:Link/Supplier:120\",\n\t`tabSupplier`.supplier_name as \"Supplier Name::120\",\n\t`tabSupplier`.supplier_type as \"Supplier Type:Link/Supplier Type:120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2), \n\t\ttabAddress.state, tabAddress.pincode, tabAddress.country\n\t) as 'Address::180',\n concat_ws(', ', `tabContact`.first_name, `tabContact`.last_name) as \"Contact Name::180\",\n\t`tabContact`.phone as \"Phone\",\n\t`tabContact`.mobile_no as \"Mobile No\",\n\t`tabContact`.email_id as \"Email Address::120\",\n\t`tabContact`.is_primary_contact as \"Is Primary Contact::120\"\nFROM\n\t`tabSupplier`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.supplier=`tabSupplier`.name\n\t)\n\tleft join `tabContact` on (\n\t\t`tabContact`.supplier=`tabSupplier`.name\n\t)\nWHERE\n\t`tabSupplier`.docstatus<2\nORDER BY\n\t`tabSupplier`.name asc",
- "ref_doctype": "Supplier",
- "report_name": "Supplier Addresses and Contacts",
- "report_type": "Query Report"
-}
\ No newline at end of file
diff --git a/erpnext/config/buying.py b/erpnext/config/buying.py
index e246266..990ca7a 100644
--- a/erpnext/config/buying.py
+++ b/erpnext/config/buying.py
@@ -172,8 +172,12 @@
{
"type": "report",
"is_query_report": True,
- "name": "Supplier Addresses and Contacts",
- "doctype": "Supplier"
+ "name": "Addresses And Contacts",
+ "label": "Supplier Addresses And Contacts",
+ "doctype": "Address",
+ "route_options": {
+ "party_type": "Supplier"
+ }
},
]
},
diff --git a/erpnext/config/selling.py b/erpnext/config/selling.py
index c406d09..bbae245 100644
--- a/erpnext/config/selling.py
+++ b/erpnext/config/selling.py
@@ -120,6 +120,16 @@
{
"type": "report",
"is_query_report": True,
+ "name": "Addresses And Contacts",
+ "label": "Sales Partner Addresses And Contacts",
+ "doctype": "Address",
+ "route_options": {
+ "party_type": "Sales Partner"
+ }
+ },
+ {
+ "type": "report",
+ "is_query_report": True,
"name": "Territory Target Variance (Item Group-Wise)",
"route": "query-report/Territory Target Variance Item Group-Wise",
"doctype": "Territory"
@@ -215,8 +225,12 @@
{
"type": "report",
"is_query_report": True,
- "name": "Customer Addresses And Contacts",
- "doctype": "Contact"
+ "name": "Addresses And Contacts",
+ "label": "Customer Addresses And Contacts",
+ "doctype": "Address",
+ "route_options": {
+ "party_type": "Customer"
+ }
},
{
"type": "report",
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 5ecab8d..032fd66 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -9,6 +9,7 @@
from erpnext.accounts.utils import get_fiscal_year
from erpnext.accounts.general_ledger import make_gl_entries, delete_gl_entries, process_gl_map
from erpnext.controllers.accounts_controller import AccountsController
+from erpnext.stock.stock_ledger import get_valuation_rate
class StockController(AccountsController):
def validate(self):
@@ -54,6 +55,7 @@
self.check_expense_account(item_row)
if not sle.stock_value_difference:
+ self.update_stock_ledger_entries(sle)
self.validate_negative_stock(sle)
gl_list.append(self.get_gl_dict({
@@ -86,6 +88,14 @@
return process_gl_map(gl_list)
+ def update_stock_ledger_entries(self, sle):
+ sle.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse,
+ sle.voucher_type, sle.voucher_no)
+ sle.stock_value = flt(sle.qty_after_transaction) * flt(sle.valuation_rate)
+ sle.stock_value_difference = sle.stock_value
+ sle.doctype="Stock Ledger Entry"
+ frappe.get_doc(sle).db_update()
+
def validate_negative_stock(self, sle):
if sle.qty_after_transaction < 0 and sle.actual_qty < 0:
frappe.throw(_("Valuation rate not found for the Item {0}, which is required to do accounting entries (for booking expenses). Please create an incoming stock transaction or mention valuation rate in Item record, and then try submiting {1} {2}")
diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js
index be3cd82..7e22125 100644
--- a/erpnext/crm/doctype/lead/lead.js
+++ b/erpnext/crm/doctype/lead/lead.js
@@ -25,6 +25,7 @@
refresh: function() {
var doc = this.frm.doc;
erpnext.toggle_naming_series();
+ frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'name', doctype: 'Lead'}
if(!this.frm.doc.__islocal && this.frm.doc.__onload && !this.frm.doc.__onload.is_customer) {
this.frm.add_custom_button(__("Customer"), this.create_customer, __("Make"));
@@ -34,9 +35,9 @@
}
if(!this.frm.doc.__islocal) {
- erpnext.utils.render_address_and_contact(cur_frm);
+ frappe.geo.render_address_and_contact(cur_frm);
} else {
- erpnext.utils.clear_address_and_contact(cur_frm);
+ frappe.geo.clear_address_and_contact(cur_frm);
}
},
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 4b2899d..411f597 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -8,7 +8,7 @@
from frappe.model.mapper import get_mapped_doc
from erpnext.controllers.selling_controller import SellingController
-from erpnext.utilities.address_and_contact import load_address_and_contact
+from frappe.geo.address_and_contact import load_address_and_contact
from erpnext.accounts.party import set_taxes
sender_field = "email_id"
@@ -127,7 +127,7 @@
@frappe.whitelist()
def make_opportunity(source_name, target_doc=None):
- target_doc = get_mapped_doc("Lead", source_name,
+ target_doc = get_mapped_doc("Lead", source_name,
{"Lead": {
"doctype": "Opportunity",
"field_map": {
diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js
index 32171b0..b5e195c 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.js
+++ b/erpnext/crm/doctype/opportunity/opportunity.js
@@ -30,7 +30,7 @@
frm.events.enquiry_from(frm);
frm.trigger('set_contact_link');
- if(doc.status!=="Lost") {
+ if(!doc.__islocal && doc.status!=="Lost") {
if(doc.with_items){
frm.add_custom_button(__('Supplier Quotation'),
function() {
@@ -121,7 +121,7 @@
erpnext.toggle_naming_series();
var frm = cur_frm;
- if(frm.perm[0].write && doc.docstatus==0) {
+ if(!doc.__islocal && frm.perm[0].write && doc.docstatus==0) {
if(frm.doc.status==="Open") {
frm.add_custom_button(__("Close"), function() {
frm.set_value("status", "Closed");
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 4bb6765..301dc82 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -106,30 +106,6 @@
lead_name, company_name = frappe.db.get_value("Lead", self.lead, ["lead_name", "company_name"])
self.customer_name = company_name or lead_name
- def get_cust_address(self,name):
- details = frappe.db.sql("""select customer_name, address, territory, customer_group
- from `tabCustomer` where name = %s and docstatus != 2""", (name), as_dict = 1)
- if details:
- ret = {
- 'customer_name': details and details[0]['customer_name'] or '',
- 'address' : details and details[0]['address'] or '',
- 'territory' : details and details[0]['territory'] or '',
- 'customer_group' : details and details[0]['customer_group'] or ''
- }
- # ********** get primary contact details (this is done separately coz. , in case there is no primary contact thn it would not be able to fetch customer details in case of join query)
-
- contact_det = frappe.db.sql("""select contact_name, contact_no, email_id
- from `tabContact` where customer = %s and is_customer = 1
- and is_primary_contact = 'Yes' and docstatus != 2""", name, as_dict = 1)
-
- ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
- ret['contact_no'] = contact_det and contact_det[0]['contact_no'] or ''
- ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''
-
- return ret
- else:
- frappe.throw(_("Customer {0} does not exist").format(name), frappe.DoesNotExistError)
-
def on_update(self):
self.add_calendar_event()
diff --git a/erpnext/docs/assets/old_images/erpnext/calender-email-digest.png b/erpnext/docs/assets/old_images/erpnext/calender-email-digest.png
new file mode 100644
index 0000000..1d95ef4
--- /dev/null
+++ b/erpnext/docs/assets/old_images/erpnext/calender-email-digest.png
Binary files differ
diff --git a/erpnext/docs/assets/old_images/erpnext/calender-event-lead.png b/erpnext/docs/assets/old_images/erpnext/calender-event-lead.png
new file mode 100644
index 0000000..dc6eb8b
--- /dev/null
+++ b/erpnext/docs/assets/old_images/erpnext/calender-event-lead.png
Binary files differ
diff --git a/erpnext/docs/assets/old_images/erpnext/calender-event-manually.png b/erpnext/docs/assets/old_images/erpnext/calender-event-manually.png
new file mode 100644
index 0000000..84cb343
--- /dev/null
+++ b/erpnext/docs/assets/old_images/erpnext/calender-event-manually.png
Binary files differ
diff --git a/erpnext/docs/assets/old_images/erpnext/calender-event-notification.png b/erpnext/docs/assets/old_images/erpnext/calender-event-notification.png
new file mode 100644
index 0000000..fa1e4ff
--- /dev/null
+++ b/erpnext/docs/assets/old_images/erpnext/calender-event-notification.png
Binary files differ
diff --git a/erpnext/docs/assets/old_images/erpnext/calender-event-permission.png b/erpnext/docs/assets/old_images/erpnext/calender-event-permission.png
new file mode 100644
index 0000000..783f968
--- /dev/null
+++ b/erpnext/docs/assets/old_images/erpnext/calender-event-permission.png
Binary files differ
diff --git a/erpnext/docs/assets/old_images/erpnext/calender-event-recurring.png b/erpnext/docs/assets/old_images/erpnext/calender-event-recurring.png
new file mode 100644
index 0000000..6147cf5
--- /dev/null
+++ b/erpnext/docs/assets/old_images/erpnext/calender-event-recurring.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/using-erpnext/calendar.md b/erpnext/docs/user/manual/en/using-erpnext/calendar.md
index 1ad325b..5e0ae29 100644
--- a/erpnext/docs/user/manual/en/using-erpnext/calendar.md
+++ b/erpnext/docs/user/manual/en/using-erpnext/calendar.md
@@ -34,7 +34,7 @@
###Permission for Event
-You can set Event as Private or Public. Private Events will be visible only to you, and if any other user selected in the participants table. Instead of User, you can also assign permission for event based on Role.
+You can set Event as Private or Public. Private Events will be visible only to you, and you can also assign permission for event based on Role in the participants table.
Public Event, like Birthday will be visible to all.
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 8443cdf..dac7c6b 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -126,16 +126,6 @@
"Discussion": "erpnext.schools.web_form.discussion.discussion.has_website_permission"
}
-permission_query_conditions = {
- "Contact": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_contact",
- "Address": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_address"
-}
-
-has_permission = {
- "Contact": "erpnext.utilities.address_and_contact.has_permission",
- "Address": "erpnext.utilities.address_and_contact.has_permission"
-}
-
dump_report_map = "erpnext.startup.report_data_map.data_map"
before_tests = "erpnext.setup.utils.before_tests"
@@ -153,7 +143,7 @@
"after_insert": "frappe.email.doctype.contact.contact.update_contact",
"validate": "erpnext.hr.doctype.employee.employee.validate_employee_role",
"on_update": "erpnext.hr.doctype.employee.employee.update_user_permissions",
- "on_update": "erpnext.utilities.address_and_contact.set_default_role"
+ "on_update": "frappe.geo.address_and_contact.set_default_role"
},
("Sales Taxes and Charges Template", 'Price List'): {
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
index 7f1c442..8105e1a 100644
--- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
+++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
@@ -30,28 +30,31 @@
return columns
def get_data(filters, leave_types):
-
+ user = frappe.session.user
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
active_employees = frappe.get_all("Employee",
filters = { "status": "Active", "company": filters.company},
- fields = ["name", "employee_name", "department"])
+ fields = ["name", "employee_name", "department", "user_id"])
data = []
for employee in active_employees:
- row = [employee.name, employee.employee_name, employee.department]
+ leave_approvers = [l.leave_approver for l in frappe.db.sql("""select leave_approver from `tabEmployee Leave Approver` where parent = %s""",
+ (employee.name),as_dict=True)]
+ if (len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) or ("HR Manager" in frappe.get_roles(user)):
+ row = [employee.name, employee.employee_name, employee.department]
- for leave_type in leave_types:
- # leaves taken
- leaves_taken = get_approved_leaves_for_period(employee.name, leave_type,
- filters.from_date, filters.to_date)
+ for leave_type in leave_types:
+ # leaves taken
+ leaves_taken = get_approved_leaves_for_period(employee.name, leave_type,
+ filters.from_date, filters.to_date)
- # closing balance
- closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
- allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
+ # closing balance
+ closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
+ allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
- row += [leaves_taken, closing]
+ row += [leaves_taken, closing]
- data.append(row)
+ data.append(row)
return data
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 9e37081..87c070e 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -367,3 +367,5 @@
erpnext.patches.v7_2.contact_address_links
erpnext.patches.v7_2.mark_students_active
erpnext.patches.v7_2.set_null_value_to_fields
+erpnext.patches.v7_2.update_guardian_name_in_student_master
+erpnext.patches.v7_2.update_abbr_in_salary_slips
diff --git a/erpnext/patches/v7_2/update_abbr_in_salary_slips.py b/erpnext/patches/v7_2/update_abbr_in_salary_slips.py
new file mode 100644
index 0000000..aa6965f
--- /dev/null
+++ b/erpnext/patches/v7_2/update_abbr_in_salary_slips.py
@@ -0,0 +1,13 @@
+import frappe
+
+def execute():
+ frappe.reload_doctype('Salary Slip')
+ if not frappe.db.has_column('Salary Detail', 'abbr'):
+ return
+
+ salary_details = frappe.db.sql("""select abbr, salary_component, name from `tabSalary Detail`
+ where abbr is null or abbr = ''""", as_dict=True)
+
+ for salary_detail in salary_details:
+ salary_component_abbr = frappe.get_value("Salary Component", salary_detail.salary_component, "salary_component_abbr")
+ frappe.db.sql("""update `tabSalary Detail` set abbr = %s where name = %s""",(salary_component_abbr, salary_detail.name))
\ No newline at end of file
diff --git a/erpnext/patches/v7_2/update_guardian_name_in_student_master.py b/erpnext/patches/v7_2/update_guardian_name_in_student_master.py
new file mode 100644
index 0000000..6ac4073
--- /dev/null
+++ b/erpnext/patches/v7_2/update_guardian_name_in_student_master.py
@@ -0,0 +1,9 @@
+import frappe
+from frappe.model.utils.rename_field import rename_field
+
+def execute():
+ frappe.reload_doc("schools", "doctype", "student_guardian")
+ student_guardians = frappe.get_all("Student Guardian", fields=["guardian"])
+ for student_guardian in student_guardians:
+ guardian_name = frappe.db.get_value("Guardian", student_guardian.guardian, "guardian_name")
+ frappe.db.sql("update `tabStudent Guardian` set guardian_name = %s where guardian= %s", (guardian_name, student_guardian.guardian))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index 9cd2aa8..7433222 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -1,7 +1,7 @@
{
"allow_copy": 0,
"allow_import": 1,
- "allow_rename": 0,
+ "allow_rename": 1,
"autoname": "TASK.#####",
"beta": 0,
"creation": "2013-01-29 19:25:50",
@@ -944,7 +944,7 @@
"istable": 0,
"max_attachments": 5,
"menu_index": 0,
- "modified": "2016-11-07 05:12:23.294476",
+ "modified": "2017-01-27 01:26:24.985167",
"modified_by": "Administrator",
"module": "Projects",
"name": "Task",
@@ -960,7 +960,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
- "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -979,5 +978,6 @@
"sort_order": "DESC",
"timeline_field": "project",
"title_field": "subject",
+ "track_changes": 0,
"track_seen": 1
}
\ No newline at end of file
diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js
index 1141f99..1963137 100644
--- a/erpnext/public/js/queries.js
+++ b/erpnext/public/js/queries.js
@@ -68,6 +68,13 @@
}
},
+ company_address_query: function(doc) {
+ return {
+ query: 'frappe.geo.doctype.address.address.address_query',
+ filters: { is_your_company_address: 1, link_doctype: 'Company', link_name: doc.company || '' }
+ };
+ },
+
supplier_filter: function(doc) {
if(!doc.supplier) {
frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype, "supplier", doc.name))));
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 74e9fb6..551ea51 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -82,32 +82,6 @@
$.extend(erpnext.utils, {
- clear_address_and_contact: function(frm) {
- $(frm.fields_dict['address_html'].wrapper).html("");
- frm.fields_dict['contact_html'] && $(frm.fields_dict['contact_html'].wrapper).html("");
- },
-
- render_address_and_contact: function(frm) {
- // render address
- $(frm.fields_dict['address_html'].wrapper)
- .html(frappe.render_template("address_list",
- cur_frm.doc.__onload))
- .find(".btn-address").on("click", function() {
- frappe.new_doc("Address");
- });
-
- // render contact
- if(frm.fields_dict['contact_html']) {
- $(frm.fields_dict['contact_html'].wrapper)
- .html(frappe.render_template("contact_list",
- cur_frm.doc.__onload))
- .find(".btn-contact").on("click", function() {
- frappe.new_doc("Contact");
- }
- );
- }
- },
-
set_party_dashboard_indicators: function(frm) {
if(frm.doc.__onload && frm.doc.__onload.dashboard_info) {
var info = frm.doc.__onload.dashboard_info;
diff --git a/erpnext/schools/doctype/student/student.js b/erpnext/schools/doctype/student/student.js
index e69de29..10fefae 100644
--- a/erpnext/schools/doctype/student/student.js
+++ b/erpnext/schools/doctype/student/student.js
@@ -0,0 +1 @@
+cur_frm.add_fetch("guardian", "guardian_name", "guardian_name");
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student/student.json b/erpnext/schools/doctype/student/student.json
index edaae07..50efdc1 100644
--- a/erpnext/schools/doctype/student/student.json
+++ b/erpnext/schools/doctype/student/student.json
@@ -472,6 +472,63 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "section_break_18",
+ "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": "Guardian Details",
+ "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,
+ "fieldname": "guardians",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Guardians",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Student Guardian",
+ "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,
"fieldname": "section_break_22",
"fieldtype": "Section Break",
"hidden": 0,
@@ -667,63 +724,6 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
- "fieldname": "section_break_18",
- "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": "Guardian Details",
- "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,
- "fieldname": "guardians",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Guardians",
- "length": 0,
- "no_copy": 0,
- "options": "Student Guardian",
- "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": 1,
- "columns": 0,
"fieldname": "section_break_20",
"fieldtype": "Section Break",
"hidden": 0,
@@ -819,7 +819,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-12-01 12:55:32.453131",
+ "modified": "2017-01-27 13:19:55.693540",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student",
@@ -836,7 +836,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
- "is_custom": 0,
"permlevel": 0,
"print": 0,
"read": 1,
@@ -857,7 +856,6 @@
"export": 1,
"if_owner": 0,
"import": 0,
- "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -875,5 +873,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.json b/erpnext/schools/doctype/student_applicant/student_applicant.json
index 2c6947c..beb5314 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.json
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.json
@@ -988,7 +988,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-11-17 10:26:13.225135",
+ "modified": "2017-01-27 13:19:56.616331",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student Applicant",
@@ -1005,7 +1005,6 @@
"export": 1,
"if_owner": 0,
"import": 1,
- "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -1023,5 +1022,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_batch_student/student_batch_student.json b/erpnext/schools/doctype/student_batch_student/student_batch_student.json
index 5933f9e..558281b 100644
--- a/erpnext/schools/doctype/student_batch_student/student_batch_student.json
+++ b/erpnext/schools/doctype/student_batch_student/student_batch_student.json
@@ -44,35 +44,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "1",
- "fieldname": "active",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Active",
- "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,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -123,6 +94,35 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "active",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Active",
+ "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
}
],
"hide_heading": 0,
@@ -135,8 +135,8 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-01-20 18:26:51.242924",
- "modified_by": "neil@frappe.io",
+ "modified": "2017-01-27 14:47:21.125366",
+ "modified_by": "Administrator",
"module": "Schools",
"name": "Student Batch Student",
"name_case": "",
diff --git a/erpnext/schools/doctype/student_group/student_group.json b/erpnext/schools/doctype/student_group/student_group.json
index 9e44f51..01e161e 100644
--- a/erpnext/schools/doctype/student_group/student_group.json
+++ b/erpnext/schools/doctype/student_group/student_group.json
@@ -216,7 +216,7 @@
{
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 1,
+ "collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"fieldname": "section_break_6",
@@ -311,7 +311,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-12-01 12:57:17.125085",
+ "modified": "2017-01-27 14:50:36.107270",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student Group",
@@ -328,7 +328,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
- "is_custom": 0,
"permlevel": 0,
"print": 0,
"read": 1,
@@ -349,7 +348,6 @@
"export": 1,
"if_owner": 0,
"import": 0,
- "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -368,5 +366,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_group_student/student_group_student.json b/erpnext/schools/doctype/student_group_student/student_group_student.json
index df49ba8..5ca7b66 100644
--- a/erpnext/schools/doctype/student_group_student/student_group_student.json
+++ b/erpnext/schools/doctype/student_group_student/student_group_student.json
@@ -44,35 +44,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "1",
- "fieldname": "active",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Active",
- "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,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -122,6 +93,35 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "active",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Active",
+ "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
}
],
"hide_heading": 0,
@@ -134,8 +134,8 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-01-20 19:11:16.837202",
- "modified_by": "neil@frappe.io",
+ "modified": "2017-01-27 14:49:54.533005",
+ "modified_by": "Administrator",
"module": "Schools",
"name": "Student Group Student",
"name_case": "",
diff --git a/erpnext/schools/doctype/student_guardian/student_guardian.json b/erpnext/schools/doctype/student_guardian/student_guardian.json
index d8e50c9..0a41538 100644
--- a/erpnext/schools/doctype/student_guardian/student_guardian.json
+++ b/erpnext/schools/doctype/student_guardian/student_guardian.json
@@ -22,6 +22,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Guardian",
"length": 0,
"no_copy": 0,
@@ -31,6 +32,35 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "guardian_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Guardian Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@@ -49,6 +79,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Relation",
"length": 0,
"no_copy": 0,
@@ -58,6 +89,7 @@
"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,
@@ -75,7 +107,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-01 14:39:03.576590",
+ "modified": "2017-01-27 13:36:47.177809",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student Guardian",
@@ -87,5 +119,6 @@
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/report/student_batch_wise_attendance/student_batch_wise_attendance.py b/erpnext/schools/report/student_batch_wise_attendance/student_batch_wise_attendance.py
index c112b59..b6bedcb 100644
--- a/erpnext/schools/report/student_batch_wise_attendance/student_batch_wise_attendance.py
+++ b/erpnext/schools/report/student_batch_wise_attendance/student_batch_wise_attendance.py
@@ -53,7 +53,7 @@
def get_student_batch_strength(student_batch):
student_batch_strength = frappe.db.sql("""select count(*) from `tabStudent Batch Student`
- where parent = %s""", student_batch)[0][0]
+ where parent = %s and active=1""", student_batch)[0][0]
return student_batch_strength
def get_student_attendance(student_batch, date):
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 747b31e..540ec28 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -37,7 +37,7 @@
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
if(!frm.doc.__islocal) {
- erpnext.utils.render_address_and_contact(frm);
+ frappe.geo.render_address_and_contact(frm);
// custom buttons
frm.add_custom_button(__('Accounting Ledger'), function() {
@@ -53,7 +53,7 @@
erpnext.utils.set_party_dashboard_indicators(frm);
} else {
- erpnext.utils.clear_address_and_contact(frm);
+ frappe.geo.clear_address_and_contact(frm);
}
var grid = cur_frm.get_field("sales_team").grid;
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index d8011af..e14cde0 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -9,7 +9,7 @@
from frappe.utils import flt, cint, cstr
from frappe.desk.reportview import build_match_conditions
from erpnext.utilities.transaction_base import TransactionBase
-from erpnext.utilities.address_and_contact import load_address_and_contact, delete_contact_and_address
+from frappe.geo.address_and_contact import load_address_and_contact, delete_contact_and_address
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
from erpnext.accounts.party_status import get_party_status
from erpnext import get_default_currency
@@ -95,9 +95,14 @@
def create_lead_address_contact(self):
if self.lead_name:
# assign lead address to customer (if already not set)
- address_name = frappe.get_value('Dynamic Link', dict(parenttype='Address', link_doctype='Lead', link_name=self.name))
- if address_name:
- address = frappe.get_doc('Address', address_name)
+ address_names = frappe.get_all('Dynamic Link', filters={
+ "parenttype":"Address",
+ "link_doctype":"Lead",
+ "link_name":self.lead_name
+ }, fields=["parent as name"])
+
+ for address_name in address_names:
+ address = frappe.get_doc('Address', address_name.get('name'))
if not address.has_link('Customer', self.name):
address.append('links', dict(link_doctype='Customer', link_name=self.name))
address.save()
@@ -105,17 +110,17 @@
lead = frappe.db.get_value("Lead", self.lead_name, ["lead_name", "email_id", "phone", "mobile_no"], as_dict=True)
# create contact from lead
- c = frappe.new_doc('Contact')
- c.first_name = lead.lead_name
- c.email_id = lead.email_id
- c.phone = lead.phone
- c.mobile_no = lead.mobile_no
- c.is_primary_contact = 1
- c.append('links', dict(link_doctype='Customer', link_name=self.name))
- c.flags.ignore_permissions = self.flags.ignore_permissions
- c.autoname()
- if not frappe.db.exists("Contact", c.name):
- c.insert()
+ contact = frappe.new_doc('Contact')
+ contact.first_name = lead.lead_name
+ contact.email_id = lead.email_id
+ contact.phone = lead.phone
+ contact.mobile_no = lead.mobile_no
+ contact.is_primary_contact = 1
+ contact.append('links', dict(link_doctype='Customer', link_name=self.name))
+ contact.flags.ignore_permissions = self.flags.ignore_permissions
+ contact.autoname()
+ if not frappe.db.exists("Contact", contact.name):
+ contact.insert()
def validate_name_with_customer_group(self):
if frappe.db.exists("Customer Group", self.name):
@@ -133,7 +138,7 @@
def on_trash(self):
delete_contact_and_address('Customer', self.name)
if self.lead_name:
- frappe.db.sql("update `tabLead` set status='Interested' where name=%s",self.lead_name)
+ frappe.db.sql("update `tabLead` set status='Interested' where name=%s", self.lead_name)
def after_rename(self, olddn, newdn, merge=False):
if frappe.defaults.get_global_default('cust_master_name') == 'Customer Name':
diff --git a/erpnext/selling/page/sales_funnel/sales_funnel.py b/erpnext/selling/page/sales_funnel/sales_funnel.py
index 4d12efd..3c4d528 100644
--- a/erpnext/selling/page/sales_funnel/sales_funnel.py
+++ b/erpnext/selling/page/sales_funnel/sales_funnel.py
@@ -12,9 +12,9 @@
where (date(`modified`) between %s and %s)
and status != "Do Not Contact" """, (from_date, to_date))[0][0]
- active_leads += frappe.db.sql("""select count(distinct customer) from `tabContact`
- where (date(`modified`) between %s and %s)
- and status != "Passive" """, (from_date, to_date))[0][0]
+ active_leads += frappe.db.sql("""select count(distinct contact.name) from `tabContact` contact
+ left join `tabDynamic Link` dl on (dl.parent=contact.name) where dl.link_doctype='Customer'
+ and (date(contact.modified) between %s and %s) and status != "Passive" """, (from_date, to_date))[0][0]
opportunities = frappe.db.sql("""select count(*) from `tabOpportunity`
where (date(`creation`) between %s and %s)
diff --git a/erpnext/selling/report/customer_addresses_and_contacts/__init__.py b/erpnext/selling/report/customer_addresses_and_contacts/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/selling/report/customer_addresses_and_contacts/__init__.py
+++ /dev/null
diff --git a/erpnext/selling/report/customer_addresses_and_contacts/customer_addresses_and_contacts.json b/erpnext/selling/report/customer_addresses_and_contacts/customer_addresses_and_contacts.json
deleted file mode 100644
index 1f6707b..0000000
--- a/erpnext/selling/report/customer_addresses_and_contacts/customer_addresses_and_contacts.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "add_total_row": 0,
- "apply_user_permissions": 1,
- "creation": "2012-10-04 18:45:27",
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "idx": 1,
- "is_standard": "Yes",
- "modified": "2015-08-24 11:44:00.711112",
- "modified_by": "Administrator",
- "module": "Selling",
- "name": "Customer Addresses And Contacts",
- "owner": "Administrator",
- "query": "SELECT\n\t`tabCustomer`.name as \"Customer ID:Link/Customer\",\n\t`tabCustomer`.customer_name as \"Customer Name\",\n\t`tabCustomer`.customer_group as \"Customer Group:Link/Customer Group\",\n\t`tabAddress`.address_line1 as \"Address Line 1\",\n\t`tabAddress`.address_line2 as \"Address Line 2\",\n\t`tabAddress`.city as \"City\",\n\t`tabAddress`.state as \"State\",\n\t`tabAddress`.pincode as \"Postal Code\",\n\t`tabAddress`.country as \"Country\",\n\t`tabAddress`.is_primary_address as \"Is Primary Address:Check\", \n\t`tabContact`.first_name as \"First Name\",\n\t`tabContact`.last_name as \"Last Name\",\n\t`tabContact`.phone as \"Phone\",\n\t`tabContact`.mobile_no as \"Mobile No\",\n\t`tabContact`.email_id as \"Email Address\",\n\t`tabContact`.is_primary_contact as \"Is Primary Contact:Check\"\nFROM\n\t`tabCustomer`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.customer=`tabCustomer`.name\n\t)\n\tleft join `tabContact` on (\n\t\t`tabContact`.customer=`tabCustomer`.name\n\t)\nWHERE\n\t`tabCustomer`.docstatus<2\nORDER BY\n\t`tabCustomer`.name asc",
- "ref_doctype": "Customer",
- "report_name": "Customer Addresses And Contacts",
- "report_type": "Query Report"
-}
\ No newline at end of file
diff --git a/erpnext/selling/report/lead_details/lead_details.json b/erpnext/selling/report/lead_details/lead_details.json
index 387b5f8..047b4b7 100644
--- a/erpnext/selling/report/lead_details/lead_details.json
+++ b/erpnext/selling/report/lead_details/lead_details.json
@@ -1,16 +1,18 @@
{
+ "add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2013-10-22 11:58:16",
+ "disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
- "modified": "2015-02-02 11:39:57.231750",
+ "modified": "2017-01-19 15:44:59.742195",
"modified_by": "Administrator",
"module": "Selling",
"name": "Lead Details",
"owner": "Administrator",
- "query": "SELECT\n `tabLead`.name as \"Lead Id:Link/Lead:120\",\n `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2)\n\t) as 'Address::180',\n\t`tabAddress`.state as \"State::100\",\n\t`tabAddress`.pincode as \"Pincode::70\",\n\t`tabAddress`.country as \"Country::100\",\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Address::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\",\n `tabLead`.owner as \"Owner:Link/User:120\"\nFROM\n\t`tabLead`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.lead=`tabLead`.name\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc",
+ "query": "SELECT\n `tabLead`.name as \"Lead Id:Link/Lead:120\",\n `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2)\n\t) as 'Address::180',\n\t`tabAddress`.state as \"State::100\",\n\t`tabAddress`.pincode as \"Pincode::70\",\n\t`tabAddress`.country as \"Country::100\",\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Id::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\",\n `tabLead`.owner as \"Owner:Link/User:120\"\nFROM\n\t`tabLead`\n\tleft join `tabDynamic Link` on (\n\t\t`tabDynamic Link`.link_name=`tabLead`.name\n\t)\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.name=`tabDynamic Link`.parent\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc",
"ref_doctype": "Lead",
"report_name": "Lead Details",
"report_type": "Query Report"
diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py
index eb5c043..eef8599 100644
--- a/erpnext/setup/doctype/company/delete_company_transactions.py
+++ b/erpnext/setup/doctype/company/delete_company_transactions.py
@@ -73,11 +73,23 @@
def delete_lead_addresses(company_name):
"""Delete addresses to which leads are linked"""
- for lead in frappe.get_all("Lead", filters={"company": company_name}):
- frappe.db.sql("""delete from `tabAddress`
- where lead=%s and (customer='' or customer is null) and (supplier='' or supplier is null)""", lead.name)
+ leads = frappe.get_all("Lead", filters={"company": company_name})
+ leads = [ "'%s'"%row.get("name") for row in leads ]
+ addresses = []
+ if leads:
+ addresses = frappe.db.sql_list("""select parent from `tabDynamic Link` where link_name
+ in ({leads})""".format(leads=",".join(leads)), debug=True)
+ addresses = ["'%s'"%addr for addr in addresses]
- frappe.db.sql("""update `tabAddress` set lead=null, lead_name=null where lead=%s""", lead.name)
+ frappe.db.sql("""delete from tabAddress where name in ({addresses}) and
+ name not in (select distinct dl1.parent from `tabDynamic Link` dl1
+ inner join `tabDynamic Link` dl2 on dl1.parent=dl2.parent
+ and dl1.link_doctype<>dl2.link_doctype)""".format(addresses=",".join(addresses)), debug=True)
+
+ frappe.db.sql("""delete from `tabDynamic Link` where link_doctype='Lead' and parenttype='Address'
+ and link_name in ({leads})""".format(leads=",".join(leads)), debug=True)
+
+ frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)), debug=True)
def delete_communications(doctype, company_name, company_fieldname):
frappe.db.sql("""
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js
index 1bfba98..84cf749 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.js
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.js
@@ -6,12 +6,12 @@
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'}
if(frm.doc.__islocal){
- hide_field(['address_html', 'contact_html']);
- erpnext.utils.clear_address_and_contact(frm);
+ hide_field(['address_html', 'contact_html', 'address_contacts']);
+ frappe.geo.clear_address_and_contact(frm);
}
else{
- unhide_field(['address_html', 'contact_html']);
- erpnext.utils.render_address_and_contact(frm);
+ unhide_field(['address_html', 'contact_html', 'address_contacts']);
+ frappe.geo.render_address_and_contact(frm);
}
}
});
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.py b/erpnext/setup/doctype/sales_partner/sales_partner.py
index 5a2aa49..96211af 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.py
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.py
@@ -5,7 +5,7 @@
import frappe
from frappe.utils import cstr, filter_strip_join
from frappe.website.website_generator import WebsiteGenerator
-from erpnext.utilities.address_and_contact import load_address_and_contact
+from frappe.geo.address_and_contact import load_address_and_contact
class SalesPartner(WebsiteGenerator):
website = frappe._dict(
@@ -28,15 +28,6 @@
if self.partner_website and not self.partner_website.startswith("http"):
self.partner_website = "http://" + self.partner_website
- def get_contacts(self, nm):
- if nm:
- return frappe.db.convert_to_lists(frappe.db.sql("""
- select name, CONCAT(IFNULL(first_name,''),
- ' ',IFNULL(last_name,'')),contact_no,email_id
- from `tabContact` where sales_partner = %s""", nm))
- else:
- return ''
-
def get_context(self, context):
address = frappe.db.get_value("Address",
{"sales_partner": self.name, "is_primary_address": 1},
diff --git a/erpnext/utilities/address_and_contact.py b/erpnext/utilities/address_and_contact.py
deleted file mode 100644
index 12ceb5b..0000000
--- a/erpnext/utilities/address_and_contact.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-def load_address_and_contact(doc, key):
- """Loads address list and contact list in `__onload`"""
- from frappe.geo.doctype.address.address import get_address_display
-
- address_list = [frappe.get_value('Address', a.parent, '*')
- for a in frappe.get_all('Dynamic Link', fields='parent',
- filters=dict(parenttype='Address', link_doctype=doc.doctype, link_name=doc.name))]
-
- address_list = [a.update({"display": get_address_display(a)})
- for a in address_list]
-
- address_list = sorted(address_list,
- lambda a, b:
- (int(a.is_primary_address - b.is_primary_address)) or
- (1 if a.modified - b.modified else 0))
-
- doc.set_onload('addr_list', address_list)
-
- if doc.doctype != "Lead":
- contact_list = [frappe.get_value('Contact', a.parent, '*')
- for a in frappe.get_all('Dynamic Link', fields='parent',
- filters=dict(parenttype='Contact', link_doctype=doc.doctype, link_name=doc.name))]
-
- contact_list = sorted(contact_list,
- lambda a, b:
- (int(a.is_primary_contact - b.is_primary_contact)) or
- (1 if a.modified - b.modified else 0))
-
- doc.set_onload('contact_list', contact_list)
-
-def set_default_role(doc, method):
- '''Set customer, supplier, student based on email'''
- if frappe.flags.setting_role:
- return
- contact_name = frappe.get_value('Contact', dict(email_id=doc.email))
- if contact_name:
- contact = frappe.get_doc('Contact', contact_name)
- for link in contact.links:
- frappe.flags.setting_role = True
- if link.link_doctype=='Customer':
- doc.add_roles('Customer')
- elif link.link_doctype=='Supplier':
- doc.add_roles('Supplier')
- elif frappe.get_value('Student', dict(student_email_id=doc.email)):
- doc.add_roles('Student')
-
-def has_permission(doc, ptype, user):
- links = get_permitted_and_not_permitted_links(doc.doctype)
- if not links.get("not_permitted_links"):
- # optimization: don't determine permissions based on link fields
- return True
-
- # True if any one is True or all are empty
- names = []
- for df in (links.get("permitted_links") + links.get("not_permitted_links")):
- doctype = df.options
- name = doc.get(df.fieldname)
- names.append(name)
-
- if name and frappe.has_permission(doctype, ptype, doc=name):
- return True
-
- if not any(names):
- return True
- return False
-
-def get_permission_query_conditions_for_contact(user):
- return get_permission_query_conditions("Contact")
-
-def get_permission_query_conditions_for_address(user):
- return get_permission_query_conditions("Address")
-
-def get_permission_query_conditions(doctype):
- links = get_permitted_and_not_permitted_links(doctype)
-
- if not links.get("not_permitted_links"):
- # when everything is permitted, don't add additional condition
- return ""
-
- elif not links.get("permitted_links"):
- conditions = []
-
- # when everything is not permitted
- for df in links.get("not_permitted_links"):
- # like ifnull(customer, '')='' and ifnull(supplier, '')=''
- conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')=''".format(doctype=doctype, fieldname=df.fieldname))
-
- return "( " + " and ".join(conditions) + " )"
-
- else:
- conditions = []
-
- for df in links.get("permitted_links"):
- # like ifnull(customer, '')!='' or ifnull(supplier, '')!=''
- conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname))
-
- return "( " + " or ".join(conditions) + " )"
-
-def get_permitted_and_not_permitted_links(doctype):
- permitted_links = []
- not_permitted_links = []
-
- meta = frappe.get_meta(doctype)
-
- for df in meta.get_link_fields():
- if df.options not in ("Customer", "Supplier", "Company", "Sales Partner"):
- continue
-
- if frappe.has_permission(df.options):
- permitted_links.append(df)
- else:
- not_permitted_links.append(df)
-
- return {
- "permitted_links": permitted_links,
- "not_permitted_links": not_permitted_links
- }
-
-def delete_contact_and_address(doctype, name):
- for parenttype in ('Contact', 'Address'):
- items = frappe.db.sql("""select parent from `tabDynamic Link`
- where parenttype=%s and link_doctype=%s and link_name=%s""",
- (parenttype, doctype, name))
-
- for name in items:
- doc = frappe.get_doc(parenttype, name)
- if len(doc.links)==1:
- doc.delete()