diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 3e86c4963b7..35afac5a508 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -391,29 +391,33 @@ class account_invoice(osv.osv):
'''
This function opens a window to compose an email, with the edi invoice template message loaded by default
'''
- mod_obj = self.pool.get('ir.model.data')
- template = mod_obj.get_object_reference(cr, uid, 'account', 'email_template_edi_invoice')
- template_id = template and template[1] or False
- res = mod_obj.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')
- res_id = res and res[1] or False
+ assert len(ids) == 1, 'This option should only be used for a single id at a time.'
+ ir_model_data = self.pool.get('ir.model.data')
+ try:
+ template_id = ir_model_data.get_object_reference(cr, uid, 'account', 'email_template_edi_invoice')[1]
+ except ValueError:
+ template_id = False
+ try:
+ compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1]
+ except ValueError:
+ compose_form_id = False
ctx = dict(context)
ctx.update({
'default_model': 'account.invoice',
'default_res_id': ids[0],
- 'default_use_template': True,
+ 'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
})
return {
+ 'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.compose.message',
- 'views': [(res_id, 'form')],
- 'view_id': res_id,
- 'type': 'ir.actions.act_window',
+ 'views': [(compose_form_id, 'form')],
+ 'view_id': compose_form_id,
'target': 'new',
'context': ctx,
- 'nodestroy': True,
}
def confirm_paid(self, cr, uid, ids, context=None):
diff --git a/addons/account/edi/invoice.py b/addons/account/edi/invoice.py
index 751eb8656f7..3e27bc5ea99 100644
--- a/addons/account/edi/invoice.py
+++ b/addons/account/edi/invoice.py
@@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Business Applications
-# Copyright (c) 2011 OpenERP S.A.
% endif
+ % if object.user_id:
Your contact: ${object.user_id.name}
+ % endif
- You can view the invoice document, download it and pay online using the following link: -
- View Invoice - % if object.company_id.paypal_account and object.type in ('out_invoice', 'in_refund'): <% comp_name = quote(object.company_id.name) diff --git a/addons/account/res_config_view.xml b/addons/account/res_config_view.xml index 52c8c8daaa9..4bfd3697d89 100644 --- a/addons/account/res_config_view.xml +++ b/addons/account/res_config_view.xml @@ -227,7 +227,7 @@Hello,
+I am interested in your company's products and I plan to buy a new laptop having latest technologies as well as an affordable price.
+Could you please send me the product catalog?
]]>Best regards,
]]>After our phonecall and discussion with our technical experts, here is the offer of YourCompany. We believe it will meet every requirement you had in mind. Please feel free to contact me for any detail or technical detail that is not clear enough for you.
+Notice that as agreed on phone, we offer you a 10% discount on the hardware!
+Best regards,
]]> styling */
- white-space: pre-line;
- width: 90%;
-}
-.oe_edi_data_row .oe_edi_inner_note {
- /* prevent wide notes from disrupting layout due to styling */
- width: 25em;
-}
-.oe_edi_shade {
- background: #e8e8e8;
-}
-.oe_edi_company_name {
- text-transform: uppercase;
- font-weight: bold;
-}
-.oe_edi_address_from {
- float: left;
-}
-.oe_edi_address_to {
- float: right;
- margin-top: 25px;
- margin-bottom: 30px;
-}
-.oe_edi_company_block_title {
- width: 375px;
- margin: 0px;
- padding: 2px 14px;
- background-color: #252525;
- border-top-left-radius: 5px 5px;
- border-top-right-radius: 5px 5px;
- background-repeat: repeat no-repeat;
-}
-.oe_edi_company_block_title .oe_edi_company_name {
- margin: 0px;
- font-size: 1em;
- color: #FFF;
-}
-.oe_edi_company_block_body {
- width: 375px;
- margin: 0px;
- padding: 5px 14px;
- line-height: 16px;
- background-color: rgb(242, 242, 242);
-}
-.oe_edi_company_block_body p {
- color: #222;
- margin: 5px 0px;
-}
-.oe_edi_summary_label {
- float: left;
-}
-.oe_edi_summary_value {
- float: right;
-}
-
-
-/** Python code highlighting **/
-/* GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
- (http://qbnz.com/highlighter/ and http://geshi.org/) */
-.python .de1, .python .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
-.python {font-family:monospace;}
-.python .imp {font-weight: bold; color: red;}
-.python li, .python .li1 {background: #ffffff; list-style: none;}
-.python .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
-.python .li2 {background: #f8f8f8;}
-.python .kw1 {color: #ff7700;font-weight:bold;}
-.python .kw2 {color: #008000;}
-.python .kw3 {color: #dc143c;}
-.python .kw4 {color: #0000cd;}
-.python .co1 {color: #808080; font-style: italic;}
-.python .coMULTI {color: #808080; font-style: italic;}
-.python .es0 {color: #000099; font-weight: bold;}
-.python .br0 {color: black;}
-.python .sy0 {color: #66cc66;}
-.python .st0 {color: #483d8b;}
-.python .nu0 {color: #ff4500;}
-.python .me1 {color: black;}
-.python span.xtra { display:block; }
-.python ol { padding: 0px; }
diff --git a/addons/edi/static/src/img/pdf.png b/addons/edi/static/src/img/pdf.png
deleted file mode 100644
index d35dfd20c2d..00000000000
Binary files a/addons/edi/static/src/img/pdf.png and /dev/null differ
diff --git a/addons/edi/static/src/js/edi.js b/addons/edi/static/src/js/edi.js
index a9c6981c6be..ee4ddbb5e87 100644
--- a/addons/edi/static/src/js/edi.js
+++ b/addons/edi/static/src/js/edi.js
@@ -1,119 +1,9 @@
-openerp.edi = function(openerp) {
-openerp.edi = {}
+openerp.edi = function(instance) {
+var _t = instance.web._t;
+instance.edi = {}
-openerp.edi.EdiView = openerp.web.Widget.extend({
- init: function(parent, db, token) {
- this._super();
- this.db = db;
- this.token = token;
- this.session = openerp.session;
- this.template = "EdiEmpty";
- this.content = "";
- this.sidebar = "";
- },
- start: function() {
- this._super();
- var self = this;
- var param = {"db": self.db, "token": self.token};
- return self.rpc('/edi/get_edi_document', param).done(this.on_document_loaded).fail(this.on_document_failed);
- },
- on_document_loaded: function(docs){
- this.doc = docs[0];
- var template_content = "Edi." + this.doc.__model + ".content";
- var template_sidebar = "Edi." + this.doc.__model + ".sidebar";
- var param = {"widget":this, "doc":this.doc};
- if (openerp.web.qweb.templates[template_sidebar]) {
- this.sidebar = openerp.web.qweb.render(template_sidebar, param);
- }
- if (openerp.web.qweb.templates[template_content]) {
- this.content = openerp.web.qweb.render(template_content, param);
- }
- this.$el.html(openerp.web.qweb.render("EdiView", param));
- this.$el.find('button.oe_edi_action_print').bind('click', this.do_print);
- this.$el.find('button#oe_edi_import_existing').bind('click', this.do_import_existing);
- this.$el.find('button#oe_edi_import_create').bind('click', this.do_import_create);
- this.$el.find('button#oe_edi_download').bind('click', this.do_download);
- this.$el.find('.oe_edi_import_choice, .oe_edi_import_choice_label').bind('click', this.toggle_choice('import'));
- this.$el.find('.oe_edi_pay_choice, .oe_edi_pay_choice_label').bind('click', this.toggle_choice('pay'));
- this.$el.find('#oe_edi_download_show_code').bind('click', this.show_code);
- },
- on_document_failed: function(response) {
- var self = this;
- var params = {
- error: response,
- //TODO: should this be _t() wrapped?
- message: "Sorry, this document cannot be located. Perhaps the link you are using has expired?"
- }
- $(openerp.web.qweb.render("DialogWarning", params)).dialog({
- title: "Document not found",
- modal: true,
- });
- },
- show_code: function($event) {
- $('#oe_edi_download_code').toggle();
- },
- get_download_url: function() {
- var l = window.location;
- var url_prefix = l.protocol + '//' + l.host;
- return url_prefix +'/edi/download?db=' + this.db + '&token=' + this.token;
- },
- get_paypal_url: function(document_type, ref_field) {
- var comp_name = encodeURIComponent(this.doc.company_id[1]);
- var doc_ref = encodeURIComponent(this.doc[ref_field]);
- var paypal_account = encodeURIComponent(this.doc.company_address.paypal_account);
- var amount = encodeURIComponent(this.doc.amount_total);
- var cur_code = encodeURIComponent(this.doc.currency.code);
- var paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick" +
- "&business=" + paypal_account +
- "&item_name=" + document_type + "%20" + comp_name + "%20" + doc_ref +
- "&invoice=" + doc_ref +
- "&amount=" + amount +
- "¤cy_code=" + cur_code +
- "&button_subtype=services&no_note=1&bn=OpenERP_PayNow_" + cur_code;
- return paypal_url;
- },
- toggle_choice: function(mode) {
- return function($e) {
- $('.oe_edi_nested_block_'+mode).hide();
- $('.'+$e.target.id+'_nested').show();
- return true;
- }
- },
- do_print: function(e){
- var l = window.location;
- window.location = l.protocol + '//' + l.host + "/edi/download_attachment?db=" + this.db + "&token=" + this.token;
- },
- do_import_existing: function(e) {
- var url_download = this.get_download_url();
- var $edi_text_server_input = this.$el.find('#oe_edi_txt_server_url');
- var server_url = $edi_text_server_input.val();
- $edi_text_server_input.removeClass('invalid');
- if (!server_url) {
- $edi_text_server_input.addClass('invalid');
- return false;
- }
- var protocol = "http://";
- if (server_url.toLowerCase().lastIndexOf('http', 0) == 0 ) {
- protocol = '';
- }
- window.location = protocol + server_url + '/edi/import_url?url=' + encodeURIComponent(url_download);
- },
- do_import_create: function(e){
- var url_download = this.get_download_url();
- window.location = "https://cc.my.openerp.com/odms/create_edi?url=" + encodeURIComponent(url_download);
- },
- do_download: function(e){
- window.location = this.get_download_url();
- }
-});
+instance.edi.EdiImport = instance.web.Widget.extend({
-openerp.edi.edi_view = function (db, token) {
- openerp.session.session_bind().done(function () {
- new openerp.edi.EdiView(null,db,token).appendTo($("body").addClass('openerp'));
- });
-}
-
-openerp.edi.EdiImport = openerp.web.Widget.extend({
init: function(parent,url) {
this._super();
this.url = url;
@@ -137,7 +27,7 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({
show_login: function() {
this.destroy_content();
- this.login = new openerp.web.Login(this);
+ this.login = new instance.web.Login(this);
this.login.appendTo(this.$el);
},
@@ -167,18 +57,18 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({
window.location = "/";
}
}
- }).html('The document has been successfully imported!');
+ }).html(_t('The document has been successfully imported!'));
}
},
on_imported_error: function(response){
var self = this;
- var msg = "Sorry, the document could not be imported.";
+ var msg = _t("Sorry, the document could not be imported.");
if (response.data.fault_code) {
- msg += "\n Reason:" + response.data.fault_code;
+ msg += "\n " + _t("Reason:") + response.data.fault_code;
}
var params = {error: response, message: msg};
- $(openerp.web.qweb.render("CrashManagerWarning", params)).dialog({
- title: "Document Import Notification",
+ $(instance.web.qweb.render("CrashManager.warning", params)).dialog({
+ title: _t("Document Import Notification"),
modal: true,
buttons: {
Ok: function() { $(this).dialog("close"); }
@@ -187,9 +77,9 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({
}
});
-openerp.edi.edi_import = function (url) {
- openerp.session.session_bind().done(function () {
- new openerp.edi.EdiImport(null,url).appendTo($("body").addClass('openerp'));
+instance.edi.edi_import = function (url) {
+ instance.session.session_bind().done(function () {
+ new instance.edi.EdiImport(null,url).appendTo($("body").addClass('openerp'));
});
}
diff --git a/addons/edi/static/src/xml/edi.xml b/addons/edi/static/src/xml/edi.xml
deleted file mode 100644
index 111cb6d9d26..00000000000
--- a/addons/edi/static/src/xml/edi.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- OpenERP's Electronic Data Interchange documents are based on a generic and language
- independent JSON serialization of the document's attribute.
- It is usually very quick and straightforward to create a small plug-in for your preferred
- application that will be capable of importing any OpenERP EDI document.
- You can find out more details about how to do this and what the content of OpenERP EDI documents
- is like in the OpenERP documentation.
-
- To get started immediately, see is all it takes to use this EDI document in Python.
-
-
- - import urllib2, simplejson
- - edi_document = urllib2.urlopen('
').read()
- - document_data = simplejson.loads(edi_document)[0]
- - print "Amount: ", document_data['amount_total']
-
-
- You can download the raw EDI document here:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/edi/static/src/xml/edi_account.xml b/addons/edi/static/src/xml/edi_account.xml
deleted file mode 100644
index 3ce1daebf93..00000000000
--- a/addons/edi/static/src/xml/edi_account.xml
+++ /dev/null
@@ -1,163 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Invoice :
-
-
- Description
- Date
- Your Reference
-
-
-
-
-
-
-
-
-
-
- Product Description
- Quantity
- Unit Price
- Discount
- Price
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Net Total:
-
-
-
-
-
-
-
-
-
-
- Taxes:
-
-
-
-
-
-
-
-
-
-
- Total:
-
-
-
-
-
-
-
-
-
-
- Tax
- Base Amount
- Amount
-
-
-
-
-
-
-
-
-
-
-
-
- Notes:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- You may directly pay this invoice online via Paypal's secure payment gateway:
-
-
-
-
-
-
-
-
-
-
-
- Please transfer to
- (postal address on the invoice header)
- using one of the following bank accounts. Be sure to mention the invoice
- reference on the transfer:
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/edi/static/src/xml/edi_sale_purchase.xml b/addons/edi/static/src/xml/edi_sale_purchase.xml
deleted file mode 100644
index 8d6bab67761..00000000000
--- a/addons/edi/static/src/xml/edi_sale_purchase.xml
+++ /dev/null
@@ -1,169 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Quotation :
-
-
- Request for Quotation :
-
-
- Order :
-
-
-
-
- Your Reference
- Date
- Salesperson
- Payment terms
-
-
-
-
-
-
-
-
-
-
-
-
-
- Product Description
- Quantity
- Unit Price
- Discount(%)
- Price
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Net Total:
-
-
-
-
-
-
-
-
-
-
- Taxes:
-
-
-
-
-
-
-
-
-
-
- Total:
-
-
-
-
-
-
-
-
- Notes:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- You may directly pay this order online via Paypal's secure payment gateway:
-
-
-
-
-
-
-
-
-
-
-
- Please transfer to
- (postal address on the order header)
- using one of the following bank accounts. Be sure to mention the document
- reference on the transfer:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/edi/test/edi_partner_test.yml b/addons/edi/test/edi_partner_test.yml
index 9fc523bf84f..97ae669e52e 100644
--- a/addons/edi/test/edi_partner_test.yml
+++ b/addons/edi/test/edi_partner_test.yml
@@ -6,11 +6,10 @@
with an attached file, check the result, the alter the data
and reimport it.
-
- !python {model: edi.document}: |
+ !python {model: edi.edi}: |
import json
- partner_obj = self.pool.get('res.partner')
- tokens = self.export_edi(cr, uid, [partner_obj.browse(cr, uid, ref('base.res_partner_2'))])
- doc = self.get_document(cr, uid, tokens[0], context=context)
+ res_partner = self.pool.get('res.partner')
+ doc = self.generate_edi(cr, uid, [res_partner.browse(cr, uid, ref('base.res_partner_2'))])
edi_doc, = json.loads(doc)
# check content of the document
@@ -36,8 +35,7 @@
"Expected (%r,> %r) after import 1, got %r" % ('res.partner', ref('base.res_partner_2'), result)
# export the same partner we just created, and see if the output matches the input
- tokens = self.export_edi(cr, uid, [partner_obj.browse(cr, uid, result[1])])
- doc_output = self.get_document(cr, uid, tokens[0], context=context)
+ doc_output = self.generate_edi(cr, uid, [res_partner.browse(cr, uid, result[1])])
edi_doc_output, = json.loads(doc_output)
for attribute in ('__model', '__module', '__id', 'name', '__attachments'):
assert edi_doc_output.get(attribute) == edi_doc.get(attribute), \
diff --git a/addons/email_template/tests/test_mail.py b/addons/email_template/tests/test_mail.py
index 7c69295ce9f..8837796bf9f 100644
--- a/addons/email_template/tests/test_mail.py
+++ b/addons/email_template/tests/test_mail.py
@@ -100,25 +100,27 @@ class test_message_compose(test_mail_mockup.TestMailMockups):
# ----------------------------------------
# 1. Comment on pigs
- compose_id = mail_compose.create(cr, uid,
- {'subject': 'Forget me subject', 'body': 'Dummy body'},
- {'default_composition_mode': 'comment',
- 'default_model': 'mail.group',
- 'default_res_id': self.group_pigs_id,
- 'default_use_template': False,
- 'default_template_id': email_template_id,
- 'active_ids': [self.group_pigs_id, self.group_bird_id]})
- compose = mail_compose.browse(cr, uid, compose_id)
-
- # 2. Perform 'toggle_template', to set use_template and use template_id
- mail_compose.toggle_template(cr, uid, [compose_id], {'default_composition_mode': 'comment', 'default_model': 'mail.group'})
+ context = {
+ 'default_composition_mode': 'comment',
+ 'default_model': 'mail.group',
+ 'default_res_id': self.group_pigs_id,
+ 'default_use_template': False,
+ 'default_template_id': email_template_id,
+ 'active_ids': [self.group_pigs_id, self.group_bird_id]
+ }
+ compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body'}, context)
+ compose = mail_compose.browse(cr, uid, compose_id, context)
+ onchange_res = compose.onchange_template_id(email_template_id, 'comment', 'mail.group', self.group_pigs_id)['value']
+ onchange_res['partner_ids'] = [(4, partner_id) for partner_id in onchange_res.pop('partner_ids', [])]
+ onchange_res['attachment_ids'] = [(4, attachment_id) for attachment_id in onchange_res.pop('attachment_ids', [])]
+ compose.write(onchange_res)
compose.refresh()
+
message_pids = [partner.id for partner in compose.partner_ids]
partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
- # Test: mail.compose.message: subject, body, content_subtype, partner_ids
+ # Test: mail.compose.message: subject, body, partner_ids
self.assertEqual(compose.subject, _subject1, 'mail.compose.message subject incorrect')
self.assertEqual(compose.body, _body_html1, 'mail.compose.message body incorrect')
- self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message content_subtype incorrect')
self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
# Test: mail.compose.message: attachments
# Test: mail.message: attachments
@@ -128,41 +130,34 @@ class test_message_compose(test_mail_mockup.TestMailMockups):
self.assertIn((attach.name, base64.b64decode(attach.datas)), _attachments_test,
'mail.message attachment name / data incorrect')
- # 3. Perform 'toggle_template': template is not set anymore
- mail_compose.toggle_template(cr, uid, [compose_id], {'default_composition_mode': 'comment', 'default_model': 'mail.group'})
- compose.refresh()
- # Test: subject, body, partner_ids
- self.assertEqual(compose.subject, False, 'mail.compose.message subject incorrect')
- self.assertEqual(compose.body, '', 'mail.compose.message body incorrect')
-
# ----------------------------------------
# CASE3: mass_mail with template
# ----------------------------------------
# 1. Mass_mail on pigs and bird, with a default_partner_ids set to check he is correctly added
- compose_id = mail_compose.create(cr, uid,
- {'subject': 'Forget me subject', 'body': 'Dummy body'},
- {'default_composition_mode': 'mass_mail',
- 'default_model': 'mail.group',
- 'default_res_id': self.group_pigs_id,
- 'default_use_template': False,
- 'default_template_id': email_template_id,
- 'default_partner_ids': [p_a_id],
- 'active_ids': [self.group_pigs_id, self.group_bird_id]})
- compose = mail_compose.browse(cr, uid, compose_id)
-
- # 2. Perform 'toggle_template', to set use_template and use template_id
- mail_compose.toggle_template(cr, uid, [compose_id], {'default_composition_mode': 'comment', 'default_model': 'mail.group'})
+ context = {
+ 'default_composition_mode': 'mass_mail',
+ 'default_model': 'mail.group',
+ 'default_res_id': self.group_pigs_id,
+ 'default_template_id': email_template_id,
+ 'default_partner_ids': [p_a_id],
+ 'active_ids': [self.group_pigs_id, self.group_bird_id]
+ }
+ compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body'}, context)
+ compose = mail_compose.browse(cr, uid, compose_id, context)
+ onchange_res = compose.onchange_template_id(email_template_id, 'mass_mail', 'mail.group', self.group_pigs_id)['value']
+ onchange_res['partner_ids'] = [(4, partner_id) for partner_id in onchange_res.pop('partner_ids', [])]
+ onchange_res['attachment_ids'] = [(4, attachment_id) for attachment_id in onchange_res.pop('attachment_ids', [])]
+ compose.write(onchange_res)
compose.refresh()
+
message_pids = [partner.id for partner in compose.partner_ids]
partner_ids = [p_a_id]
- # Test: mail.compose.message: subject, body, content_subtype, partner_ids
self.assertEqual(compose.subject, '${object.name}', 'mail.compose.message subject incorrect')
self.assertEqual(compose.body, '${object.description}', 'mail.compose.message body incorrect')
- self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message content_subtype incorrect')
self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
- # 3. Post the comment, get created message
+ # 2. Post the comment, get created message
mail_compose.send_mail(cr, uid, [compose_id], {'default_res_id': -1, 'active_ids': [self.group_pigs_id, self.group_bird_id]})
group_pigs.refresh()
group_bird.refresh()
diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py
index e9141029166..168d93cdbe5 100644
--- a/addons/email_template/wizard/mail_compose_message.py
+++ b/addons/email_template/wizard/mail_compose_message.py
@@ -19,11 +19,8 @@
#
##############################################################################
-import tools
-
-from osv import osv
-from osv import fields
-
+from openerp import tools
+from openerp.osv import osv, fields
def _reopen(self, res_id, model):
return {'type': 'ir.actions.act_window',
@@ -39,7 +36,6 @@ def _reopen(self, res_id, model):
},
}
-
class mail_compose_message(osv.TransientModel):
_inherit = 'mail.compose.message'
@@ -60,37 +56,19 @@ class mail_compose_message(osv.TransientModel):
record_ids = email_template_obj.search(cr, uid, [('model', '=', model)], context=context)
return email_template_obj.name_get(cr, uid, record_ids, context) + [(False, '')]
- def default_get(self, cr, uid, fields, context=None):
- if context is None:
- context = {}
- result = super(mail_compose_message, self).default_get(cr, uid, fields, context=context)
- result['template_id'] = context.get('default_template_id', context.get('mail.compose.template_id', False))
-
- # pre-render the template if any
- if result.get('use_template') and result.get('template_id'):
- onchange_res = self.onchange_use_template(cr, uid, [], result.get('use_template'), result.get('template_id'),
- result.get('composition_mode'), result.get('model'), result.get('res_id'), context=context)
- result.update(onchange_res['value'])
- return result
-
_columns = {
- 'use_template': fields.boolean('Use Template'),
# incredible hack of the day: size=-1 means we want an int db column instead of an str one
'template_id': fields.selection(_get_templates, 'Template', size=-1),
}
- _defaults = {
- 'use_template': True,
- }
-
- def onchange_template_id(self, cr, uid, ids, use_template, template_id, composition_mode, model, res_id, context=None):
- """ - use_template not set: return default_get
- - use_template set in mass_mailing: we cannot render, so return the template values
- - use_template set: return rendered values """
- if use_template and template_id and composition_mode == 'mass_mail':
+ def onchange_template_id(self, cr, uid, ids, template_id, composition_mode, model, res_id, context=None):
+ """ - mass_mailing: we cannot render, so return the template values
+ - normal mode: return rendered values """
+ if template_id and composition_mode == 'mass_mail':
values = self.pool.get('email.template').read(cr, uid, template_id, ['subject', 'body_html'], context)
values.pop('id')
- elif use_template and template_id:
+ elif template_id:
+ # FIXME odo: change the mail generation to avoid attachment duplication
values = self.generate_email_for_composer(cr, uid, template_id, res_id, context=context)
# transform attachments into attachment_ids
values['attachment_ids'] = []
@@ -102,39 +80,16 @@ class mail_compose_message(osv.TransientModel):
'datas_fname': attach_fname,
'res_model': model,
'res_id': res_id,
- 'type': 'binary', # overwrite the context default_value
+ 'type': 'binary', # override default_type from context, possibly meant for another model!
}
values['attachment_ids'].append(ir_attach_obj.create(cr, uid, data_attach, context=context))
else:
- values = self.default_get(cr, uid, ['body', 'body_html', 'subject', 'partner_ids', 'attachment_ids'], context=context)
+ values = self.default_get(cr, uid, ['body', 'subject', 'partner_ids', 'attachment_ids'], context=context)
if values.get('body_html'):
values['body'] = values.pop('body_html')
- values.update(use_template=use_template, template_id=template_id)
return {'value': values}
- def toggle_template(self, cr, uid, ids, context=None):
- """ hit toggle template mode button: calls onchange_use_template to
- emulate an on_change, then writes the values to update the form. """
- for record in self.browse(cr, uid, ids, context=context):
- onchange_res = self.onchange_use_template(cr, uid, ids, not record.use_template,
- record.template_id, record.composition_mode, record.model, record.res_id, context=context).get('value', {})
- # update partner_ids and attachment_ids
- onchange_res['partner_ids'] = [(4, partner_id) for partner_id in onchange_res.pop('partner_ids', [])]
- onchange_res['attachment_ids'] = [(4, attachment_id) for attachment_id in onchange_res.pop('attachment_ids', [])]
- record.write(onchange_res)
- return _reopen(self, record.id, record.model)
-
- def onchange_use_template(self, cr, uid, ids, use_template, template_id, composition_mode, model, res_id, context=None):
- """ onchange_use_template (values: True or False). If use_template is
- False, we do as an onchange with template_id False for values """
- values = self.onchange_template_id(cr, uid, ids, use_template,
- template_id, composition_mode, model, res_id, context=context)
- # force html when using templates
- if use_template:
- values['value']['content_subtype'] = 'html'
- return values
-
def save_as_template(self, cr, uid, ids, context=None):
""" hit save as template button: current form value will be a new
template attached to the current document. """
@@ -155,7 +110,7 @@ class mail_compose_message(osv.TransientModel):
'attachment_ids': [(6, 0, [att.id for att in record.attachment_ids])]
}
template_id = email_template.create(cr, uid, values, context=context)
- record.write(record.onchange_template_id(True, template_id, record.composition_mode, record.model, record.res_id)['value'])
+ record.write(record.onchange_template_id(template_id, record.composition_mode, record.model, record.res_id)['value'])
return _reopen(self, record.id, record.model)
#------------------------------------------------------
@@ -167,7 +122,7 @@ class mail_compose_message(osv.TransientModel):
mail.compose.message, transform email_cc and email_to into partner_ids """
template_values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
# filter template values
- fields = ['body', 'body_html', 'subject', 'email_to', 'email_recipients', 'email_cc', 'attachments']
+ fields = ['body_html', 'subject', 'email_to', 'email_recipients', 'email_cc', 'attachments']
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
values['body'] = values.pop('body_html', '')
# transform email_to, email_cc into partner_ids
diff --git a/addons/email_template/wizard/mail_compose_message_view.xml b/addons/email_template/wizard/mail_compose_message_view.xml
index 5afaf9745e1..34a2112e1ac 100644
--- a/addons/email_template/wizard/mail_compose_message_view.xml
+++ b/addons/email_template/wizard/mail_compose_message_view.xml
@@ -7,25 +7,17 @@
mail.compose.message
-
-
-
-
-
-
- Use template
-
-
-
-
-
-
+
+
+ Use template
+
+
+
+
+
diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py
index 155f20daf4d..de1539da55a 100644
--- a/addons/hr_recruitment/hr_recruitment.py
+++ b/addons/hr_recruitment/hr_recruitment.py
@@ -356,7 +356,8 @@ class hr_applicant(base_stage, osv.Model):
"""
if isinstance(ids, (str, int, long)):
ids = [ids]
- if update_vals is None: vals = {}
+ if update_vals is None:
+ update_vals = {}
update_vals.update({
'description': msg.get('body'),
@@ -373,12 +374,12 @@ class hr_applicant(base_stage, osv.Model):
}
for line in msg.get('body', '').split('\n'):
line = line.strip()
- res = tools.misc.command_re.match(line)
+ res = tools.command_re.match(line)
if res and maps.get(res.group(1).lower(), False):
key = maps.get(res.group(1).lower())
update_vals[key] = res.group(2).lower()
- return super(hr_applicant, self).message_update(cr, uids, ids, update_vals=update_vals, context=context)
+ return super(hr_applicant, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
def create(self, cr, uid, vals, context=None):
obj_id = super(hr_applicant, self).create(cr, uid, vals, context=context)
@@ -420,7 +421,7 @@ class hr_applicant(base_stage, osv.Model):
self.write(cr, uid, [applicant.id], {'emp_id': emp_id}, context=context)
self.case_close(cr, uid, [applicant.id], context)
else:
- raise osv.except_osv(_('Warning!'),_('You must define Applied Job for this applicant.'))
+ raise osv.except_osv(_('Warning!'), _('You must define Applied Job for this applicant.'))
action_model, action_id = model_data.get_object_reference(cr, uid, 'hr', 'open_view_employee_list')
dict_act_window = act_window.read(cr, uid, action_id, [])
@@ -433,13 +434,13 @@ class hr_applicant(base_stage, osv.Model):
"""Overrides cancel for crm_case for setting probability
"""
res = super(hr_applicant, self).case_cancel(cr, uid, ids, context)
- self.write(cr, uid, ids, {'probability' : 0.0})
+ self.write(cr, uid, ids, {'probability': 0.0})
return res
def case_pending(self, cr, uid, ids, context=None):
"""Marks case as pending"""
res = super(hr_applicant, self).case_pending(cr, uid, ids, context)
- self.write(cr, uid, ids, {'probability' : 0.0})
+ self.write(cr, uid, ids, {'probability': 0.0})
return res
def case_reset(self, cr, uid, ids, context=None):
@@ -452,7 +453,7 @@ class hr_applicant(base_stage, osv.Model):
def set_priority(self, cr, uid, ids, priority, *args):
"""Set applicant priority
"""
- return self.write(cr, uid, ids, {'priority' : priority})
+ return self.write(cr, uid, ids, {'priority': priority})
def set_high_priority(self, cr, uid, ids, *args):
"""Set applicant priority to high
@@ -475,7 +476,7 @@ class hr_applicant(base_stage, osv.Model):
return self.message_post(cr, uid, ids, body=_("Stage changed to %s.") % (stage_name), context=context)
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
- return 'Applicant'
+ return 'Applicant'
def case_open_send_note(self, cr, uid, ids, context=None):
message = _("Applicant has been set in progress.")
diff --git a/addons/lunch/lunch_demo.xml b/addons/lunch/lunch_demo.xml
index 9e92291b62d..7488208fd42 100644
--- a/addons/lunch/lunch_demo.xml
+++ b/addons/lunch/lunch_demo.xml
@@ -100,28 +100,28 @@
-
+
new
-
+
confirmed
-
+
- cancelled
+ partially
-
+
new
@@ -131,7 +131,7 @@
-
+
confirmed
@@ -141,7 +141,7 @@
-
+
cancelled
@@ -150,9 +150,18 @@
+
+
+
+
+ confirmed
+
+ +Salad +Tomatoes +Eggs
+
+
-
+
Pizza Italiana
-7.40
@@ -161,7 +170,16 @@
-
+
+
+ Chicken curry
+ -2.60
+
+ order
+
+
+
+
Payment: 5 lunch tickets (6€)
30
diff --git a/addons/lunch/security/lunch_security.xml b/addons/lunch/security/lunch_security.xml
index 75ab0836b12..654f844c876 100644
--- a/addons/lunch/security/lunch_security.xml
+++ b/addons/lunch/security/lunch_security.xml
@@ -1,11 +1,19 @@
-
- Lunch / Manager
+
+ Lunch
+ Helps you handle your lunch needs, if you are a manager you will be able to create new products, cashmoves and to confirm or cancel orders.
+ 16
- Lunch / User
+ User
+
+
+
+ Manager
+
+
diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py
index 9ad3232d396..c535e3f7024 100644
--- a/addons/mail/__openerp__.py
+++ b/addons/mail/__openerp__.py
@@ -65,7 +65,10 @@ Main Features
'mail_alias_view.xml',
'res_users_view.xml',
],
- 'demo': ['data/mail_demo.xml'],
+ 'demo': [
+ 'data/mail_demo.xml',
+ 'data/mail_group_demo_data.xml',
+ ],
'installable': True,
'auto_install': False,
'application': True,
diff --git a/addons/mail/data/mail_demo.xml b/addons/mail/data/mail_demo.xml
index a5eaa63956a..fc11f31670a 100644
--- a/addons/mail/data/mail_demo.xml
+++ b/addons/mail/data/mail_demo.xml
@@ -2,90 +2,354 @@
-
+
none
-
-
-
- mail.group
-
- Your monthly meal vouchers arrived. You can get them at Christine's office.]]>
- comment
-
-
+
+ none
-
- mail.group
-
- Oh, I had forgotten. This month you also get 250 EUR of eco-vouchers if you have been in the company for more than a year.]]>
-
- comment
-
-
+
+ none
-
- mail.group
-
- Thanks! Could you please remind me where is Christine's office, if I may ask? I'm new here!]]>
-
- comment
-
-
+
+ none
-
-
- mail.group
-
- Building B3, second floor on the right :-).]]>
-
- comment
-
-
-
+
+ none
-
- mail.group
-
- Many thanks. Actually that's good news, next year I'll have to buy a new fridge, I think I will pay it with the eco-vouchers!]]>
-
- comment
-
-
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
+
+
+ none
-
-
- Hello Demo User! I was wondering whether you had some issues with our secret task about putting cats everywhere in OpenERP.
+
+
+ bWlncmF0aW9uIHRlc3Q=
+ RedHat_spec.doc
+ RedHat_spec.doc
+
+
+ bWlncmF0aW9uIHRlc3Q=
+ RedHat_spec_draft_v3.doc
+ RedHat_spec_draft_v3.doc
+
+
+ RedHat server updated spec
+ Hello Demo,
+ We have a lot of inquiries about our now solution based on RedHat servers. However I do not have the updated specification ready at hand.
+ Could you please send me the last version of the file asap?
+ Thanks,
]]>
comment
+
-
- No specific issues, I think everything is clear.
-
+
+ Sure, here it is. Have a nice day!]]>
comment
+
+
+
-
- Ow, just to be sure... we were talking about lolcats, right ?
-
+
+ I just found a more recent draft of the spec. Jon did some cleaning in the specifications. Could you merge the two documents to have an updated one?When it's done, put it on the internal document management system.
Thanks,
]]>
comment
+
+
+
-
- Absolutely!
-
+
+
+
+ Plan to install backup servers
+ Hello,
+We need to deploy new backup servers, with the following requirements:
+
+ - daily incremental backups, with an history of 15 days,
+ - 45 servers should be backuped between 1am and 3am when our offices are closed,
+ - two redundant servers,
+ - total capacity of 200Gb.
+
+
+ Do you have a simple solution with servers running on Redhat Linux?
+
+Best regards,
+ ]]>
+ email
+
+ virginie@agrolait.fr
+
+
+
+
+
+
+
+ bWlncmF0aW9uIHRlc3Q=
+ catalog.doc
+ catalog.doc
+
+
+ activity_graph_2012.jpg
+ activity_graph_2012
+
+ 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
+ kxzLdwM111ZhJXPm0ixn3/rQxvK6Vd4vn//Z
+
+
+
+ Hi Demo,
+ The next version of our products catalog is scheduled for next month. Our product team send me their updated document holding the prices and costs, and I updated our catalog.
+ You will find it in attachment, as well as a comparative benchmark of the different solutions currently existing on the market.
Have a nice reading!
+ Sincerely,
]]>
comment
+
+
+
+
+ Thank you!
Could you send me the updated pricelists as negotiated at the beginning of this year?
+ Sincerely,
]]>
+ comment
+
+
+
+
+
+
+
+
+
+ Hello,I have a friend working at Epic Technologies. He told me they plan to upgrade their backup servers within the next 3 months.
I think that someone should contact them and check if there is an opportunity.
]]>
+ comment
+
+
+
+
+
+
+
+
+ comment
+
+
+
+
+
+
+
+
+ Information meeting
+ Hello,Epic Technologies is a small company specialized in software managing huge volume of data. Having an efficient and reliable backup system is very important for us, and critical for our customers. I eared you have some interesting solutions to manage our backups. Could we meet each other as soon as possible to discuss our need? Here is a first list of requirements:
+
+ - about 25 backup servers, running on Redhat Linux
+ - minimum 200Gb of storage per server
+ - setup a VPN between all our servers in New York and Chicago
+
+ Thanks,
+ ]]>
+ comment
+
+
+
+
+
+
+ RE: Information meeting
+ Hello Epic!
+ I am glad you are interested in our products. Indeed, we are have several backup solutions that should meet your requirements. In order to prepare a detailed offer, we will have to discuss several technical points about your needs and the context of your data management.
+ I propose to have a meeting tomorrow at 2 PM. Does it seem suitable for you ?
Best regards,
]]>
+
+ comment
+
+
+
+
+
+
+ RE: Information meeting
+ It is not possible for me to come tomorrow at 2 PM. Maybe at 4 PM?]]>
+
+ comment
+
+
+
+
+
+ RE: Information meeting
+ 4 PM is fine! See you tomorrow!
Best regards,]]>
+
+ comment
+
+
+
+
+
+
+ RE: Information meeting
+ Ok! See you tomorrow.]]>
+
+ comment
+
+
+
+
+
+
+
+
+ Feedback about our On Site Assistance
+ Hi Virginie,I writing to you about our On Site Assistance Service that we delivered to Agrolait last week. Do you have any feedback or remark about our service? I noticed you requested new IP phones. Will it be used for new employees, or did you have any issue with the ones we provided?
Best regards,
]]>
+ comment
+
+
+
+
+
+
+ RE: Feedback about our On Site Assistance
+ Hello Administrator,Glad to hearing from you! Everything is perfect, thanks for asking. Concerning the order of 2 IP phones, I ordered them for new employees. We are satisfied with the products of YourCompany, and we plan to fit out each new employee with one of your phone this year.
Regards,
]]>
+
+ comment
+
+
+
+
+
+
+
+
+ FWD: Meeting with Demo
+ Hello Administrator,A small email to inform you that we will have a meeting with Mr Demo next Tuesday. Everything is under control!
Regards,
]]>
+ comment
+
+
+
+
diff --git a/addons/mail/data/mail_group_data.xml b/addons/mail/data/mail_group_data.xml
index 64d989f9e9d..84258d619ba 100644
--- a/addons/mail/data/mail_group_data.xml
+++ b/addons/mail/data/mail_group_data.xml
@@ -2,10 +2,6 @@
-
- Sales
- Discussion about best sales practices and deals.
-
Whole Company
@@ -19,9 +15,9 @@
notification
Welcome to OpenERP!
- Your homepage is a summary of messages you received and key information about documents you follow.
-The top menu bar contains all applications you installed. You can use the Settings menu to install more applications, activate others features or give access to new users.
-To setup your preferences (name, email signature, avatar), click on the top right corner.
]]>
+ Your homepage is a summary of messages you received and key information about documents you follow.
+ The top menu bar contains all applications you installed. You can use the Settings menu to install more applications, activate others features or give access to new users.
+ To setup your preferences (name, email signature, avatar), click on the top right corner.
]]>
diff --git a/addons/mail/data/mail_group_demo_data.xml b/addons/mail/data/mail_group_demo_data.xml
new file mode 100644
index 00000000000..a6879c52a1a
--- /dev/null
+++ b/addons/mail/data/mail_group_demo_data.xml
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+ Best Sales Practices
+ Discussion about best sales practices and deals.
+
+
+
+
+
+ Board meetings
+ Board meetings, budgets, strategic plans
+
+
+
+
+
+ R&D
+ Research and development discussion group
+
+
+ HR Policies
+ Company cars, holidays and other advantages
+
+
+
+
+
+ Support
+ Support team
+
+
+
+
+ mail.group
+
+ Selling a training session and selling the products after the training session is more efficient than directly selling a pack with the training session and the products.]]>
+ comment
+
+
+
+
+
+ mail.group
+
+ I noted I can not manage efficiently my pipeline when I have more than 50 opportunities in the qualification stage.Any advice on this? How do you organize your activities with more than 50 opportunities?
]]>
+ comment
+
+
+
+
+
+ mail.group
+
+ When I have too much opportunities in the pipe, I start communicating with prospects more by email than phonecalls.I send an email to create a sense of emergency, like "can I call you this week about our quote?" and I call only those that answer this email.
You can use the email template feature of OpenERP to automate email composition.
]]>
+ comment
+
+
+
+
+
+
+
+ mail.group
+
+ When you sell a tablet PC, don't forget to propose a docking station with it. I offer 20% on the docking stating (not the tablet) and I have a 70% success rate with this combo.]]>
+ comment
+
+
+
+
+
+
+
+
+ mail.group
+
+ Your monthly meal vouchers arrived. You can get them at the HR's office.]]>
+ comment
+
+
+
+
+ mail.group
+
+ Oh, I had forgotten. This month you also get 250 EUR of eco-vouchers if you have been in the company for more than a year.]]>
+
+ comment
+
+
+
+
+ mail.group
+
+ Thanks! Could you please remind me where is Christine's office, if I may ask? I'm new here!]]>
+
+ comment
+
+
+
+
+ mail.group
+
+ Building B3, second floor on the right :-).]]>
+
+ comment
+
+
+
+
+
+
+ mail.group
+
+
+ Dear Board Members,
+
+
+ The main events of the month of October are:
+
+
+ Sales:
+
+
+ - Invoicing is respectively of 442k€ for our European company (66% of the budget) and $404k for the U.S. office (75% of the budget). Despite these numbers that are far bellow our initial expectations, the growth of the month of October is 51% compared to last year.
+ - The month of September having been better than our initial forecasts, the consolidated yearly revenue is only of $20k bellow our forecast made during the board of September.
+ - The consolidated forecast for the end of the year is $6.749k, which is a growth of 76% compared to last year and an achievement of 87% of the budget.
+ - The recruitment of new resellers has been very good, especially in Europe, where we signed 30 new resellers this month.
+
+
+ Finance :
+
+
+ - The profit and loss has been negatively impacted this month by revenues that are far beyond the budget and charges that are 15% above the budget. The main extra we had in our charges this month is due to the provisioning of the salaries for the holidays period, $50k.
+ - We also got the payment of our long awaited subsidies, the cash level has increased of 300K€ which gives a current balance of 963 K€ without including the straight loan of 350 K€.
+ - The aged customer balance has been similar to the one of the last month with a small decrease of the DSO. We have recruited a new accountant assistant for the credit collection. She is mostly doing phone calls for all invoices that are due since 30 days, so we should get improvements of the DSO in November. The sum of the invoicing on which we have a risk in the aged customer balance is 100K€.
+
+
+ Resellers and Customers:
+
+
+ - The total number of resellers is 429, across 87 countries.
+ - The total number of installations of our software increased to 37K, against 33K for the month of September but we still did not reached the highest level we reached during this year (44K in march and may)
+ - We have passed the 10000th customer in production with 10271 customers at the end of October. The paying customer ratio is 6,6%.
+
+
+ Launch of the new release:
+
+
+ We are working actively on the new release which is scheduled for the end of November.
+
+
+ - We will publish the release note this week
+ - The whole sales team will be trained on the new version this Friday
+ - We will do a public announce to our resellers the 21th of November. We plan to show them: a description of the new features, the new distribution strategy, the new pricing and the communication plan.
+
+
+
+ Nicolas, can you book a meeting room for our meeting of Friday 2pm?
+
+
+ Regards.
+
+]]>
+ comment
+
+
+
+
+
+
+
+
+
+ mail.group
+
+
+ Great news!
+ Our company has received the Deloitte Fast 50 award. We are the fastest
+ growing company of the country, with a growth of 1549% over the past 5
+ years. You can get more information on our blog.
+
+]]>
+ comment
+
+
+
+
+
+
+
+
diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py
index b163882577b..30a31e2b701 100644
--- a/addons/mail/mail_group.py
+++ b/addons/mail/mail_group.py
@@ -114,7 +114,7 @@ class mail_group(osv.Model):
alias_id = mail_alias.create_unique_alias(cr, uid,
# Using '+' allows using subaddressing for those who don't
# have a catchall domain setup.
- {'alias_name': "group+"+vals['name']},
+ {'alias_name': "group+" + vals['name']},
model_name=self._name, context=context)
vals['alias_id'] = alias_id
@@ -133,6 +133,7 @@ class mail_group(osv.Model):
'context': {'default_model': 'mail.group', 'default_res_id': mail_group_id, 'search_default_message_unread': True},
'res_model': 'mail.message',
'thread_level': 1,
+ 'header_description': vals.get('description'),
}
cobj = self.pool.get('ir.actions.client')
newref = cobj.copy(cr, SUPERUSER_ID, ref[1], default={'params': str(params), 'name': vals['name']}, context=context)
@@ -160,6 +161,13 @@ class mail_group(osv.Model):
result = super(mail_group, self).write(cr, uid, ids, vals, context=context)
if vals.get('group_ids'):
self._subscribe_users(cr, uid, ids, context=context)
+ # if description is changed: update client action
+ if vals.get('description'):
+ cobj = self.pool.get('ir.actions.client')
+ for action in [group.action for group in self.browse(cr, SUPERUSER_ID, ids, context=context) if group.action]:
+ new_params = action.params
+ new_params['header_description'] = vals.get('description')
+ cobj.write(cr, SUPERUSER_ID, [action.id], {'params': str(new_params)}, context=context)
return result
def action_follow(self, cr, uid, ids, context=None):
diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml
index 4a880a13c14..34506cf4104 100644
--- a/addons/mail/mail_group_view.xml
+++ b/addons/mail/mail_group_view.xml
@@ -6,6 +6,17 @@
Discussion Group
mail.wall
mail.message
+ {
+ 'search_default_message_unread': True
+ }
+ {
+ 'read_action': 'read'
+ }
+
+
+ No message in this group.
+
+
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index 9fd476d9d7f..e7288a46853 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -377,7 +377,9 @@ class mail_message(osv.Model):
id_max = child_id
elif nb > 0:
exp_domain = [('id', '>=', id_min), ('id', '<=', id_max), ('id', 'child_of', message_id)]
- messages.append(_get_expandable(exp_domain, nb, message_id, False))
+ idx = [msg.get('id') for msg in messages].index(child_id) + 1
+ # messages.append(_get_expandable(exp_domain, nb, message_id, False))
+ messages.insert(idx, _get_expandable(exp_domain, nb, message_id, False))
id_min, id_max, nb = max(child_ids), 0, 0
else:
id_min, id_max, nb = max(child_ids), 0, 0
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index ee1a015396b..15bc53223ba 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -79,7 +79,7 @@ class mail_thread(osv.AbstractModel):
# search for unread messages, directly in SQL to improve performances
cr.execute(""" SELECT m.res_id FROM mail_message m
RIGHT JOIN mail_notification n
- ON (n.message_id = m.id AND n.partner_id = %s AND n.read = False)
+ ON (n.message_id = m.id AND n.partner_id = %s AND (n.read = False or n.read IS NULL))
WHERE m.model = %s AND m.res_id in %s""",
(user_pid, self._name, tuple(ids),))
msg_ids = [result[0] for result in cr.fetchall()]
@@ -341,7 +341,7 @@ class mail_thread(osv.AbstractModel):
message = self.pool.get('mail.message').browse(cr, uid, message_ids[0], context=context)
_logger.debug('Routing mail with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s',
message_id, message.id, custom_values, uid)
- return [(False, 0, custom_values, uid)]
+ return [(message.model, message.res_id, custom_values, uid)]
# 2. Look for a matching mail.alias entry
# Delivered-To is a safe bet in most modern MTAs, but we have to fallback on To + Cc values
@@ -767,13 +767,19 @@ class mail_thread(osv.AbstractModel):
# 3. Post-processing
# HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
if attachment_ids:
+ # TDE FIXME (?): when posting a private message, we use mail.thread as a model
+ # However, attaching doc to mail.thread is not possible, mail.thread does not have any table
+ model = self._name
+ if model == 'mail.thread':
+ model = False
filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
('res_model', '=', 'mail.compose.message'),
('res_id', '=', 0),
('create_uid', '=', uid),
('id', 'in', attachment_ids)], context=context)
if filtered_attachment_ids:
- ir_attachment.write(cr, SUPERUSER_ID, attachment_ids, {'res_model': self._name, 'res_id': thread_id}, context=context)
+ if thread_id and model:
+ ir_attachment.write(cr, SUPERUSER_ID, attachment_ids, {'res_model': model, 'res_id': thread_id}, context=context)
mail_message.write(cr, SUPERUSER_ID, [new_message_id], {'attachment_ids': [(6, 0, [pid for pid in attachment_ids])]}, context=context)
return new_message_id
diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml
index 3a37218c813..1721b3df1d4 100644
--- a/addons/mail/mail_thread_view.xml
+++ b/addons/mail/mail_thread_view.xml
@@ -84,29 +84,11 @@
'search_default_message_read': True
}
-
-
- No message found.
-
-
-
-
-
- Sent
- mail.wall
- {
- 'default_model': 'res.users',
- 'default_res_id': uid
- }
-
- No message sent yet.
+ No message found and no message sent yet.
Click on the top-right icon to compose a message. This
message will be sent by email if it's an internal contact.
@@ -150,11 +132,5 @@
-
- Sent
-
-
-
-
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index b0ce6d499b5..94a5c2d1f41 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -220,9 +220,8 @@
/* --------------------- ATTACHMENTS --------------------- */
.openerp .oe_mail .oe_msg_attachment_list{
- display: none;
- margin-top: 12px;
- margin-bottom: 12px;
+ margin-top: 4px;
+ margin-bottom: 4px;
}
.openerp .oe_mail .oe_msg_composer .oe_msg_attachment_list{
display: block;
@@ -230,7 +229,7 @@
.openerp .oe_mail .oe_attachment{
display: inline-block;
width: 100px;
- margin: 2px;
+ margin: 4px 2px;
min-height: 80px;
position: relative;
border-radius: 3px;
@@ -243,7 +242,7 @@
padding: 1px 3px;
margin-top: 50px;
margin-bottom: 5px;
- background: rgba(124, 123, 173, 0.13);
+ background: #F4F5FA;
overflow: hidden;
color: #4c4c4c;
text-shadow: none;
@@ -299,12 +298,13 @@
.openerp .oe_mail .oe_attachment.oe_preview .oe_name{
position: absolute;
bottom: 0px;
- margin: 0px;
+ margin: 3px;
left: 0px;
right: 0px;
max-height: 64px;
background: rgba(0,0,0,0.8);
color: white;
+ border-radius: 1px;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
opacity: 0;
@@ -333,9 +333,11 @@
position: relative;
margin:0px;
width: 100px;
- height: 100px;
- border-radius: 3px;
+ height: 80px;
+ border-radius: 1px;
+ border: solid 3px #FFF;
margin-left: -50px;
+ box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.19);
}
.openerp .oe_mail .oe_attachment .oe_delete{
display: none;
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index dc265a343d5..040b83e8f33 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -251,7 +251,7 @@ openerp.mail = function (session) {
this.format_data();
// record options and data
- this.show_record_name = this.record_name && !this.thread_level && this.model != 'res.partner';
+ this.show_record_name = this.options.show_record_name && this.record_name && !this.thread_level && this.model != 'res.partner';
this.options.show_read = false;
this.options.show_unread = false;
if (this.options.show_read_unread_button) {
@@ -591,17 +591,17 @@ openerp.mail = function (session) {
//session.web.blockUI();
this.parent_thread.ds_thread.call('message_post_user_api', [
this.context.default_res_id,
- mail.ChatterUtils.get_text2html(body),
+ body,
false,
this.context.default_parent_id,
attachments,
this.parent_thread.context
]).done(function (record) {
var thread = self.parent_thread;
+ var root = thread == self.options.root_thread;
if (self.options.display_indented_thread < self.thread_level && thread.parent_message) {
var thread = thread.parent_message.parent_thread;
}
- var root = thread == self.options.root_thread;
// create object and attach to the thread object
thread.message_fetch([['id', 'child_of', [self.id]]], false, [record], function (arg, data) {
var message = thread.create_message_object( data[0] );
@@ -734,7 +734,7 @@ openerp.mail = function (session) {
if(this.thread_level < this.options.display_indented_thread) {
this.create_thread();
}
- this.$('.oe_msg_attachments, .oe_msg_images').addClass("oe_hidden");
+ this.display_attachments();
this.ds_notification = new session.web.DataSetSearch(this, 'mail.notification');
this.ds_message = new session.web.DataSetSearch(this, 'mail.message');
@@ -752,8 +752,6 @@ openerp.mail = function (session) {
this.$('.oe_reply').on('click', this.on_message_reply);
this.$('.oe_star').on('click', this.on_star);
this.$('.oe_msg_vote').on('click', this.on_vote);
- this.$('.oe_view_attachments').on('click', this.on_view_attachments);
-
},
/* Call the on_compose_message on the thread of this message. */
@@ -812,17 +810,6 @@ openerp.mail = function (session) {
}
},
- /* Call the on_compose_message on the thread of this message. */
- on_view_attachments:function (event) {
- event.stopPropagation();
- var self = this;
- if (!this.toggle_attachment) {
- self.display_attachments();
- this.toggle_attachment = true;
- }
- this.$('.oe_msg_attachment_list').toggle(200);
- },
-
/**
* Wait a confirmation for delete the message on the DB.
* Make an animate destroy
@@ -857,7 +844,10 @@ openerp.mail = function (session) {
msg.animated_destroy(150);
} else {
msg.renderElement();
- msg.start()
+ msg.start();
+ }
+ if( self.options.root_thread.__parentedParent.__parentedParent.do_reload_menu_emails ) {
+ self.options.root_thread.__parentedParent.__parentedParent.do_reload_menu_emails();
}
});
@@ -997,10 +987,7 @@ openerp.mail = function (session) {
init: function (parent, datasets, options) {
this._super(parent, options);
this.domain = options.domain || [];
- this.context = _.extend({
- default_model: 'mail.thread',
- default_res_id: 0,
- default_parent_id: false }, options.context || {});
+ this.context = _.extend(options.context || {});
this.options = options.options;
this.options.root_thread = (options.options.root_thread != undefined ? options.options.root_thread : this);
@@ -1243,6 +1230,7 @@ openerp.mail = function (session) {
'default_parent_id': self.id,
}});
} else {
+ data.record_name= (data.record_name != '' && data.record_name) || (self.parent_message && self.parent_message.record_name);
var message = new mail.ThreadMessage(self, data, {'context':{
'default_model': data.model,
'default_res_id': data.res_id,
@@ -1252,8 +1240,7 @@ openerp.mail = function (session) {
// check if the message is already create
for (var i in self.messages) {
- if (self.messages[i] && self.messages[i].id == message.id) {
- console.log('Reload message', message.id);
+ if (message.id && self.messages[i] && self.messages[i].id == message.id) {
self.messages[i].destroy();
}
}
@@ -1280,10 +1267,9 @@ openerp.mail = function (session) {
this.$('.oe_view_nocontent').remove();
-
if (dom_insert_after) {
message.insertAfter(dom_insert_after);
- }if (prepend) {
+ } else if (prepend) {
message.prependTo(self.$el);
} else {
message.appendTo(self.$el);
@@ -1460,6 +1446,7 @@ openerp.mail = function (session) {
'show_record_name' : false,
'show_compose_message' : false,
'show_compact_message' : false,
+ 'compose_placeholder': false,
'view_inbox': false,
'message_ids': undefined,
}, this.action.params);
@@ -1524,14 +1511,18 @@ openerp.mail = function (session) {
init: function (parent, node) {
this._super.apply(this, arguments);
this.node = _.clone(node);
-
this.node.params = _.extend({
'display_indented_thread': -1,
'show_reply_button': false,
'show_read_unread_button': false,
+ 'show_record_name': false,
'show_compact_message': 1,
}, this.node.params);
+ if (this.node.attrs.placeholder) {
+ this.node.params.compose_placeholder = this.node.attrs.placeholder;
+ }
+
this.domain = this.node.params && this.node.params.domain || [];
},
@@ -1603,7 +1594,7 @@ openerp.mail = function (session) {
this.action = _.clone(action);
this.domain = this.action.params.domain || this.action.domain || [];
- this.context = this.action.params.context || this.action.context || {};
+ this.context = _.extend(this.action.params.context || {}, this.action.context || {});
this.defaults = {};
for (var key in this.context) {
@@ -1617,6 +1608,7 @@ openerp.mail = function (session) {
'show_reply_button': true,
'show_read_unread_button': true,
'show_compose_message': true,
+ 'show_record_name': true,
'show_compact_message': this.action.params.view_mailbox ? false : 1,
'view_inbox': false,
}, this.action.params);
@@ -1629,7 +1621,23 @@ openerp.mail = function (session) {
if (! this.searchview.has_defaults) {
this.message_render();
}
-
+ },
+
+ /**
+ * crete an object "related_menu"
+ * contain the menu widget and the the sub menu related of this wall
+ */
+ do_reload_menu_emails: function () {
+ var menu = this.__parentedParent.__parentedParent.menu;
+ // return this.rpc("/web/menu/load", {'menu_id': 100}).done(function(r) {
+ // _.each(menu.data.data.children, function (val) {
+ // if (val.id == 100) {
+ // val.children = _.find(r.data.children, function (r_val) {return r_val.id == 100;}).children;
+ // }
+ // });
+ // var r = menu.data;
+ // window.setTimeout(function(){menu.do_reload();}, 0);
+ // });
},
/**
diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js
index 7bb019cde4f..d299b9eb6f6 100644
--- a/addons/mail/static/src/js/mail_followers.js
+++ b/addons/mail/static/src/js/mail_followers.js
@@ -194,6 +194,7 @@ openerp_mail_followers = function(session, mail) {
display_subtypes:function (data) {
var self = this;
var subtype_list_ul = this.$('.oe_subtype_list');
+ subtype_list_ul.empty();
var records = data[this.view.datarecord.id || this.view.dataset.ids[0]].message_subtype_data;
_(records).each(function (record, record_name) {
record.name = record_name;
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index 89fbe45dc36..bb787c9a21b 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -39,8 +39,9 @@
Pigs rules' + _body = 'Pigs rule' + _reply_subject = 'Re: Pigs' _attachments = [ {'name': 'First', 'datas_fname': 'first.txt', 'datas': 'My first attachment'.encode('base64')}, {'name': 'Second', 'datas_fname': 'second.txt', 'datas': 'My second attachment'.encode('base64')} @@ -462,9 +461,9 @@ class test_mail(test_mail_mockup.TestMailMockups): # 1. Comment group_pigs with body_text and subject compose_id = mail_compose.create(cr, uid, - {'subject': _subject, 'body_text': _body_text, 'partner_ids': [(4, p_c_id), (4, p_d_id)]}, + {'subject': _subject, 'body': _body, 'partner_ids': [(4, p_c_id), (4, p_d_id)]}, {'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id, - 'default_content_subtype': 'plaintext'}) + 'default_content_subtype': 'plaintext'}) compose = mail_compose.browse(cr, uid, compose_id) # Test: mail.compose.message: composition_mode, model, res_id self.assertEqual(compose.composition_mode, 'comment', 'mail.compose.message incorrect composition_mode') @@ -476,8 +475,8 @@ class test_mail(test_mail_mockup.TestMailMockups): group_pigs.refresh() message = group_pigs.message_ids[0] # Test: mail.message: subject, body inside pre - self.assertEqual(message.subject, False, 'mail.message incorrect subject') - self.assertEqual(message.body, _msg_body, 'mail.message incorrect body') + self.assertEqual(message.subject, _subject, 'mail.message incorrect subject') + self.assertEqual(message.body, _body, 'mail.message incorrect body') # Test: mail.message: notified_partner_ids = entries in mail.notification: group_pigs fans (a, b) + mail.compose.message partner_ids (c, d) msg_pids = [partner.id for partner in message.notified_partner_ids] test_pids = [p_b_id, p_c_id, p_d_id] @@ -495,13 +494,12 @@ class test_mail(test_mail_mockup.TestMailMockups): {'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])]}, {'default_composition_mode': 'reply', 'default_model': 'mail.thread', 'default_res_id': self.group_pigs_id, 'default_parent_id': message.id}) compose = mail_compose.browse(cr, uid, compose_id) - # Test: model, res_id, parent_id, content_subtype + # Test: model, res_id, parent_id self.assertEqual(compose.model, 'mail.group', 'mail.compose.message incorrect model') self.assertEqual(compose.res_id, self.group_pigs_id, 'mail.compose.message incorrect res_id') self.assertEqual(compose.parent_id.id, message.id, 'mail.compose.message incorrect parent_id') - self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message incorrect content_subtype') # Test: mail.message: subject as Re:.., body in html, parent_id - self.assertEqual(compose.subject, _msg_reply, 'mail.message incorrect subject') + self.assertEqual(compose.subject, _reply_subject, 'mail.message incorrect subject') # self.assertIn('Administrator wrote:
', compose.body, 'mail.message body is incorrect') self.assertEqual(compose.parent_id and compose.parent_id.id, message.id, 'mail.message parent_id incorrect') # Test: mail.message: attachments @@ -518,8 +516,6 @@ class test_mail(test_mail_mockup.TestMailMockups): {'default_composition_mode': 'mass_mail', 'default_model': 'mail.group', 'default_res_id': False, 'active_ids': [self.group_pigs_id, group_bird_id]}) compose = mail_compose.browse(cr, uid, compose_id) - # Test: content_subtype is html - self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message content_subtype incorrect') # 2. Post the comment, get created message for each group mail_compose.send_mail(cr, uid, [compose_id], diff --git a/addons/mail/tests/test_mail_access_rights.py b/addons/mail/tests/test_mail_access_rights.py index 7594de87faf..1b2f7f85d71 100644 --- a/addons/mail/tests/test_mail_access_rights.py +++ b/addons/mail/tests/test_mail_access_rights.py @@ -21,7 +21,7 @@ from openerp.addons.mail.tests import test_mail_mockup from openerp.osv.orm import except_orm -from openerp.tools.misc import mute_logger +from openerp.tools import mute_logger class test_mail_access_rights(test_mail_mockup.TestMailMockups): @@ -52,6 +52,7 @@ class test_mail_access_rights(test_mail_mockup.TestMailMockups): self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id) self.partner_raoul_id = self.user_raoul.partner_id.id + @mute_logger('openerp.addons.base.ir.ir_model','openerp.osv.orm') def test_00_mail_message_search_access_rights(self): """ Test mail_message search override about access rights. """ cr, uid, group_pigs_id = self.cr, self.uid, self.group_pigs_id @@ -85,7 +86,7 @@ class test_mail_access_rights(test_mail_mockup.TestMailMockups): msg_ids = self.mail_message.search(cr, uid, [('subject', 'like', '_Test')]) self.assertEqual(set([msg_id1, msg_id2, msg_id3, msg_id4, msg_id5, msg_id6, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed') - @mute_logger('openerp.osv.orm') + @mute_logger('openerp.addons.base.ir.ir_model','openerp.osv.orm') def test_05_mail_message_read_access_rights(self): """ Test basic mail_message read access rights. """ cr, uid = self.cr, self.uid @@ -133,8 +134,7 @@ class test_mail_access_rights(test_mail_mockup.TestMailMockups): self.assertRaises(except_orm, self.mail_message.read, cr, user_bert_id, message_id) - @mute_logger('openerp.addons.base.ir.ir_model') - @mute_logger('openerp.osv.orm') + @mute_logger('openerp.addons.base.ir.ir_model','openerp.osv.orm') def test_10_mail_flow_access_rights(self): """ Test a Chatter-looks alike flow. """ cr, uid = self.cr, self.uid @@ -182,14 +182,14 @@ class test_mail_access_rights(test_mail_mockup.TestMailMockups): # Do: Bert create a mail.compose.message record, because he uses the wizard compose_id = mail_compose.create(cr, user_bert_id, - {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': []}, + {'subject': 'Subject', 'body': 'Body text', 'partner_ids': []}, # {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': [(4, p_c_id), (4, p_d_id)]}, {'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_jobs_id}) mail_compose.send_mail(cr, user_bert_id, [compose_id]) self.user_demo_id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')[1] compose_id = mail_compose.create(cr, self.user_demo_id, - {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': []}, + {'subject': 'Subject', 'body': 'Body text', 'partner_ids': []}, # {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': [(4, p_c_id), (4, p_d_id)]}, {'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_jobs_id}) mail_compose.send_mail(cr, self.user_demo_id, [compose_id]) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index c409d4ab076..58066c6f2c2 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -81,7 +81,7 @@ class mail_compose_message(osv.TransientModel): elif composition_mode == 'comment' and model and res_id: vals = self.get_record_data(cr, uid, model, res_id, context=context) elif composition_mode == 'mass_mail' and model and active_ids: - vals = {'model': model, 'res_id': res_id, 'content_subtype': 'html'} + vals = {'model': model, 'res_id': res_id} else: vals = {'model': model, 'res_id': res_id} if composition_mode: @@ -106,16 +106,10 @@ class mail_compose_message(osv.TransientModel): 'mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id', 'Attachments'), 'filter_id': fields.many2one('ir.filters', 'Filters'), - 'body_text': fields.text('Plain-text Contents'), - 'content_subtype': fields.char('Message content subtype', size=32, readonly=1, - help="Type of message, usually 'html' or 'plain', used to select "\ - "plain-text or rich-text contents accordingly"), } _defaults = { 'composition_mode': 'comment', - 'content_subtype': lambda self, cr, uid, ctx={}: 'html', - 'body_text': lambda self, cr, uid, ctx={}: False, 'body': lambda self, cr, uid, ctx={}: '', 'subject': lambda self, cr, uid, ctx={}: False, 'partner_ids': lambda self, cr, uid, ctx={}: [], @@ -172,32 +166,9 @@ class mail_compose_message(osv.TransientModel): 'parent_id': message_data.id, 'subject': reply_subject, 'partner_ids': partner_ids, - 'content_subtype': 'html', } return result - def toggle_content_subtype(self, cr, uid, ids, context=None): - """ toggle content_subtype: calls onchange_formatting to emulate an - on_change, then writes the value to update the form. """ - for record in self.browse(cr, uid, ids, context=context): - content_st_new_value = 'plain' if record.content_subtype == 'html' else 'html' - onchange_res = self.onchange_content_subtype(cr, uid, ids, content_st_new_value, record.model, record.res_id, context=context) - self.write(cr, uid, [record.id], onchange_res['value'], context=context) - return True - - def onchange_content_subtype(self, cr, uid, ids, value, model, res_id, context=None): - """ This onchange allows to have some specific behavior when switching - between text or html mode. This method can be overridden. - :param values: 'plain' or 'html' - """ - return {'value': {'content_subtype': value}} - - def dummy(self, cr, uid, ids, context=None): - """ TDE: defined to have buttons that do basically nothing. It is - currently impossible to have buttons that do nothing special - in views (if type not specified, considered as 'object'). """ - return True - #------------------------------------------------------ # Wizard validation and send #------------------------------------------------------ @@ -218,8 +189,8 @@ class mail_compose_message(osv.TransientModel): for res_id in res_ids: # default values, according to the wizard options post_values = { - 'subject': wizard.subject if wizard.content_subtype == 'html' else False, - 'body': wizard.body if wizard.content_subtype == 'html' else 'Pigs rules
%s' % tools.ustr(wizard.body_text), + 'subject': wizard.subject, + 'body': wizard.body, 'parent_id': wizard.parent_id and wizard.parent_id.id, 'partner_ids': [(4, partner.id) for partner in wizard.partner_ids], 'attachments': [(attach.datas_fname or attach.name, base64.b64decode(attach.datas)) for attach in wizard.attachment_ids], diff --git a/addons/mail/wizard/mail_compose_message_view.xml b/addons/mail/wizard/mail_compose_message_view.xml index 01ceb770f49..57fc0aaf729 100644 --- a/addons/mail/wizard/mail_compose_message_view.xml +++ b/addons/mail/wizard/mail_compose_message_view.xml @@ -12,7 +12,6 @@
Hello${object.partner_id.name and ' ' or ''}${object.partner_id.name or ''},
+ +Here is your ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'} from ${object.company_id.name}:
+ +
+ REFERENCES
+ Order number: ${object.name}
+ Order total: ${object.amount_total} ${object.pricelist_id.currency_id.name}
+ Order date: ${object.date_order}
+ % if object.origin:
+ Order reference: ${object.origin}
+ % endif
+ % if object.client_order_ref:
+ Your reference: ${object.client_order_ref}
+ % endif
+ % if object.user_id:
+ Your contact: ${object.user_id.name}
+ % endif
+
+ You can access this document and pay online via our Customers Portal: +
+ View ${object.state in ('draft', 'sent') and 'Quotation' or 'Order'} + % endif + + % if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account and object.state != 'draft': + <% + comp_name = quote(object.company_id.name) + order_name = quote(object.name) + paypal_account = quote(object.company_id.paypal_account) + order_amount = quote(str(object.residual)) + cur_name = quote(object.pricelist_id.currency_id.name) + paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=%s%%20Order%%20%s" \ + "&invoice=%s&amount=%s¤cy_code=%s&button_subtype=services&no_note=1" \ + "&bn=OpenERP_Order_PayNow_%s" % \ + (paypal_account,comp_name,order_name,order_name,order_amount,cur_name,cur_name) + %> +It is also possible to directly pay with Paypal:
+ +
+
+ % endif
+
+ If you have any question, do not hesitate to contact us.
+Thank you for choosing ${object.company_id.name or 'us'}!
+Hello${object.partner_id.name and ' ' or ''}${object.partner_id.name or ''},
+ +A new invoice is available for ${object.partner_id.name}:
+ +
+ REFERENCES
+ Invoice number: ${object.number}
+ Invoice total: ${object.amount_total} ${object.currency_id.name}
+ Invoice date: ${object.date_invoice}
+ % if object.origin:
+ Order reference: ${object.origin}
+ % endif
+ % if object.user_id:
+ Your contact: ${object.user_id.name}
+ % endif
+
+ You can access the invoice document and pay online via our Customers Portal: +
+ View Invoice + % endif + + % if object.company_id.paypal_account and object.type in ('out_invoice', 'in_refund'): + <% + comp_name = quote(object.company_id.name) + inv_number = quote(object.number) + paypal_account = quote(object.company_id.paypal_account) + inv_amount = quote(str(object.amount_residual)) + cur_name = quote(object.currency_id.name) + paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=%s%%20Invoice%%20%s&" \ + "invoice=%s&amount=%s¤cy_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s" % \ + (paypal_account,comp_name,inv_number,inv_number,inv_amount,cur_name,cur_name) + %> +It is also possible to directly pay with Paypal:
+ +
+
+ % endif
+
+ If you have any question, do not hesitate to contact us.
+Thank you for choosing ${object.company_id.name or 'us'}!
+- You can view the ${object.state in ('draft', 'sent') and 'request for quotation' or 'order confirmation'} document and download it using the following link: -
- View Order -If you have any question, do not hesitate to contact us.
Thank you!
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 5bb38316604..ad7563140b2 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -384,29 +384,32 @@ class purchase_order(osv.osv): ''' This function opens a window to compose an email, with the edi purchase template message loaded by default ''' - mod_obj = self.pool.get('ir.model.data') - template = mod_obj.get_object_reference(cr, uid, 'purchase', 'email_template_edi_purchase') - template_id = template and template[1] or False - res = mod_obj.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form') - res_id = res and res[1] or False + ir_model_data = self.pool.get('ir.model.data') + try: + template_id = ir_model_data.get_object_reference(cr, uid, 'purchase', 'email_template_edi_purchase')[1] + except ValueError: + template_id = False + try: + compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1] + except ValueError: + compose_form_id = False ctx = dict(context) ctx.update({ 'default_model': 'purchase.order', 'default_res_id': ids[0], - 'default_use_template': True, + 'default_use_template': bool(template_id), 'default_template_id': template_id, 'default_composition_mode': 'comment', - }) + }) return { + 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'mail.compose.message', - 'views': [(res_id, 'form')], - 'view_id': res_id, - 'type': 'ir.actions.act_window', + 'views': [(compose_form_id, 'form')], + 'view_id': compose_form_id, 'target': 'new', 'context': ctx, - 'nodestroy': True, } #TODO: implement messages system diff --git a/addons/purchase/test/process/edi_purchase_order.yml b/addons/purchase/test/process/edi_purchase_order.yml index d0e90f3788d..8e34606afb4 100644 --- a/addons/purchase/test/process/edi_purchase_order.yml +++ b/addons/purchase/test/process/edi_purchase_order.yml @@ -27,36 +27,36 @@ - Then I export the purchase order via EDI - - !python {model: edi.document}: | - order_pool = self.pool.get('purchase.order') - order = order_pool.browse(cr, uid, ref("purchase_order_edi_1")) - token = self.export_edi(cr, uid, [order]) - assert token, 'Invalid EDI Token' - + !python {model: edi.edi}: | + import json + order_pool = self.pool.get('purchase.order') + order = order_pool.browse(cr, uid, ref("purchase_order_edi_1")) + edi_doc = self.generate_edi(cr, uid, [order]) + assert isinstance(json.loads(edi_doc)[0], dict), 'EDI doc should be a JSON dict' - - Then I import a sample EDI document of a sale order + Then I import a sample EDI document of a sale order (v7.0) - - !python {model: edi.document}: | + !python {model: edi.edi}: | purchase_order_pool = self.pool.get('purchase.order') edi_document = { - "__id": "sale:724f93ec-ddd0-11e0-88ec-701a04e25543.sale_order_test", + "__id": "sale:724f9v70-dv70-1v70-8v70-701a04e25v70.sale_order_test", "__module": "sale", "__model": "sale.order", "__import_module": "purchase", "__import_model": "purchase.order", - "__version": [6,1,0], + "__version": [7,0,0], "name": "SO008", "currency": { - "__id": "base:724f93ec-ddd0-11e0-88ec-701a04e25543.EUR", + "__id": "base:724f9v70-dv70-1v70-8v70-701a04e25v70.EUR", "__module": "base", "__model": "res.currency", "code": "EUR", "symbol": "€", }, "date_order": "2011-09-13", - "partner_id": ["sale:724f93ec-ddd0-11e0-88ec-701a04e25543.res_partner_test22", "Junjun wala"], + "partner_id": ["sale:724f9v70-dv70-1v70-8v70-701a04e25v70.res_partner_test22", "Junjun wala"], "partner_address": { - "__id": "base:724f93ec-ddd0-11e0-88ec-701a04e25543.res_partner_address_7wdsjasdjh", + "__id": "base:724f9v70-dv70-1v70-8v70-701a04e25v70.res_partner_address_7wdsjasdjh", "__module": "base", "__model": "res.partner", "phone": "(+32).81.81.37.00", @@ -65,48 +65,48 @@ "zip": "1367", "country_id": ["base:5af1272e-dd26-11e0-b65e-701a04e25543.be", "Belgium"], }, - "company_id": ["base:724f93ec-ddd0-11e0-88ec-701a04e25543.main_company", "Supplier S.A."], + "company_id": ["base:724f9v70-dv70-1v70-8v70-701a04e25v70.main_company", "Supplier S.A."], "company_address": { - "__id": "base:724f93ec-ddd0-11e0-88ec-701a04e25543.main_address", + "__id": "base:724f9v70-dv70-1v70-8v70-701a04e25v70.main_address", "__module": "base", "__model": "res.partner", "city": "Gerompont", "zip": "1367", - "country_id": ["base:724f93ec-ddd0-11e0-88ec-701a04e25543.be", "Belgium"], + "country_id": ["base:724f9v70-dv70-1v70-8v70-701a04e25v70.be", "Belgium"], "phone": "(+32).81.81.37.00", "street": "Chaussee de Namur 40", "street2": "mailbox 34", "bank_ids": [ - ["base:724f93ec-ddd0-11e0-88ec-701a04e25543.res_partner_bank-XiwqnxKWzGbp","Guys bank: 123477777-156113"] + ["base:724f9v70-dv70-1v70-8v70-701a04e25v70.res_partner_bank-XiwqnxKWzGbp","Guys bank: 123477777-156113"] ], }, "order_line": [{ - "__id": "sale:724f93ec-ddd0-11e0-88ec-701a04e25543.sale_order_line-LXEqeuI-SSP0", + "__id": "sale:724f9v70-dv70-1v70-8v70-701a04e25v70.sale_order_line-LXEqeuI-SSP0", "__module": "sale", "__model": "sale.order.line", "__import_module": "purchase", "__import_model": "purchase.order.line", "name": "PC Assemble SC234", - "product_uom": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_uom_unit", "Unit"], + "product_uom": ["product:724f9v70-dv70-1v70-8v70-701a04e25v70.product_uom_unit", "Unit"], "product_qty": 1.0, "date_planned": "2011-09-30", "sequence": 10, "price_unit": 150.0, - "product_id": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_product_3", "[PCSC234] PC Assemble SC234"], + "product_id": ["product:724f9v70-dv70-1v70-8v70-701a04e25v70.product_product_3", "[PCSC234] PC Assemble SC234"], }, { - "__id": "sale:724f93ec-ddd0-11e0-88ec-701a04e25543.sale_order_line-LXEqeadasdad", + "__id": "sale:724f9v70-dv70-1v70-8v70-701a04e25v70.sale_order_line-LXEqeadasdad", "__module": "sale", "__model": "sale.order.line", "__import_module": "purchase", "__import_model": "purchase.order.line", "name": "PC on Demand", - "product_uom": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_uom_unit", "Unit"], + "product_uom": ["product:724f9v70-dv70-1v70-8v70-701a04e25v70.product_uom_unit", "Unit"], "product_qty": 10.0, "sequence": 11, "date_planned": "2011-09-15", "price_unit": 20.0, - "product_id": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_product_5", "[PC-DEM] PC on Demand"], + "product_id": ["product:724f9v70-dv70-1v70-8v70-701a04e25v70.product_product_5", "[PC-DEM] PC on Demand"], }], } new_purchase_order_id = purchase_order_pool.edi_import(cr, uid, edi_document, context=context) @@ -114,6 +114,7 @@ order_new = purchase_order_pool.browse(cr, uid, new_purchase_order_id) # check bank info on partner + assert order_new.partner_id.supplier, "Imported partner should be a supplier, as we just imported the document as a purchase order" assert len(order_new.partner_id.bank_ids) == 1, "Expected 1 bank entry related to partner" bank_info = order_new.partner_id.bank_ids[0] assert bank_info.acc_number == "Guys bank: 123477777-156113", 'Expected "Guys bank: 123477777-156113", got %s' % bank_info.acc_number @@ -133,3 +134,104 @@ assert purchase_line.product_qty == 10 , "product qty is not same" else: raise AssertionError('unknown order line: %s' % purchase_line) +- + "Then I import a sample EDI document of a sale order (v6.1 - to test backwards compatibility)" +- + !python {model: edi.edi}: | + purchase_order_pool = self.pool.get('purchase.order') + edi_document = { + "__id": "sale:724f93ec-ddd0-11e0-88ec-701a04e25543.sale_order_test", + "__module": "sale", + "__model": "sale.order", + "__import_module": "purchase", + "__import_model": "purchase.order", + "__version": [6,1,0], + "name": "SO08v61", + "currency": { + "__id": "base:724f93ec-ddd0-11e0-88ec-701a04e25543.EUR", + "__module": "base", + "__model": "res.currency", + "code": "EUR", + "symbol": "€", + }, + "date_order": "2011-09-13", + "partner_id": ["sale:724f93ec-ddd0-11e0-88ec-701a04e25543.res_partner_test22", "Junjun wala"], + "partner_address": { + "__id": "base:724f93ec-ddd0-11e0-88ec-701a04e25543.res_partner_address_7wdsjasdjh", + "__module": "base", + "__model": "res.partner.address", + "phone": "(+32).81.81.37.00", + "street": "Chaussee de Namur 40", + "city": "Gerompont", + "zip": "1367", + "country_id": ["base:5af1272e-dd26-11e0-b65e-701a04e25543.be", "Belgium"], + }, + "company_id": ["base:724f93ec-ddd0-11e0-88ec-701a04e25543.main_company", "Supplier S.A."], + "company_address": { + "__id": "base:724f93ec-ddd0-11e0-88ec-701a04e25543.main_address", + "__module": "base", + "__model": "res.partner.address", + "city": "Gerompont", + "zip": "1367", + "country_id": ["base:724f93ec-ddd0-11e0-88ec-701a04e25543.be", "Belgium"], + "phone": "(+32).81.81.37.00", + "street": "Chaussee de Namur 40", + "street2": "mailbox 34", + "bank_ids": [ + ["base:724f93ec-ddd0-11e0-88ec-701a04e25543.res_partner_bank-XiwqnxKWzGbp","Another bank: 123477700-156113"] + ], + }, + "order_line": [{ + "__id": "sale:724f93ec-ddd0-11e0-88ec-701a04e25543.sale_order_line-LXEqeuI-SSP0", + "__module": "sale", + "__model": "sale.order.line", + "__import_module": "purchase", + "__import_model": "purchase.order.line", + "name": "Basic PC", + "product_uom": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_uom_unit", "PCE"], + "product_qty": 1.0, + "date_planned": "2011-09-30", + "sequence": 10, + "price_unit": 150.0, + "product_id": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_product_pc1", "[PC1] Basic PC"], + }, + { + "__id": "sale:724f93ec-ddd0-11e0-88ec-701a04e25543.sale_order_line-LXEqeadasdad", + "__module": "sale", + "__model": "sale.order.line", + "__import_module": "purchase", + "__import_model": "purchase.order.line", + "name": "Medium PC", + "product_uom": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_uom_unit", "PCE"], + "product_qty": 10.0, + "sequence": 11, + "date_planned": "2011-09-15", + "price_unit": 20.0, + "product_id": ["product:724f93ec-ddd0-11e0-88ec-701a04e25543.product_product_pc3", "[PC3] Medium PC"], + }], + } + new_purchase_order_id = purchase_order_pool.edi_import(cr, uid, edi_document, context=context) + assert new_purchase_order_id, 'Purchase order import failed' + order_new = purchase_order_pool.browse(cr, uid, new_purchase_order_id) + + # check bank info on partner + assert order_new.partner_id.supplier, "Imported partner should be a supplier, as we just imported the document as a purchase order" + assert len(order_new.partner_id.bank_ids) == 1, "Expected 1 bank entry related to partner" + bank_info = order_new.partner_id.bank_ids[0] + assert bank_info.acc_number == "Another bank: 123477700-156113", 'Expected "Another bank: 123477700-156113", got %s' % bank_info.acc_number + + assert order_new.pricelist_id.name == 'Default Purchase Pricelist' , "Default Purchase Pricelist was not automatically assigned" + assert order_new.amount_total == 350, "Amount total is not same" + assert order_new.amount_untaxed == 350, "untaxed amount is not same" + assert len(order_new.order_line) == 2, "Purchase order lines number mismatch" + for purchase_line in order_new.order_line: + if purchase_line.name == 'Basic PC': + assert purchase_line.product_uom.name == "PCE" , "uom is not same" + assert purchase_line.price_unit == 150 , "unit price is not same, got %s, expected 150"%(purchase_line.price_unit,) + assert purchase_line.product_qty == 1 , "product qty is not same" + elif purchase_line.name == 'Medium PC': + assert purchase_line.product_uom.name == "PCE" , "uom is not same" + assert purchase_line.price_unit == 20 , "unit price is not same, got %s, expected 20"%(purchase_line.price_unit,) + assert purchase_line.product_qty == 10 , "product qty is not same" + else: + raise AssertionError('unknown order line: %s' % purchase_line) \ No newline at end of file diff --git a/addons/sale/edi/sale_order.py b/addons/sale/edi/sale_order.py index edec15a86ae..15389f1481c 100644 --- a/addons/sale/edi/sale_order.py +++ b/addons/sale/edi/sale_order.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Business Applications -# Copyright (c) 2011 OpenERP S.A.- You can view the ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'} document, download it and pay online using the following link: -
- View Order - - % if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account and object.state not in ('draft', 'sent'): + % if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account and object.state != 'draft': <% comp_name = quote(object.company_id.name) order_name = quote(object.name) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index c1af024ad9c..3c568cc8227 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -636,30 +636,33 @@ class sale_order(osv.osv): This function opens a window to compose an email, with the edi sale template message loaded by default ''' assert len(ids) == 1, 'This option should only be used for a single id at a time.' - mod_obj = self.pool.get('ir.model.data') - template = mod_obj.get_object_reference(cr, uid, 'sale', 'email_template_edi_sale') - template_id = template and template[1] or False - res = mod_obj.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form') - res_id = res and res[1] or False + ir_model_data = self.pool.get('ir.model.data') + try: + template_id = ir_model_data.get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1] + except ValueError: + template_id = False + try: + compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1] + except ValueError: + compose_form_id = False ctx = dict(context) ctx.update({ 'default_model': 'sale.order', 'default_res_id': ids[0], - 'default_use_template': True, + 'default_use_template': bool(template_id), 'default_template_id': template_id, 'default_composition_mode': 'comment', 'mark_so_as_sent': True }) return { + 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'mail.compose.message', - 'views': [(res_id, 'form')], - 'view_id': res_id, - 'type': 'ir.actions.act_window', + 'views': [(compose_form_id, 'form')], + 'view_id': compose_form_id, 'target': 'new', 'context': ctx, - 'nodestroy': True, } def action_done(self, cr, uid, ids, context=None): diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 9f385339173..419047dbbd2 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -166,8 +166,8 @@