Merge pull request #17556 from Alchez/develop-lead-import-fix
feat(crm): Allow leads to be imported without person name
diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js
index bb059f6..f7f1a5f 100644
--- a/erpnext/accounts/doctype/account/account.js
+++ b/erpnext/accounts/doctype/account/account.js
@@ -42,15 +42,14 @@
// show / hide convert buttons
frm.trigger('add_toolbar_buttons');
}
- frm.add_custom_button(__('Update Account Name / Number'), function () {
- frm.trigger("update_account_number");
- });
- }
-
- if(!frm.doc.__islocal) {
- frm.add_custom_button(__('Merge Account'), function () {
- frm.trigger("merge_account");
- });
+ if (frm.has_perm('write')) {
+ frm.add_custom_button(__('Update Account Name / Number'), function () {
+ frm.trigger("update_account_number");
+ });
+ frm.add_custom_button(__('Merge Account'), function () {
+ frm.trigger("merge_account");
+ });
+ }
}
},
account_type: function (frm) {
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index ecf67dd..68efe37 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -268,7 +268,7 @@
new_name = get_account_autoname(account_number, account_name, account.company)
if name != new_name:
- frappe.rename_doc("Account", name, new_name, ignore_permissions=1)
+ frappe.rename_doc("Account", name, new_name, force=1)
return new_name
@frappe.whitelist()
@@ -287,7 +287,7 @@
frappe.db.set_value("Account", new, "parent_account",
frappe.db.get_value("Account", old, "parent_account"))
- frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
+ frappe.rename_doc("Account", old, new, merge=1, force=1)
return new
diff --git a/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js
index 36bd29e..29db227 100644
--- a/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js
+++ b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js
@@ -5,6 +5,12 @@
frappe.query_reports["Inactive Sales Items"] = {
"filters": [
{
+ fieldname: "territory",
+ label: __("Territory"),
+ fieldtype: "Link",
+ options: "Territory"
+ },
+ {
fieldname: "item",
label: __("Item"),
fieldtype: "Link",
diff --git a/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py
index fd169f8f..42761a5 100644
--- a/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py
+++ b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py
@@ -7,13 +7,11 @@
from frappe import _
def execute(filters=None):
-
columns = get_columns()
data = get_data(filters)
return columns, data
def get_columns():
-
columns = [
{
"fieldname": "territory",
@@ -74,36 +72,37 @@
def get_data(filters):
-
data = []
items = get_items(filters)
+ territories = get_territories(filters)
sales_invoice_data = get_sales_details(filters)
- for item in items:
- row = {
+ for territory in territories:
+ for item in items:
+ row = {
+ "territory": territory.name,
"item_group": item.item_group,
"item": item.name,
"item_name": item.item_name
- }
+ }
- if sales_invoice_data.get(item.name):
- item_obj = sales_invoice_data[item.name]
- if item_obj.days_since_last_order > cint(filters['days']):
- row.update({
- "territory": item_obj.territory,
- "customer": item_obj.customer,
- "last_order_date": item_obj.last_order_date,
- "qty": item_obj.qty,
- "days_since_last_order": item_obj.days_since_last_order
- })
+ if sales_invoice_data.get((territory.name,item.name)):
+ item_obj = sales_invoice_data[(territory.name,item.name)]
+ if item_obj.days_since_last_order > cint(filters['days']):
+ row.update({
+ "territory": item_obj.territory,
+ "customer": item_obj.customer,
+ "last_order_date": item_obj.last_order_date,
+ "qty": item_obj.qty,
+ "days_since_last_order": item_obj.days_since_last_order
+ })
- data.append(row)
+ data.append(row)
return data
def get_sales_details(filters):
-
data = []
item_details_map = {}
@@ -118,12 +117,21 @@
.format(date_field = date_field, doctype = filters['based_on']), as_dict=1)
for d in sales_data:
- item_details_map.setdefault(d.item_name, d)
+ item_details_map.setdefault((d.territory,d.item_name), d)
return item_details_map
-def get_items(filters):
+def get_territories(filters):
+ filter_dict = {}
+ if filters.get("territory"):
+ filter_dict.update({'name': filters['territory']})
+
+ territories = frappe.get_all("Territory", fields=["name"], filters=filter_dict)
+
+ return territories
+
+def get_items(filters):
filters_dict = {
"disabled": 0,
"is_stock_item": 1
diff --git a/erpnext/hr/doctype/training_event/training_event.py b/erpnext/hr/doctype/training_event/training_event.py
index 1b13b70..5064f03 100644
--- a/erpnext/hr/doctype/training_event/training_event.py
+++ b/erpnext/hr/doctype/training_event/training_event.py
@@ -5,9 +5,19 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
+from frappe import _
+from frappe.utils import time_diff_in_seconds
from erpnext.hr.doctype.employee.employee import get_employee_emails
class TrainingEvent(Document):
def validate(self):
+ self.set_employee_emails()
+ self.validate_period()
+
+ def set_employee_emails(self):
self.employee_emails = ', '.join(get_employee_emails([d.employee
for d in self.employees]))
+
+ def validate_period(self):
+ if time_diff_in_seconds(self.end_time, self.start_time) <= 0:
+ frappe.throw(_('End time cannot be before start time'))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 61db3e1..a66fac3 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -485,16 +485,17 @@
projects = get_projects_for_collect_progress("Daily", fields)
for project in projects:
- if not check_project_update_exists(project.name, project.get("daily_time_to_send")):
+ if allow_to_make_project_update(project.name, project.get("daily_time_to_send"), "Daily"):
send_project_update_email_to_users(project.name)
def twice_daily_reminder():
fields = ["first_email", "second_email"]
projects = get_projects_for_collect_progress("Twice Daily", fields)
+ fields.remove("name")
for project in projects:
for d in fields:
- if not check_project_update_exists(project.name, project.get(d)):
+ if allow_to_make_project_update(project.name, project.get(d), "Twicely"):
send_project_update_email_to_users(project.name)
def weekly_reminder():
@@ -506,14 +507,19 @@
if current_day != project.day_to_send:
continue
- if not check_project_update_exists(project.name, project.get("weekly_time_to_send")):
+ if allow_to_make_project_update(project.name, project.get("weekly_time_to_send"), "Weekly"):
send_project_update_email_to_users(project.name)
-def check_project_update_exists(project, time):
+def allow_to_make_project_update(project, time, frequency):
data = frappe.db.sql(""" SELECT name from `tabProject Update`
- WHERE project = %s and date = %s and time >= %s """, (project, today(), time))
+ WHERE project = %s and date = %s """, (project, today()))
- return True if data and data[0][0] else False
+ # len(data) > 1 condition is checked for twicely frequency
+ if data and (frequency in ['Daily', 'Weekly'] or len(data) > 1):
+ return False
+
+ if get_time(nowtime()) >= get_time(time):
+ return True
def get_projects_for_collect_progress(frequency, fields):
fields.extend(["name"])