186 lines
5.5 KiB
JavaScript
186 lines
5.5 KiB
JavaScript
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
|
// MIT License. See license.txt
|
|
|
|
wn.ui.form.States = Class.extend({
|
|
init: function(opts) {
|
|
$.extend(this, opts);
|
|
this.state_fieldname = wn.workflow.get_state_fieldname(this.frm.doctype);
|
|
|
|
// no workflow?
|
|
if(!this.state_fieldname)
|
|
return;
|
|
|
|
this.update_fields = wn.workflow.get_update_fields(this.frm.doctype);
|
|
|
|
var me = this;
|
|
$(this.frm.wrapper).bind("render_complete", function() {
|
|
me.refresh();
|
|
})
|
|
},
|
|
|
|
make: function() {
|
|
this.parent = this.frm.appframe.parent
|
|
.find(".workflow-button-area")
|
|
.empty()
|
|
.removeClass("hide");
|
|
|
|
this.workflow_button = $('<button class="btn btn-default dropdown-toggle">\
|
|
<i class="icon-small"></i> <span class="state-text"></span>\
|
|
<span class="caret"></span></button>')
|
|
.appendTo(this.parent).dropdown();
|
|
this.dropdown = $('<ul class="dropdown-menu">').insertAfter(this.workflow_button);
|
|
this.help_btn = $('<button class="btn btn-default"><i class="icon-question-sign"></i></button').
|
|
insertBefore(this.workflow_button);
|
|
this.setup_help();
|
|
this.bind_action();
|
|
},
|
|
|
|
setup_help: function() {
|
|
var me = this;
|
|
this.help_btn.click(function() {
|
|
wn.workflow.setup(me.frm.doctype);
|
|
var state = me.get_state();
|
|
var d = new wn.ui.Dialog({
|
|
title: "Workflow: "
|
|
+ wn.workflow.workflows[me.frm.doctype].name
|
|
})
|
|
var next_html = $.map(wn.workflow.get_transitions(me.frm.doctype, state),
|
|
function(d) {
|
|
return d.action.bold() + wn._(" by Role ") + d.allowed;
|
|
}).join(", ") || wn._("None: End of Workflow").bold();
|
|
|
|
$(d.body).html("<p>"+wn._("Current status")+": " + state.bold() + "</p>"
|
|
+ "<p>"+wn._("Document is only editable by users of role")+": "
|
|
+ wn.workflow.get_document_state(me.frm.doctype,
|
|
state).allow_edit.bold() + "</p>"
|
|
+ "<p>"+wn._("Next actions")+": "+ next_html +"</p>"
|
|
+ (me.frm.doc.__islocal ? ("<div class='alert alert-info'>"
|
|
+wn._("Workflow will start after saving.")+"</div>") : "")
|
|
+ "<p class='help'>"+wn._("Note: Other permission rules may also apply")+"</p>"
|
|
).css({padding: '15px'});
|
|
d.show();
|
|
});
|
|
},
|
|
|
|
refresh: function() {
|
|
// hide if its not yet saved
|
|
if(this.frm.doc.__islocal) {
|
|
this.set_default_state();
|
|
this.parent.toggle(false);
|
|
return;
|
|
}
|
|
|
|
this.make();
|
|
|
|
// state text
|
|
var state = this.get_state();
|
|
|
|
if(state) {
|
|
// show current state on the button
|
|
this.workflow_button.find(".state-text").text(state);
|
|
|
|
var state_doc = wn.model.get("Workflow State", {name:state})[0];
|
|
|
|
// set the icon
|
|
this.workflow_button.find('i').removeClass()
|
|
.addClass("icon-white")
|
|
.addClass("icon-" + state_doc.icon);
|
|
|
|
// set the style
|
|
this.workflow_button.removeClass().addClass("btn btn-default dropdown-toggle")
|
|
|
|
if(state_doc && state_doc.style)
|
|
this.workflow_button.addClass("btn-" + state_doc.style.toLowerCase());
|
|
|
|
// show actions from that state
|
|
this.show_actions(state);
|
|
|
|
if(this.frm.doc.__islocal) {
|
|
this.workflow_button.prop('disabled', true);
|
|
}
|
|
}
|
|
},
|
|
|
|
show_actions: function(state) {
|
|
var $ul = this.dropdown;
|
|
$ul.empty();
|
|
|
|
$.each(wn.workflow.get_transitions(this.frm.doctype, state), function(i, d) {
|
|
if(in_list(user_roles, d.allowed)) {
|
|
d.icon = wn.model.get("Workflow State", {name:d.next_state})[0].icon;
|
|
|
|
$(repl('<li><a href="#" data-action="%(action)s">\
|
|
<i class="icon icon-%(icon)s"></i> %(action)s</a></li>', d))
|
|
.appendTo($ul);
|
|
}
|
|
});
|
|
|
|
// disable the button if user cannot change state
|
|
var is_final = !$ul.find("li").length;
|
|
this.workflow_button
|
|
.prop('disabled', is_final);
|
|
this.workflow_button.find(".caret").toggle(is_final ? false : true)
|
|
},
|
|
|
|
set_default_state: function() {
|
|
var default_state = wn.workflow.get_default_state(this.frm.doctype);
|
|
if(default_state) {
|
|
this.frm.set_value(this.state_fieldname, default_state);
|
|
}
|
|
},
|
|
|
|
get_state: function() {
|
|
if(!this.frm.doc[this.state_fieldname]) {
|
|
this.set_default_state();
|
|
}
|
|
return this.frm.doc[this.state_fieldname];
|
|
},
|
|
|
|
bind_action: function() {
|
|
var me = this;
|
|
this.dropdown.on("click", "[data-action]", function() {
|
|
var action = $(this).attr("data-action");
|
|
// capture current state
|
|
var doc_before_action = copy_dict(me.frm.doc);
|
|
|
|
// set new state
|
|
var next_state = wn.workflow.get_next_state(me.frm.doctype,
|
|
me.frm.doc[me.state_fieldname], action);
|
|
me.frm.doc[me.state_fieldname] = next_state;
|
|
var new_state = wn.workflow.get_document_state(me.frm.doctype, next_state);
|
|
var new_docstatus = cint(new_state.doc_status);
|
|
|
|
// update field and value
|
|
if(new_state.update_field) {
|
|
me.frm.set_value(new_state.update_field, new_state.update_value);
|
|
}
|
|
|
|
// revert state on error
|
|
var on_error = function() {
|
|
// reset in locals
|
|
locals[me.frm.doctype][me.frm.docname] = doc_before_action;
|
|
me.frm.refresh();
|
|
}
|
|
|
|
if(new_docstatus==1 && me.frm.doc.docstatus==0) {
|
|
me.frm.savesubmit(null, on_error);
|
|
} else if(new_docstatus==0 && me.frm.doc.docstatus==0) {
|
|
me.frm.save("Save", null, null, on_error);
|
|
} else if(new_docstatus==1 && me.frm.doc.docstatus==1) {
|
|
me.frm.save("Update", null, null, on_error);
|
|
} else if(new_docstatus==2 && me.frm.doc.docstatus==1) {
|
|
me.frm.savecancel(null, on_error);
|
|
} else {
|
|
msgprint(wn._("Document Status transition from ") + me.frm.doc.docstatus + " "
|
|
+ wn._("to") +
|
|
new_docstatus + " " + wn._("is not allowed."));
|
|
return false;
|
|
}
|
|
|
|
// hide dropdown
|
|
$(this).parents(".dropdown-menu:first").prev().dropdown('toggle');
|
|
|
|
return false;
|
|
})
|
|
}
|
|
});
|