[enhancement] bulk update tool!
This commit is contained in:
parent
058c95cbdd
commit
db9ba845e5
11 changed files with 318 additions and 11 deletions
|
|
@ -1180,6 +1180,17 @@ def attach_print(doctype, name, file_name=None, print_format=None, style=None, h
|
|||
|
||||
return out
|
||||
|
||||
def publish_progress(*args, **kwargs):
|
||||
"""Show the user progress for a long request
|
||||
|
||||
:param percent: Percent progress
|
||||
:param title: Title
|
||||
:param doctype: Optional, for DocType
|
||||
:param name: Optional, for Document name
|
||||
"""
|
||||
import frappe.async
|
||||
return frappe.async.publish_progress(*args, **kwargs)
|
||||
|
||||
def publish_realtime(*args, **kwargs):
|
||||
"""Publish real-time updates
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ def remove_old_task_logs():
|
|||
def is_file_old(file_path):
|
||||
return ((time.time() - os.stat(file_path).st_mtime) > TASK_LOG_MAX_AGE)
|
||||
|
||||
def publish_progress(percent, title=None, doctype=None, docname=None):
|
||||
publish_realtime('progress', {'percent': percent, 'title': title},
|
||||
user=frappe.session.user, doctype=doctype, docname=docname)
|
||||
|
||||
def publish_realtime(event=None, message=None, room=None,
|
||||
user=None, doctype=None, docname=None, task_id=None,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ def get_bootinfo():
|
|||
load_desktop_icons(bootinfo)
|
||||
|
||||
bootinfo.module_app = frappe.local.module_app
|
||||
bootinfo.single_types = frappe.db.sql_list("""select name from tabDocType where issingle=1""")
|
||||
bootinfo.single_types = frappe.db.sql_list("""select name from tabDocType
|
||||
where issingle=1""")
|
||||
add_home_page(bootinfo, doclist)
|
||||
bootinfo.page_info = get_allowed_pages()
|
||||
load_translations(bootinfo)
|
||||
|
|
|
|||
|
|
@ -109,6 +109,13 @@ def get_data():
|
|||
"description": _("Rename many items by uploading a .csv file."),
|
||||
"hide_count": True
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Bulk Update",
|
||||
"label": _("Bulk Update"),
|
||||
"description": _("Update many values at one time."),
|
||||
"hide_count": True
|
||||
},
|
||||
{
|
||||
"type": "page",
|
||||
"name": "backups",
|
||||
|
|
|
|||
0
frappe/desk/doctype/bulk_update/__init__.py
Normal file
0
frappe/desk/doctype/bulk_update/__init__.py
Normal file
36
frappe/desk/doctype/bulk_update/bulk_update.js
Normal file
36
frappe/desk/doctype/bulk_update/bulk_update.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2016, Frappe Technologies and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Bulk Update', {
|
||||
refresh: function(frm) {
|
||||
frm.page.set_primary_action(__('Update'), function() {
|
||||
frappe.call({
|
||||
method: 'frappe.desk.doctype.bulk_update.bulk_update.update',
|
||||
args: {
|
||||
doctype: frm.doc.document_type,
|
||||
field: frm.doc.field,
|
||||
value: frm.doc.update_value,
|
||||
condition: frm.doc.condition,
|
||||
limit: frm.doc.limit
|
||||
},
|
||||
callback: function() {
|
||||
frappe.hide_progress();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
document_type: function(frm) {
|
||||
// set field options
|
||||
frappe.model.with_doctype(frm.doc.document_type, function() {
|
||||
var options = $.map(frappe.get_meta(frm.doc.document_type).fields,
|
||||
function(d) {
|
||||
if(d.fieldname && frappe.model.no_value_type.indexOf(d.fieldtype)===-1) {
|
||||
return d.fieldname;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
frm.set_df_property('field', 'options', options);
|
||||
});
|
||||
}
|
||||
});
|
||||
187
frappe/desk/doctype/bulk_update/bulk_update.json
Normal file
187
frappe/desk/doctype/bulk_update/bulk_update.json
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-07-15 05:51:29.224123",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "document_type",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Document Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 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": "field",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Field",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 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": "update_value",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Update Value",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 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": "SQL Conditions. Example: status=\"Open\"",
|
||||
"fieldname": "condition",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Condition",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 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": "500",
|
||||
"description": "Max 500 records at a time",
|
||||
"fieldname": "limit",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Limit",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 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": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-07-15 06:24:42.575613",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "Bulk Update",
|
||||
"name_case": "",
|
||||
"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": 0,
|
||||
"role": "System Manager",
|
||||
"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
|
||||
}
|
||||
39
frappe/desk/doctype/bulk_update/bulk_update.py
Normal file
39
frappe/desk/doctype/bulk_update/bulk_update.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
from frappe.utils import cint
|
||||
|
||||
class BulkUpdate(Document):
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def update(doctype, field, value, condition='', limit=500):
|
||||
if not limit or cint(limit) > 500:
|
||||
limit = 500
|
||||
|
||||
if condition:
|
||||
condition = ' where ' + condition
|
||||
|
||||
if ';' in condition:
|
||||
frappe.throw('; not allowed in condition')
|
||||
|
||||
items = frappe.db.sql_list('select name from `tab{0}`{1} limit 0, {2}'.format(doctype,
|
||||
condition, limit), debug=1)
|
||||
n = len(items)
|
||||
|
||||
for i, d in enumerate(items):
|
||||
doc = frappe.get_doc(doctype, d)
|
||||
doc.set(field, value)
|
||||
doc.save()
|
||||
|
||||
frappe.publish_progress(float(i)*100/n,
|
||||
title = _('Updating Records'), doctype='Bulk Update', docname='Bulk Update')
|
||||
|
||||
# clear messages
|
||||
frappe.local.message_log = []
|
||||
frappe.msgprint(_('{0} records updated').format(n), title=_('Success'), indicator='green')
|
||||
|
|
@ -6,7 +6,7 @@ frappe.start_app = function() {
|
|||
return;
|
||||
frappe.assets.check();
|
||||
frappe.provide('frappe.app');
|
||||
$.extend(frappe.app, new frappe.Application());
|
||||
frappe.app = new frappe.Application();
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
|
@ -249,22 +249,28 @@ frappe.Application = Class.extend({
|
|||
$('<link rel="icon" href="' + link + '" type="image/x-icon">').appendTo("head");
|
||||
},
|
||||
|
||||
trigger_primary_action: function() {
|
||||
if(cur_dialog) {
|
||||
// trigger primary
|
||||
cur_dialog.get_primary_btn().trigger("click");
|
||||
} else if(cur_frm && cur_frm.page.btn_primary.is(':visible')) {
|
||||
cur_frm.page.btn_primary.trigger('click');
|
||||
} else if(frappe.container.page.save_action) {
|
||||
frappe.container.page.save_action();
|
||||
}
|
||||
},
|
||||
|
||||
setup_keyboard_shortcuts: function() {
|
||||
var me = this;
|
||||
|
||||
$(document)
|
||||
.keydown("meta+g ctrl+g", function(e) {
|
||||
$("#navbar-search").focus()
|
||||
$("#navbar-search").focus();
|
||||
return false;
|
||||
})
|
||||
.keydown("meta+s ctrl+s", function(e) {
|
||||
e.preventDefault();
|
||||
if(cur_dialog) {
|
||||
// trigger primary
|
||||
cur_dialog.get_primary_btn().trigger("click");
|
||||
} else if(cur_frm && cur_frm.page.btn_primary.is(':visible')) {
|
||||
cur_frm.page.btn_primary.trigger('click');
|
||||
} else if(frappe.container.page.save_action) {
|
||||
frappe.container.page.save_action();
|
||||
}
|
||||
me.trigger_primary_action();
|
||||
return false;
|
||||
})
|
||||
.keydown("meta+b ctrl+b", function(e) {
|
||||
|
|
|
|||
|
|
@ -421,6 +421,13 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
this.has_input = true;
|
||||
this.bind_change_event();
|
||||
this.bind_focusout();
|
||||
|
||||
// somehow this event does not bubble up to document
|
||||
// after v7, if you can debug, remove this
|
||||
this.$input.keydown("ctrl+s meta+s", function(e) {
|
||||
e.preventDefault();
|
||||
frappe.app && frappe.app.trigger_primary_action();
|
||||
});
|
||||
},
|
||||
set_input_attributes: function() {
|
||||
this.$input
|
||||
|
|
|
|||
|
|
@ -31,6 +31,16 @@ frappe.socket = {
|
|||
eval(message);
|
||||
});
|
||||
|
||||
frappe.socket.socket.on('progress', function(data) {
|
||||
if(data.percent) {
|
||||
if(data.percent==100) {
|
||||
frappe.hide_progress();
|
||||
} else {
|
||||
frappe.show_progress(data.title || __("Progress"), data.percent, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.socket.setup_listeners();
|
||||
frappe.socket.setup_reconnect();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue