You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
12 KiB

  1. /* Copyright 2016-2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
  2. Copyright 2016 manavi <https://github.com/manawi>
  3. Copyright 2017-2018 Artyom Losev <https://github.com/ArtyomLosev>
  4. Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
  5. Copyright 2019 Artem Rafailov <https://it-projects.info/team/Ommo73/>
  6. License MIT (https://opensource.org/licenses/MIT). */
  7. odoo.define("mail_private", function(require) {
  8. "use strict";
  9. var Chatter = require("mail.Chatter");
  10. var ChatterComposer = require("mail.composer.Chatter");
  11. var session = require("web.session");
  12. var rpc = require("web.rpc");
  13. var mailUtils = require("mail.utils");
  14. Chatter.include({
  15. init: function() {
  16. this._super.apply(this, arguments);
  17. this.private = false;
  18. this.events["click .oe_compose_post_private"] =
  19. "on_open_composer_private_message";
  20. },
  21. on_open_composer_private_message: function(event) {
  22. var self = this;
  23. this.fetch_recipients_for_internal_message().then(function(data) {
  24. self._openComposer({
  25. is_private: true,
  26. suggested_partners: data,
  27. });
  28. });
  29. },
  30. _openComposer: function(options) {
  31. var self = this;
  32. var old_composer = this._composer;
  33. // Create the new composer
  34. this._composer = new ChatterComposer(
  35. this,
  36. this.record.model,
  37. options.suggested_partners || [],
  38. {
  39. commandsEnabled: false,
  40. context: this.context,
  41. inputMinHeight: 50,
  42. isLog: options && options.isLog,
  43. recordName: this.recordName,
  44. defaultBody:
  45. old_composer &&
  46. old_composer.$input &&
  47. old_composer.$input.val(),
  48. defaultMentionSelections:
  49. old_composer && old_composer.getMentionListenerSelections(),
  50. attachmentIds:
  51. (old_composer && old_composer.get("attachment_ids")) || [],
  52. is_private: options.is_private,
  53. }
  54. );
  55. this._composer.on("input_focused", this, function() {
  56. this._composer.mentionSetPrefetchedPartners(
  57. this._mentionSuggestions || []
  58. );
  59. });
  60. this._composer.insertAfter(this.$(".o_chatter_topbar")).then(function() {
  61. // Destroy existing composer
  62. if (old_composer) {
  63. old_composer.destroy();
  64. }
  65. self._composer.focus();
  66. self._composer.on("post_message", self, function(messageData) {
  67. if (options.is_private) {
  68. self._composer.options.isLog = true;
  69. }
  70. self._discardOnReload(messageData).then(function() {
  71. self._disableComposer();
  72. self.fields.thread
  73. .postMessage(messageData)
  74. .then(function() {
  75. self._closeComposer(true);
  76. if (self._reloadAfterPost(messageData)) {
  77. self.trigger_up("reload");
  78. } else if (messageData.attachment_ids.length) {
  79. self._reloadAttachmentBox();
  80. self.trigger_up("reload", {
  81. fieldNames: ["message_attachment_count"],
  82. keepChanges: true,
  83. });
  84. }
  85. })
  86. .fail(function() {
  87. self._enableComposer();
  88. });
  89. });
  90. });
  91. var toggle_post_private = self._composer.options.is_private || false;
  92. self._composer.on(
  93. "need_refresh",
  94. self,
  95. self.trigger_up.bind(self, "reload")
  96. );
  97. self._composer.on(
  98. "close_composer",
  99. null,
  100. self._closeComposer.bind(self, true)
  101. );
  102. self.$el.addClass("o_chatter_composer_active");
  103. self.$(
  104. ".o_chatter_button_new_message, .o_chatter_button_log_note, .oe_compose_post_private"
  105. ).removeClass("o_active");
  106. self.$(".o_chatter_button_new_message").toggleClass(
  107. "o_active",
  108. !self._composer.options.isLog && !self._composer.options.is_private
  109. );
  110. self.$(".o_chatter_button_log_note").toggleClass(
  111. "o_active",
  112. self._composer.options.isLog && !options.is_private
  113. );
  114. self.$(".oe_compose_post_private").toggleClass(
  115. "o_active",
  116. toggle_post_private
  117. );
  118. });
  119. },
  120. fetch_recipients_for_internal_message: function() {
  121. var self = this;
  122. self.result = {};
  123. var follower_ids_domain = [["id", "=", self.context.default_res_id]];
  124. return rpc
  125. .query({
  126. model: "mail.message",
  127. method: "send_recepients_for_internal_message",
  128. args: [[], self.context.default_model, follower_ids_domain],
  129. })
  130. .then(function(res) {
  131. return _.filter(res, function(obj) {
  132. return obj.partner_id !== session.partner_id;
  133. });
  134. });
  135. },
  136. });
  137. ChatterComposer.include({
  138. init: function(parent, model, suggestedPartners, options) {
  139. this._super(parent, model, suggestedPartners, options);
  140. this.events["click .oe_composer_uncheck"] = "on_uncheck_recipients";
  141. if (typeof options.is_private === "undefined") {
  142. // Otherwise it causes an error in context creating function
  143. options.is_private = false;
  144. }
  145. },
  146. _preprocessMessage: function() {
  147. var self = this;
  148. var def = $.Deferred();
  149. this._super().then(function(message) {
  150. message = _.extend(message, {
  151. subtype: "mail.mt_comment",
  152. message_type: "comment",
  153. context: _.defaults({}, self.context, session.user_context),
  154. });
  155. // Subtype
  156. if (self.options.isLog) {
  157. message.subtype = "mail.mt_note";
  158. }
  159. if (self.options.is_private) {
  160. message.context.is_private = true;
  161. message.channel_ids = self.get_checked_channel_ids();
  162. }
  163. // Partner_ids
  164. if (self.options.isLog) {
  165. def.resolve(message);
  166. } else {
  167. var check_suggested_partners = self._getCheckedSuggestedPartners();
  168. self._checkSuggestedPartners(check_suggested_partners).done(
  169. function(partnerIDs) {
  170. message.partner_ids = (message.partner_ids || []).concat(
  171. partnerIDs
  172. );
  173. // Update context
  174. message.context = _.defaults({}, message.context, {
  175. mail_post_autofollow: true,
  176. });
  177. def.resolve(message);
  178. }
  179. );
  180. }
  181. });
  182. return def;
  183. },
  184. on_uncheck_recipients: function() {
  185. this.$(".o_composer_suggested_partners input:checked").each(function() {
  186. $(this).prop("checked", false);
  187. });
  188. },
  189. _onOpenFullComposer: function() {
  190. if (!this._doCheckAttachmentUpload()) {
  191. return false;
  192. }
  193. var self = this;
  194. var recipientDoneDef = $.Deferred();
  195. this.trigger_up("discard_record_changes", {
  196. proceed: function() {
  197. if (self.options.isLog) {
  198. recipientDoneDef.resolve([]);
  199. } else {
  200. var checkedSuggestedPartners = self._getCheckedSuggestedPartners();
  201. self._checkSuggestedPartners(checkedSuggestedPartners).then(
  202. recipientDoneDef.resolve.bind(recipientDoneDef)
  203. );
  204. }
  205. },
  206. });
  207. recipientDoneDef.then(function(partnerIDs) {
  208. var context = {
  209. default_parent_id: self.id,
  210. default_body: mailUtils.getTextToHTML(self.$input.val()),
  211. default_attachment_ids: _.pluck(self.get("attachment_ids"), "id"),
  212. default_partner_ids: partnerIDs,
  213. default_is_log: self.options.isLog,
  214. mail_post_autofollow: true,
  215. is_private: self.options.is_private,
  216. };
  217. if (self.options && self.options.is_private) {
  218. context.default_is_private = self.options.is_private;
  219. }
  220. if (self.context.default_model && self.context.default_res_id) {
  221. context.default_model = self.context.default_model;
  222. context.default_res_id = self.context.default_res_id;
  223. }
  224. var action = {
  225. type: "ir.actions.act_window",
  226. res_model: "mail.compose.message",
  227. view_mode: "form",
  228. view_type: "form",
  229. views: [[false, "form"]],
  230. target: "new",
  231. context: context,
  232. };
  233. self.do_action(action, {
  234. on_close: self.trigger.bind(self, "need_refresh"),
  235. }).then(self.trigger.bind(self, "close_composer"));
  236. });
  237. },
  238. _getCheckedSuggestedPartners: function() {
  239. var checked_partners = this._super(this, arguments);
  240. // Workaround: odoo code works only when all partners are checked intially,
  241. // while may select only some of them (internal recepients)
  242. _.each(checked_partners, function(partner) {
  243. partner.checked = true;
  244. });
  245. checked_partners = _.uniq(
  246. _.filter(checked_partners, function(obj) {
  247. return obj.reason !== "Channel";
  248. })
  249. );
  250. this.get_checked_channel_ids();
  251. return checked_partners;
  252. },
  253. get_checked_channel_ids: function() {
  254. var self = this;
  255. var checked_channels = [];
  256. this.$(".o_composer_suggested_partners input:checked").each(function() {
  257. var full_name = $(this).data("fullname");
  258. checked_channels = checked_channels.concat(
  259. _.filter(self.suggested_partners, function(item) {
  260. return full_name === item.full_name;
  261. })
  262. );
  263. });
  264. checked_channels = _.uniq(
  265. _.filter(checked_channels, function(obj) {
  266. return obj.reason === "Channel";
  267. })
  268. );
  269. return _.pluck(checked_channels, "channel_id");
  270. },
  271. });
  272. });