Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

187 linhas
5.5 KiB

  1. // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  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. // set the icon
  71. this.workflow_button.find('i').removeClass()
  72. .addClass("icon-white")
  73. .addClass("icon-" + state_doc.icon);
  74. // set the style
  75. this.workflow_button.removeClass().addClass("btn btn-default dropdown-toggle")
  76. if(state_doc && state_doc.style)
  77. this.workflow_button.addClass("btn-" + state_doc.style.toLowerCase());
  78. // show actions from that state
  79. this.show_actions(state);
  80. if(this.frm.doc.__islocal) {
  81. this.workflow_button.prop('disabled', true);
  82. }
  83. }
  84. },
  85. show_actions: function(state) {
  86. var $ul = this.dropdown;
  87. $ul.empty();
  88. $.each(wn.workflow.get_transitions(this.frm.doctype, state), function(i, d) {
  89. if(in_list(user_roles, d.allowed)) {
  90. d.icon = wn.model.get("Workflow State", {name:d.next_state})[0].icon;
  91. $(repl('<li><a href="#" data-action="%(action)s">\
  92. <i class="icon icon-%(icon)s"></i> %(action)s</a></li>', d))
  93. .appendTo($ul);
  94. }
  95. });
  96. // disable the button if user cannot change state
  97. var is_final = !$ul.find("li").length;
  98. this.workflow_button
  99. .prop('disabled', is_final);
  100. this.workflow_button.find(".caret").toggle(is_final ? false : true)
  101. },
  102. set_default_state: function() {
  103. var default_state = wn.workflow.get_default_state(this.frm.doctype);
  104. if(default_state) {
  105. this.frm.set_value(this.state_fieldname, default_state);
  106. }
  107. },
  108. get_state: function() {
  109. if(!this.frm.doc[this.state_fieldname]) {
  110. this.set_default_state();
  111. }
  112. return this.frm.doc[this.state_fieldname];
  113. },
  114. bind_action: function() {
  115. var me = this;
  116. this.dropdown.on("click", "[data-action]", function() {
  117. var action = $(this).attr("data-action");
  118. // capture current state
  119. var doc_before_action = copy_dict(me.frm.doc);
  120. // set new state
  121. var next_state = wn.workflow.get_next_state(me.frm.doctype,
  122. me.frm.doc[me.state_fieldname], action);
  123. me.frm.doc[me.state_fieldname] = next_state;
  124. var new_state = wn.workflow.get_document_state(me.frm.doctype, next_state);
  125. var new_docstatus = cint(new_state.doc_status);
  126. // update field and value
  127. if(new_state.update_field) {
  128. me.frm.set_value(new_state.update_field, new_state.update_value);
  129. }
  130. // revert state on error
  131. var on_error = function() {
  132. // reset in locals
  133. locals[me.frm.doctype][me.frm.docname] = doc_before_action;
  134. me.frm.refresh();
  135. }
  136. if(new_docstatus==1 && me.frm.doc.docstatus==0) {
  137. me.frm.savesubmit(null, on_error);
  138. } else if(new_docstatus==0 && me.frm.doc.docstatus==0) {
  139. me.frm.save("Save", null, null, on_error);
  140. } else if(new_docstatus==1 && me.frm.doc.docstatus==1) {
  141. me.frm.save("Update", null, null, on_error);
  142. } else if(new_docstatus==2 && me.frm.doc.docstatus==1) {
  143. me.frm.savecancel(null, on_error);
  144. } else {
  145. msgprint(wn._("Document Status transition from ") + me.frm.doc.docstatus + " "
  146. + wn._("to") +
  147. new_docstatus + " " + wn._("is not allowed."));
  148. return false;
  149. }
  150. // hide dropdown
  151. me.workflow_button.dropdown('toggle');
  152. return false;
  153. })
  154. }
  155. });