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.

297 lines
12 KiB

  1. /* Copyright 2016 x620 <https://github.com/x620>
  2. Copyright 2016 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
  3. Copyright 2016 manawi <https://github.com/manawi>
  4. Copyright 2017 Artyom Losev <https://github.com/ArtyomLosev>
  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 MailComposer = require("mail_base.base").MailComposer;
  11. var chat_manager = require("mail.chat_manager");
  12. var session = require("web.session");
  13. var Model = require("web.Model");
  14. var utils = require("mail.utils");
  15. Chatter.include({
  16. init: function() {
  17. this._super.apply(this, arguments);
  18. this.private = false;
  19. this.events["click .oe_compose_post_private"] =
  20. "on_open_composer_private_message";
  21. },
  22. on_post_message: function(message) {
  23. var self = this;
  24. if (this.private) {
  25. message.subtype = false;
  26. message.channel_ids = this.get_checked_channels_ids();
  27. }
  28. var options = {model: this.model, res_id: this.res_id};
  29. chat_manager
  30. .post_message(message, options)
  31. .then(function() {
  32. self.close_composer();
  33. if (message.partner_ids.length) {
  34. self.refresh_followers();
  35. }
  36. })
  37. .fail(function() {
  38. // Todo: display notification
  39. });
  40. },
  41. on_open_composer_private_message: function(event) {
  42. var self = this;
  43. this.private = true;
  44. this.get_recipients_for_internal_message()
  45. .then(function(data) {
  46. self.recipients_for_internal_message = data;
  47. return self.get_channels_for_internal_message();
  48. })
  49. .then(function(data) {
  50. self.channels_for_internal_message = data;
  51. self.get_internal_users_ids().then(function(res_ids) {
  52. self.open_composer({is_private: true, internal_ids: res_ids});
  53. });
  54. });
  55. },
  56. on_open_composer_new_message: function() {
  57. this._super.apply(this, arguments);
  58. this.private = false;
  59. this.context.is_private = false;
  60. },
  61. open_composer: function(options) {
  62. var self = this;
  63. this._super.apply(this, arguments);
  64. if (options && options.is_private) {
  65. self.internal_users_ids = options.internal_ids;
  66. this.composer.options.is_private = options.is_private;
  67. _.each(self.recipients_for_internal_message, function(partner) {
  68. self.composer.suggested_partners.push({
  69. checked:
  70. _.intersection(self.internal_users_ids, partner.user_ids)
  71. .length > 0,
  72. partner_id: partner.id,
  73. full_name: partner.name,
  74. name: partner.name,
  75. email_address: partner.email,
  76. reason: _.include(partner.user_ids, self.session.uid)
  77. ? "Partner"
  78. : "Follower",
  79. });
  80. });
  81. _.each(self.channels_for_internal_message, function(channel) {
  82. self.composer.suggested_channels.push({
  83. checked: true,
  84. channel_id: channel.id,
  85. full_name: channel.name,
  86. name: "# " + channel.name,
  87. });
  88. });
  89. }
  90. },
  91. get_recipients_for_internal_message: function() {
  92. var self = this;
  93. self.result = {};
  94. return new Model(this.context.default_model)
  95. .query(["message_follower_ids", "partner_id"])
  96. .filter([["id", "=", self.context.default_res_id]])
  97. .all()
  98. .then(function(thread) {
  99. var follower_ids = thread[0].message_follower_ids;
  100. self.result[self.context.default_res_id] = [];
  101. self.customer = thread[0].partner_id;
  102. // Fetch partner ids
  103. return new Model("mail.followers")
  104. .call("read", [follower_ids, ["partner_id"]])
  105. .then(function(res_partners) {
  106. // Filter result and push to array
  107. var res_partners_filtered = _.map(res_partners, function(
  108. partner
  109. ) {
  110. if (
  111. partner.partner_id[0] &&
  112. partner.partner_id[0] !== session.partner_id
  113. ) {
  114. return partner.partner_id[0];
  115. }
  116. }).filter(function(partner) {
  117. return typeof partner !== "undefined";
  118. });
  119. return new Model("res.partner")
  120. .call("read", [
  121. res_partners_filtered,
  122. ["name", "email", "user_ids"],
  123. ])
  124. .then(function(recipients) {
  125. return recipients;
  126. });
  127. });
  128. });
  129. },
  130. get_channels_for_internal_message: function() {
  131. var self = this;
  132. self.result = {};
  133. return new Model(this.context.default_model)
  134. .query(["message_follower_ids", "partner_id"])
  135. .filter([["id", "=", self.context.default_res_id]])
  136. .all()
  137. .then(function(thread) {
  138. var follower_ids = thread[0].message_follower_ids;
  139. self.result[self.context.default_res_id] = [];
  140. self.customer = thread[0].partner_id;
  141. // Fetch channels ids
  142. return new Model("mail.followers")
  143. .call("read", [follower_ids, ["channel_id"]])
  144. .then(function(res_channels) {
  145. // Filter result and push to array
  146. var res_channels_filtered = _.map(res_channels, function(
  147. channel
  148. ) {
  149. if (channel.channel_id[0]) {
  150. return channel.channel_id[0];
  151. }
  152. }).filter(function(channel) {
  153. return typeof channel !== "undefined";
  154. });
  155. return new Model("mail.channel")
  156. .call("read", [res_channels_filtered, ["name", "id"]])
  157. .then(function(recipients) {
  158. return recipients;
  159. });
  160. });
  161. });
  162. },
  163. get_internal_users_ids: function() {
  164. var ResUser = new Model("mail.compose.message");
  165. this.users_ids = ResUser.call("get_internal_users_ids", [[]]).then(function(
  166. users_ids
  167. ) {
  168. return users_ids;
  169. });
  170. return this.users_ids;
  171. },
  172. get_checked_channels_ids: function() {
  173. var self = this;
  174. var checked_channels = [];
  175. this.$(".o_composer_suggested_channels input:checked").each(function() {
  176. var full_name = $(this)
  177. .data("fullname")
  178. .toString();
  179. _.each(self.channels_for_internal_message, function(item) {
  180. if (full_name === item.name) {
  181. checked_channels.push(item.id);
  182. }
  183. });
  184. });
  185. return checked_channels;
  186. },
  187. });
  188. MailComposer.include({
  189. init: function(parent, dataset, options) {
  190. this._super(parent, dataset, options);
  191. this.events["click .oe_composer_uncheck"] = "on_uncheck_recipients";
  192. this.suggested_channels = [];
  193. },
  194. on_uncheck_recipients: function() {
  195. this.$(".o_composer_suggested_partners input:checked").each(function() {
  196. $(this).prop("checked", false);
  197. });
  198. this.$(".o_composer_suggested_channels input:checked").each(function() {
  199. $(this).prop("checked", false);
  200. });
  201. },
  202. preprocess_message: function() {
  203. var self = this;
  204. if (self.options.is_private) {
  205. self.context.is_private = true;
  206. }
  207. return this._super();
  208. },
  209. on_open_full_composer: function() {
  210. if (!this.do_check_attachment_upload()) {
  211. return false;
  212. }
  213. var self = this;
  214. var recipient_done = $.Deferred();
  215. if (this.options.is_log) {
  216. recipient_done.resolve([]);
  217. } else {
  218. var checked_suggested_partners = this.get_checked_suggested_partners();
  219. recipient_done = this.check_suggested_partners(
  220. checked_suggested_partners
  221. );
  222. }
  223. recipient_done.then(function(partner_ids) {
  224. var context = {
  225. default_parent_id: self.id,
  226. default_body: utils.get_text2html(self.$input.val()),
  227. default_attachment_ids: _.pluck(self.get("attachment_ids"), "id"),
  228. default_partner_ids: partner_ids,
  229. default_is_log: self.options.is_log,
  230. mail_post_autofollow: true,
  231. };
  232. if (self.options && self.options.is_private) {
  233. context.default_is_private = self.options.is_private;
  234. }
  235. if (self.context.default_model && self.context.default_res_id) {
  236. context.default_model = self.context.default_model;
  237. context.default_res_id = self.context.default_res_id;
  238. }
  239. self.do_action(
  240. {
  241. type: "ir.actions.act_window",
  242. res_model: "mail.compose.message",
  243. view_mode: "form",
  244. view_type: "form",
  245. views: [[false, "form"]],
  246. target: "new",
  247. context: context,
  248. },
  249. {
  250. on_close: function() {
  251. self.trigger("need_refresh");
  252. var parent = self.getParent();
  253. chat_manager.get_messages({
  254. model: parent.model,
  255. res_id: parent.res_id,
  256. });
  257. },
  258. }
  259. ).then(self.trigger.bind(self, "close_composer"));
  260. });
  261. },
  262. get_checked_suggested_partners: function() {
  263. var checked_partners = this._super(this, arguments);
  264. // Workaround: odoo code works only when all partners are checked intially,
  265. // while may select only some of them (internal recepients)
  266. _.each(checked_partners, function(partner) {
  267. partner.checked = true;
  268. });
  269. return checked_partners;
  270. },
  271. });
  272. });