您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

189 行
5.6 KiB

  1. // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. wn.ui.form.States = Class.extend({
  4. init: function(opts) {
  5. $.extend(this, opts);
  6. this.state_fieldname = wn.workflow.get_state_fieldname(this.frm.doctype);
  7. // no workflow?
  8. if(!this.state_fieldname)
  9. return;
  10. this.update_fields = wn.workflow.get_update_fields(this.frm.doctype);
  11. var me = this;
  12. $(this.frm.wrapper).bind("render_complete", function() {
  13. me.refresh();
  14. })
  15. },
  16. make: function() {
  17. this.parent = this.frm.appframe.parent
  18. .find(".workflow-button-area")
  19. .empty()
  20. .removeClass("hide");
  21. this.workflow_button = $('<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">\
  22. <i class="icon-small"></i> <span class="state-text"></span>\
  23. <span class="caret"></span></button>')
  24. .appendTo(this.parent).dropdown();
  25. this.dropdown = $('<ul class="dropdown-menu">').insertAfter(this.workflow_button);
  26. this.help_btn = $('<button class="btn btn-default"><i class="icon-question-sign"></i></button').
  27. insertBefore(this.workflow_button);
  28. this.setup_help();
  29. this.bind_action();
  30. },
  31. setup_help: function() {
  32. var me = this;
  33. this.help_btn.click(function() {
  34. wn.workflow.setup(me.frm.doctype);
  35. var state = me.get_state();
  36. var d = new wn.ui.Dialog({
  37. title: "Workflow: "
  38. + wn.workflow.workflows[me.frm.doctype].name
  39. })
  40. var next_html = $.map(wn.workflow.get_transitions(me.frm.doctype, state),
  41. function(d) {
  42. return d.action.bold() + wn._(" by Role ") + d.allowed;
  43. }).join(", ") || wn._("None: End of Workflow").bold();
  44. $(d.body).html("<p>"+wn._("Current status")+": " + state.bold() + "</p>"
  45. + "<p>"+wn._("Document is only editable by users of role")+": "
  46. + wn.workflow.get_document_state(me.frm.doctype,
  47. state).allow_edit.bold() + "</p>"
  48. + "<p>"+wn._("Next actions")+": "+ next_html +"</p>"
  49. + (me.frm.doc.__islocal ? ("<div class='alert alert-info'>"
  50. +wn._("Workflow will start after saving.")+"</div>") : "")
  51. + "<p class='help'>"+wn._("Note: Other permission rules may also apply")+"</p>"
  52. ).css({padding: '15px'});
  53. d.show();
  54. });
  55. },
  56. refresh: function() {
  57. // hide if its not yet saved
  58. if(this.frm.doc.__islocal) {
  59. this.set_default_state();
  60. this.parent.toggle(false);
  61. return;
  62. }
  63. this.make();
  64. // state text
  65. var state = this.get_state();
  66. if(state) {
  67. // show current state on the button
  68. this.workflow_button.find(".state-text").text(state);
  69. var state_doc = wn.model.get("Workflow State", {name:state})[0];
  70. if (state_doc) {
  71. // set the icon
  72. this.workflow_button.find('i').removeClass()
  73. .addClass("icon-white")
  74. .addClass("icon-" + state_doc.icon);
  75. // set the style
  76. this.workflow_button.removeClass().addClass("btn btn-default dropdown-toggle")
  77. if(state_doc && state_doc.style)
  78. this.workflow_button.addClass("btn-" + state_doc.style.toLowerCase());
  79. }
  80. // show actions from that state
  81. this.show_actions(state);
  82. if(this.frm.doc.__islocal) {
  83. this.workflow_button.prop('disabled', true);
  84. }
  85. }
  86. },
  87. show_actions: function(state) {
  88. var $ul = this.dropdown;
  89. $ul.empty();
  90. $.each(wn.workflow.get_transitions(this.frm.doctype, state), function(i, d) {
  91. if(in_list(user_roles, d.allowed)) {
  92. d.icon = wn.model.get("Workflow State", {name:d.next_state})[0].icon;
  93. $(repl('<li><a href="#" data-action="%(action)s">\
  94. <i class="icon icon-%(icon)s"></i> %(action)s</a></li>', d))
  95. .appendTo($ul);
  96. }
  97. });
  98. // disable the button if user cannot change state
  99. var is_final = !$ul.find("li").length;
  100. this.workflow_button
  101. .prop('disabled', is_final);
  102. this.workflow_button.find(".caret").toggle(is_final ? false : true)
  103. },
  104. set_default_state: function() {
  105. var default_state = wn.workflow.get_default_state(this.frm.doctype);
  106. if(default_state) {
  107. this.frm.set_value(this.state_fieldname, default_state);
  108. }
  109. },
  110. get_state: function() {
  111. if(!this.frm.doc[this.state_fieldname]) {
  112. this.set_default_state();
  113. }
  114. return this.frm.doc[this.state_fieldname];
  115. },
  116. bind_action: function() {
  117. var me = this;
  118. this.dropdown.on("click", "[data-action]", function() {
  119. var action = $(this).attr("data-action");
  120. // capture current state
  121. var doc_before_action = copy_dict(me.frm.doc);
  122. // set new state
  123. var next_state = wn.workflow.get_next_state(me.frm.doctype,
  124. me.frm.doc[me.state_fieldname], action);
  125. me.frm.doc[me.state_fieldname] = next_state;
  126. var new_state = wn.workflow.get_document_state(me.frm.doctype, next_state);
  127. var new_docstatus = cint(new_state.doc_status);
  128. // update field and value
  129. if(new_state.update_field) {
  130. me.frm.set_value(new_state.update_field, new_state.update_value);
  131. }
  132. // revert state on error
  133. var on_error = function() {
  134. // reset in locals
  135. locals[me.frm.doctype][me.frm.docname] = doc_before_action;
  136. me.frm.refresh();
  137. }
  138. if(new_docstatus==1 && me.frm.doc.docstatus==0) {
  139. me.frm.savesubmit(null, on_error);
  140. } else if(new_docstatus==0 && me.frm.doc.docstatus==0) {
  141. me.frm.save("Save", null, null, on_error);
  142. } else if(new_docstatus==1 && me.frm.doc.docstatus==1) {
  143. me.frm.save("Update", null, null, on_error);
  144. } else if(new_docstatus==2 && me.frm.doc.docstatus==1) {
  145. me.frm.savecancel(null, on_error);
  146. } else {
  147. msgprint(wn._("Document Status transition from ") + me.frm.doc.docstatus + " "
  148. + wn._("to") +
  149. new_docstatus + " " + wn._("is not allowed."));
  150. return false;
  151. }
  152. // hide dropdown
  153. me.workflow_button.dropdown('toggle');
  154. return false;
  155. })
  156. }
  157. });