, )
+ */
+ get_text2html: function(text){
+ return text
+ .replace(/[\n\r]/g,'
')
+ .replace(/((?:https?|ftp):\/\/[\S]+)/g,'$1 ')
+ }
};
@@ -84,160 +109,301 @@ openerp.mail = function(session) {
* This widget handles the display of a form to compose a new message.
* This form is a mail.compose.message form_view.
*/
-
- mail.ComposeMessage = session.web.Widget.extend({
+
+ mail.ThreadComposeMessage = session.web.Widget.extend({
template: 'mail.compose_message',
-
+
/**
* @param {Object} parent parent
* @param {Object} [options]
- * @param {Object} [options.context] context passed to the
- * mail.compose.message DataSetSearch. Please refer to this model
- * for more details about fields and default values.
+ * @param {Object} [context] context passed to the
+ * mail.compose.message DataSetSearch. Please refer to this model
+ * for more details about fields and default values.
+ * @param {Boolean} [show_attachment_delete]
*/
init: function (parent, options) {
var self = this;
this._super(parent);
this.attachment_ids = [];
- // options
- this.options = options || {};
- this.options.context = options.context || {};
- this.options.form_xml_id = options.form_xml_id || 'email_compose_message_wizard_form_chatter';
- this.options.form_view_id = options.form_view_id || false;
- this.show_attachment_delete = true;
+
+ this.context = options.context || {};
+
+ this.id = options.parameters.id;
+ this.model = options.parameters.model;
+ this.res_id = options.parameters.res_id;
+ this.is_private = options.parameters.is_private;
+ this.partner_ids = options.parameters.partner_ids;
+ this.options={thread:{}};
+ this.options.thread.show_header_compose = options.parameters.options.thread.show_header_compose;
+ this.options.thread.display_on_flat = options.parameters.options.thread.display_on_flat;
+
+ this.attachment_ids = [];
+ this.options.thread.show_attachment_delete = true;
+ this.options.thread.show_attachment_link = true;
+
+ this.parent_thread= parent.messages!= undefined ? parent : false;
+
+
+ this.ds_attachment = new session.web.DataSetSearch(this, 'ir.attachment');
+ this.fileupload_id = _.uniqueId('oe_fileupload_temp');
+ $(window).on(self.fileupload_id, self.on_attachment_loaded);
},
- start: function () {
- this._super.apply(this, arguments);
- // customize display: add avatar, clean previous content
+ start: function(){
+ this.display_attachments();
+ this.bind_events();
+
+ //load avatar img
var user_avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid);
this.$('img.oe_mail_icon').attr('src', user_avatar);
- this.$('div.oe_mail_msg_content').empty();
- // create a context for the dataset and default_get of the wizard
- var context = _.extend({}, this.options.context);
- this.ds_compose = new session.web.DataSetSearch(this, 'mail.compose.message', context);
- // find the id of the view to display in the chatter form
- if (this.options.form_view_id) {
- return this.create_form_view();
- }
- else {
- var data_ds = new session.web.DataSetSearch(this, 'ir.model.data');
- return data_ds.call('get_object_reference', ['mail', this.options.form_xml_id]).pipe(this.proxy('create_form_view'));
- }
},
- /** Create a FormView, then append it to the to widget DOM. */
- create_form_view: function (new_form_view_id) {
+ /* upload the file on the server, add in the attachments list and reload display
+ */
+ display_attachments: function(){
var self = this;
- this.options.form_view_id = (new_form_view_id && new_form_view_id[1]) || this.options.form_view_id;
- // destroy previous form_view if any
- if (this.form_view) { this.form_view.destroy(); }
- // create the FormView
- this.form_view = new session.web.FormView(this, this.ds_compose, this.options.form_view_id, {
- action_buttons: false,
- pager: false,
- initial_mode: 'edit',
- disable_autofocus: true,
- });
- // add the form, bind events, activate the form
- var msg_node = this.$('div.oe_mail_msg_content');
- return $.when(this.form_view.appendTo(msg_node)).pipe(this.proxy('postprocess_create_form_view'));
- },
+ var render = $(session.web.qweb.render('mail.thread.message.attachments', {'widget': self}));
+ if(!this.list_attachment){
+ this.$('.oe_mail_compose_attachment_list').replaceWith( render );
+ } else {
+ this.list_attachment.replaceWith( render );
+ }
+ this.list_attachment = this.$("ul.oe_mail_msg_attachments");
- postprocess_create_form_view: function () {
- // handle attachment button
- this.fileupload_id = _.uniqueId('oe_fileupload');
- var button_attach = this.$('button.oe_mail_compose_message_attachment');
- var rendered = session.web.qweb.render('mail.compose_message.add_attachment', {'widget': this});
- $(rendered).insertBefore(button_attach);
- // move the button inside div.oe_hidden_input_file
- var input_node = this.$('input[name=ufile]');
- button_attach.detach().insertAfter(input_node);
- // set the function called when attachments are added
- this.$('input.oe_form_binary_file').change(this.on_attachment_change);
- this.bind_events();
- this.form_view.do_show();
+ // event: delete an attachment
+ this.$el.on('click', '.oe_mail_attachment_delete', self.on_attachment_delete);
},
-
on_attachment_change: function (event) {
+ event.stopPropagation();
+ var self = this;
var $target = $(event.target);
if ($target.val() !== '') {
- this.$('form.oe_form_binary_form').submit();
- session.web.blockUI();
+
+ var filename = $target.val().replace(/.*[\\\/]/,'');
+
+ // if the files exits for this answer, delete the file before upload
+ var attachments=[];
+ for(var i in this.attachment_ids){
+ if((this.attachment_ids[i].filename || this.attachment_ids[i].name) == filename){
+ if(this.attachment_ids[i].upload){
+ return false;
+ }
+ this.ds_attachment.unlink([this.attachment_ids[i].id]);
+ } else {
+ attachments.push(this.attachment_ids[i]);
+ }
+ }
+ this.attachment_ids = attachments;
+
+ // submit file
+ //session.web.blockUI();
+ self.$('form.oe_form_binary_form').submit();
+ //self.submit_ajax_attachment();
+
+ this.$(".oe_attachment_file").hide();
+
+ this.attachment_ids.push({
+ 'id': 0,
+ 'name': filename,
+ 'filename': filename,
+ 'url': '',
+ 'upload': true
+ });
+ this.display_attachments();
}
},
+
+ submit_ajax_attachment: function(){
+ var self=this;
+ var $form = self.$('form.oe_form_binary_form');
+ var filename = this.$('input.oe_form_binary_file').val().replace(/.*[\\\/]/,'');
+ // create form data
+ var fomdata = new FormData();
+ $.each($form.find('input'), function(i, field) {
+ var $field=$(field);
+ if($field.attr('type')!='file'){
+ fomdata.append($field.attr('name'), $field.val());
+ } else {
+ fomdata.append($field.attr('name'), field.files[0]);
+ }
+ });
+
+ var progress=function(event) {
+ self.$("span[name='"+filename+"'] div:lt("+Math.floor(event.loaded / event.total*5)+")").show();
+ };
+
+ $.ajax({
+ url: $form.attr("action"),
+ data: fomdata,
+ cache: false,
+ contentType: false,
+ processData: false,
+ type: 'POST',
+ enctype: 'multipart/form-data',
+ xhr: function() {
+ // custom xhr
+ myXhr = $.ajaxSettings.xhr();
+ if(myXhr.upload){
+ // for handling the progress of the upload
+ myXhr.upload.addEventListener('progress', progress, false);
+ }
+ myXhr.addEventListener('progress', progress, false);
+ return myXhr;
+ },
+ success: function(data){
+ $iframe=$('').html(data);
+ $iframe.appendTo(self.$el);
+ $iframe.remove();
+ }
+ });
+ },
+
+ on_attachment_loaded: function (event, result) {
+ //session.web.unblockUI();
+ for(var i in this.attachment_ids){
+ if(this.attachment_ids[i].filename == result.filename && this.attachment_ids[i].upload){
+ this.attachment_ids[i]={
+ 'id': result.id,
+ 'name': result.name,
+ 'filename': result.filename,
+ 'url': mail.ChatterUtils.get_attachment_url(this.session, result)
+ };
+ }
+ }
+ this.display_attachments();
+
+ var $input = this.$('input.oe_form_binary_file');
+ $input.after($input.clone(true)).remove();
+ this.$(".oe_attachment_file").show();
+ },
+ /* unlink the file on the server and reload display
+ */
on_attachment_delete: function (event) {
- if (event.target.dataset && event.target.dataset.id) {
- var attachment_id = parseInt(event.target.dataset.id);
- var idx = _.pluck(this.attachment_ids, 'id').indexOf(attachment_id);
- if (idx == -1) return false;
- new session.web.DataSetSearch(this, 'ir.attachment').unlink(attachment_id);
- this.attachment_ids.splice(idx, 1);
+ event.stopPropagation();
+ var attachment_id=$(event.target).data("id");
+ if (attachment_id) {
+ var attachments=[];
+ for(var i in this.attachment_ids){
+ if(attachment_id!=this.attachment_ids[i].id){
+ attachments.push(this.attachment_ids[i]);
+ }
+ else {
+ this.ds_attachment.unlink([attachment_id]);
+ }
+ }
+ this.attachment_ids = attachments;
this.display_attachments();
}
},
- display_attachments: function () {
- var attach_node = this.$('div.oe_mail_compose_message_attachments');
- var rendered = session.web.qweb.render('mail.thread.message.attachments', {'record': this});
- attach_node.empty();
- $(rendered).appendTo(attach_node);
- this.$('.oe_mail_msg_attachments').show();
- var composer_attachment_ids = _.pluck(this.attachment_ids, 'id');
- var onchange_like = {'value': {'attachment_ids': composer_attachment_ids}}
- this.form_view.on_processed_onchange(onchange_like, []);
- },
-
- /**
- * Reinitialize the widget field values to the default values obtained
- * using default_get on mail.compose.message. This allows to reinitialize
- * the widget without having to rebuild a complete form view.
- * @param {Object} new_context: context of the refresh */
- refresh: function (new_context) {
- if (! this.form_view) return;
- var self = this;
- this.attachments = [];
- this.options.context = _.extend(this.options.context, new_context || {});
- this.ds_compose.context = _.extend(this.ds_compose.context, this.options.context);
- return this.ds_compose.call('default_get', [
- ['subject', 'body_text', 'body', 'partner_ids', 'composition_mode',
- 'use_template', 'template_id', 'model', 'res_id', 'parent_id', 'content_subtype'],
- this.ds_compose.get_context(),
- ]).then( function (result) {
- self.form_view.on_processed_onchange({'value': result}, []);
- self.attachment_ids = [];
+ /* to avoid having unsorted file on the server.
+ we will show the users files of the first message post
+ */
+ set_free_attachments: function(){
+ var self=this;
+ this.parent_thread.ds_message.call('user_free_attachment').then(function(attachments){
+ this.attachment_ids=[];
+ for(var i in attachments){
+ self.attachment_ids[i]={
+ 'id': attachments[i].id,
+ 'name': attachments[i].name,
+ 'filename': attachments[i].filename,
+ 'url': mail.ChatterUtils.get_attachment_url(self.session, attachments[i])
+ };
+ }
self.display_attachments();
});
},
- /**
- * Bind events in the widget. Each event is slightly described
- * in the function. */
bind_events: function() {
var self = this;
- // event: add a new attachment
- $(window).on(this.fileupload_id, function() {
- var args = [].slice.call(arguments).slice(1);
- var attachment = args[0];
- attachment['url'] = mail.ChatterUtils.get_attachment_url(self.session, attachment);
- self.attachment_ids.push(attachment);
- self.display_attachments();
- session.web.unblockUI();
- });
- // event: delete an attachment
- this.$el.on('click', '.oe_mail_attachment_delete', self.on_attachment_delete);
+
+ // set the function called when attachments are added
+ this.$el.on('change', 'input.oe_form_binary_file', self.on_attachment_change );
+ this.$el.on('click', 'a.oe_cancel', self.on_cancel );
+ this.$el.on('click', 'button.oe_post', function(){self.on_message_post()} );
+ this.$el.on('click', 'button.oe_full', function(){self.on_compose_fullmail()} );
},
- }),
-
+
+ on_compose_fullmail: function(){
+ var attachments=[];
+ for(var i in this.attachment_ids){
+ attachments.push(this.attachment_ids[i].id);
+ }
+ var action = {
+ type: 'ir.actions.act_window',
+ res_model: 'mail.compose.message',
+ view_mode: 'form',
+ view_type: 'form',
+ action_from: 'mail.ThreadComposeMessage',
+ views: [[false, 'form']],
+ target: 'new',
+ context: {
+ 'default_res_model': this.context.default_res_model,
+ 'default_res_id': this.context.default_res_id,
+ 'default_content_subtype': 'html',
+ 'default_is_private': true,
+ 'default_parent_id': this.id,
+ 'default_body': mail.ChatterUtils.get_text2html(this.$('textarea').val() || ''),
+ 'default_attachment_ids': attachments
+ },
+ };
+ this.do_action(action);
+ },
+
+ on_cancel: function(){
+ event.stopPropagation();
+ this.$('textarea').val("");
+ this.$('input[data-id]').remove();
+ //this.attachment_ids=[];
+ this.display_attachments();
+ if(!this.options.thread.show_header_compose || !this.options.thread.display_on_flat){
+ this.$el.hide();
+ }
+ },
+
+ /*post a message and fetch the message*/
+ on_message_post: function (body) {
+
+ if (! body) {
+ var comment_node = this.$('textarea');
+ var body = comment_node.val();
+ comment_node.val('');
+ }
+
+ var attachments=[];
+ for(var i in this.attachment_ids){
+ if(this.attachment_ids[i].upload){
+ session.web.dialog($('
+ | |
+ + + | +
+ When you sell this service, nothing special will be trigered + to deliver the customer, as you set the procurement method as + 'Make to Stock'. +
+
+ When you sell this product, OpenERP will use the available
+ inventory for the delivery order.
+
+ If there are not enough quantities available, the delivery order
+ will wait for new products. To fulfill the inventory, you should
+ create others rules like orderpoints.
+
+ When you sell this product, a delivery order will be created. + OpenERP will consider that the required quantities are always + available as it's a consumable (as a result of this, the quantity + on hand may become negative). +
+