@@ -14,7 +14,7 @@ import os, sys, importlib, inspect, json | |||||
from .exceptions import * | from .exceptions import * | ||||
from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template | from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template | ||||
__version__ = '9.0.5' | |||||
__version__ = '9.0.6' | |||||
__title__ = "Frappe Framework" | __title__ = "Frappe Framework" | ||||
local = Local() | local = Local() | ||||
@@ -138,8 +138,10 @@ def get_user_page_or_report(parent): | |||||
and tab{parent}.name not in ( | and tab{parent}.name not in ( | ||||
select `tabCustom Role`.{field} from `tabCustom Role` | select `tabCustom Role`.{field} from `tabCustom Role` | ||||
where `tabCustom Role`.{field} is not null) | where `tabCustom Role`.{field} is not null) | ||||
""".format(parent=parent, column=column, | |||||
roles = ', '.join(['%s']*len(roles)), field=parent.lower()), roles, as_dict=True) | |||||
{condition} | |||||
""".format(parent=parent, column=column, roles = ', '.join(['%s']*len(roles)), | |||||
field=parent.lower(), condition="and tabReport.disabled=0" if parent == "Report" else ""), | |||||
roles, as_dict=True) | |||||
for p in standard_roles: | for p in standard_roles: | ||||
if p.name not in has_role: | if p.name not in has_role: | ||||
@@ -4,6 +4,7 @@ import json, os, sys | |||||
from distutils.spawn import find_executable | from distutils.spawn import find_executable | ||||
import frappe | import frappe | ||||
from frappe.commands import pass_context, get_site | from frappe.commands import pass_context, get_site | ||||
from frappe.utils import update_progress_bar | |||||
@click.command('build') | @click.command('build') | ||||
@click.option('--make-copy', is_flag=True, default=False, help='Copy the files instead of symlinking') | @click.option('--make-copy', is_flag=True, default=False, help='Copy the files instead of symlinking') | ||||
@@ -484,6 +485,24 @@ def setup_help(context): | |||||
finally: | finally: | ||||
frappe.destroy() | frappe.destroy() | ||||
@click.command('rebuild-global-search') | |||||
@pass_context | |||||
def rebuild_global_search(context): | |||||
'''Setup help table in the current site (called after migrate)''' | |||||
from frappe.utils.global_search import (get_doctypes_with_global_search, rebuild_for_doctype) | |||||
for site in context.sites: | |||||
try: | |||||
frappe.init(site) | |||||
frappe.connect() | |||||
doctypes = get_doctypes_with_global_search() | |||||
for i, doctype in enumerate(doctypes): | |||||
rebuild_for_doctype(doctype) | |||||
update_progress_bar('Rebuilding Global Search', i, len(doctypes)) | |||||
finally: | |||||
frappe.destroy() | |||||
commands = [ | commands = [ | ||||
build, | build, | ||||
@@ -512,5 +531,6 @@ commands = [ | |||||
_bulk_rename, | _bulk_rename, | ||||
add_to_email_queue, | add_to_email_queue, | ||||
setup_global_help, | setup_global_help, | ||||
setup_help | |||||
setup_help, | |||||
rebuild_global_search | |||||
] | ] |
@@ -685,27 +685,36 @@ def pull(now=False): | |||||
frappe.cache().set_value("workers:no-internet", False) | frappe.cache().set_value("workers:no-internet", False) | ||||
else: | else: | ||||
return | return | ||||
queued_jobs = get_jobs(site=frappe.local.site, key='job_name')[frappe.local.site] | queued_jobs = get_jobs(site=frappe.local.site, key='job_name')[frappe.local.site] | ||||
for email_account in frappe.get_list("Email Account", | |||||
filters={"enable_incoming": 1, "awaiting_password": 0}): | |||||
if now: | |||||
pull_from_email_account(email_account.name) | |||||
email_accounts = frappe.db.sql_list("""select name from `tabEmail Account` where | |||||
enable_incoming=1 and awaiting_password=0""") | |||||
else: | |||||
# job_name is used to prevent duplicates in queue | |||||
job_name = 'pull_from_email_account|{0}'.format(email_account.name) | |||||
# No incoming email account available | |||||
if not email_accounts: | |||||
return | |||||
if job_name not in queued_jobs: | |||||
enqueue(pull_from_email_account, 'short', event='all', job_name=job_name, | |||||
email_account=email_account.name) | |||||
if now: | |||||
pull_from_email_accounts(email_accounts) | |||||
else: | |||||
# job_name is used to prevent duplicates in queue | |||||
job_name = 'pull_from_email_accounts|{0}'.format(",".join(email_accounts)) | |||||
def pull_from_email_account(email_account): | |||||
if job_name not in queued_jobs: | |||||
enqueue(pull_from_email_accounts, 'short', event='all', job_name=job_name, | |||||
email_accounts=email_accounts) | |||||
def pull_from_email_accounts(email_accounts): | |||||
'''Runs within a worker process''' | '''Runs within a worker process''' | ||||
email_account = frappe.get_doc("Email Account", email_account) | |||||
email_account.receive() | |||||
if not email_accounts: | |||||
return | |||||
for email_account in email_accounts: | |||||
email_account = frappe.get_doc("Email Account", email_account) | |||||
email_account.receive() | |||||
# mark Email Flag Queue mail as read | |||||
email_account.mark_emails_as_read_unread() | |||||
# mark Email Flag Queue mail as read | |||||
email_account.mark_emails_as_read_unread() | |||||
def get_max_email_uid(email_account): | def get_max_email_uid(email_account): | ||||
# get maximum uid of emails | # get maximum uid of emails | ||||
@@ -47,7 +47,9 @@ def get_outgoing_email_account(raise_exception_not_set=True, append_to=None, sen | |||||
if not getattr(frappe.local, "outgoing_email_account", None): | if not getattr(frappe.local, "outgoing_email_account", None): | ||||
frappe.local.outgoing_email_account = {} | frappe.local.outgoing_email_account = {} | ||||
if not frappe.local.outgoing_email_account.get(append_to or sender_email_id or "default"): | |||||
if not frappe.local.outgoing_email_account.get(append_to) \ | |||||
or frappe.local.outgoing_email_account.get(sender_email_id) \ | |||||
or frappe.local.outgoing_email_account.get("default"): | |||||
email_account = None | email_account = None | ||||
if append_to: | if append_to: | ||||
@@ -77,7 +79,9 @@ def get_outgoing_email_account(raise_exception_not_set=True, append_to=None, sen | |||||
frappe.local.outgoing_email_account[append_to or sender_email_id or "default"] = email_account | frappe.local.outgoing_email_account[append_to or sender_email_id or "default"] = email_account | ||||
return frappe.local.outgoing_email_account[append_to or sender_email_id or "default"] | |||||
return frappe.local.outgoing_email_account.get(append_to) \ | |||||
or frappe.local.outgoing_email_account.get(sender_email_id) \ | |||||
or frappe.local.outgoing_email_account.get("default") | |||||
def get_default_outgoing_email_account(raise_exception_not_set=True): | def get_default_outgoing_email_account(raise_exception_not_set=True): | ||||
'''conf should be like: | '''conf should be like: | ||||
@@ -391,7 +391,7 @@ frappe.views.ReportView = frappe.ui.BaseList.extend({ | |||||
var me = this; | var me = this; | ||||
var data = this.get_unique_data(this.column_info); | var data = this.get_unique_data(this.column_info); | ||||
this.set_totals_row(); | |||||
this.set_totals_row(data); | |||||
// add sr in data | // add sr in data | ||||
$.each(data, function(i, v) { | $.each(data, function(i, v) { | ||||
@@ -475,25 +475,24 @@ frappe.views.ReportView = frappe.ui.BaseList.extend({ | |||||
get_unique_data: function(columns) { | get_unique_data: function(columns) { | ||||
// if child columns are selected, show parent data only once | // if child columns are selected, show parent data only once | ||||
var me = this; | |||||
if (this.show_all_data || !this.has_child_column()) { | |||||
return this.data; | |||||
} | |||||
let has_child_column = this.has_child_column(); | |||||
var data = [], prev_row = null; | var data = [], prev_row = null; | ||||
this.data.forEach(function(d) { | |||||
if(prev_row && d.name == prev_row.name) { | |||||
this.data.forEach((d) => { | |||||
if (this.show_all_data || !has_child_column) { | |||||
data.push(d); | |||||
} else if (prev_row && d.name == prev_row.name) { | |||||
var new_row = {}; | var new_row = {}; | ||||
columns.forEach(function(c) { | |||||
if(!c.docfield || c.docfield.parent!==me.doctype) { | |||||
columns.forEach((c) => { | |||||
if(!c.docfield || c.docfield.parent!==this.doctype) { | |||||
var val = d[c.field]; | var val = d[c.field]; | ||||
// add child table row name for update | // add child table row name for update | ||||
if(c.docfield && c.docfield.parent!==me.doctype) { | |||||
if(c.docfield && c.docfield.parent!==this.doctype) { | |||||
new_row[c.docfield.parent+":name"] = d[c.docfield.parent+":name"]; | new_row[c.docfield.parent+":name"] = d[c.docfield.parent+":name"]; | ||||
} | } | ||||
} else { | } else { | ||||
var val = ''; | var val = ''; | ||||
new_row.__is_repeat = true; | |||||
} | } | ||||
new_row[c.field] = val; | new_row[c.field] = val; | ||||
}); | }); | ||||
@@ -613,21 +612,16 @@ frappe.views.ReportView = frappe.ui.BaseList.extend({ | |||||
var me = this; | var me = this; | ||||
this.page.add_inner_button(__('Show Totals'), function() { | this.page.add_inner_button(__('Show Totals'), function() { | ||||
me.add_totals_row = 1 - (me.add_totals_row ? me.add_totals_row : 0); | |||||
me.add_totals_row = !!!me.add_totals_row; | |||||
me.render_view(); | me.render_view(); | ||||
}); | }); | ||||
}, | }, | ||||
set_totals_row: function() { | |||||
// remove existing totals row | |||||
if(this.data.length && this.data[this.data.length-1]._totals_row) { | |||||
this.data.pop(); | |||||
} | |||||
set_totals_row: function(data) { | |||||
if(this.add_totals_row) { | if(this.add_totals_row) { | ||||
var totals_row = {_totals_row: 1}; | var totals_row = {_totals_row: 1}; | ||||
if(this.data.length) { | |||||
this.data.forEach(function(row, ri) { | |||||
if(data.length) { | |||||
data.forEach(function(row, ri) { | |||||
$.each(row, function(key, value) { | $.each(row, function(key, value) { | ||||
if($.isNumeric(value)) { | if($.isNumeric(value)) { | ||||
totals_row[key] = (totals_row[key] || 0) + value; | totals_row[key] = (totals_row[key] || 0) + value; | ||||
@@ -635,7 +629,7 @@ frappe.views.ReportView = frappe.ui.BaseList.extend({ | |||||
}); | }); | ||||
}); | }); | ||||
} | } | ||||
this.data.push(totals_row); | |||||
data.push(totals_row); | |||||
} | } | ||||
}, | }, | ||||