+
diff --git a/addons/mail/security/ir.model.access.csv b/addons/mail/security/ir.model.access.csv
index 011e8b27dc5..1fb909f4435 100644
--- a/addons/mail/security/ir.model.access.csv
+++ b/addons/mail/security/ir.model.access.csv
@@ -1,7 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_mail_message,mail.message,model_mail_message,,1,0,1,0
-access_mail_message_all,mail.message.all,model_mail_message,base.group_user,1,1,1,1
+access_mail_message_all,mail.message.all,model_mail_message,,1,0,0,0
+access_mail_message_group_user,mail.message.group.user,model_mail_message,base.group_user,1,1,1,1
access_mail_thread,mail.thread,model_mail_thread,base.group_user,1,1,1,0
-access_mail_subscription,mail.subscription,model_mail_subscription,,1,1,1,1
-access_mail_notification,mail.notification,model_mail_notification,,1,1,1,1
+access_mail_subscription_all,mail.subscription.all,model_mail_subscription,,1,1,1,1
+access_mail_notification_all,mail.notification.all,model_mail_notification,,1,1,1,1
access_mail_group,mail.group,model_mail_group,base.group_user,1,1,1,1
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index 0cf932f9a25..03f1078e6d5 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -1,7 +1,6 @@
-
-/* ------------------------------ */
-/* Wall */
-/* ------------------------------ */
+/* ------------------------------------------------------------ */
+/* Wall
+/* ------------------------------------------------------------ */
.openerp div.oe_mail_wall {
overflow: auto;
@@ -9,6 +8,17 @@
background: white;
}
+.openerp div.oe_mail_wall_main {
+ float: left;
+ width: 560px;
+ margin: 8px;
+}
+
+.openerp div.oe_mail_wall_aside {
+ margin-left: 565px;
+ margin: 8px;
+}
+
.openerp div.oe_mail_wall_action {
padding: 8px;
background: #eee;
@@ -21,36 +31,32 @@
clear: both;
}
-.openerp .oe_mail_wall_action textarea {
+.openerp div.oe_mail_wall_action .oe_mail_msg_content {
+ width: 484px;
+}
+
+.openerp div.oe_mail_wall_action textarea.oe_mail_compose_textarea,
+.openerp div.oe_mail_wall_action div.oe_mail_compose_message_body_text textarea {
width: 474px;
height: 60px;
padding: 4px;
- margin-bottom: 8px;
- float: right;
+ margin-bottom: 2px;
}
-/* 2 columns view */
-.openerp div.oe_mail_wall_main {
- float: left;
- width: 560px;
- margin: 8px;
-}
-
-.openerp div.oe_mail_wall_aside {
- margin-left: 565px;
- margin: 8px;
-}
-
-/* Threads */
-.openerp .oe_mail_wall_threads {
+.openerp ul.oe_mail_wall_threads {
margin-top: 8px;
}
-.openerp .oe_mail_wall_threads textarea {
- height: 40px;
+
+/* Specific display of threads in the wall */
+/* ------------------------------------------------------------ */
+
+.openerp ul.oe_mail_wall_threads .oe_mail_msg_content textarea {
+ width: 434px;
+ height: 30px;
padding: 4px;
}
-.openerp .oe_mail_wall_thread:first .oe_mail_msg_notification {
+.openerp li.oe_mail_wall_thread:first .oe_mail_msg_notification {
border-top: 0;
}
@@ -64,7 +70,7 @@
width: 486px;
}
-.openerp div.oe_mail_msg_content li{
+.openerp div.oe_mail_msg_content li {
float: left;
margin-right: 3px;
}
@@ -79,40 +85,28 @@
}
-/* ------------------------------ */
-/* RecordThread */
-/* ------------------------------ */
+/* ------------------------------------------------------------ */
+/* RecordThread
+/* ------------------------------------------------------------ */
.openerp div.oe_mail_recthread {
overflow: auto;
}
-/* Left-side CSS */
-.openerp div.oe_mail_recthread_actions {
- margin-bottom: 8px;
-}
-
-.openerp div.oe_mail_recthread_followers {
- margin-bottom: 8px;
-}
-
-.openerp div.oe_mail_recthread_followers img.oe_mail_msg_image {
- width: 28px;
- height: 28px;
- margin: 4px;
-}
-
-/* RecordThread: 2 columns view */
-.openerp div.oe_mail_recthread_left {
+.openerp div.oe_mail_recthread_main {
float: left;
width: 560px;
}
-.openerp div.oe_mail_recthread_right {
+.openerp div.oe_mail_recthread_aside {
float: right;
width: 250px;
}
+.openerp div.oe_mail_recthread_actions {
+ margin-bottom: 8px;
+}
+
.openerp div.oe_mail_recthread_actions button {
width: 120px;
}
@@ -144,16 +138,17 @@
background-image: linear-gradient(to bottom, #dc5f59, #b33630);
}
-.openerp textarea.oe_mail_action_textarea {
- height: 60px;
- padding: 5px;
+.openerp div.oe_mail_recthread_followers {
+ margin-bottom: 8px;
}
-/* ------------------------------ */
-/* ThreadDisplay */
-/* ------------------------------ */
+
+/* ------------------------------------------------------------ */
+/* Thread
+/* ------------------------------------------------------------ */
.openerp div.oe_mail_thread_action {
+ display: none;
white-space: normal;
padding: 8px;
background: #eee;
@@ -166,6 +161,26 @@
clear: both;
}
+/* default textarea (oe_mail_compose_textarea), and body_text textarea for compose form view */
+.openerp .oe_mail_msg_content textarea.oe_mail_compose_textarea,
+.openerp .oe_mail_msg_content div.oe_mail_compose_message_body_text textarea {
+ width: 474px;
+ height: 60px;
+ padding: 4px;
+ font-size: 12px;
+ border: 1px solid #cccccc;
+}
+
+/* default textarea (oe_mail_compose_textarea), and body_text textarea for compose form view */
+.openerp .oe_mail_msg_content textarea.oe_mail_compose_textarea:focus,
+.openerp .oe_mail_msg_content div.oe_mail_compose_message_body_text textarea:focus {
+ outline: 0;
+ border-color: rgba(82, 168, 236, 0.8);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ -box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
.openerp div.oe_mail_thread_display {
white-space: normal;
}
@@ -174,7 +189,7 @@
margin-left: 66px;
}
-.openerp div.oe_mail_thread_subthread .oe_mail_thread_msg:last-child {
+.openerp div.oe_mail_thread_subthread li.oe_mail_thread_msg:last-child {
margin-bottom: 8px;
}
@@ -183,18 +198,23 @@
border-bottom: 1px solid #D2D9E7;
}
-.openerp .oe_mail_thread_msg:after {
+.openerp li.oe_mail_thread_msg:after {
content: "";
display: block;
clear: both;
}
-.openerp .oe_mail_thread_msg > div:after {
+.openerp li.oe_mail_thread_msg > div:after {
content: "";
display: block;
clear: both;
}
+.openerp div.oe_mail_msg {
+ padding: 0;
+ margin: 0 0 4px 0;
+}
+
.openerp .oe_mail_msg_notification,
.openerp .oe_mail_msg_comment,
.openerp .oe_mail_msg_email {
@@ -203,11 +223,6 @@
border-top: 1px solid #ccc;
}
-.openerp .oe_email_icon {
- width: 50px;
- height: 50px;
-}
-
.openerp div.oe_mail_thread_subthread .oe_mail_msg_comment {
background: #eee;
}
@@ -230,9 +245,18 @@
clear: both;
}
-.openerp img.oe_mail_msg_image {
+.openerp img.oe_mail_icon {
width: 50px;
height: 50px;
+}
+
+.openerp img.oe_mail_thumbnail {
+ width: 28px;
+ height: 28px;
+ margin: 4px;
+}
+
+.openerp img.oe_mail_frame {
text-align: center;
overflow: hidden;
-moz-border-radius: 3px;
@@ -247,48 +271,60 @@
clip: rect(5px, 40px, 45px, 0px);
}
-/* ------------------------------ */
-/* Styling (should be openerp) */
-/* ------------------------------ */
+.openerp .oe_mail_invisible {
+ display: none;
+}
-.openerp input.oe_mail, textarea.oe_mail {
- width: 432px;
- padding: 4px;
- font-size: 12px;
+/* ------------------------------------------------------------ */
+/* mail.compose.message form view & OpenERP hacks
+/* ------------------------------------------------------------ */
+
+/* form_view: delete white background */
+.openerp .oe_mail_msg_content div.oe_formview {
+ background-color: transparent;
+}
+
+.openerp .oe_mail_msg_content div.oe_form_nosheet {
+ margin: 0px;
+}
+
+.openerp .oe_mail_msg_content table.oe_form_group {
+ margin: 0px;
+}
+
+.openerp .oe_mail_msg_content table.oe_form_field,
+.openerp .oe_mail_msg_content div.oe_form_field {
+ padding: 0px;
+}
+
+.openerp .oe_mail_msg_content td.oe_form_group_cell {
+ vertical-align: bottom;
+}
+
+/* subject: change width */
+.openerp .oe_mail_msg_content .oe_form .oe_form_field input {
+ width: 472px;
+}
+
+/* body_html: cleditor */
+.openerp .oe_mail_msg_content div.cleditorMain {
border: 1px solid #cccccc;
- -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
- -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
- -ms-transition: border linear 0.2s, box-shadow linear 0.2s;
- -o-transition: border linear 0.2s, box-shadow linear 0.2s;
- transition: border linear 0.2s, box-shadow linear 0.2s;
- -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
- -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
- -box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
}
-.openerp input.oe_mail:focus, textarea.oe_mail:focus {
- outline: 0;
- border-color: rgba(82, 168, 236, 0.8);
- -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
- -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
- -box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+/* destination_partner_ids */
+.openerp .oe_mail_msg_content div.text-core {
+ height: 22px !important;
+ width: 472px;
}
-.openerp div.oe_mail_msg {
- padding: 0;
- margin: 0 0 4px 0;
+/* buttons */
+.openerp .oe_mail_msg_content .oe_mail_compose_message_icons button.oe_form_button {
+ padding: 1px;
}
-.openerp .oe_mail_oe_bold {
- font-weight: bold;
-}
-
-/* ------------------------------ */
-/* Messages layout */
-/* ------------------------------ */
+/* ------------------------------------------------------------ */
+/* Messages layout
+/* ------------------------------------------------------------ */
.openerp .oe_mail_msg .oe_mail_msg_title {
margin: 0;
@@ -318,6 +354,10 @@
display: inline;
}
+.openerp .oe_mail_oe_bold {
+ font-weight: bold;
+}
+
/* Read more/less link */
.openerp .oe_mail_msg_content .expand,
.openerp .oe_mail_msg_content .reduce {
@@ -360,35 +400,3 @@
padding: 0;
list-style-type: square;
}
-
-
-/* ------------------------------ */
-/* Group Form */
-/* ------------------------------ */
-
-div.oe_mail_group_advanced_details {
- display: none;
-}
-
-.oe_form_sheetbg.openerp_mail_group_sheet {
- min-height: 0px;
- max-height: none;
-}
-
-.oe_form_sheetbg.openerp_mail_group_sheet .oe_form_sheet {
- min-height: 0px;
- max-height: none;
- padding: 0px 18px;
- max-width: 80%;
-}
-
-/* Resize group logo */
-.oe_form_sheetbg.openerp_mail_group_sheet .oe_form_field_image > img {
- max-width: 100px;
- max-height: 100px;
-}
-
-/* Resize group description */
-.oe_form_sheetbg.openerp_mail_group_sheet .oe_form_field_text > textarea {
- height: 40px;
-}
diff --git a/addons/mail/static/src/css/mail_compose_message.css b/addons/mail/static/src/css/mail_compose_message.css
new file mode 100644
index 00000000000..4cd1339ded4
--- /dev/null
+++ b/addons/mail/static/src/css/mail_compose_message.css
@@ -0,0 +1,16 @@
+/* ------------------------------ */
+/* Compose Message Wizard Form */
+/* ------------------------------ */
+
+.openerp tr td .oe_form_field.oe_mail_compose_message_invisible {
+ display: none;
+}
+
+.openerp .oe_mail_compose_message_icons {
+ text-align: right;
+}
+
+.openerp .oe_mail_compose_message_icons img {
+ width: 20px;
+ height: 20px;
+}
diff --git a/addons/mail/static/src/img/_fp.png b/addons/mail/static/src/img/_fp.png
deleted file mode 100644
index 17dce2a047c..00000000000
Binary files a/addons/mail/static/src/img/_fp.png and /dev/null differ
diff --git a/addons/mail/static/src/img/attachment.png b/addons/mail/static/src/img/attachment.png
new file mode 100644
index 00000000000..5cc0c33257d
Binary files /dev/null and b/addons/mail/static/src/img/attachment.png differ
diff --git a/addons/mail/static/src/img/checklist.png b/addons/mail/static/src/img/checklist.png
new file mode 100644
index 00000000000..d252606ff53
Binary files /dev/null and b/addons/mail/static/src/img/checklist.png differ
diff --git a/addons/mail/static/src/img/feeds-hover.png b/addons/mail/static/src/img/feeds-hover.png
deleted file mode 100644
index 67070d3e7df..00000000000
Binary files a/addons/mail/static/src/img/feeds-hover.png and /dev/null differ
diff --git a/addons/mail/static/src/img/feeds.png b/addons/mail/static/src/img/feeds.png
deleted file mode 100644
index ac2293c0bf5..00000000000
Binary files a/addons/mail/static/src/img/feeds.png and /dev/null differ
diff --git a/addons/mail/static/src/img/formatting.png b/addons/mail/static/src/img/formatting.png
new file mode 100644
index 00000000000..cf45fdf192f
Binary files /dev/null and b/addons/mail/static/src/img/formatting.png differ
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index 2140bbe474a..8ce050fd144 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -5,210 +5,652 @@ openerp.mail = function(session) {
var mail = session.mail = {};
/**
- * Add records to sorted_comments array
- * @param {Array} records records from mail.message sorted by date desc
- * @returns {Object} cs comments_structure: dict
- * cs.model_to_root_ids = {model: [root_ids], }
- * cs.new_root_ids = [new_root_ids]
- * cs.root_ids = [root_ids]
- * cs.msgs = {record.id: record,}
- * cs.tree_struct = {record.id: {
- * 'level': record_level in hierarchy, 0 is root,
- * 'msg_nbr': number of childs,
- * 'direct_childs': [msg_ids],
- * 'all_childs': [msg_ids],
- * 'for_thread_msgs': [records],
- * 'ancestors': [msg_ids], } }
+ * ------------------------------------------------------------
+ * FormView
+ * ------------------------------------------------------------
+ *
+ * Override of formview do_action method, to catch all return action about
+ * mail.compose.message. The purpose is to bind 'Send by e-mail' buttons
+ * and redirect them to the Chatter.
*/
- function tools_sort_comments(cs, records, parent_id) {
- var cur_iter = 0; var max_iter = 10; var modif = true;
- while ( modif && (cur_iter++) < max_iter) {
- modif = false;
- _(records).each(function (record) {
- // root and not yet recorded
- if ( (record.parent_id == false || record.parent_id[0] == parent_id) && ! cs['msgs'][record.id]) {
- // add to model -> root_list ids
- if (! cs['model_to_root_ids'][record.model]) cs['model_to_root_ids'][record.model] = [record.id];
- else cs['model_to_root_ids'][record.model].push(record.id);
- // add root data
- cs['new_root_ids'].push(record.id);
- // add record
- cs['tree_struct'][record.id] = {'level': 0, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [record], 'msg_nbr': -1, 'ancestors': []};
- cs['msgs'][record.id] = record;
- modif = true;
- }
- // not yet recorded, but parent is recorded
- else if (! cs['msgs'][record.id] && cs['msgs'][record.parent_id[0]]) {
- var parent_level = cs['tree_struct'][record.parent_id[0]]['level'];
- // update parent structure
- cs['tree_struct'][record.parent_id[0]]['direct_childs'].push(record.id);
- cs['tree_struct'][record.parent_id[0]]['for_thread_msgs'].push(record);
- // update ancestors structure
- for (ancestor_id in cs['tree_struct'][record.parent_id[0]]['ancestors']) {
- cs['tree_struct'][ancestor_id]['all_childs'].push(record.id);
+
+ session.web.FormView = session.web.FormView.extend({
+ do_action: function(action, on_close) {
+ if (action.res_model == 'mail.compose.message' && this.fields && this.fields.message_ids) {
+ var record_thread = this.fields.message_ids;
+ var thread = record_thread.thread;
+ thread.instantiate_composition_form('comment', true, false, 0, action.context);
+ return false;
+ }
+ else {
+ return this._super(action, on_close);
+ }
+ },
+ });
+
+
+ /**
+ * ------------------------------------------------------------
+ * ChatterUtils
+ * ------------------------------------------------------------
+ *
+ * This class holds a few tools method that will be used by
+ * the various Chatter widgets.
+ */
+
+ mail.ChatterUtils = {
+
+ /**
+ * mail_int_mapping: structure to keep a trace of internal links mapping
+ * mail_int_mapping['model'] = {
+ * 'name_get': [[id,label], [id,label], ...]
+ * 'fetch_ids': [id, id, ...] } */
+ //var mail_int_mapping = {};
+
+ /**
+ * mail_msg_struct: structure to orrganize chatter messages
+ */
+ //var mail_msg_struct = {}; // TODO: USE IT OR NOT :)
+
+ /* generic chatter events binding */
+ bind_events: function(widget) {
+ // event: click on an internal link to a document: model, login
+ widget.$element.delegate('a.oe_mail_internal_link', 'click', function (event) {
+ event.preventDefault();
+ // lazy implementation: fetch data and try to redirect
+ if (! event.srcElement.dataset.resModel) return false;
+ else var res_model = event.srcElement.dataset.resModel;
+ var res_login = event.srcElement.dataset.resLogin;
+ if (! res_login) return false;
+ var ds = new session.web.DataSet(widget, res_model);
+ var defer = ds.call('search', [[['login', '=', res_login]]]).pipe(function (records) {
+ if (records[0]) {
+ widget.do_action({ type: 'ir.actions.act_window', res_model: res_model, res_id: parseInt(records[0]), views: [[false, 'form']]});
}
- // add record
- cs['tree_struct'][record.id] = {'level': parent_level+1, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [], 'msg_nbr': -1, 'ancestors': []};
- cs['msgs'][record.id] = record;
- modif = true;
- }
+ else return false;
+ });
});
- }
- return cs;
- }
+ },
+
+ /** get an image in /web/binary/image?... */
+ get_image: function(session_prefix, session_id, model, field, id) {
+ return session_prefix + '/web/binary/image?session_id=' + session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
+ },
+
+ /** checks if tue current user is the message author */
+ is_author: function (widget, message_user_id) {
+ return (widget.session && widget.session.uid != 0 && widget.session.uid == message_user_id);
+ },
+
+ /**
+ * Add records to comments_structure array
+ * @param {Array} records records from mail.message sorted by date desc
+ * @returns {Object} cs comments_structure: dict
+ * cs.model_to_root_ids = {model: [root_ids], }
+ * cs.new_root_ids = [new_root_ids]
+ * cs.root_ids = [root_ids]
+ * cs.msgs = {record.id: record,}
+ * cs.tree_struct = {record.id: {
+ * 'level': record_level in hierarchy, 0 is root,
+ * 'msg_nbr': number of childs,
+ * 'direct_childs': [msg_ids],
+ * 'all_childs': [msg_ids],
+ * 'for_thread_msgs': [records],
+ * 'ancestors': [msg_ids], } }
+ */
+ records_struct_add_records: function(cs, records, parent_id) {
+ var cur_iter = 0; var max_iter = 10; var modif = true;
+ while ( modif && (cur_iter++) < max_iter) {
+ modif = false;
+ _(records).each(function (record) {
+ // root and not yet recorded
+ if ( (record.parent_id == false || record.parent_id[0] == parent_id) && ! cs['msgs'][record.id]) {
+ // add to model -> root_list ids
+ if (! cs['model_to_root_ids'][record.model]) cs['model_to_root_ids'][record.model] = [record.id];
+ else cs['model_to_root_ids'][record.model].push(record.id);
+ // add root data
+ cs['new_root_ids'].push(record.id);
+ // add record
+ cs['tree_struct'][record.id] = {'level': 0, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [record], 'msg_nbr': -1, 'ancestors': []};
+ cs['msgs'][record.id] = record;
+ modif = true;
+ }
+ // not yet recorded, but parent is recorded
+ else if (! cs['msgs'][record.id] && cs['msgs'][record.parent_id[0]]) {
+ var parent_level = cs['tree_struct'][record.parent_id[0]]['level'];
+ // update parent structure
+ cs['tree_struct'][record.parent_id[0]]['direct_childs'].push(record.id);
+ cs['tree_struct'][record.parent_id[0]]['for_thread_msgs'].push(record);
+ // update ancestors structure
+ for (ancestor_id in cs['tree_struct'][record.parent_id[0]]['ancestors']) {
+ cs['tree_struct'][ancestor_id]['all_childs'].push(record.id);
+ }
+ // add record
+ cs['tree_struct'][record.id] = {'level': parent_level+1, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [], 'msg_nbr': -1, 'ancestors': []};
+ cs['msgs'][record.id] = record;
+ modif = true;
+ }
+ });
+ }
+ return cs;
+ },
+
+ /* copy cs.new_root_ids into cs.root_ids */
+ records_struct_update_after_display: function(cs) {
+ // update TODO
+ cs['root_ids'] = _.union(cs['root_ids'], cs['new_root_ids']);
+ cs['new_root_ids'] = [];
+ return cs;
+ },
+
+ /**
+ * CONTENT MANIPULATION
+ *
+ * Regular expressions
+ * - (^|\s)@((\w|@|\.)*): @login@log.log, supports inner '@' for
+ * logins that are emails
+ * 1. '(void)'
+ * 2. login@log.log
+ * - (^|\s)\[(\w+).(\w+),(\d)\|*((\w|[@ .,])*)\]: [ir.attachment,3|My Label],
+ * for internal links to model ir.attachment, id=3, and with
+ * optional label 'My Label'. Note that having a '|Label' is not
+ * mandatory, because the regex should still be correct.
+ * 1. '(void)'
+ * 2. 'ir'
+ * 3. 'attachment'
+ * 4. '3'
+ * 5. 'My Label'
+ */
+
+ /** Removes html tags, except b, em, br, ul, li */
+ do_text_remove_html_tags: function (string) {
+ var html = $('
').text(string.replace(/\s+/g, ' ')).html().replace(new RegExp('<(/)?(b|em|br|br /|ul|li|div)\\s*>', 'gi'), '<$1$2>');
+ return html;
+ },
+
+ /** Replaces line breaks by html line breaks (br) */
+ do_text_nl2br: function (str, is_xhtml) {
+ var break_tag = (is_xhtml || typeof is_xhtml === 'undefined') ? '
' : '
';
+ return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ break_tag +'$2');
+ },
+
+ /* Add a prefix before each new line of the original string */
+ do_text_quote: function (str, prefix) {
+ return str.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ break_tag +'$2' + prefix || '> ');
+ },
+
+ /**
+ * Replaces some expressions
+ * - @login - shorcut to link to a res.user, given its login
+ * - [ir.attachment,3|My Label] - shortcut to an internal
+ * document
+ * - :name - shortcut to an image
+ */
+ do_replace_expressions: function (string) {
+ var self = this;
+ var icon_list = ['al', 'pinky']
+ /* shortcut to user: @login */
+ var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
+ var regex_res = regex_login.exec(string);
+ while (regex_res != null) {
+ var login = regex_res[2];
+ string = string.replace(regex_res[0], regex_res[1] + '
@' + login + ' ');
+ regex_res = regex_login.exec(string);
+ }
+ /* shortcut for internal document */
+ var regex_login = new RegExp(/(^|\s)\[(\w+).(\w+),(\d)\|*((\w|[@ .,])*)\]/g);
+ var regex_res = regex_login.exec(string);
+ while (regex_res != null) {
+ var res_model = regex_res[2] + '.' + regex_res[3];
+ var res_id = regex_res[4];
+ if (! regex_res[5]) {
+ var label = res_model + ':' + res_id }
+ else {
+ var label = regex_res[5];
+ }
+ string = string.replace(regex_res[0], regex_res[1] + '
');
+ regex_res = regex_login.exec(string);
+ }
+ return string;
+ },
+
+ /**
+ * Checks a string to find an expression that will be replaced
+ * by an internal link and requiring a name_get to replace
+ * the expression.
+ * :param mapping: structure to keep a trace of internal links mapping
+ * mapping['model'] = {
+ * name_get': [[id,label], [id,label], ...]
+ * 'to_fetch_ids': [id, id, ...]
+ * }
+ * CURRENTLY NOT IMPLEMENTED */
+ do_check_for_name_get_mapping: function(string, mapping) {
+ /* shortcut to user: @login */
+ //var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
+ //var regex_res = regex_login.exec(string);
+ //while (regex_res != null) {
+ //var login = regex_res[2];
+ //if (! ('res.users' in this.map_hash)) { this.map_hash['res.users']['name'] = []; }
+ //this.map_hash['res.users']['login'].push(login);
+ //regex_res = regex_login.exec(string);
+ //}
+ /* document link with name_get: [res.model,name] */
+ /* internal link with id: [res.model,id], or [res.model,id|display_name] */
+ //var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g);
+ //regex_res = regex_intlink.exec(string);
+ //while (regex_res != null) {
+ //var res_model = regex_res[2] + '.' + regex_res[3];
+ //var res_name = regex_res[4];
+ //if (! (res_model in this.map_hash)) { this.map_hash[res_model]['name'] = []; }
+ //this.map_hash[res_model]['name'].push(res_name);
+ //regex_res = regex_intlink.exec(string);
+ //}
+ },
+
+ /**
+ * Updates the mapping; check for to_fetch_ids for each recorded
+ * model, and perform a name_get to update the mapping.
+ * CURRENTLY NOT IMPLEMENTED */
+ do_update_name_get_mapping: function(mapping) {
+ },
+ };
+
+
+ /**
+ * ------------------------------------------------------------
+ * ComposeMessage widget
+ * ------------------------------------------------------------
+ *
+ * This widget handles the display of a form to compose a new message.
+ * This form is an OpenERP form_view, build on a mail.compose.message
+ * wizard.
+ */
+
+ mail.ComposeMessage = session.web.Widget.extend({
+ template: 'mail.compose_message',
+
+ /**
+ * @param {Object} parent parent
+ * @param {Object} [params]
+ * @param {String} [params.res_model] res_model of document [REQUIRED]
+ * @param {Number} [params.res_id] res_id of record [REQUIRED]
+ * @param {Number} [params.email_mode] true/false, tells whether
+ * we are in email sending mode
+ * @param {Number} [params.formatting] true/false, tells whether
+ * we are in advance formatting mode
+ * @param {String} [params.model] mail.compose.message.mode (see
+ * composition wizard)
+ * @param {Number} [params.msg_id] id of a message in case we are in
+ * reply mode
+ */
+ init: function(parent, params) {
+ var self = this;
+ this._super(parent);
+ // options
+ this.params = params || {};
+ this.params.context = params.context || {};
+ this.params.email_mode = params.email_mode || false;
+ this.params.formatting = params.formatting || false;
+ this.params.mode = params.mode || 'comment';
+ this.params.form_xml_id = params.form_xml_id || 'email_compose_message_wizard_form_chatter';
+ this.params.form_view_id = false;
+ if (this.params.mode == 'reply') {
+ this.params.active_id = this.params.msg_id;
+ } else {
+ this.params.active_id = this.params.res_id;
+ }
+ this.email_mode = false;
+ this.formatting = false;
+ },
+
+ /**
+ * Reinitialize the widget field values to the default values. The
+ * purpose is to avoid to destroy and re-build a form view. Default
+ * values are therefore given as for an onchange. */
+ reinit: function() {
+ var self = this;
+ if (! this.form_view) return;
+ var call_defer = this.ds_compose.call('default_get', [['subject', 'body_text', 'body_html', 'dest_partner_ids'], this.ds_compose.get_context()]).then(
+ function (result) {
+ self.form_view.on_processed_onchange({'value': result}, []);
+ });
+ return call_defer;
+ },
+
+ /**
+ * Override-hack of do_action: clean the form */
+ do_action: function(action, on_close) {
+ // this.init_comments();
+ return this._super(action, on_close);
+ },
+
+ /**
+ * Widget start function
+ * - builds and initializes the form view */
+ start: function() {
+ var self = this;
+ this._super.apply(this, arguments);
+ // customize display: add avatar, clean previous content
+ var user_avatar = mail.ChatterUtils.get_image(this.session.prefix,
+ this.session.session_id, 'res.users', 'avatar', this.session.uid);
+ this.$element.find('img.oe_mail_icon').attr('src', user_avatar);
+ this.$element.find('div.oe_mail_msg_content').empty();
+ // create a context for the default_get of the compose form
+ var widget_context = {
+ 'active_model': this.params.res_model,
+ 'active_id': this.params.active_id,
+ 'mail.compose.message.mode': this.params.mode,
+ };
+ var context = _.extend({}, this.params.context, widget_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
+ var data_ds = new session.web.DataSetSearch(this, 'ir.model.data');
+ var deferred_form_id =data_ds.call('get_object_reference', ['mail', this.params.form_xml_id]).then( function (result) {
+ if (result) {
+ self.params.form_view_id = result[1];
+ }
+ }).pipe(this.proxy('create_form_view'));
+ return deferred_form_id;
+ },
+
+ /**
+ * Create a FormView, then append it to the to widget DOM. */
+ create_form_view: function () {
+ var self = this;
+ // 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.params.form_view_id, {
+ action_buttons: false,
+ pager: false,
+ initial_mode: 'edit',
+ });
+ // add the form, bind events, activate the form
+ var msg_node = this.$element.find('div.oe_mail_msg_content');
+ return $.when(this.form_view.appendTo(msg_node)).pipe(function() {
+ self.bind_events();
+ self.form_view.do_show();
+ if (self.params.email_mode) { self.toggle_email_mode(); }
+ if (self.params.formatting) { self.toggle_formatting_mode(); }
+ });
+ },
+
+ destroy: function() {
+ this._super.apply(this, arguments);
+ },
+
+ /**
+ * Bind events in the widget. Each event is slightly described
+ * in the function. */
+ bind_events: function() {
+ var self = this;
+ this.$element.find('button.oe_form_button').click(function (event) {
+ event.preventDefault();
+ });
+ // event: click on 'Send an Email' link that toggles the form for
+ // sending an email (partner_ids)
+ this.$element.find('a.oe_mail_compose_message_email').click(function (event) {
+ event.preventDefault();
+ self.toggle_email_mode();
+ });
+ // event: click on 'Formatting' icon-link that toggles the advanced
+ // formatting options for writing a message (subject, body_html)
+ this.$element.find('a.oe_mail_compose_message_formatting').click(function (event) {
+ event.preventDefault();
+ self.toggle_formatting_mode();
+ });
+ // event: click on 'Attachment' icon-link that opens the dialog to
+ // add an attachment.
+ this.$element.find('a.oe_mail_compose_message_attachment').click(function (event) {
+ event.preventDefault();
+ // not yet implemented
+ self.set_body_value('attachment', 'attachment');
+ });
+ // event: click on 'Checklist' icon-link that toggles the options
+ // for adding checklist.
+ this.$element.find('a.oe_mail_compose_message_checklist').click(function (event) {
+ event.preventDefault();
+ // not yet implemented
+ self.set_body_value('checklist', 'checklist');
+ });
+ },
+
+ /**
+ * Toggle the formatting mode. */
+ toggle_formatting_mode: function() {
+ var self = this;
+ this.formatting = ! this.formatting;
+ // calls onchange
+ var call_defer = this.ds_compose.call('onchange_formatting', [[], this.formatting, this.params.res_model, this.params.res_id]).then(
+ function (result) {
+ self.form_view.on_processed_onchange(result, []);
+ });
+ // update context of datasetsearch
+ this.ds_compose.context.formatting = this.formatting;
+ // toggle display
+ this.$element.find('span.oe_mail_compose_message_subject').toggleClass('oe_mail_compose_message_invisible');
+ this.$element.find('div.oe_mail_compose_message_body_text').toggleClass('oe_mail_compose_message_invisible');
+ this.$element.find('div.oe_mail_compose_message_body_html').toggleClass('oe_mail_compose_message_invisible');
+ },
+
+ /**
+ * Toggle the email mode. */
+ toggle_email_mode: function() {
+ var self = this;
+ this.email_mode = ! this.email_mode;
+ // calls onchange
+ var call_defer = this.ds_compose.call('onchange_email_mode', [[], this.email_mode, this.params.res_model, this.params.res_id]).then(
+ function (result) {
+ self.form_view.on_processed_onchange(result, []);
+ });
+ // update context of datasetsearch
+ this.ds_compose.context.email_mode = this.email_mode;
+ // update 'Post' button -> 'Send'
+ // update 'Send an Email' link -> 'Post a comment'
+ if (this.email_mode) {
+ this.$element.find('button.oe_mail_compose_message_button_send').html('
Send ');
+ this.$element.find('a.oe_mail_compose_message_email').html('Comment');
+ } else {
+ this.$element.find('button.oe_mail_compose_message_button_send').html('
Post ');
+ this.$element.find('a.oe_mail_compose_message_email').html('Send an Email');
+ }
+ // toggle display
+ this.$element.find('div.oe_mail_compose_message_partner_ids').toggleClass('oe_mail_compose_message_invisible');
+ },
+
+ /**
+ * Update the values of the composition form; with possible different
+ * values for body_text and body_html. */
+ set_body_value: function(body_text, body_html) {
+ this.form_view.fields.body_text.set_value(body_text);
+ this.form_view.fields.body_html.set_value(body_html);
+ },
+ }),
/**
- * ThreadDisplay widget: this widget handles the display of a thread of
- * messages. The [thread_level] parameter sets the thread level number:
+ * ------------------------------------------------------------
+ * Thread Widget
+ * ------------------------------------------------------------
+ *
+ * This widget handles the display of a thread of messages. The
+ * [thread_level] parameter sets the thread level number:
* - root message
* - - sub message (parent_id = root message)
* - - - sub sub message (parent id = sub message)
* - - sub message (parent_id = root message)
- * This widget has 2 ways of initialization, either you give records to be rendered,
- * either it will fetch [limit] messages related to [res_model]:[res_id].
+ * This widget has 2 ways of initialization, either you give records
+ * to be rendered, either it will fetch [limit] messages related to
+ * [res_model]:[res_id].
*/
+
mail.Thread = session.web.Widget.extend({
- template: 'mail.Thread',
+ template: 'mail.thread',
/**
* @param {Object} parent parent
* @param {Object} [params]
- * @param {String} [params.res_model] res_model of mail.thread object
- * @param {Number} [params.res_id] res_id of record
- * @param {Number} [params.parent_id=false] parent_id of message
- * @param {Number} [params.uid] user id
- * @param {Number} [params.thread_level=0] number of levels in the thread (only 0 or 1 currently)
- * @param {Number} [params.msg_more_limit=100] number of character to display before having a "show more" link;
- * note that the text will not be truncated if it does not have 110% of
- * the parameter (ex: 110 characters needed to be truncated and be displayed
- * as a 100-characters message)
- * @param {Number} [params.limit=10] maximum number of messages to fetch
+ * @param {String} [params.res_model] res_model of document [REQUIRED]
+ * @param {Number} [params.res_id] res_id of record [REQUIRED]
+ * @param {Number} [params.uid] user id [REQUIRED]
+ * @param {Bool} [params.parent_id=false] parent_id of message
+ * @param {Number} [params.thread_level=0] number of levels in the thread
+ * (only 0 or 1 currently)
+ * @param {Bool} [params.is_wall=false] thread is displayed in the wall
+ * @param {Number} [params.msg_more_limit=150] number of character to
+ * display before having a "show more" link; note that the text
+ * will not be truncated if it does not have 110% of the parameter
+ * (ex: 110 characters needed to be truncated and be displayed as
+ * a 100-characters message)
+ * @param {Number} [params.limit=100] maximum number of messages to fetch
* @param {Number} [params.offset=0] offset for fetching messages
* @param {Number} [params.records=null] records to show instead of fetching messages
*/
init: function(parent, params) {
this._super(parent);
+ // options
this.params = params;
this.params.parent_id = this.params.parent_id || false;
this.params.thread_level = this.params.thread_level || 0;
- this.params.msg_more_limit = this.params.msg_more_limit || 290;
+ this.params.is_wall = this.params.is_wall || (this.params.records != undefined) || false;
+ this.params.msg_more_limit = this.params.msg_more_limit || 150;
this.params.limit = this.params.limit || 100;
+ // this.params.limit = 3; // tmp for testing
this.params.offset = this.params.offset || 0;
this.params.records = this.params.records || null;
// datasets and internal vars
- this.ds = new session.web.DataSet(this, this.params.res_model);
- this.ds_users = new session.web.DataSet(this, 'res.users');
- this.ds_msg = new session.web.DataSet(this, 'mail.message');
- this.sorted_comments = {'root_ids': [], 'root_id_msg_list': {}};
+ this.ds = new session.web.DataSetSearch(this, this.params.res_model);
+ this.ds_users = new session.web.DataSetSearch(this, 'res.users');
+ this.ds_msg = new session.web.DataSetSearch(this, 'mail.message');
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
// display customization vars
this.display = {};
this.display.show_post_comment = this.params.show_post_comment || false;
- this.display.show_reply = (this.params.thread_level > 0);
- this.display.show_delete = true;
- this.display.show_hide = this.params.show_hide || false;
+ this.display.show_reply = (this.params.thread_level > 0 && this.params.is_wall);
+ this.display.show_delete = ! this.params.is_wall;
+ this.display.show_hide = this.params.is_wall;
+ this.display.show_reply_by_email = ! this.params.is_wall;
this.display.show_more = (this.params.thread_level == 0);
- // not used currently
- this.intlinks_mapping = {};
},
start: function() {
- var self = this;
-
this._super.apply(this, arguments);
- // customize display
- if (! this.display.show_post_comment) {
- this.$element.find('div.oe_mail_thread_action').hide();
- }
// add events
- this.add_events();
-
+ this.bind_events();
// display user, fetch comments
this.display_current_user();
-
- if (this.params.records) {
- var display_done = this.display_comments_from_parameters(this.params.records);
- } else {
- var display_done = this.init_comments();
+ if (this.params.records) var display_done = this.display_comments_from_parameters(this.params.records);
+ else var display_done = this.init_comments();
+ // customize display
+ $.when(display_done).then(this.proxy('do_customize_display'));
+ // add message composition form view
+ if (this.display.show_post_comment) {
+ var compose_done = this.instantiate_composition_form();
}
- return display_done
+ return display_done && compose_done;
},
-
- add_events: function() {
+
+ /**
+ * Override-hack of do_action: automatically reload the chatter.
+ * Normally it should be called only when clicking on 'Post/Send'
+ * in the composition form. */
+ do_action: function(action, on_close) {
+ this.init_comments();
+ if (this.compose_message_widget) {
+ this.compose_message_widget.reinit(); }
+ return this._super(action, on_close);
+ },
+
+ instantiate_composition_form: function(mode, email_mode, formatting, msg_id, context) {
+ if (this.compose_message_widget) {
+ this.compose_message_widget.destroy();
+ }
+ this.compose_message_widget = new mail.ComposeMessage(this, {
+ 'extended_mode': false, 'uid': this.params.uid, 'res_model': this.params.res_model,
+ 'res_id': this.params.res_id, 'mode': mode || 'comment', 'msg_id': msg_id,
+ 'email_mode': email_mode || false, 'formatting': formatting || false,
+ 'context': context || false } );
+ var composition_node = this.$element.find('div.oe_mail_thread_action');
+ composition_node.empty();
+ var compose_done = this.compose_message_widget.appendTo(composition_node);
+ return compose_done;
+ },
+
+ do_customize_display: function() {
+ if (this.display.show_post_comment) { this.$element.find('div.oe_mail_thread_action').eq(0).show(); }
+ },
+
+ /**
+ * Bind events in the widget. Each event is slightly described
+ * in the function. */
+ bind_events: function() {
var self = this;
+ // generic events from Chatter Mixin
+ mail.ChatterUtils.bind_events(this);
// event: click on 'more' at bottom of thread
this.$element.find('button.oe_mail_button_more').click(function () {
self.do_more();
});
- // event: writing in textarea
- this.$element.find('textarea.oe_mail_action_textarea').keyup(function (event) {
+ // event: writing in basic textarea of composition form (quick reply)
+ this.$element.find('textarea.oe_mail_compose_textarea').keyup(function (event) {
var charCode = (event.which) ? event.which : window.event.keyCode;
if (event.shiftKey && charCode == 13) { this.value = this.value+"\n"; }
else if (charCode == 13) { return self.do_comment(); }
});
- // event: click on 'reply' in msg
+ // event: click on 'Reply' in msg
this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_reply', 'click', function (event) {
var act_dom = $(this).parents('div.oe_mail_thread_display').find('div.oe_mail_thread_action:first');
act_dom.toggle();
event.preventDefault();
});
- // event: click on 'delete' in msg
- this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_delete', 'click', function (event) {
- //console.log('deleting');
- if (! confirm(_t("Do you really want to delete this message?"))) { return false; }
- var msg_id = event.srcElement.dataset.id;
- if (! msg_id) return false;
- var call_defer = self.ds_msg.unlink([parseInt(msg_id)]);
- $(event.srcElement).parents('.oe_mail_thread_msg').eq(0).hide();
- if (self.params.thread_level > 0) {
- $(event.srcElement).parents('.oe_mail_thread').eq(0).hide();
- }
- return false;
- });
- // event: click on 'hide' in msg
- this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_hide', 'click', function (event) {
- //console.log('hiding');
- if (! confirm(_t("Do you really want to hide this thread ?"))) { return false; }
- var msg_id = event.srcElement.dataset.id;
- if (! msg_id) return false;
- //console.log(msg_id);
- var call_defer = self.ds.call('message_remove_pushed_notifications', [[self.params.res_id], [parseInt(msg_id)], true]);
- $(event.srcElement).parents('.oe_mail_thread_msg').eq(0).hide();
- if (self.params.thread_level > 0) {
- $(event.srcElement).parents('.oe_mail_thread').eq(0).hide();
- }
- return false;
- });
- // event: click on an internal link
- this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_internal_link', 'click', function (event) {
- // lazy implementation: fetch data and try to redirect
- if (! event.srcElement.dataset.resModel) return false;
- else var res_model = event.srcElement.dataset.resModel;
- var res_login = event.srcElement.dataset.resLogin;
- var res_id = event.srcElement.dataset.resId;
- if ((! res_login) && (! res_id)) return false;
- if (! res_id) {
- var ds = new session.web.DataSet(self, res_model);
- var defer = ds.call('search', [[['login', '=', res_login]]]).then(function (records) {
- if (records[0]) {
- self.do_action({ type: 'ir.actions.act_window', res_model: res_model, res_id: parseInt(records[0]), views: [[false, 'form']]});
- }
- else return false;
- });
- }
- else self.do_action({ type: 'ir.actions.act_window', res_model: res_model, res_id: parseInt(res_id), views: [[false, 'form']]});
- });
// event: click on 'attachment(s)' in msg
this.$element.delegate('a.oe_mail_msg_view_attachments', 'click', function (event) {
var act_dom = $(this).parent().parent().parent().find('.oe_mail_msg_attachments');
act_dom.toggle();
- return false;
+ event.preventDefault();
});
- // see more
- this.$element.on('click','a.oe_mail_msg_more', function (event) {
- $(this).siblings('.oe_mail_msg_tail').show();
- $(this).hide();
- return false;
+ // event: click on 'Delete' in msg side menu
+ this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_delete', 'click', function (event) {
+ if (! confirm(_t("Do you really want to delete this message?"))) { return false; }
+ var msg_id = event.srcElement.dataset.id;
+ if (! msg_id) return false;
+ var call_defer = self.ds_msg.unlink([parseInt(msg_id)]);
+ $(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).hide();
+ if (self.params.thread_level > 0) {
+ $(event.srcElement).parents('.oe_mail_thread').eq(0).hide();
+ }
+ event.preventDefault();
+ return call_defer;
+ });
+ // event: click on 'Hide' in msg side menu
+ this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_hide', 'click', function (event) {
+ if (! confirm(_t("Do you really want to hide this thread ?"))) { return false; }
+ var msg_id = event.srcElement.dataset.id;
+ if (! msg_id) return false;
+ var call_defer = self.ds.call('message_remove_pushed_notifications', [[self.params.res_id], [parseInt(msg_id)], true]);
+ $(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).hide();
+ if (self.params.thread_level > 0) {
+ $(event.srcElement).parents('.oe_mail_thread').eq(0).hide();
+ }
+ event.preventDefault();
+ return call_defer;
+ });
+ // event: click on "Reply" in msg side menu (email style)
+ this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_reply_by_email', 'click', function (event) {
+ var msg_id = event.srcElement.dataset.msg_id;
+ var email_mode = (event.srcElement.dataset.type == 'email');
+ var formatting = (event.srcElement.dataset.formatting == 'html');
+ if (! msg_id) return false;
+ self.instantiate_composition_form('reply', email_mode, formatting, msg_id);
+ event.preventDefault();
});
},
@@ -219,21 +661,22 @@ openerp.mail = function(session) {
init_comments: function() {
var self = this;
this.params.offset = 0;
- this.sorted_comments = {'root_ids': [], 'root_id_msg_list': {}};
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
this.$element.find('div.oe_mail_thread_display').empty();
- domain = this.get_fetch_domain(this.sorted_comments);
+ var domain = this.get_fetch_domain(this.comments_structure);
return this.fetch_comments(this.params.limit, this.params.offset, domain).then();
},
fetch_comments: function (limit, offset, domain) {
var self = this;
- var defer = this.ds.call('message_load', [[this.params.res_id], ( (limit+1)||(this.params.limit+1) ), (offset||this.params.offset), (domain||[]), (this.params.thread_level > 0), (this.sorted_comments['root_ids'])]);
- $.when(defer).then(function (records) {
+ var defer = this.ds.call('message_read', [[this.params.res_id], (this.params.thread_level > 0), (this.comments_structure['root_ids']),
+ (limit+1) || (this.params.limit+1), offset||this.params.offset, domain||undefined ]).then(function (records) {
if (records.length <= self.params.limit) self.display.show_more = false;
- else { self.display.show_more = true; records.pop(); }
-
+ // else { self.display.show_more = true; records.pop(); }
+ // else { self.display.show_more = true; records.splice(0, 1); }
+ else { self.display.show_more = true; }
self.display_comments(records);
+ // TODO: move to customize display
if (self.display.show_more == true) self.$element.find('div.oe_mail_thread_more:last').show();
else self.$element.find('div.oe_mail_thread_more:last').hide();
});
@@ -245,6 +688,7 @@ openerp.mail = function(session) {
if (records.length > 0 && records.length < (records[0].child_ids.length+1) ) this.display.show_more = true;
else this.display.show_more = false;
var defer = this.display_comments(records);
+ // TODO: move to customize display
if (this.display.show_more == true) $('div.oe_mail_thread_more').eq(-2).show();
else $('div.oe_mail_thread_more').eq(-2).hide();
return defer;
@@ -252,7 +696,8 @@ openerp.mail = function(session) {
display_comments: function (records) {
var self = this;
-
+ // sort the records
+ mail.ChatterUtils.records_struct_add_records(this.comments_structure, records, this.params.parent_id);
//build attachments download urls and compute time-relative from dates
for (var k in records) {
records[k].timerelative = $.timeago(records[k].date);
@@ -263,11 +708,10 @@ openerp.mail = function(session) {
}
}
}
- this.cs = this.sort_comments_tmp(records);
_(records).each(function (record) {
var sub_msgs = [];
if ((record.parent_id == false || record.parent_id[0] == self.params.parent_id) && self.params.thread_level > 0 ) {
- var sub_list = self.cs['tree_struct'][record.id]['direct_childs'];
+ var sub_list = self.comments_structure['tree_struct'][record.id]['direct_childs'];
_(records).each(function (record) {
//if (record.parent_id == false || record.parent_id[0] == self.params.parent_id) return;
if (_.indexOf(sub_list, record.id) != -1) {
@@ -276,35 +720,40 @@ openerp.mail = function(session) {
});
self.display_comment(record);
self.thread = new mail.Thread(self, {'res_model': self.params.res_model, 'res_id': self.params.res_id, 'uid': self.params.uid,
- 'records': sub_msgs, 'thread_level': (self.params.thread_level-1), 'parent_id': record.id});
- self.$element.find('.oe_mail_thread_msg:last').append('
');
+ 'records': sub_msgs, 'thread_level': (self.params.thread_level-1), 'parent_id': record.id,
+ 'is_wall': self.params.is_wall});
+ self.$element.find('li.oe_mail_thread_msg:last').append('
');
self.thread.appendTo(self.$element.find('div.oe_mail_thread_subthread:last'));
}
else if (self.params.thread_level == 0) {
self.display_comment(record);
}
});
+ mail.ChatterUtils.records_struct_update_after_display(this.comments_structure);
// update offset for "More" buttons
if (this.params.thread_level == 0) this.params.offset += records.length;
},
- /**
- * Display a record
- */
+ /** Displays a record, performs text/link formatting */
display_comment: function (record) {
- record.body = this.do_text_nl2br(record.body, true);
+ record.body = mail.ChatterUtils.do_text_nl2br(record.body, true);
+ // if (record.type == 'email' && record.state == 'received') {
if (record.type == 'email') {
record.mini_url = ('/mail/static/src/img/email_icon.png');
- } else {
- record.mini_url = this.thread_get_avatar('res.users', 'avatar', record.user_id[0]);
+ } else {
+ record.mini_url = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'avatar', record.user_id[0]);
}
// body text manipulation
- record.body = this.do_clean_text(record.body);
- record.body = this.do_replace_internal_links(record.body);
-
+ if (record.subtype == 'plain') {
+ record.body = mail.ChatterUtils.do_text_remove_html_tags(record.body);
+ }
+ record.body = mail.ChatterUtils.do_replace_expressions(record.body);
// format date according to the user timezone
record.date = session.web.format_value(record.date, {type:"datetime"});
- var rendered = session.web.qweb.render('mail.Thread.message', {'record': record, 'thread': this, 'params': this.params, 'display': this.display});
+ // is the user the author ?
+ record.is_author = mail.ChatterUtils.is_author(this, record.user_id[0]);
+ // render
+ var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'params': this.params, 'display': this.display});
$(rendered).appendTo(this.$element.children('div.oe_mail_thread_display:first'));
// expand feature
this.$element.find('div.oe_mail_msg_body:last').expander({
@@ -316,84 +765,33 @@ openerp.mail = function(session) {
lesClass: 'oe_mail_reduce',
});
},
-
- /**
- * Add records to sorted_comments array
- * @param {Array} records records from mail.message sorted by date desc
- * @returns {Object} sc sorted_comments: dict {
- * 'root_id_list': list or root_ids
- * 'root_id_msg_list': {'record_id': [ancestor_ids]}, still sorted by date desc
- * 'id_to_root': {'root_id': [records]}, still sorted by date desc
- * }
- */
- sort_comments: function (records) {
- var self = this;
- sc = {'root_id_list': [], 'root_id_msg_list': {}, 'id_to_root': {}}
- var cur_iter = 0; var max_iter = 10; var modif = true;
- /* step1: get roots */
- while ( modif && (cur_iter++) < max_iter) {
- modif = false;
- _(records).each(function (record) {
- if ( (record.parent_id == false || record.parent_id[0] == self.params.parent_id) && (_.indexOf(sc['root_id_list'], record.id) == -1)) {
- sc['root_id_list'].push(record.id);
- sc['root_id_msg_list'][record.id] = [];
- self.sorted_comments['root_ids'].push(record.id);
- modif = true;
- }
- else {
- if (_.indexOf(sc['root_id_list'], record.parent_id[0]) != -1) {
- sc['id_to_root'][record.id] = record.parent_id[0];
- modif = true;
- }
- else if ( sc['id_to_root'][record.parent_id[0]] ) {
- sc['id_to_root'][record.id] = sc['id_to_root'][record.parent_id[0]];
- modif = true;
- }
- }
- });
- }
- /* step2: add records */
- _(records).each(function (record) {
- var root_id = sc['id_to_root'][record.id];
- if (! root_id) return;
- sc['root_id_msg_list'][root_id].push(record);
- //self.sorted_comments['root_id_msg_list'][root_id].push(record.id);
- });
- return sc;
- },
-
- /**
- * Add records to comments_structure object: see function for details
- */
- sort_comments_tmp: function(records) {
- return tools_sort_comments(this.comments_structure, records, this.params.parent_id);
- },
-
+
display_current_user: function () {
- return this.$element.find('img.oe_mail_msg_image').attr('src', this.thread_get_avatar('res.users', 'avatar', this.params.uid));
+ var avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'avatar', this.params.uid);
+ return this.$element.find('img.oe_mail_icon').attr('src', avatar);
},
do_comment: function () {
var comment_node = this.$element.find('textarea');
var body_text = comment_node.val();
comment_node.val('');
- return this.ds.call('message_append_note', [[this.params.res_id], 'Reply', body_text, this.params.parent_id, 'comment', 'html']).then(
+ return this.ds.call('message_append_note', [[this.params.res_id], '', body_text, this.params.parent_id, 'comment', 'plain']).then(
this.proxy('init_comments'));
},
/**
* Create a domain to fetch new comments according to
- * comment already present in sorted_comments
- * @param {Object} sorted_comments (see sort_comments)
+ * comment already present in comments_structure
+ * @param {Object} comments_structure (see chatter utils)
* @returns {Array} fetch_domain (OpenERP domain style)
*/
- get_fetch_domain: function (sorted_comments) {
+ get_fetch_domain: function (comments_structure) {
var domain = [];
- var ids = sorted_comments.root_ids.slice();
+ var ids = comments_structure.root_ids.slice();
var ids2 = [];
// must be child of current parent
if (this.params.parent_id) { domain.push(['id', 'child_of', this.params.parent_id]); }
- _(sorted_comments.root_ids).each(function (id) { // each record
+ _(comments_structure.root_ids).each(function (id) { // each record
ids.push(id);
ids2.push(id);
});
@@ -413,109 +811,46 @@ openerp.mail = function(session) {
},
do_more: function () {
- domain = this.get_fetch_domain(this.sorted_comments);
+ domain = this.get_fetch_domain(this.comments_structure);
return this.fetch_comments(this.params.limit, this.params.offset, domain);
},
-
- /**
- *
- * var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
- * var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g);
- */
- do_replace_internal_links: function (string) {
- var self = this;
- var icon_list = ['al', 'pinky']
- /* shortcut to user: @login */
- var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
- var regex_res = regex_login.exec(string);
- while (regex_res != null) {
- var login = regex_res[2];
- string = string.replace(regex_res[0], regex_res[1] + '
@' + login + ' ');
- regex_res = regex_login.exec(string);
- }
- /* special shortcut: :name, try to find an icon if in list */
- var regex_login = new RegExp(/(^|\s):((\w)*)/g);
- var regex_res = regex_login.exec(string);
- while (regex_res != null) {
- var icon_name = regex_res[2];
- if (_.include(icon_list, icon_name))
- string = string.replace(regex_res[0], regex_res[1] + '
');
- regex_res = regex_login.exec(string);
- }
- return string;
- },
-
- thread_get_avatar: function(model, field, id) {
- return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
- },
-
- /** Removes html tags, except b, em, br */
- do_clean_text: function (string) {
- var html = $('
').text(string.replace(/\s+/g, ' ')).html().replace(new RegExp('<(/)?(b|em|br|br /)\\s*>', 'gi'), '<$1$2>');
- return html;
- },
-
- /** Replaces line bracks by html line breaks (br) */
- do_text_nl2br: function (str, is_xhtml) {
- var break_tag = (is_xhtml || typeof is_xhtml === 'undefined') ? '
' : '
';
- return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ break_tag +'$2');
- },
-
- /**
- *
- * var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
- * var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g);
- */
- do_check_internal_links: function(string) {
- /* shortcut to user: @login */
- var regex_login = new RegExp(/(^|\s)@((\w|@|\.)*)/g);
- var regex_res = regex_login.exec(string);
- while (regex_res != null) {
- var login = regex_res[2];
- if (! ('res.users' in this.map_hash)) { this.map_hash['res.users']['name'] = []; }
- this.map_hash['res.users']['login'].push(login);
- regex_res = regex_login.exec(string);
- }
- /* internal links: #res.model,name */
- var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g);
- regex_res = regex_intlink.exec(string);
- while (regex_res != null) {
- var res_model = regex_res[2] + '.' + regex_res[3];
- var res_name = regex_res[4];
- if (! (res_model in this.map_hash)) { this.map_hash[res_model]['name'] = []; }
- this.map_hash[res_model]['name'].push(res_name);
- regex_res = regex_intlink.exec(string);
- }
- },
-
- /** checks if tue current user is the message author */
- _is_author: function (id) {
- return (this.session.uid == id);
- },
-
});
- session.web.form.widgets.add( 'Thread', 'openerp.mail.Thread');
+
+
+ /**
+ * ------------------------------------------------------------
+ * mail_thread Widget
+ * ------------------------------------------------------------
+ *
+ * This widget handles the display of the Chatter on documents.
+ */
+
+ /* Add mail_thread widget to registry */
+ session.web.form.widgets.add('mail_thread', 'openerp.mail.RecordThread');
/** mail_thread widget: thread of comments */
mail.RecordThread = session.web.form.AbstractField.extend({
- template: 'mail.RecordThread',
+ // QWeb template to use when rendering the object
+ template: 'mail.record_thread',
init: function() {
this._super.apply(this, arguments);
- this.see_subscribers = true;
- this.thread = null;
this.params = this.get_definition_options();
this.params.thread_level = this.params.thread_level || 0;
- // datasets
+ this.params.see_subscribers = true;
+ this.params.see_subscribers_options = this.params.see_subscribers_options || false;
+ this.thread = null;
this.ds = new session.web.DataSet(this, this.view.model);
this.ds_users = new session.web.DataSet(this, 'res.users');
},
start: function() {
- this._super.apply(this, arguments);
var self = this;
- // bind buttons
- this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); }).hide();
+ this._super.apply(this, arguments);
+ mail.ChatterUtils.bind_events(this);
+ this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); });
+ if (! this.params.see_subscribers_options) {
+ this.$element.find('button.oe_mail_button_followers').hide(); }
this.$element.find('button.oe_mail_button_follow').click(function () { self.do_follow(); })
.mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
.mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
@@ -530,7 +865,8 @@ openerp.mail = function(session) {
},
reinit: function() {
- this.see_subscribers = true;
+ this.params.see_subscribers = true;
+ this.params.see_subscribers_options = this.params.see_subscribers_options || false;
this.$element.find('button.oe_mail_button_followers').html('Hide followers')
this.$element.find('button.oe_mail_button_follow').hide();
this.$element.find('button.oe_mail_button_unfollow').hide();
@@ -548,11 +884,11 @@ openerp.mail = function(session) {
// fetch followers
var fetch_sub_done = this.fetch_subscribers();
// create and render Thread widget
- this.$element.find('div.oe_mail_recthread_left').empty();
+ this.$element.find('div.oe_mail_recthread_main').empty();
if (this.thread) this.thread.destroy();
this.thread = new mail.Thread(this, {'res_model': this.view.model, 'res_id': this.view.datarecord.id, 'uid': this.session.uid,
- 'thread_level': this.params.thread_level, 'show_post_comment': true, 'limit': 15});
- var thread_done = this.thread.appendTo(this.$element.find('div.oe_mail_recthread_left'));
+ 'thread_level': this.params.thread_level, 'show_post_comment': true, 'limit': 15});
+ var thread_done = this.thread.appendTo(this.$element.find('div.oe_mail_recthread_main'));
return fetch_sub_done && thread_done;
},
@@ -567,9 +903,8 @@ openerp.mail = function(session) {
this.$element.find('div.oe_mail_recthread_followers h4').html('Followers (' + records.length + ')');
_(records).each(function (record) {
if (record.id == self.session.uid) { self.is_subscriber = true; }
- var mini_url = self.thread_get_avatar('res.users', 'avatar', record.id);
- $('
' +
- '' + record.name + ' ').appendTo(user_list);
+ record.avatar_url = mail.ChatterUtils.get_image(self.session.prefix, self.session.session_id, 'res.users', 'avatar', record.id);
+ $(session.web.qweb.render('mail.record_thread.subscriber', {'record': record})).appendTo(user_list);
});
if (self.is_subscriber) {
self.$element.find('button.oe_mail_button_follow').hide();
@@ -591,30 +926,35 @@ openerp.mail = function(session) {
},
do_toggle_followers: function () {
- this.see_subscribers = ! this.see_subscribers;
- if (this.see_subscribers) { this.$element.find('button.oe_mail_button_followers').html('Hide followers'); }
- else { this.$element.find('button.oe_mail_button_followers').html('Display followers'); }
+ this.params.see_subscribers = ! this.params.see_subscribers;
+ if (this.params.see_subscribers) { this.$element.find('button.oe_mail_button_followers').html('Hide followers'); }
+ else { this.$element.find('button.oe_mail_button_followers').html('Show followers'); }
this.$element.find('div.oe_mail_recthread_followers').toggle();
},
-
- thread_get_avatar: function(model, field, id) {
- return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
- },
});
- session.web.form.widgets.add( 'mail_thread', 'openerp.mail.RecordThread');
- /** WallView widget: a wall of messages */
- mail.WallView = session.web.Widget.extend({
- template: 'mail.Wall',
+
+ /**
+ * ------------------------------------------------------------
+ * WallView Widget
+ * ------------------------------------------------------------
+ *
+ * This widget handles the display of the Chatter on the Wall.
+ */
+
+ /* Add WallView widget to registry */
+ session.web.client_actions.add('mail.wall', 'session.mail.Wall');
+
+ /* WallView widget: a wall of messages */
+ mail.Wall = session.web.Widget.extend({
+ template: 'mail.wall',
/**
* @param {Object} parent parent
* @param {Object} [params]
* @param {Number} [params.limit=20] number of messages to show and fetch
* @param {Number} [params.search_view_id=false] search view id for messages
- * @var {Array} sorted_comments records sorted by res_model and res_id
- * records.res_model = {res_ids}
- * records.res_model.res_id = [records]
+ * @var {Array} comments_structure (see chatter utils)
*/
init: function (parent, params) {
this._super(parent);
@@ -637,26 +977,49 @@ openerp.mail = function(session) {
start: function () {
this._super.apply(this, arguments);
- var self = this;
this.display_current_user();
// add events
this.add_event_handlers();
// load mail.message search view
var search_view_ready = this.load_search_view(this.params.search_view_id, {}, false);
+ // load composition form
+ var compose_done = this.instantiate_composition_form();
// fetch first threads
var comments_ready = this.init_and_fetch_comments(this.params.limit, 0);
- return (search_view_ready && comments_ready);
+ return (search_view_ready && comments_ready && compose_done);
},
-
- stop: function () {
+
+ /**
+ * Override-hack of do_action: automatically reload the chatter.
+ * Normally it should be called only when clicking on 'Post/Send'
+ * in the composition form. */
+ do_action: function(action, on_close) {
+ this.init_and_fetch_comments();
+ if (this.compose_message_widget) {
+ this.compose_message_widget.reinit(); }
+ return this._super(action, on_close);
+ },
+
+ destroy: function () {
this._super.apply(this, arguments);
},
-
+
+ instantiate_composition_form: function(mode, msg_id) {
+ if (this.compose_message_widget) {
+ this.compose_message_widget.destroy();
+ }
+ this.compose_message_widget = new mail.ComposeMessage(this, {
+ 'extended_mode': false, 'uid': this.session.uid, 'res_model': 'res.users',
+ 'res_id': this.session.uid, 'mode': mode || 'comment', 'msg_id': msg_id });
+ var composition_node = this.$element.find('div.oe_mail_wall_action');
+ composition_node.empty();
+ var compose_done = this.compose_message_widget.appendTo(composition_node);
+ return compose_done;
+ },
+
/** Add events */
add_event_handlers: function () {
var self = this;
- // post a comment
- this.$element.find('.oe_mail_wall_action button').click(function () { return self.do_comment(); });
// display more threads
this.$element.find('button.oe_mail_wall_button_more').click(function () { return self.do_more(); });
},
@@ -699,13 +1062,9 @@ openerp.mail = function(session) {
},
display_current_user: function () {
- return this.$element.find('img.oe_mail_msg_image').attr('src', this.thread_get_avatar('res.users', 'avatar', this.session.uid));
- },
-
- thread_get_avatar: function(model, field, id) {
- return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
- },
-
+ //return this.$element.find('img.oe_mail_msg_image').attr('src', this.thread_get_avatar('res.users', 'avatar', this.session.uid));
+ },
+
/**
* Initializes the wall and calls fetch_comments
* @param {Number} limit: number of notifications to fetch
@@ -735,8 +1094,8 @@ openerp.mail = function(session) {
else var fetch_domain = this.search['domain'];
if (additional_context) var fetch_context = _.extend(this.search['context'], additional_context);
else var fetch_context = this.search['context'];
- return this.ds_thread.call('get_pushed_messages',
- [[this.session.uid], (limit || 0), (offset || 0), fetch_domain, true, [], fetch_context]).then(this.proxy('display_comments'));
+ return this.ds_thread.call('message_get_pushed_messages',
+ [[this.session.uid], true, [], (limit || 0), (offset || 0), fetch_domain, fetch_context]).then(this.proxy('display_comments'));
},
/**
@@ -745,16 +1104,16 @@ openerp.mail = function(session) {
display_comments: function (records) {
var self = this;
this.do_update_show_more(records.length >= self.params.limit);
- this.sort_comments(records);
+ mail.ChatterUtils.records_struct_add_records(this.comments_structure, records, false);
_(this.comments_structure['new_root_ids']).each(function (root_id) {
var records = self.comments_structure.tree_struct[root_id]['for_thread_msgs'];
var model_name = self.comments_structure.msgs[root_id]['model'];
var res_id = self.comments_structure.msgs[root_id]['res_id'];
- var render_res = session.web.qweb.render('mail.WallThreadContainer', {});
+ var render_res = session.web.qweb.render('mail.wall_thread_container', {});
$('
').html(render_res).appendTo(self.$element.find('ul.oe_mail_wall_threads'));
var thread = new mail.Thread(self, {
'res_model': model_name, 'res_id': res_id, 'uid': self.session.uid, 'records': records,
- 'parent_id': false, 'thread_level': self.params.thread_level, 'show_hide': true}
+ 'parent_id': false, 'thread_level': self.params.thread_level, 'show_hide': true, 'is_wall': true}
);
self.thread_list.push(thread);
return thread.appendTo(self.$element.find('li.oe_mail_wall_thread:last'));
@@ -764,19 +1123,11 @@ openerp.mail = function(session) {
this.comments_structure['new_root_ids'] = [];
},
- /**
- * Add records to comments_structure object: see function for details
- */
- sort_comments: function(records) {
- tools_sort_comments(this.comments_structure, records, false);
- },
-
/**
* Create a domain to fetch new comments according to
- * comments already present in sorted_comments
+ * comments already present in comments_structure
* - for each model:
* -- should not be child of already displayed ids
- * @param {Object} sorted_comments (see sort_comments)
* @returns {Array} fetch_domain (OpenERP domain style)
*/
get_fetch_domain: function () {
@@ -801,17 +1152,5 @@ openerp.mail = function(session) {
var domain = this.get_fetch_domain();
return this.fetch_comments(this.params.limit, 0, domain);
},
-
- /** Action: Posts a comment */
- do_comment: function () {
- var comment_node = this.$element.find('.oe_mail_wall_action textarea');
- var body_text = comment_node.val();
- comment_node.val('');
- var call_done = this.ds_users.call('message_append_note', [[this.session.uid], 'Tweet', body_text, false, 'comment', 'html']).then(this.proxy('init_and_fetch_comments'));
- },
});
- session.web.client_actions.add('mail.all_feeds', 'session.mail.WallView');
-
};
-
-// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index 982fb8aeb2f..bf8d7fd1475 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -1,7 +1,11 @@
-
+
+
-
-
-
+
+
-
+
See more discussions
-
+
+
+
-
+
+
-
-
-
+
+
+
+
+
+
+
Not following
Following
- Display followers
+ Show followers
Followers
@@ -53,44 +71,87 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
Load more messages
-
+
-
+
-
+
-
+
+
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index 1b19a383c10..d26511464f8 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -33,7 +33,7 @@ from ..mail_message import to_email
# main mako-like expression pattern
EXPRESSION_PATTERN = re.compile('(\$\{.+?\})')
-class mail_compose_message(osv.osv_memory):
+class mail_compose_message(osv.TransientModel):
"""Generic Email composition wizard. This wizard is meant to be inherited
at model and view level to provide specific wizard features.
@@ -41,13 +41,12 @@ class mail_compose_message(osv.osv_memory):
parameters, among which are:
* mail.compose.message.mode: if set to 'reply', the wizard is in
- reply mode and pre-populated with the original quote.
- If set to 'mass_mail', the wizard is in mass mailing
- where the mail details can contain template placeholders
- that will be merged with actual data before being sent
- to each recipient. Recipients will be derived from the
- records determined via ``context['active_model']`` and
- ``context['active_ids']``.
+ reply to a previous message mode and pre-populated with the original
+ quote. If set to 'comment', it means you are writing a new message to
+ be attached to a document. If set to 'mass_mail', the wizard is in
+ mass mailing where the mail details can contain template placeholders
+ that will be merged with actual data before being sent to each
+ recipient.
* active_model: model name of the document to which the mail being
composed is related
* active_id: id of the document to which the mail being composed is
@@ -61,119 +60,179 @@ class mail_compose_message(osv.osv_memory):
_description = 'Email composition wizard'
def default_get(self, cr, uid, fields, context=None):
- """Overridden to provide specific defaults depending on the context
- parameters.
+ """ Overridden to provide specific defaults depending on the context
+ parameters.
+
+ Composition mode
+ - comment: default mode; active_model, active_id = model and ID of a
+ document we are commenting,
+ - reply: active_id = ID of a mail.message to which we are replying.
+ From this message we can find the related model and res_id,
+ - mass_mailing mode: active_model, active_id = model and ID of a
+ document we are commenting,
:param dict context: several context values will modify the behavior
of the wizard, cfr. the class description.
"""
if context is None:
context = {}
+ compose_mode = context.get('mail.compose.message.mode', 'comment')
+ active_model = context.get('active_model')
+ active_id = context.get('active_id')
result = super(mail_compose_message, self).default_get(cr, uid, fields, context=context)
+
+ # get default values according to the composition mode
vals = {}
- reply_mode = context.get('mail.compose.message.mode') == 'reply'
- if (not reply_mode) and context.get('active_model') and context.get('active_id'):
- # normal mode when sending an email related to any document, as specified by
- # active_model and active_id in context
- vals = self.get_value(cr, uid, context.get('active_model'), context.get('active_id'), context)
- elif reply_mode and context.get('active_id'):
- # reply mode, consider active_id is the ID of a mail.message to which we're
- # replying
- vals = self.get_message_data(cr, uid, int(context['active_id']), context)
- else:
- # default mode
- result['model'] = context.get('active_model', False)
+ if compose_mode in ['reply']:
+ vals = self.get_message_data(cr, uid, int(context['active_id']), context=context)
+ elif compose_mode in ['comment', 'mass_mail'] and active_model and active_id:
+ vals = self.get_value(cr, uid, active_model, active_id, context)
for field in vals:
if field in fields:
- result.update({field : vals[field]})
+ result[field] = vals[field]
# link to model and record if not done yet
- if not result.get('model') or not result.get('res_id'):
- active_model = context.get('active_model')
- res_id = context.get('active_id')
- if active_model and active_model not in (self._name, 'mail.message'):
- result['model'] = active_model
- if res_id:
- result['res_id'] = res_id
+ if not result.get('model') and active_model:
+ result['model'] = active_model
+ if not result.get('res_id') and active_id:
+ result['res_id'] = active_id
# Try to provide default email_from if not specified yet
if not result.get('email_from'):
- current_user = self.pool.get('res.users').browse(cr, uid, uid, context)
+ current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
result['email_from'] = current_user.user_email or False
return result
_columns = {
+ 'dest_partner_ids': fields.many2many('res.partner',
+ 'email_message_send_partner_rel',
+ 'wizard_id', 'partner_id', 'Destination partners',
+ help="When sending emails through the social network composition wizard"\
+ "you may choose to send a copy of the mail to partners."),
'attachment_ids': fields.many2many('ir.attachment','email_message_send_attachment_rel', 'wizard_id', 'attachment_id', 'Attachments'),
'auto_delete': fields.boolean('Auto Delete', help="Permanently delete emails after sending"),
'filter_id': fields.many2one('ir.filters', 'Filters'),
}
def get_value(self, cr, uid, model, res_id, context=None):
- """Returns a defaults-like dict with initial values for the composition
- wizard when sending an email related to the document record identified
- by ``model`` and ``res_id``.
+ """ Returns a defaults-like dict with initial values for the composition
+ wizard when sending an email related to the document record
+ identified by ``model`` and ``res_id``.
- The default implementation returns an empty dictionary, and is meant
- to be overridden by subclasses.
+ The default implementation returns an empty dictionary, and is meant
+ to be overridden by subclasses.
- :param str model: model name of the document record this mail is related to.
- :param int res_id: id of the document record this mail is related to.
- :param dict context: several context values will modify the behavior
- of the wizard, cfr. the class description.
+ :param str model: model name of the document record this mail is
+ related to.
+ :param int res_id: id of the document record this mail is related to.
+ :param dict context: several context values will modify the behavior
+ of the wizard, cfr. the class description.
"""
- return {}
+ result = {}
+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
+ result.update({
+ 'model': model,
+ 'res_id': res_id,
+ 'email_from': user.user_email or tools.config.get('email_from', False),
+ 'body_html': False,
+ 'body_text': False,
+ 'subject': False,
+ 'dest_partner_ids': [],
+ })
+ return result
+
+ def onchange_email_mode(self, cr, uid, ids, value, model, res_id, context=None):
+ """ email_mode (values: True or False). This onchange on the email mode
+ allows to have some specific behavior when going in email mode, or
+ when going out of email mode.
+ Basically, dest_partner_ids is reset when going out of email
+ mode.
+ This method can be overridden for models that want to have their
+ specific behavior.
+ Note that currently, this onchange is used in mail.js and called
+ manually on the form instantiated in the Chatter.
+ """
+ if not value:
+ return {'value': {'dest_partner_ids': []}}
+ return {'value': {}}
+
+ def onchange_formatting(self, cr, uid, ids, value, model, res_id, context=None):
+ """ onchange_formatting (values: True or False). This onchange on the
+ formatting allows to have some specific behavior when going in
+ formatting mode, or when going out of formatting.
+ Basically, subject is reset when going out of formatting mode.
+ This method can be overridden for models that want to have their
+ specific behavior.
+ Note that currently, this onchange is used in mail.js and called
+ manually on the form instantiated in the Chatter.
+ """
+ if not value:
+ return {'value': {'subject': False}}
+ return {'value': {}}
def get_message_data(self, cr, uid, message_id, context=None):
- """Returns a defaults-like dict with initial values for the composition
- wizard when replying to the given message (e.g. including the quote
- of the initial message, and the correct recipient).
- Should not be called unless ``context['mail.compose.message.mode'] == 'reply'``.
+ """ Returns a defaults-like dict with initial values for the composition
+ wizard when replying to the given message (e.g. including the quote
+ of the initial message, and the correct recipient). It should not be
+ called unless ``context['mail.compose.message.mode'] == 'reply'``.
- :param int message_id: id of the mail.message to which the user
- is replying.
- :param dict context: several context values will modify the behavior
- of the wizard, cfr. the class description.
- When calling this method, the ``'mail'`` value
- in the context should be ``'reply'``.
+ :param int message_id: id of the mail.message to which the user
+ is replying.
+ :param dict context: several context values will modify the behavior
+ of the wizard, cfr. the class description.
"""
if context is None:
context = {}
result = {}
- mail_message = self.pool.get('mail.message')
- if message_id:
- message_data = mail_message.browse(cr, uid, message_id, context)
- subject = tools.ustr(message_data.subject or '')
- # we use the plain text version of the original mail, by default,
- # as it is easier to quote than the HTML version.
- # XXX TODO: make it possible to switch to HTML on the fly
- current_user = self.pool.get('res.users').browse(cr, uid, uid, context)
- body = message_data.body_text or current_user.signature or ''
- if context.get('mail.compose.message.mode') == 'reply':
- sent_date = _('On %(date)s, ') % {'date': message_data.date} if message_data.date else ''
- sender = _('%(sender_name)s wrote:') % {'sender_name': tools.ustr(message_data.email_from or _('You'))}
- quoted_body = '> %s' % tools.ustr(body.replace('\n', "\n> ") or '')
- body = '\n'.join(["\n", (sent_date + sender), quoted_body])
- body += "\n" + (current_user.signature or '')
- re_prefix = _("Re:")
- if not (subject.startswith('Re:') or subject.startswith(re_prefix)):
- subject = "%s %s" % (re_prefix, subject)
- result.update({
- 'subtype' : 'plain', # default to the text version due to quoting
- 'body_text' : body,
- 'subject' : subject,
- 'attachment_ids' : [],
- 'model' : message_data.model or False,
- 'res_id' : message_data.res_id or False,
- 'email_from' : current_user.user_email or message_data.email_to or False,
- 'email_to' : message_data.reply_to or message_data.email_from or False,
- 'email_cc' : message_data.email_cc or False,
- 'user_id' : uid,
+ if not message_id:
+ return result
- # pass msg-id and references of mail we're replying to, to construct the
- # new ones later when sending
- 'message_id' : message_data.message_id or False,
- 'references' : message_data.references and tools.ustr(message_data.references) or False,
- })
+ current_user = self.pool.get('res.users').browse(cr, uid, uid, context)
+ message_data = self.pool.get('mail.message').browse(cr, uid, message_id, context)
+ # Form the subject
+ re_prefix = _("Re:")
+ reply_subject = tools.ustr(message_data.subject or '')
+ if not (reply_subject.startswith('Re:') or reply_subject.startswith(re_prefix)):
+ reply_subject = "%s %s" % (re_prefix, reply_subject)
+ # Form the bodies (text and html). We use the plain text version of the
+ # original mail, by default, as it is easier to quote than the HTML
+ # version. TODO: make it possible to switch to HTML on the fly
+ sent_date = _('On %(date)s, ') % {'date': message_data.date} if message_data.date else ''
+ sender = _('%(sender_name)s wrote:') % {'sender_name': tools.ustr(message_data.email_from or _('You'))}
+ body_text = message_data.body_text or ''
+ body_html = message_data.body_html or ''
+ quoted_body_text = '> %s' % tools.ustr(body_text.replace('\n', "\n> ") or '')
+ quoted_body_html = '
%s ' % (tools.ustr(body_html)),
+ reply_body_text = '\n%s%s\n%s\n%s' % (sent_date, sender, quoted_body_text, current_user.signature)
+ reply_body_html = '
%s%s
%s
%s' % (sent_date, sender, quoted_body_html, current_user.signature)
+ # form dest_partner_ids
+ dest_partner_ids = [partner.id for partner in message_data.partner_ids]
+ # Update header and references
+ reply_headers = {}
+ reply_references = message_data.references and tools.ustr(message_data.references) or False
+ reply_message_id = message_data.message_id or False
+ if reply_message_id:
+ reply_references = (reply_references or '') + " " + message_data.message_id
+ reply_headers['In-Reply-To'] = message_data.message_id
+ # update the result
+ result.update({
+ 'body_text': reply_body_text,
+ 'body_html': reply_body_html,
+ 'subject': reply_subject,
+ 'attachment_ids': [],
+ 'dest_partner_ids': dest_partner_ids,
+ 'model': message_data.model or False,
+ 'res_id': message_data.res_id or False,
+ 'email_from': current_user.user_email or message_data.email_to or False,
+ 'email_to': message_data.reply_to or message_data.email_from or False,
+ 'email_cc': message_data.email_cc or False,
+ 'user_id': uid,
+ # pass msg-id and references of mail we're replying to, to construct the
+ # new ones later when sending
+ 'message_id': reply_message_id,
+ 'references': reply_references,
+ 'headers': reply_headers,
+ })
return result
def send_mail(self, cr, uid, ids, context=None):
@@ -190,76 +249,81 @@ class mail_compose_message(osv.osv_memory):
'''
if context is None:
context = {}
- mail_message = self.pool.get('mail.message')
- for mail in self.browse(cr, uid, ids, context=context):
+ # composition wizard options
+ email_mode = context.get('email_mode')
+ formatting = context.get('formatting')
+ mass_mail_mode = context.get('mail.compose.message.mode') == 'mass_mail'
+
+ mail_message_obj = self.pool.get('mail.message')
+ for mail_wiz in self.browse(cr, uid, ids, context=context):
+ # attachments
attachment = {}
- for attach in mail.attachment_ids:
+ for attach in mail_wiz.attachment_ids:
attachment[attach.datas_fname] = attach.datas and attach.datas.decode('base64')
+
+ # default values, according to the wizard options
+ subject = mail_wiz.subject if formatting else False
+ content_subtype = 'html' if formatting else 'plain'
+ type = 'email' if email_mode else 'comment'
+ state = 'outgoing' if email_mode else False
+ partner_ids = [partner.id for partner in mail_wiz.dest_partner_ids]
references = None
headers = {}
+ body = mail_wiz.body_html if content_subtype == 'html' else mail_wiz.body_text
- body = mail.body_html if mail.subtype == 'html' else mail.body_text
-
- # Get model, and check whether it is OpenChatter enabled, aka inherit from mail.thread
- if context.get('mail.compose.message.mode') == 'mass_mail':
- if context.get('active_ids') and context.get('active_model'):
- active_ids = context['active_ids']
- active_model = context['active_model']
- else:
- active_model = mail.model
- active_model_pool = self.pool.get(active_model)
- active_ids = active_model_pool.search(cr, uid, ast.literal_eval(mail.filter_id.domain), context=ast.literal_eval(mail.filter_id.context))
+ # get model, active_ids, and check if model is openchatter-enabled
+ if mass_mail_mode and context.get('active_ids') and context.get('active_model'):
+ active_ids = context['active_ids']
+ active_model = context['active_model']
+ elif mass_mail_mode:
+ active_model = mail_wiz.model
+ active_model_pool = self.pool.get(active_model)
+ active_ids = active_model_pool.search(cr, uid, ast.literal_eval(mail_wiz.filter_id.domain), context=ast.literal_eval(mail_wiz.filter_id.context))
else:
- active_model = mail.model
- active_ids = [int(mail.res_id)]
+ active_model = mail_wiz.model
+ active_ids = [mail_wiz.res_id]
active_model_pool = self.pool.get(active_model)
- if hasattr(active_model_pool, '_inherit') and 'mail.thread' in active_model_pool._inherit:
- mail_thread_enabled = True
- else:
- mail_thread_enabled = False
-
- # Reply Email
- if context.get('mail.compose.message.mode') == 'reply' and mail.message_id:
- references = (mail.references or '') + " " + mail.message_id
- headers['In-Reply-To'] = mail.message_id
+ mail_thread_enabled = hasattr(active_model_pool, 'message_append')
if context.get('mail.compose.message.mode') == 'mass_mail':
# Mass mailing: must render the template patterns
for active_id in active_ids:
- subject = self.render_template(cr, uid, mail.subject, active_model, active_id)
- rendered_body = self.render_template(cr, uid, body, active_model, active_id)
- email_from = self.render_template(cr, uid, mail.email_from, active_model, active_id)
- email_to = self.render_template(cr, uid, mail.email_to, active_model, active_id)
- email_cc = self.render_template(cr, uid, mail.email_cc, active_model, active_id)
- email_bcc = self.render_template(cr, uid, mail.email_bcc, active_model, active_id)
- reply_to = self.render_template(cr, uid, mail.reply_to, active_model, active_id)
-
+ rendered_subject = self.render_template(cr, uid, subject, active_model, active_id)
+ rendered_body_html = self.render_template(cr, uid, mail_wiz.body_html, active_model, active_id)
+ rendered_body_text = self.render_template(cr, uid, mail_wiz.body_text, active_model, active_id)
+ email_from = self.render_template(cr, uid, mail_wiz.email_from, active_model, active_id)
+ email_to = self.render_template(cr, uid, mail_wiz.email_to, active_model, active_id)
+ email_cc = self.render_template(cr, uid, mail_wiz.email_cc, active_model, active_id)
+ email_bcc = self.render_template(cr, uid, mail_wiz.email_bcc, active_model, active_id)
+ reply_to = self.render_template(cr, uid, mail_wiz.reply_to, active_model, active_id)
+
# in mass-mailing mode we only schedule the mail for sending, it will be
# processed as soon as the mail scheduler runs.
if mail_thread_enabled:
- active_model_pool.message_append(cr, uid, [active_id],
- subject, body_text=mail.body_text, body_html=mail.body_html, subtype=mail.subtype, state='outgoing',
- email_to=email_to, email_from=email_from, email_cc=email_cc, email_bcc=email_bcc,
+ active_model_pool.message_append(cr, uid, [active_id], rendered_subject, rendered_body_text, rendered_body_html,
+ type=type, content_subtype=content_subtype, state=state, partner_ids=partner_ids,
+ email_from=email_from, email_to=email_to, email_cc=email_cc, email_bcc=email_bcc,
reply_to=reply_to, references=references, attachments=attachment, headers=headers, context=context)
else:
- mail_message.schedule_with_attach(cr, uid, email_from, to_email(email_to), subject, rendered_body,
- model=mail.model, email_cc=to_email(email_cc), email_bcc=to_email(email_bcc), reply_to=reply_to,
- attachments=attachment, references=references, res_id=active_id,
- subtype=mail.subtype, headers=headers, context=context)
+ mail_message_obj.schedule_with_attach(cr, uid, email_from, to_email(email_to), subject, rendered_body_text,
+ model=mail_wiz.model, email_cc=to_email(email_cc), email_bcc=to_email(email_bcc), reply_to=reply_to,
+ attachments=attachment, references=references, res_id=active_id, partner_ids=partner_ids,
+ content_subtype=mail_wiz.content_subtype, headers=headers, context=context)
else:
# normal mode - no mass-mailing
if mail_thread_enabled:
- msg_ids = active_model_pool.message_append(cr, uid, active_ids,
- mail.subject, body_text=mail.body_text, body_html=mail.body_html, subtype=mail.subtype, state='outgoing',
- email_to=mail.email_to, email_from=mail.email_from, email_cc=mail.email_cc, email_bcc=mail.email_bcc,
- reply_to=mail.reply_to, references=references, attachments=attachment, headers=headers, context=context)
+ msg_ids = active_model_pool.message_append(cr, uid, active_ids, subject, mail_wiz.body_text, mail_wiz.body_html,
+ type=type, content_subtype=content_subtype, state=state, partner_ids=partner_ids,
+ email_from=mail_wiz.email_from, email_to=mail_wiz.email_to, email_cc=mail_wiz.email_cc, email_bcc=mail_wiz.email_bcc,
+ reply_to=mail_wiz.reply_to, references=references, attachments=attachment, headers=headers, context=context)
else:
- msg_ids = [mail_message.schedule_with_attach(cr, uid, mail.email_from, to_email(mail.email_to), mail.subject, body,
- model=mail.model, email_cc=to_email(mail.email_cc), email_bcc=to_email(mail.email_bcc), reply_to=mail.reply_to,
- attachments=attachment, references=references, res_id=int(mail.res_id),
- subtype=mail.subtype, headers=headers, context=context)]
+ msg_ids = [mail_message_obj.schedule_with_attach(cr, uid, mail_wiz.email_from, to_email(mail_wiz.email_to), subject, mail_wiz.body_text,
+ type=type, model=mail_wiz.model, email_cc=to_email(mail_wiz.email_cc), email_bcc=to_email(mail_wiz.email_bcc), reply_to=mail_wiz.reply_to,
+ attachments=attachment, references=references, res_id=int(mail_wiz.res_id), partner_ids=partner_ids,
+ content_subtype=mail_wiz.content_subtype, headers=headers, context=context)]
# in normal mode, we send the email immediately, as the user expects us to (delay should be sufficiently small)
- mail_message.send(cr, uid, msg_ids, context=context)
+ if type == 'email':
+ mail_message_obj.send(cr, uid, msg_ids, context=context)
return {'type': 'ir.actions.act_window_close'}
@@ -293,8 +357,7 @@ class mail_compose_message(osv.osv_memory):
return template and EXPRESSION_PATTERN.sub(merge, template)
-
-class mail_compose_message_extended(osv.osv_memory):
+class mail_compose_message_extended(osv.TransientModel):
""" Extension of 'mail.compose.message' to support default field values related
to CRM-like models that follow the following conventions:
@@ -309,26 +372,64 @@ class mail_compose_message_extended(osv.osv_memory):
_inherit = 'mail.compose.message'
def get_value(self, cr, uid, model, res_id, context=None):
- """Overrides the default implementation to provide more default field values
- related to the corresponding CRM case.
+ """ Overrides the default implementation to provide more default field values
+ related to the corresponding CRM case.
"""
- result = super(mail_compose_message_extended, self).get_value(cr, uid, model, res_id, context=context)
+ result = super(mail_compose_message_extended, self).get_value(cr, uid, model, res_id, context=context)
model_obj = self.pool.get(model)
if getattr(model_obj, '_mail_compose_message', False) and res_id:
data = model_obj.browse(cr, uid , res_id, context)
- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
result.update({
- 'model': model,
- 'res_id': res_id,
- 'email_from': user.user_email or tools.config.get('email_from', False),
'email_to': data.email_from or False,
'email_cc': tools.ustr(data.email_cc or ''),
'subject': data.name or False,
- 'body_text': '\n' + tools.ustr(user.signature or ''),
- 'subtype': 'plain',
})
if hasattr(data, 'section_id'):
result['reply_to'] = data.section_id and data.section_id.reply_to or False
return result
+ def onchange_email_mode(self, cr, uid, ids, value, model, res_id, context=None):
+ """ Overrides the default implementation to provide default values for
+ dest_partner_ids. This method checks that a partner maching the
+ ``email_from`` of the record exists. It it does not exist, it
+ creates a new partner. The found or created partner is then added
+ in dest_partner_ids.
+ Partner check/creation valid inly if the value is True, and if
+ the model has the ``_mail_compose_message`` attribute.
+ """
+ result = super(mail_compose_message_extended, self).onchange_email_mode(cr, uid, ids, value, model, res_id, context=context)
+ model_obj = self.pool.get(model)
+ if not value or not (getattr(model_obj, '_mail_compose_message', False) and res_id):
+ return result
+ data = model_obj.browse(cr, uid , res_id, context=context)
+ partner_obj = self.pool.get('res.partner')
+ partner_ids = partner_obj.search(cr, uid, [('email', '=', data.email_from)], context=context)
+ if partner_ids:
+ partner_id = partner_ids[0]
+ else:
+ partner_id = partner_obj.name_create(cr, uid, data.email_from, context=context)[0]
+ result['value'].update({
+ 'dest_partner_ids': [partner_id],
+ 'email_cc': tools.ustr(data.email_cc or ''),
+ })
+ if hasattr(data, 'section_id'):
+ result['value']['reply_to'] = data.section_id and data.section_id.reply_to or False
+ return result
+
+ def onchange_formatting(self, cr, uid, ids, value, model, res_id, context=None):
+ """ Overrides the default implementation to provide default values for
+ the subject.
+ Subject re-creation valid only if the value is True, and if the
+ model has the ``_mail_compose_message`` attribute.
+ """
+ result = super(mail_compose_message_extended, self).onchange_formatting(cr, uid, ids, value, model, res_id, context=context)
+ model_obj = self.pool.get(model)
+ if not value or not (getattr(model_obj, '_mail_compose_message', False) and res_id):
+ return result
+ data = model_obj.browse(cr, uid , res_id, context=context)
+ result['value'].update({
+ 'subject': data.name or False,
+ })
+ return result
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mail/wizard/mail_compose_message_view.xml b/addons/mail/wizard/mail_compose_message_view.xml
index bcc11c4111d..8fa4eaa9c50 100644
--- a/addons/mail/wizard/mail_compose_message_view.xml
+++ b/addons/mail/wizard/mail_compose_message_view.xml
@@ -37,6 +37,50 @@
+
+ mail.compose.message.form
+ mail.compose.message
+ 18
+ form
+
+
+
+
+
Compose Email
mail.compose.message
diff --git a/addons/marketing/marketing_view.xml b/addons/marketing/marketing_view.xml
index a697d586cd4..b4c8a295241 100644
--- a/addons/marketing/marketing_view.xml
+++ b/addons/marketing/marketing_view.xml
@@ -2,14 +2,11 @@
-
+
+ sequence="120"/>
diff --git a/addons/marketing_campaign/res_partner_view.xml b/addons/marketing_campaign/res_partner_view.xml
index ebbefeeb1f4..ee619f041e8 100644
--- a/addons/marketing_campaign/res_partner_view.xml
+++ b/addons/marketing_campaign/res_partner_view.xml
@@ -2,27 +2,21 @@
-
-
- res.partner.crm.history.inherit1
- res.partner
- form
-
-
-
- False
-
-
-
+
res.partner.workitem.info.inherit
res.partner
form
-
-
-
+
+ False
+
+
+
+
+
+
diff --git a/addons/membership/membership.py b/addons/membership/membership.py
index dc4eadbada9..06b84ec80c5 100644
--- a/addons/membership/membership.py
+++ b/addons/membership/membership.py
@@ -315,11 +315,11 @@ class Partner(osv.osv):
return self._membership_state(*args, **kwargs)
_columns = {
- 'associate_member': fields.many2one('res.partner', 'Associate member',help="A member with whom you want to associate your membership.It will consider the membership state of the associated member."),
+ 'associate_member': fields.many2one('res.partner', 'Associate Member',help="A member with whom you want to associate your membership.It will consider the membership state of the associated member."),
'member_lines': fields.one2many('membership.membership_line', 'partner', 'Membership'),
- 'free_member': fields.boolean('Free member', help = "Select if you want to give membership free of cost."),
+ 'free_member': fields.boolean('Free Member', help = "Select if you want to give membership free of cost."),
'membership_amount': fields.float(
- 'Membership amount', digits=(16, 2),
+ 'Membership Amount', digits=(16, 2),
help = 'The price negotiated by the partner'),
'membership_state': fields.function(
__get_membership_state,
@@ -338,7 +338,7 @@ class Partner(osv.osv):
-Paid Member: A member who has paid the membership amount."""),
'membership_start': fields.function(
_membership_date, multi = 'membeship_start',
- string = 'Start membership date', type = 'date',
+ string = 'Start Membership Date', type = 'date',
store = {
'account.invoice': (_get_invoice_partner, ['state'], 10),
'membership.membership_line': (_get_partner_id, ['state'], 10, ),
@@ -346,7 +346,7 @@ class Partner(osv.osv):
}, help="Date from which membership becomes active."),
'membership_stop': fields.function(
_membership_date,
- string = 'Stop membership date', type='date', multi='membership_stop',
+ string = 'Stop Membership Date', type='date', multi='membership_stop',
store = {
'account.invoice': (_get_invoice_partner, ['state'], 10),
'membership.membership_line': (_get_partner_id, ['state'], 10),
@@ -354,7 +354,7 @@ class Partner(osv.osv):
}, help="Date until which membership remains active."),
'membership_cancel': fields.function(
_membership_date,
- string = 'Cancel membership date', type='date', multi='membership_cancel',
+ string = 'Cancel Membership Date', type='date', multi='membership_cancel',
store = {
'account.invoice': (_get_invoice_partner, ['state'], 11),
'membership.membership_line': (_get_partner_id, ['state'], 10),
diff --git a/addons/membership/membership_data.xml b/addons/membership/membership_data.xml
index 60c21fc6cf6..14fbb00f9a2 100644
--- a/addons/membership/membership_data.xml
+++ b/addons/membership/membership_data.xml
@@ -5,10 +5,10 @@
-
- Member Price
- member_price
-
+
+ Member Price
+ member_price
+
@@ -71,7 +69,7 @@
- -
+ -
@@ -282,7 +280,7 @@
-
+
product.normal.form
form
diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py
index bdf6f63b755..d1f5625e09f 100644
--- a/addons/mrp/__openerp__.py
+++ b/addons/mrp/__openerp__.py
@@ -27,6 +27,7 @@
"website" : "http://www.openerp.com",
"category" : "Manufacturing",
"sequence": 18,
+ "summary": "Manufacturing, Production, Bill of Materials",
"images" : ["images/bill_of_materials.jpeg", "images/manufacturing_order.jpeg", "images/planning_manufacturing_order.jpeg", "images/production_analysis.jpeg", "images/production_dashboard.jpeg","images/routings.jpeg","images/work_centers.jpeg"],
"depends" : ["procurement", "stock", "resource", "purchase", "product","process"],
"description": """
diff --git a/addons/mrp/i18n/mn.po b/addons/mrp/i18n/mn.po
new file mode 100644
index 00000000000..7c97b68cc46
--- /dev/null
+++ b/addons/mrp/i18n/mn.po
@@ -0,0 +1,2231 @@
+# Mongolian translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-02-08 00:49+0000\n"
+"PO-Revision-Date: 2012-07-21 12:33+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Mongolian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-07-22 04:45+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
+
+#. module: mrp
+#: view:mrp.routing.workcenter:0
+msgid "Routing Work Centers"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_production_action
+msgid ""
+"Manufacturing Orders are usually proposed automatically by OpenERP based on "
+"the bill of materials and the procurement rules, but you can also create "
+"manufacturing orders manually. OpenERP will handle the consumption of the "
+"raw materials (stock decrease) and the production of the finished products "
+"(stock increase) when the order is processed."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.production,location_src_id:0
+msgid "Location where the system will look for components."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,workcenter_lines:0
+msgid "Work Centers Utilisation"
+msgstr ""
+
+#. module: mrp
+#: model:product.template,name:mrp.product_sugar_product_template
+msgid "Sugar"
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "No. Of Cycles"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.routing.workcenter,cycle_nbr:0
+msgid "Number of Cycles"
+msgstr ""
+
+#. module: mrp
+#: model:product.uom.categ,name:mrp.product_uom_categ_fluid
+msgid "Fluid"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_minimumstockprocure0
+msgid ""
+"The 'Minimum stock rule' allows the system to create procurement orders "
+"automatically as soon as the minimum stock is reached."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,picking_id:0
+msgid "Picking list"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:130
+#, python-format
+msgid "Hourly Cost"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:139
+#, python-format
+msgid "Cost Price per Uom"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Scrap Products"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_routing_action
+#: model:ir.ui.menu,name:mrp.menu_mrp_routing_action
+msgid "Routings"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,product_id:0
+msgid "Work Center Product"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+msgid "Search Bill Of Material"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_stockproduct1
+msgid "For stockable products and consumables"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_stockproduction0
+msgid "To Produce"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.routing.workcenter,cycle_nbr:0
+msgid ""
+"Number of iterations this work center has to do in the specified operation "
+"of the routing."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+#: field:mrp.bom,code:0
+#: view:mrp.production:0
+#: field:mrp.production,name:0
+msgid "Reference"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Finished Products"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Manufacturing Orders which are currently in production."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_servicerfq0
+#: model:process.transition,name:mrp.process_transition_stockrfq0
+msgid "To Buy"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_purchaseprocure0
+msgid "The system launches automatically a RFQ to the preferred supplier."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Products to Finish"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.bom,method:0
+msgid "Set / Pack"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: field:mrp.production,state:0
+msgid "State"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,costs_hour:0
+msgid "Cost per hour"
+msgstr ""
+
+#. module: mrp
+#: model:product.template,name:mrp.product_orange_product_template
+msgid "Orange"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_servicemts0
+msgid ""
+"This is used in case of a service without any impact in the system, a "
+"training session for instance."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "UOM"
+msgstr ""
+
+#. module: mrp
+#: field:change.production.qty,product_qty:0
+#: field:mrp.bom,product_qty:0
+#: field:mrp.production,product_qty:0
+#: field:mrp.production.product.line,product_qty:0
+msgid "Product Qty"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,product_id:0
+msgid ""
+"Fill this product to track easily your production costs in the analytic "
+"accounting."
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_purchaseprocure0
+msgid "For purchased material"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom.revision,indice:0
+msgid "Revision"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.product_form_config_action
+msgid ""
+"Create a product form for everything you buy or sell. Specify a supplier if "
+"the product can be purchased."
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.next_id_77
+msgid "Reporting"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,costs_cycle_account_id:0
+msgid "Cycle Account"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:130
+#, python-format
+msgid "Work Cost"
+msgstr ""
+
+#. module: mrp
+#: report:bom.structure:0
+msgid "["
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_procureserviceproduct0
+msgid "Procurement of services"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.workcenter:0
+msgid "Capacity Information"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,move_created_ids2:0
+msgid "Produced Products"
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "Destination Location"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_mrp_bom
+msgid "Master Data"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_stockmts0
+msgid ""
+"The system waits for the products to be available in the stock. These "
+"products are typically procured manually or through a minimum stock rule."
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "Partner Ref"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,origin:0
+#: report:mrp.production.order:0
+msgid "Source Document"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,product_lines:0
+msgid "Scheduled goods"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.bom,type:0
+msgid "Sets / Phantom"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,position:0
+msgid "Reference to a position in an external plan."
+msgstr ""
+
+#. module: mrp
+#: constraint:stock.move:0
+msgid "You try to assign a lot which is not from the same product"
+msgstr ""
+
+#. module: mrp
+#: model:product.template,name:mrp.product_cloth_product_template
+msgid "Cloth"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_product_produce
+msgid "Product Produce"
+msgstr ""
+
+#. module: mrp
+#: constraint:mrp.bom:0
+msgid "Error ! You cannot create recursive BoM."
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_routing_workcenter
+msgid "Work Center Usage"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_procurestockableproduct0
+msgid "Procurement of stockable Product"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+msgid "Default UOM"
+msgstr ""
+
+#. module: mrp
+#: sql_constraint:mrp.production:0
+#: sql_constraint:stock.picking:0
+msgid "Reference must be unique per Company!"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:139
+#: report:bom.structure:0
+#: field:mrp.product_price,number:0
+#: report:mrp.production.order:0
+#, python-format
+msgid "Quantity"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production.workcenter.line,hour:0
+msgid "Nbr of hours"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Confirm Production"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_stockproduct0
+msgid ""
+"The system creates an order (production or purchased) depending on the sold "
+"quantity and the products parameters."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_stockproduction0
+msgid ""
+"In case the Supply method of the product is Produce, the system creates a "
+"production order."
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_property_action
+msgid ""
+"The Properties in OpenERP are used to select the right bill of materials for "
+"manufacturing a product when you have different ways of building the same "
+"product. You can assign several properties to each Bill of Materials. When a "
+"sales person creates a sales order, he can relate it to several properties "
+"and OpenERP will automatically select the BoM to use according the needs."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.production,picking_id:0
+msgid ""
+"This is the Internal Picking List that brings the finished product to the "
+"production plan"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_view_resource_calendar_search_mrp
+msgid "Working Time"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.action_report_in_out_picking_tree
+msgid "Weekly Stock Value Variation"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: field:mrp.production,date_planned_date:0
+#: report:mrp.production.order:0
+msgid "Scheduled Date"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+msgid "Component Product"
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "Bill Of Material"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.routing,location_id:0
+msgid ""
+"Keep empty if you produce at the location where the finished products are "
+"needed.Set a location if you produce at a fixed location. This can be a "
+"partner location if you subcontract the manufacturing operations."
+msgstr ""
+
+#. module: mrp
+#: view:board.board:0
+msgid "Stock Value Variation"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.action2
+msgid "Bill of Materials Structure"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_serviceproduct0
+msgid "Product type is service"
+msgstr ""
+
+#. module: mrp
+#: sql_constraint:res.company:0
+msgid "The company name must be unique !"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_property_group_action
+msgid ""
+"Define specific property groups that can be assigned to the properties of "
+"your bill of materials."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,costs_cycle:0
+msgid "Specify Cost of Work Center per cycle."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_bom0
+msgid "Manufacturing decomposition"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_serviceproduct1
+msgid "For Services."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom.revision,date:0
+msgid "Modification Date"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,costs_cycle_account_id:0
+#: help:mrp.workcenter,costs_hour_account_id:0
+msgid ""
+"Complete this only if you want automatic analytic accounting entries on "
+"production orders."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production.workcenter.line,cycle:0
+msgid "Nbr of cycles"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_orderrfq0
+#: model:process.node,note:mrp.process_node_rfq0
+msgid "Request for Quotation."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_billofmaterialrouting0
+msgid ""
+"The Bill of Material is linked to a routing, i.e. the succession of work "
+"centers."
+msgstr ""
+
+#. module: mrp
+#: constraint:product.product:0
+msgid "Error: Invalid ean code"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,move_created_ids:0
+msgid "Products to Produce"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.routing:0
+#: field:mrp.routing,location_id:0
+msgid "Production Location"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Change Qty"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.action_configure_workcenter
+msgid "Configure your work centers"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Force Reservation"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom.revision,author_id:0
+msgid "Author"
+msgstr ""
+
+#. module: mrp
+#: field:report.mrp.inout,value:0
+msgid "Stock value"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.action_product_bom_structure
+msgid "Product BoM Structure"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Search Production"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:139
+#, python-format
+msgid "Supplier Price per Uom"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.routing.workcenter,sequence:0
+msgid ""
+"Gives the sequence order when displaying a list of routing Work Centers."
+msgstr ""
+
+#. module: mrp
+#: constraint:stock.move:0
+msgid "You can not move products from or to a location of the type view."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,child_complete_ids:0
+msgid "BoM Hierarchy"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,product_uom:0
+#: field:mrp.production,product_uom:0
+#: field:mrp.production.product.line,product_uom:0
+msgid "Product UOM"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,state:0
+msgid "Picking Exception"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,bom_lines:0
+msgid "BoM Lines"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,time_start:0
+msgid "Time before prod."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.routing,active:0
+msgid ""
+"If the active field is set to False, it will allow you to hide the routing "
+"without removing it."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_billofmaterialrouting0
+msgid "Material Routing"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: field:mrp.production,move_lines2:0
+#: report:mrp.production.order:0
+msgid "Consumed Products"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.action_mrp_workcenter_load_wizard
+#: model:ir.model,name:mrp.model_mrp_workcenter_load
+#: model:ir.model,name:mrp.model_report_workcenter_load
+msgid "Work Center Load"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/procurement.py:43
+#, python-format
+msgid "No BoM defined for this product !"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_bom_form_action2
+#: model:ir.ui.menu,name:mrp.menu_mrp_bom_form_action2
+msgid "Bill of Material Components"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_stock_move
+msgid "Stock Move"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_mrp_planning
+msgid "Planning"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Ready"
+msgstr ""
+
+#. module: mrp
+#: model:product.template,name:mrp.product_buttons_product_template
+msgid "Shirt Buttons"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.production,routing_id:0
+msgid ""
+"The list of operations (list of work centers) to produce the finished "
+"product. The routing is mainly used to compute work center costs during "
+"operations and to plan future loads on work centers based on production "
+"plannification."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,time_cycle:0
+msgid "Time in hours for doing one cycle."
+msgstr ""
+
+#. module: mrp
+#: constraint:mrp.bom:0
+msgid "BoM line product should not be same as BoM product."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "In Production"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_mrp_property
+msgid "Master Bill of Materials"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,product_uos:0
+msgid ""
+"Product UOS (Unit of Sale) is the unit of measurement for the invoicing and "
+"promotion of stock."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.product_price:0
+#: view:mrp.workcenter.load:0
+msgid "Print"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+#: view:mrp.workcenter:0
+msgid "Type"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_minimumstockrule0
+msgid "Linked to the 'Minimum stock rule' supplying method."
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.workcenter.load,time_unit:0
+msgid "Per month"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/wizard/change_production_qty.py:78
+#: code:addons/mrp/wizard/change_production_qty.py:83
+#, python-format
+msgid "Couldn't find bill of material for product"
+msgstr ""
+
+#. module: mrp
+#: report:bom.structure:0
+msgid "Product Name"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:503
+#, python-format
+msgid "Invalid action !"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,product_efficiency:0
+msgid "A factor of 0.9 means a loss of 10% within the production process."
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:734
+#: code:addons/mrp/mrp.py:762
+#, python-format
+msgid "Warning!"
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "Printing date"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_orderrfq0
+#: model:process.node,name:mrp.process_node_rfq0
+msgid "RFQ"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_producttostockrules0
+msgid "Procurement rule"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Partial"
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "WorkCenter"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_procureserviceproduct0
+msgid ""
+"Depending on the chosen method to 'supply' the service, the procurement "
+"order creates a RFQ for a subcontracting purchase order or waits until the "
+"service is done (= the delivery of the products)."
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,priority:0
+msgid "Urgent"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Manufacturing Orders which are waiting for raw materials."
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_workcenter_action
+msgid ""
+"Work Centers allow you to create and manage manufacturing units. They "
+"consist of workers and/or machines, which are considered as units for "
+"capacity and planning forecast. Keep in mind that the working time and "
+"resource leave are not taken into account in the time computation of the "
+"work center."
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_production
+msgid "Manufacturing Order"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_productionprocureproducts0
+msgid "Procurement of raw material"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: field:mrp.production,cycle_total:0
+msgid "Total Cycles"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,state:0
+msgid "Ready to Produce"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom.revision,name:0
+msgid "Modification name"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+#: view:mrp.production:0
+msgid "Date"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,type:0
+msgid "BoM Type"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/procurement.py:45
+#, python-format
+msgid ""
+"Procurement '%s' has an exception: 'No BoM defined for this product !'"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.property:0
+msgid "Search"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:626
+#, python-format
+msgid "Could not cancel manufacturing order !"
+msgstr ""
+
+#. module: mrp
+#: field:report.workcenter.load,cycle:0
+msgid "Nbr of cycle"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:627
+#, python-format
+msgid ""
+"You must first cancel related internal picking attached to this "
+"manufacturing order."
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_minimumstockrule0
+#: model:process.node,name:mrp.process_node_productminimumstockrule0
+msgid "Minimum Stock"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:503
+#, python-format
+msgid "Cannot delete a manufacturing order in state '%s'"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menus_dash_mrp
+msgid "Dashboard"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:160
+#: code:addons/mrp/report/price.py:211
+#, python-format
+msgid "Total Cost of %s %s"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_stockproduct0
+#: model:process.node,name:mrp.process_node_stockproduct1
+#: model:process.process,name:mrp.process_process_stockableproductprocess0
+msgid "Stockable Product"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:130
+#, python-format
+msgid "Work Center name"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.routing,code:0
+msgid "Code"
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "No. Of Hours"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.property:0
+#: view:mrp.property.group:0
+msgid "Property Group"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Qty"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_production0
+msgid "Manufacturing Plan."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.routing:0
+#: view:mrp.workcenter:0
+msgid "Inactive"
+msgstr ""
+
+#. module: mrp
+#: view:change.production.qty:0
+#: view:mrp.product.produce:0
+#: view:mrp.product_price:0
+#: view:mrp.production:0
+#: view:mrp.workcenter.load:0
+msgid "Cancel"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/wizard/change_production_qty.py:63
+#, python-format
+msgid "Active Id is not found"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_servicerfq0
+msgid ""
+"If the service has a 'Buy' supply method, this creates a RFQ, a "
+"subcontracting demand for instance."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,move_prod_id:0
+msgid "Move product"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Late"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_servicemts0
+msgid "Make to stock"
+msgstr ""
+
+#. module: mrp
+#: report:bom.structure:0
+msgid "BOM Name"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Start Production"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.open_board_manufacturing
+#: model:ir.ui.menu,name:mrp.menu_board_manufacturing
+msgid "Production Dashboard"
+msgstr ""
+
+#. module: mrp
+#: model:res.groups,name:mrp.group_mrp_manager
+msgid "Manager"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Source Loc."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,position:0
+msgid "Internal Reference"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_billofmaterial0
+msgid "Product's structure"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,name:0
+#: report:mrp.production.order:0
+#: field:mrp.production.product.line,name:0
+#: field:mrp.routing,name:0
+#: field:mrp.routing.workcenter,name:0
+msgid "Name"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.product.produce,mode:0
+msgid "Mode"
+msgstr ""
+
+#. module: mrp
+#: report:bom.structure:0
+msgid "]"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter.load,measure_unit:0
+msgid "Amount measuring unit"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_production_action_planning
+msgid ""
+"Manufacturing Orders describe the operations that need to be carried out and "
+"the raw materials usage for each production stage. You use specifications "
+"(bills of materials or BoM) to work out the raw material requirements and "
+"the manufacturing orders needed for the finished products. Once the bills of "
+"materials have been defined, OpenERP is capable of automatically deciding on "
+"the manufacturing route depending on the needs of the company."
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.todo.category,name:mrp.category_mrp_config
+msgid "MRP Management"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,costs_hour:0
+msgid "Specify Cost of Work Center per hour."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,capacity_per_cycle:0
+msgid ""
+"Number of operations this Work Center can do in parallel. If this Work "
+"Center represents a team of 5 workers, the capacity per cycle is 5."
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_production_action3
+msgid "Manufacturing Orders in Progress"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+#: view:mrp.production:0
+#: view:mrp.property:0
+#: view:mrp.routing:0
+#: view:mrp.workcenter:0
+msgid "Group By..."
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:130
+#, python-format
+msgid "Cycles Cost"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.workcenter.load,measure_unit:0
+msgid "Amount in cycles"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,location_dest_id:0
+msgid "Finished Products Location"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_pm_resources_config
+msgid "Resources"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.routing.workcenter,hour_nbr:0
+msgid ""
+"Time in hours for this Work Center to achieve the operation of the specified "
+"routing."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,costs_journal_id:0
+msgid "Analytic Journal"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_workcenter_action
+#: model:ir.ui.menu,name:mrp.menu_view_resource_search_mrp
+#: field:mrp.routing,workcenter_lines:0
+msgid "Work Centers"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.workcenter.load,time_unit:0
+msgid "Per week"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_routing_action
+msgid ""
+"Routings allow you to create and manage the manufacturing operations that "
+"should be followed within your work centers in order to produce a product. "
+"They are attached to bills of materials that will define the required raw "
+"materials."
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.product_form_config_action
+msgid "Create or Import Products"
+msgstr ""
+
+#. module: mrp
+#: field:report.workcenter.load,hour:0
+msgid "Nbr of hour"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.routing:0
+msgid "Work Center Operations"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.routing:0
+msgid "Notes"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Manufacturing Orders which are ready to start production."
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_bom
+#: view:mrp.bom:0
+#: field:mrp.production,bom_id:0
+#: model:process.node,name:mrp.process_node_billofmaterial0
+msgid "Bill of Material"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.workcenter.load:0
+msgid "Select time unit"
+msgstr ""
+
+#. module: mrp
+#: view:report.workcenter.load:0
+msgid "Work Center load"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.production,location_dest_id:0
+msgid "Location where the system will stock the finished products."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.routing.workcenter,routing_id:0
+msgid ""
+"Routing indicates all the Work Centers used, for how long and/or cycles.If "
+"Routing is indicated then,the third tab of a production order (Work Centers) "
+"will be automatically pre-completed."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_producttostockrules0
+msgid ""
+"The Minimum Stock Rule is an automatic procurement rule based on a mini and "
+"maxi quantity. It's available in the Inventory management menu and "
+"configured by product."
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:187
+#, python-format
+msgid "Components Cost of %s %s"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.workcenter.load,time_unit:0
+msgid "Day by day"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+msgid "Revisions"
+msgstr ""
+
+#. module: mrp
+#: model:product.template,name:mrp.product_shirt_product_template
+msgid "Shirt"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,priority:0
+msgid "Priority"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_stock_picking
+msgid "Picking List"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:1000
+#, python-format
+msgid "Manufacturing order '%s' is scheduled for the %s."
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "Production Order N° :"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:647
+#, python-format
+msgid "Manufacturing order '%s' is ready to produce."
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_production_product_line
+msgid "Production Scheduled Product"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:204
+#, python-format
+msgid "Work Cost of %s %s"
+msgstr ""
+
+#. module: mrp
+#: help:res.company,manufacturing_lead:0
+msgid "Security days for each manufacturing operation."
+msgstr ""
+
+#. module: mrp
+#: model:product.template,name:mrp.product_water_product_template
+msgid "Water"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+msgid "Component Name"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_mts0
+#: model:process.transition,name:mrp.process_transition_servicemts0
+#: model:process.transition,name:mrp.process_transition_stockmts0
+msgid "Make to Stock"
+msgstr ""
+
+#. module: mrp
+#: constraint:mrp.production:0
+msgid "Order quantity cannot be negative or zero!"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_bom_form_action
+msgid ""
+"Master Bills of Materials allow you to create and manage the list of "
+"necessary raw materials used to make a finished product. OpenERP will use "
+"these BoMs to automatically propose manufacturing orders according to "
+"product needs. You can either create a bill of materials to define specific "
+"production steps or define a single multi-level bill of materials."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_stockrfq0
+msgid ""
+"In case the Supply method of the product is Buy, the system creates a "
+"purchase order."
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_procurement_order
+msgid "Procurement"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.action_view_mrp_product_price_wizard
+#: view:mrp.product_price:0
+msgid "Product Cost Structure"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:139
+#, python-format
+msgid "Components suppliers"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Production Work Centers"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Split in production lots"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.workcenter:0
+msgid "Search for mrp workcenter"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+msgid "BoM Structure"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,date_start:0
+msgid "Start Date"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,costs_hour_account_id:0
+msgid "Hour Account"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Destination Loc."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,method:0
+msgid "Method"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Pending"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:603
+#, python-format
+msgid "Couldn't find a bill of material for this product."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,active:0
+#: field:mrp.routing,active:0
+msgid "Active"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_procureproducts0
+msgid "Procure Products"
+msgstr ""
+
+#. module: mrp
+#: view:report.workcenter.load:0
+msgid "Work Center Loads"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_bom_revision
+msgid "Bill of Material Revision"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.production,origin:0
+msgid ""
+"Reference of the document that generated this production order request."
+msgstr ""
+
+#. module: mrp
+#: sql_constraint:mrp.bom:0
+msgid ""
+"All product quantities must be greater than 0.\n"
+"You should install the mrp_subproduct module if you want to manage extra "
+"products on BoMs !"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Extra Information"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_change_production_qty
+msgid "Change Quantity of Products"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_productionorder0
+msgid "Drives the procurement orders for raw material."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,costs_general_account_id:0
+msgid "General Account"
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "SO Number"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,state:0
+msgid "Done"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_production_action4
+msgid "Manufacturing Orders Waiting Products"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,priority:0
+msgid "Not urgent"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,user_id:0
+msgid "Responsible"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_production_action2
+msgid "Manufacturing Orders To Start"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_workcenter
+#: field:mrp.production.workcenter.line,workcenter_id:0
+#: field:mrp.routing.workcenter,workcenter_id:0
+#: view:mrp.workcenter:0
+#: field:report.workcenter.load,workcenter_id:0
+msgid "Work Center"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,capacity_per_cycle:0
+msgid "Capacity per Cycle"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_product_product
+#: view:mrp.bom:0
+#: field:mrp.bom,product_id:0
+#: view:mrp.production:0
+#: field:mrp.production,product_id:0
+#: report:mrp.production.order:0
+#: field:mrp.production.product.line,product_id:0
+msgid "Product"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: field:mrp.production,hour_total:0
+msgid "Total Hours"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,location_src_id:0
+msgid "Raw Materials Location"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.product_price:0
+msgid "Print Cost Structure of Product."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,product_uos:0
+#: field:mrp.production.product.line,product_uos:0
+msgid "Product UOS"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Consume Products"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.act_mrp_product_produce
+#: view:mrp.product.produce:0
+#: view:mrp.production:0
+msgid "Produce"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_stock0
+#: model:process.transition,name:mrp.process_transition_servicemto0
+#: model:process.transition,name:mrp.process_transition_stockproduct0
+msgid "Make to Order"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:358
+#, python-format
+msgid "Copy"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,note:0
+msgid ""
+"Description of the Work Center. Explain here what's a cycle according to "
+"this Work Center."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production.lot.line:0
+msgid "Production Products"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,date_finished:0
+msgid "End Date"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,resource_id:0
+msgid "Resource"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,date_start:0
+#: help:mrp.bom,date_stop:0
+msgid "Validity of this BoM or component. Keep empty if it's always valid."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,product_uos:0
+msgid "Product UoS"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,priority:0
+msgid "Very Urgent"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,routing_id:0
+msgid ""
+"The list of operations (list of work centers) to produce the finished "
+"product. The routing is mainly used to compute work center costs during "
+"operations and to plan future loads on work centers based on production "
+"planning."
+msgstr ""
+
+#. module: mrp
+#: view:change.production.qty:0
+msgid "Approve"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.property.group:0
+msgid "Properties categories"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.production.workcenter.line,sequence:0
+msgid "Gives the sequence order when displaying a list of work orders."
+msgstr ""
+
+#. module: mrp
+#: report:mrp.production.order:0
+msgid "Source Location"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: view:mrp.production.product.line:0
+msgid "Scheduled Products"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production.lot.line:0
+msgid "Production Products Consommation"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.act_product_manufacturing_open
+#: model:ir.actions.act_window,name:mrp.mrp_production_action
+#: model:ir.actions.act_window,name:mrp.mrp_production_action_planning
+#: model:ir.ui.menu,name:mrp.menu_mrp_production_action
+#: model:ir.ui.menu,name:mrp.menu_mrp_production_order_action
+#: view:mrp.production:0
+msgid "Manufacturing Orders"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.product.produce,mode:0
+msgid ""
+"'Consume only' mode will only consume the products with the quantity "
+"selected.\n"
+"'Consume & Produce' mode will consume as well as produce the products with "
+"the quantity selected and it will finish the production order when total "
+"ordered quantities are produced."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: report:mrp.production.order:0
+msgid "Work Orders"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,costs_cycle:0
+msgid "Cost per cycle"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_serviceproduct0
+#: model:process.node,name:mrp.process_node_serviceproduct1
+msgid "Service"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,product_uom:0
+msgid ""
+"UoM (Unit of Measure) is the unit of measurement for the inventory control"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:734
+#, python-format
+msgid ""
+"You are going to consume total %s quantities of \"%s\".\n"
+"But you can only consume up to total %s quantities."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_bom0
+msgid ""
+"The Bill of Material is the product's decomposition. The components (that "
+"are products themselves) can also have their own Bill of Material (multi-"
+"level)."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,company_id:0
+#: field:mrp.production,company_id:0
+#: field:mrp.routing,company_id:0
+#: field:mrp.routing.workcenter,company_id:0
+#: view:mrp.workcenter:0
+msgid "Company"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.workcenter.load,measure_unit:0
+msgid "Amount in hours"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,time_cycle:0
+msgid "Time for 1 cycle (hour)"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.report.xml,name:mrp.report_mrp_production_report
+#: field:mrp.production.product.line,production_id:0
+#: field:mrp.production.workcenter.line,production_id:0
+#: model:process.node,name:mrp.process_node_production0
+#: model:process.node,name:mrp.process_node_productionorder0
+msgid "Production Order"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_productminimumstockrule0
+msgid "Automatic procurement rule"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Compute Data"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,product_uos_qty:0
+msgid "Product UoS Qty"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:139
+#: view:mrp.bom:0
+#, python-format
+msgid "Components"
+msgstr ""
+
+#. module: mrp
+#: report:bom.structure:0
+#: model:ir.actions.report.xml,name:mrp.report_bom_structure
+msgid "BOM Structure"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,date_stop:0
+msgid "Valid Until"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,date_start:0
+msgid "Valid From"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.bom,type:0
+msgid "Normal BoM"
+msgstr ""
+
+#. module: mrp
+#: field:res.company,manufacturing_lead:0
+msgid "Manufacturing Lead Time"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,product_uos_qty:0
+#: field:mrp.production.product.line,product_uos_qty:0
+msgid "Product UOS Qty"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.action_report_in_out_picking_tree
+msgid ""
+"Weekly Stock Value Variation enables you to track the stock value evolution "
+"linked to manufacturing activities, receptions of products and delivery "
+"orders."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.product.produce:0
+msgid "Confirm"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,product_efficiency:0
+msgid "Manufacturing Efficiency"
+msgstr ""
+
+#. module: mrp
+#: constraint:res.company:0
+msgid "Error! You can not create recursive companies."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,active:0
+msgid ""
+"If the active field is set to False, it will allow you to hide the bills of "
+"material without removing it."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,product_rounding:0
+msgid "Product Rounding"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,state:0
+msgid "New"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.product.produce,mode:0
+msgid "Consume Only"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Recreate Picking"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,type:0
+msgid ""
+"If a sub-product is used in several products, it can be useful to create its "
+"own BoM. Though if you don't want separated production orders for this sub-"
+"product, select Set/Phantom as BoM type. If a Phantom BoM is used for a root "
+"product, it will be sold and shipped as a set of components, instead of "
+"being produced."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.production,state:0
+msgid ""
+"When the production order is created the state is set to 'Draft'.\n"
+" If the order is confirmed the state is set to 'Waiting Goods'.\n"
+" If any exceptions are there, the state is set to 'Picking Exception'. "
+" \n"
+"If the stock is available then the state is set to 'Ready to Produce'.\n"
+" When the production gets started then the state is set to 'In Production'.\n"
+" When the production is over, the state is set to 'Done'."
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.bom,method:0
+msgid "On Order"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_mrp_configuration
+#: view:res.company:0
+msgid "Configuration"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom:0
+msgid "Starting Date"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter,time_stop:0
+msgid "Time after prod."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.workcenter.load,time_unit:0
+msgid "Type of period"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Total Qty"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.routing.workcenter,hour_nbr:0
+msgid "Number of Hours"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.workcenter:0
+msgid "Costing Information"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,name:mrp.process_node_purchaseprocure0
+msgid "Procurement Orders"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,product_rounding:0
+msgid "Rounding applied on the product quantity."
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_stock0
+msgid "Assignment from Production or Purchase Order."
+msgstr ""
+
+#. module: mrp
+#: field:mrp.routing.workcenter,routing_id:0
+msgid "Parent Routing"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,time_start:0
+msgid "Time in hours for the setup."
+msgstr ""
+
+#. module: mrp
+#: model:product.template,name:mrp.product_orangejuice_product_template
+msgid "Orange Juice"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom.revision,bom_id:0
+#: field:procurement.order,bom_id:0
+msgid "BoM"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_report_mrp_inout
+#: view:report.mrp.inout:0
+msgid "Stock value variation"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_mts0
+#: model:process.node,note:mrp.process_node_servicemts0
+msgid "Assignment from stock."
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,state:0
+msgid "Waiting Goods"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom.revision,last_indice:0
+msgid "last indice"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,revision_ids:0
+#: view:mrp.bom.revision:0
+msgid "BoM Revisions"
+msgstr ""
+
+#. module: mrp
+#: field:report.mrp.inout,date:0
+#: field:report.workcenter.load,name:0
+msgid "Week"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,priority:0
+msgid "Normal"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Production started late"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_routing0
+msgid "Manufacturing Steps."
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/report/price.py:146
+#: model:ir.actions.report.xml,name:mrp.report_cost_structure
+#, python-format
+msgid "Cost Structure"
+msgstr ""
+
+#. module: mrp
+#: model:res.groups,name:mrp.group_mrp_user
+msgid "User"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.product.produce,mode:0
+msgid "Consume & Produce"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,bom_id:0
+msgid "Parent BoM"
+msgstr ""
+
+#. module: mrp
+#: report:bom.structure:0
+msgid "BOM Ref"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,help:mrp.mrp_bom_form_action2
+msgid ""
+"Bills of materials components are components and sub-products used to create "
+"master bills of materials. Use this menu to search in which BoM a specific "
+"component is used."
+msgstr ""
+
+#. module: mrp
+#: model:product.uom,name:mrp.product_uom_litre
+msgid "Litre"
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:762
+#, python-format
+msgid ""
+"You are going to produce total %s quantities of \"%s\".\n"
+"But you can only produce up to total %s quantities."
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_stockproduct0
+msgid "Product type is Stockable or Consumable."
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:603
+#: code:addons/mrp/wizard/change_production_qty.py:78
+#: code:addons/mrp/wizard/change_production_qty.py:83
+#, python-format
+msgid "Error"
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.production,state:0
+msgid "Production Started"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.product.produce,product_qty:0
+msgid "Select Quantity"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.act_product_product_2_mrp_bom
+#: model:ir.actions.act_window,name:mrp.mrp_bom_form_action
+#: model:ir.ui.menu,name:mrp.menu_mrp_bom_form_action
+#: field:product.product,bom_ids:0
+msgid "Bill of Materials"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_property_action
+#: model:ir.ui.menu,name:mrp.menu_mrp_property_action
+#: view:mrp.bom:0
+#: field:mrp.bom,property_ids:0
+#: view:mrp.property:0
+#: view:procurement.order:0
+#: field:procurement.order,property_ids:0
+msgid "Properties"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.routing.workcenter:0
+#: view:mrp.workcenter:0
+msgid "General Information"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+msgid "Productions"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_routing
+#: view:mrp.bom:0
+#: field:mrp.bom,routing_id:0
+#: view:mrp.production:0
+#: field:mrp.production,routing_id:0
+#: view:mrp.routing:0
+#: model:process.node,name:mrp.process_node_routing0
+msgid "Routing"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,date_planned:0
+msgid "Scheduled date"
+msgstr ""
+
+#. module: mrp
+#: constraint:stock.move:0
+msgid "You must assign a production lot for this product"
+msgstr ""
+
+#. module: mrp
+#: field:stock.move,production_id:0
+msgid "Production"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_production_workcenter_line
+#: field:mrp.production.workcenter.line,name:0
+msgid "Work Order"
+msgstr ""
+
+#. module: mrp
+#: view:board.board:0
+msgid "Procurements in Exception"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_minimumstockprocure0
+msgid "'Minimum stock rule' material"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_mrp_product_price
+msgid "Product Price"
+msgstr ""
+
+#. module: mrp
+#: model:ir.model,name:mrp.model_stock_move_split
+msgid "Split in Production lots"
+msgstr ""
+
+#. module: mrp
+#: view:change.production.qty:0
+msgid "Change Quantity"
+msgstr ""
+
+#. module: mrp
+#: view:change.production.qty:0
+#: model:ir.actions.act_window,name:mrp.action_change_production_qty
+msgid "Change Product Qty"
+msgstr ""
+
+#. module: mrp
+#: view:mrp.bom.revision:0
+#: field:mrp.bom.revision,description:0
+#: view:mrp.property:0
+#: view:mrp.property.group:0
+#: field:mrp.routing,note:0
+#: view:mrp.routing.workcenter:0
+#: field:mrp.routing.workcenter,note:0
+#: view:mrp.workcenter:0
+#: field:mrp.workcenter,note:0
+msgid "Description"
+msgstr ""
+
+#. module: mrp
+#: view:board.board:0
+msgid "Manufacturing board"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.production,date_planned_end:0
+msgid "Scheduled End Date"
+msgstr ""
+
+#. module: mrp
+#: model:process.node,note:mrp.process_node_procureproducts0
+msgid "The way to procurement depends on the product type."
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_mrp_manufacturing
+msgid "Manufacturing"
+msgstr ""
+
+#. module: mrp
+#: view:board.board:0
+msgid "Next Production Orders"
+msgstr ""
+
+#. module: mrp
+#: model:ir.actions.act_window,name:mrp.mrp_property_group_action
+#: model:ir.ui.menu,name:mrp.menu_mrp_property_group_action
+msgid "Property Groups"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_procurestockableproduct0
+msgid ""
+"Depending on the chosen method to supply the stockable products, the "
+"procurement order creates a RFQ, a production order, ... "
+msgstr ""
+
+#. module: mrp
+#: code:addons/mrp/mrp.py:874
+#: code:addons/mrp/mrp.py:929
+#: code:addons/mrp/mrp.py:954
+#, python-format
+msgid "PROD: %s"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.workcenter,time_stop:0
+msgid "Time in hours for the cleaning."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,name:mrp.process_transition_purchaseprocure0
+msgid "Automatic RFQ"
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_servicemto0
+msgid ""
+"If the service has a 'Produce' supply method, this creates a task in the "
+"project management module of OpenERP."
+msgstr ""
+
+#. module: mrp
+#: model:process.transition,note:mrp.process_transition_productionprocureproducts0
+msgid ""
+"In order to supply raw material (to be purchased or produced), the "
+"production order creates as much procurement orders as components listed in "
+"the BOM, through a run of the schedulers (MRP)."
+msgstr ""
+
+#. module: mrp
+#: help:mrp.product_price,number:0
+msgid ""
+"Specify quantity of products to produce or buy. Report of Cost structure "
+"will be displayed base on this quantity."
+msgstr ""
+
+#. module: mrp
+#: selection:mrp.bom,method:0
+msgid "On Stock"
+msgstr ""
+
+#. module: mrp
+#: field:mrp.bom,sequence:0
+#: report:mrp.production.order:0
+#: field:mrp.production.workcenter.line,sequence:0
+#: field:mrp.routing.workcenter,sequence:0
+msgid "Sequence"
+msgstr ""
+
+#. module: mrp
+#: model:ir.ui.menu,name:mrp.menu_view_resource_calendar_leaves_search_mrp
+msgid "Resource Leaves"
+msgstr ""
+
+#. module: mrp
+#: help:mrp.bom,sequence:0
+msgid "Gives the sequence order when displaying a list of bills of material."
+msgstr ""
+
+#. module: mrp
+#: view:mrp.production:0
+#: field:mrp.production,move_lines:0
+#: report:mrp.production.order:0
+msgid "Products to Consume"
+msgstr ""
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index c4a4d8df895..56ac47095a1 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -206,7 +206,7 @@ class mrp_bom(osv.osv):
'product_id': fields.many2one('product.product', 'Product', required=True),
'product_uos_qty': fields.float('Product UOS Qty'),
'product_uos': fields.many2one('product.uom', 'Product UOS', help="Product UOS (Unit of Sale) is the unit of measurement for the invoicing and promotion of stock."),
- 'product_qty': fields.float('Product Qty', required=True, digits_compute=dp.get_precision('Product Unit of Measure')),
+ 'product_qty': fields.float('Product Quantity', required=True, digits_compute=dp.get_precision('Product Unit of Measure')),
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True, help="Unit of Measure (Unit of Measure) is the unit of measurement for the inventory control"),
'product_rounding': fields.float('Product Rounding', help="Rounding applied on the product quantity."),
'product_efficiency': fields.float('Manufacturing Efficiency', required=True, help="A factor of 0.9 means a loss of 10% within the production process."),
@@ -456,7 +456,7 @@ class mrp_production(osv.osv):
'product_id': fields.many2one('product.product', 'Product', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'product_qty': fields.float('Product Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True, states={'draft':[('readonly',False)]}, readonly=True),
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True, states={'draft':[('readonly',False)]}, readonly=True),
- 'product_uos_qty': fields.float('Product UoS Qty', states={'draft':[('readonly',False)]}, readonly=True),
+ 'product_uos_qty': fields.float('Product UoS Quantity', states={'draft':[('readonly',False)]}, readonly=True),
'product_uos': fields.many2one('product.uom', 'Product UoS', states={'draft':[('readonly',False)]}, readonly=True),
'location_src_id': fields.many2one('stock.location', 'Raw Materials Location', required=True,
@@ -474,7 +474,7 @@ class mrp_production(osv.osv):
'routing_id': fields.many2one('mrp.routing', string='Routing', on_delete='set null', readonly=True, states={'draft':[('readonly',False)]}, help="The list of operations (list of work centers) to produce the finished product. The routing is mainly used to compute work center costs during operations and to plan future loads on work centers based on production plannification."),
'picking_id': fields.many2one('stock.picking', 'Picking List', readonly=True, ondelete="restrict",
help="This is the Internal Picking List that brings the finished product to the production plan"),
- 'move_prod_id': fields.many2one('stock.move', 'Move product', readonly=True),
+ 'move_prod_id': fields.many2one('stock.move', 'Product Move', readonly=True),
'move_lines': fields.many2many('stock.move', 'mrp_production_move_ids', 'production_id', 'move_id', 'Products to Consume', domain=[('state','not in', ('done', 'cancel'))], states={'done':[('readonly',True)]}),
'move_lines2': fields.many2many('stock.move', 'mrp_production_move_ids', 'production_id', 'move_id', 'Consumed Products', domain=[('state','in', ('done', 'cancel'))]),
'move_created_ids': fields.one2many('stock.move', 'production_id', 'Products to Produce', domain=[('state','not in', ('done', 'cancel'))], states={'done':[('readonly',True)]}),
@@ -1108,7 +1108,7 @@ class mrp_production_product_line(osv.osv):
'product_id': fields.many2one('product.product', 'Product', required=True),
'product_qty': fields.float('Product Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
- 'product_uos_qty': fields.float('Product UOS Qty'),
+ 'product_uos_qty': fields.float('Product UOS Quantity'),
'product_uos': fields.many2one('product.uom', 'Product UOS'),
'production_id': fields.many2one('mrp.production', 'Production Order', select=True),
}
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index 86b0fcee0d5..2d3e90c341a 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -2,17 +2,21 @@
-
+
+
-
+
+ sequence="5"/>
- Work Centers
+ Work Center
ir.actions.act_window
mrp.workcenter
form
@@ -1024,7 +1053,7 @@
-
+
diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml
index 0a16626ecd9..2dccc92a51e 100644
--- a/addons/mrp_operations/mrp_operations_view.xml
+++ b/addons/mrp_operations/mrp_operations_view.xml
@@ -8,18 +8,17 @@
form
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -80,7 +79,7 @@
-
+
@@ -351,7 +350,7 @@
mrp.production
form
-
+
diff --git a/addons/mrp_repair/i18n/ar.po b/addons/mrp_repair/i18n/ar.po
index 35ac83fec75..ddc13ca9742 100644
--- a/addons/mrp_repair/i18n/ar.po
+++ b/addons/mrp_repair/i18n/ar.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:07+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -184,8 +184,8 @@ msgstr "تحذير !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "ضريبة القيمة المضافة"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -803,6 +803,9 @@ msgstr "جاهز للتصليح"
msgid "No partner !"
msgstr "لا يوجد شريك !"
+#~ msgid "VAT"
+#~ msgstr "ضريبة القيمة المضافة"
+
#~ msgid "Do you really want to create the invoice(s) ?"
#~ msgstr "هل تريد فعلاً إنشاء الفاتورة/الفواتبر؟"
diff --git a/addons/mrp_repair/i18n/bg.po b/addons/mrp_repair/i18n/bg.po
index 08191fcf27d..75c633410ca 100644
--- a/addons/mrp_repair/i18n/bg.po
+++ b/addons/mrp_repair/i18n/bg.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,8 +169,8 @@ msgstr "Предупреждение!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "ДДС"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -785,5 +785,8 @@ msgstr "Няма контрагент!"
#~ "Името на обекта трябва да започва с \"x_\" и да не съдържа никакви специални "
#~ "символи!"
+#~ msgid "VAT"
+#~ msgstr "ДДС"
+
#~ msgid "Do you really want to create the invoice(s) ?"
#~ msgstr "Искате ли да създадете фактурата/ите"
diff --git a/addons/mrp_repair/i18n/bs.po b/addons/mrp_repair/i18n/bs.po
index 526d3c41d1c..413d19342b0 100644
--- a/addons/mrp_repair/i18n/bs.po
+++ b/addons/mrp_repair/i18n/bs.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:07+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/ca.po b/addons/mrp_repair/i18n/ca.po
index f298ca712d8..7d0c984c5ac 100644
--- a/addons/mrp_repair/i18n/ca.po
+++ b/addons/mrp_repair/i18n/ca.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -193,8 +193,8 @@ msgstr "Avís!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "CIF/NIF"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -842,6 +842,9 @@ msgstr "No existeix empresa!"
#~ msgid "Repair Order Ref"
#~ msgstr "Referència comanda reparació"
+#~ msgid "VAT"
+#~ msgstr "CIF/NIF"
+
#~ msgid "Repairs in quotation"
#~ msgstr "Reparacions en pressupost"
diff --git a/addons/mrp_repair/i18n/cs.po b/addons/mrp_repair/i18n/cs.po
index 0c8bd6f3af8..ddfe269417d 100644
--- a/addons/mrp_repair/i18n/cs.po
+++ b/addons/mrp_repair/i18n/cs.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/da.po b/addons/mrp_repair/i18n/da.po
index 2f74c448a7a..fc36b6c5917 100644
--- a/addons/mrp_repair/i18n/da.po
+++ b/addons/mrp_repair/i18n/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -170,7 +170,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/de.po b/addons/mrp_repair/i18n/de.po
index c559b16d6f5..36647265cf2 100644
--- a/addons/mrp_repair/i18n/de.po
+++ b/addons/mrp_repair/i18n/de.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -191,8 +191,8 @@ msgstr "Warnung !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "USt."
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -926,6 +926,9 @@ msgstr "Kein Partner"
#~ msgid "Do you really want to create the invoice(s) ?"
#~ msgstr "Wollen Sie wirklich die Rechnung(en) erstellen ?"
+#~ msgid "VAT"
+#~ msgstr "USt."
+
#~ msgid ""
#~ "\n"
#~ " The aim is to have a complete module to manage all products "
diff --git a/addons/mrp_repair/i18n/es.po b/addons/mrp_repair/i18n/es.po
index f0b5d2205cb..d44970c0c80 100644
--- a/addons/mrp_repair/i18n/es.po
+++ b/addons/mrp_repair/i18n/es.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -191,8 +191,8 @@ msgstr "¡Aviso!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "CIF/NIF"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -870,6 +870,9 @@ msgstr "¡No existe empresa!"
#~ msgid "Make invoices"
#~ msgstr "Realizar facturas"
+#~ msgid "VAT"
+#~ msgstr "CIF/NIF"
+
#, python-format
#~ msgid "You have to select a partner in the repair form !"
#~ msgstr "¡Debe seleccionar una empresa en el formulario de reparación!"
diff --git a/addons/mrp_repair/i18n/es_AR.po b/addons/mrp_repair/i18n/es_AR.po
index 40858dd108c..368ffcbd7d5 100644
--- a/addons/mrp_repair/i18n/es_AR.po
+++ b/addons/mrp_repair/i18n/es_AR.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,8 +169,8 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "CUIT"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -865,6 +865,9 @@ msgstr "Sin Partner !"
#~ msgid "Repair State"
#~ msgstr "Reparar Estado"
+#~ msgid "VAT"
+#~ msgstr "CUIT"
+
#~ msgid "Repair Ref"
#~ msgstr "Ref de Reparación"
diff --git a/addons/mrp_repair/i18n/es_CR.po b/addons/mrp_repair/i18n/es_CR.po
index e5cd95f091f..09f38dcda23 100644
--- a/addons/mrp_repair/i18n/es_CR.po
+++ b/addons/mrp_repair/i18n/es_CR.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
"Language: \n"
#. module: mrp_repair
@@ -192,8 +192,8 @@ msgstr "¡Aviso!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "CIF/NIF"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -823,6 +823,9 @@ msgstr "Listo para reparar"
msgid "No partner !"
msgstr "¡No existe empresa!"
+#~ msgid "VAT"
+#~ msgstr "CIF/NIF"
+
#~ msgid "Do you really want to create the invoice(s) ?"
#~ msgstr "¿Desea crear la(s) factura(s)?"
diff --git a/addons/mrp_repair/i18n/es_EC.po b/addons/mrp_repair/i18n/es_EC.po
index 3c9cf62af31..ded01d3dcfc 100644
--- a/addons/mrp_repair/i18n/es_EC.po
+++ b/addons/mrp_repair/i18n/es_EC.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,8 +169,8 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "CIF/NIF"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -790,6 +790,9 @@ msgstr ""
#~ msgid "Repair State"
#~ msgstr "Estado de reparación"
+#~ msgid "VAT"
+#~ msgstr "CIF/NIF"
+
#~ msgid "Repairs in quotation"
#~ msgstr "Reparaciones en presupuesto"
diff --git a/addons/mrp_repair/i18n/et.po b/addons/mrp_repair/i18n/et.po
index ec12e85f5bd..4917c9c1a57 100644
--- a/addons/mrp_repair/i18n/et.po
+++ b/addons/mrp_repair/i18n/et.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -174,8 +174,8 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "KM"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -883,3 +883,6 @@ msgstr "Partner puudub!"
#~ msgid "Repairs to be invoiced"
#~ msgstr "Remondid arveldamiseks"
+
+#~ msgid "VAT"
+#~ msgstr "KM"
diff --git a/addons/mrp_repair/i18n/fi.po b/addons/mrp_repair/i18n/fi.po
index ad73e5efe54..17352e0098b 100644
--- a/addons/mrp_repair/i18n/fi.po
+++ b/addons/mrp_repair/i18n/fi.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -174,8 +174,8 @@ msgstr "Varoitus !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "ALV"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -877,6 +877,9 @@ msgstr "Ei kumppania!"
#~ msgid "Quality"
#~ msgstr "Laatu"
+#~ msgid "VAT"
+#~ msgstr "ALV"
+
#~ msgid "Make invoices"
#~ msgstr "Luo laskut"
diff --git a/addons/mrp_repair/i18n/fr.po b/addons/mrp_repair/i18n/fr.po
index 37f960e2e4e..f6b929a2c88 100644
--- a/addons/mrp_repair/i18n/fr.po
+++ b/addons/mrp_repair/i18n/fr.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -191,8 +191,8 @@ msgstr "Avertissement !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "TVA"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -821,6 +821,9 @@ msgstr "Prêt à Réparer"
msgid "No partner !"
msgstr "Pas de partenaire !"
+#~ msgid "VAT"
+#~ msgstr "TVA"
+
#~ msgid "Repairs"
#~ msgstr "Réparations"
diff --git a/addons/mrp_repair/i18n/hi.po b/addons/mrp_repair/i18n/hi.po
index ed579111c0d..3aab3ba0656 100644
--- a/addons/mrp_repair/i18n/hi.po
+++ b/addons/mrp_repair/i18n/hi.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -170,8 +170,8 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "वैट"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -783,6 +783,9 @@ msgstr ""
#~ msgid "Repair Order Ref"
#~ msgstr "मरम्मत के आदेश संदर्भ"
+#~ msgid "VAT"
+#~ msgstr "वैट"
+
#~ msgid "Repair Fees line"
#~ msgstr "मरम्मत शुल्क लाइन"
diff --git a/addons/mrp_repair/i18n/hr.po b/addons/mrp_repair/i18n/hr.po
index 1c9ee5684f9..f7870013e05 100644
--- a/addons/mrp_repair/i18n/hr.po
+++ b/addons/mrp_repair/i18n/hr.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -185,8 +185,8 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "PDV"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -806,5 +806,8 @@ msgstr "Spremno za popravak"
msgid "No partner !"
msgstr ""
+#~ msgid "VAT"
+#~ msgstr "PDV"
+
#~ msgid "Do you really want to create the invoice(s) ?"
#~ msgstr "Kreirati račun(e) ?"
diff --git a/addons/mrp_repair/i18n/hu.po b/addons/mrp_repair/i18n/hu.po
index 140027c8895..eed7cc7f539 100644
--- a/addons/mrp_repair/i18n/hu.po
+++ b/addons/mrp_repair/i18n/hu.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -170,8 +170,8 @@ msgstr "Vigyázat!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "ÁFA"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -777,5 +777,8 @@ msgstr ""
msgid "No partner !"
msgstr "Nincs partner!"
+#~ msgid "VAT"
+#~ msgstr "ÁFA"
+
#~ msgid "Do you really want to create the invoice(s) ?"
#~ msgstr "Valóban el akarja készíteni a számlá(ka)t?"
diff --git a/addons/mrp_repair/i18n/id.po b/addons/mrp_repair/i18n/id.po
index 73d46eefe95..c5a715bf5b9 100644
--- a/addons/mrp_repair/i18n/id.po
+++ b/addons/mrp_repair/i18n/id.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/it.po b/addons/mrp_repair/i18n/it.po
index ac804044667..a93f02cac15 100644
--- a/addons/mrp_repair/i18n/it.po
+++ b/addons/mrp_repair/i18n/it.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,8 +169,8 @@ msgstr "Attenzione!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "IVA"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -784,6 +784,9 @@ msgstr "Nessun partner!"
#~ msgid "Repair Order Ref"
#~ msgstr "Rif. Ordine riparazione"
+#~ msgid "VAT"
+#~ msgstr "IVA"
+
#~ msgid "Invalid XML for View Architecture!"
#~ msgstr "XML non valido per Visualizzazione Architettura!"
diff --git a/addons/mrp_repair/i18n/ja.po b/addons/mrp_repair/i18n/ja.po
index 338d7de68db..2b28d8f1bba 100644
--- a/addons/mrp_repair/i18n/ja.po
+++ b/addons/mrp_repair/i18n/ja.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -180,8 +180,8 @@ msgstr "警告"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "消費税"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -793,3 +793,6 @@ msgstr "修理準備完了"
#, python-format
msgid "No partner !"
msgstr "パートナがありません。"
+
+#~ msgid "VAT"
+#~ msgstr "消費税"
diff --git a/addons/mrp_repair/i18n/ko.po b/addons/mrp_repair/i18n/ko.po
index dd1dc6dca74..51a13009fbc 100644
--- a/addons/mrp_repair/i18n/ko.po
+++ b/addons/mrp_repair/i18n/ko.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -170,7 +170,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/lt.po b/addons/mrp_repair/i18n/lt.po
index 7b661b27a5e..b3cf1cb3461 100644
--- a/addons/mrp_repair/i18n/lt.po
+++ b/addons/mrp_repair/i18n/lt.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/mrp_repair.pot b/addons/mrp_repair/i18n/mrp_repair.pot
index 884f6a30d00..3f21da6f93d 100644
--- a/addons/mrp_repair/i18n/mrp_repair.pot
+++ b/addons/mrp_repair/i18n/mrp_repair.pot
@@ -154,7 +154,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/nl.po b/addons/mrp_repair/i18n/nl.po
index f7543992873..82518015dea 100644
--- a/addons/mrp_repair/i18n/nl.po
+++ b/addons/mrp_repair/i18n/nl.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -191,8 +191,8 @@ msgstr "Waarschuwing !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "BTW"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -758,7 +758,7 @@ msgstr "Verwijder"
#: field:mrp.repair.fee,product_uom:0
#: field:mrp.repair.line,product_uom:0
msgid "Product UoM"
-msgstr "Produkt UoM"
+msgstr "Product maateenheid"
#. module: mrp_repair
#: field:mrp.repair,partner_invoice_id:0
@@ -818,6 +818,9 @@ msgstr "Gereed voor reparatie"
msgid "No partner !"
msgstr "Geen relatie !"
+#~ msgid "VAT"
+#~ msgstr "BTW"
+
#~ msgid "Invalid XML for View Architecture!"
#~ msgstr "Ongeldige XML voor overzicht"
diff --git a/addons/mrp_repair/i18n/nl_BE.po b/addons/mrp_repair/i18n/nl_BE.po
index 6c424a6abd1..0f680be7664 100644
--- a/addons/mrp_repair/i18n/nl_BE.po
+++ b/addons/mrp_repair/i18n/nl_BE.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/pl.po b/addons/mrp_repair/i18n/pl.po
index 5055793e582..036178a1f9b 100644
--- a/addons/mrp_repair/i18n/pl.po
+++ b/addons/mrp_repair/i18n/pl.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,8 +169,8 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "VAT"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -788,6 +788,9 @@ msgstr "Brak partnera !"
#~ msgid "Repair State"
#~ msgstr "Stan naprawy"
+#~ msgid "VAT"
+#~ msgstr "VAT"
+
#~ msgid "Repairs in quotation"
#~ msgstr "Naprawy w ofercie"
diff --git a/addons/mrp_repair/i18n/pt.po b/addons/mrp_repair/i18n/pt.po
index f10ee11ad74..acaab4321d6 100644
--- a/addons/mrp_repair/i18n/pt.po
+++ b/addons/mrp_repair/i18n/pt.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -190,8 +190,8 @@ msgstr "Atenção!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "IVA"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -828,6 +828,9 @@ msgstr "Nenhum Parceiro !"
#~ msgid "Make invoices"
#~ msgstr "Criar Facturas"
+#~ msgid "VAT"
+#~ msgstr "IVA"
+
#~ msgid "Repairs"
#~ msgstr "Reparações"
diff --git a/addons/mrp_repair/i18n/pt_BR.po b/addons/mrp_repair/i18n/pt_BR.po
index 1cd89664a02..6eb1ae72199 100644
--- a/addons/mrp_repair/i18n/pt_BR.po
+++ b/addons/mrp_repair/i18n/pt_BR.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr "Atenção !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/ro.po b/addons/mrp_repair/i18n/ro.po
index 8c91256235f..887b9708cde 100644
--- a/addons/mrp_repair/i18n/ro.po
+++ b/addons/mrp_repair/i18n/ro.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -192,8 +192,8 @@ msgstr "Avertizare !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "TVA"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -843,6 +843,9 @@ msgstr "Niciun partener !"
#~ " * Raport cotatie reparatii\n"
#~ " * Note pentru tehnician si pentru clientul final\n"
+#~ msgid "VAT"
+#~ msgstr "TVA"
+
#~ msgid "Products Repairs Module - Manage All products Repairs"
#~ msgstr "Modulul Reparatii Produse - Gestionează toate Reparatiile produselor"
diff --git a/addons/mrp_repair/i18n/ru.po b/addons/mrp_repair/i18n/ru.po
index 58751496f16..f41e1f1b5c9 100644
--- a/addons/mrp_repair/i18n/ru.po
+++ b/addons/mrp_repair/i18n/ru.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/sl.po b/addons/mrp_repair/i18n/sl.po
index 16a321ff926..c3e764f9843 100644
--- a/addons/mrp_repair/i18n/sl.po
+++ b/addons/mrp_repair/i18n/sl.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,8 +169,8 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "DDV"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -793,6 +793,9 @@ msgstr ""
#~ msgid "Repair State"
#~ msgstr "Stanje popravila"
+#~ msgid "VAT"
+#~ msgstr "DDV"
+
#~ msgid "Repairs"
#~ msgstr "Popravila"
diff --git a/addons/mrp_repair/i18n/sq.po b/addons/mrp_repair/i18n/sq.po
index 61096ec3734..8343c292e16 100644
--- a/addons/mrp_repair/i18n/sq.po
+++ b/addons/mrp_repair/i18n/sq.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:07+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -170,7 +170,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/sr.po b/addons/mrp_repair/i18n/sr.po
index 7c89079387b..f66154ebcb9 100644
--- a/addons/mrp_repair/i18n/sr.po
+++ b/addons/mrp_repair/i18n/sr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -186,8 +186,8 @@ msgstr "Upozorenje!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "PDV"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -823,6 +823,9 @@ msgstr "Nema partnera !"
#~ msgid "Repair Order Ref"
#~ msgstr "Ref.Nalog za Popravku"
+#~ msgid "VAT"
+#~ msgstr "PDV"
+
#~ msgid "Repair Fees line"
#~ msgstr "Dodatne Linije Popravke"
diff --git a/addons/mrp_repair/i18n/sr@latin.po b/addons/mrp_repair/i18n/sr@latin.po
index 0e913194736..8a44ede0215 100644
--- a/addons/mrp_repair/i18n/sr@latin.po
+++ b/addons/mrp_repair/i18n/sr@latin.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -186,8 +186,8 @@ msgstr "Upozorenje!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "PDV"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -817,6 +817,9 @@ msgstr "Nema partnera !"
#~ msgid "Invalid model name in the action definition."
#~ msgstr "Pogrešno ime modela u definiciji akcije."
+#~ msgid "VAT"
+#~ msgstr "PDV"
+
#~ msgid "Invalid XML for View Architecture!"
#~ msgstr "Nevažeći XML za pregled arhitekture"
diff --git a/addons/mrp_repair/i18n/sv.po b/addons/mrp_repair/i18n/sv.po
index 81317b71571..d326c90147e 100644
--- a/addons/mrp_repair/i18n/sv.po
+++ b/addons/mrp_repair/i18n/sv.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,8 +169,8 @@ msgstr "Varning !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "Moms"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -781,6 +781,9 @@ msgstr ""
#~ msgstr ""
#~ "Objektnamnet måste börja med x_ och får inte innehålla några specialtecken!"
+#~ msgid "VAT"
+#~ msgstr "Moms"
+
#~ msgid "Invalid XML for View Architecture!"
#~ msgstr "Felaktig XML för Vyarkitektur!"
diff --git a/addons/mrp_repair/i18n/tlh.po b/addons/mrp_repair/i18n/tlh.po
index 562251fcba6..078acaa976e 100644
--- a/addons/mrp_repair/i18n/tlh.po
+++ b/addons/mrp_repair/i18n/tlh.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/tr.po b/addons/mrp_repair/i18n/tr.po
index 90945430991..8f1ed46113e 100644
--- a/addons/mrp_repair/i18n/tr.po
+++ b/addons/mrp_repair/i18n/tr.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -188,8 +188,8 @@ msgstr "Uyarı !"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "KDV"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -822,6 +822,9 @@ msgstr "Paydaş Yok !"
#~ msgid "Repair State"
#~ msgstr "Onarım Durum"
+#~ msgid "VAT"
+#~ msgstr "KDV"
+
#~ msgid "Repairs in quotation"
#~ msgstr "Teklifdeki Onarımlar"
diff --git a/addons/mrp_repair/i18n/uk.po b/addons/mrp_repair/i18n/uk.po
index d6608c0a998..14bfa2e1d2a 100644
--- a/addons/mrp_repair/i18n/uk.po
+++ b/addons/mrp_repair/i18n/uk.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/vi.po b/addons/mrp_repair/i18n/vi.po
index 70f543586be..5b3f98caff0 100644
--- a/addons/mrp_repair/i18n/vi.po
+++ b/addons/mrp_repair/i18n/vi.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -170,7 +170,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/i18n/zh_CN.po b/addons/mrp_repair/i18n/zh_CN.po
index 896df443961..a477872aa63 100644
--- a/addons/mrp_repair/i18n/zh_CN.po
+++ b/addons/mrp_repair/i18n/zh_CN.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -177,8 +177,8 @@ msgstr "警告!"
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
-msgstr "增值税"
+msgid "Tax"
+msgstr ""
#. module: mrp_repair
#: view:mrp.repair:0
@@ -785,6 +785,9 @@ msgstr "准备修理"
msgid "No partner !"
msgstr "没有输入业务伙伴"
+#~ msgid "VAT"
+#~ msgstr "增值税"
+
#~ msgid "Status"
#~ msgstr "状态"
diff --git a/addons/mrp_repair/i18n/zh_TW.po b/addons/mrp_repair/i18n/zh_TW.po
index c6872a43a62..22b842543b1 100644
--- a/addons/mrp_repair/i18n/zh_TW.po
+++ b/addons/mrp_repair/i18n/zh_TW.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-07-14 06:13+0000\n"
-"X-Generator: Launchpad (build 15614)\n"
+"X-Launchpad-Export-Date: 2012-07-21 05:08+0000\n"
+"X-Generator: Launchpad (build 15654)\n"
#. module: mrp_repair
#: view:mrp.repair:0
@@ -169,7 +169,7 @@ msgstr ""
#. module: mrp_repair
#: report:repair.order:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: mrp_repair
diff --git a/addons/mrp_repair/report/order.rml b/addons/mrp_repair/report/order.rml
index 539ea69ba63..be5737d4b85 100644
--- a/addons/mrp_repair/report/order.rml
+++ b/addons/mrp_repair/report/order.rml
@@ -169,7 +169,7 @@
Description
- VAT
+ Tax
Quantity
@@ -278,7 +278,7 @@
Description
- VAT
+ Tax
Quantity
diff --git a/addons/pad/LICENSE b/addons/pad/LICENSE
deleted file mode 100644
index ff64be448e9..00000000000
--- a/addons/pad/LICENSE
+++ /dev/null
@@ -1,15 +0,0 @@
-OpenERP, Open Source Management Solution
-Copyright © 2010-2011 OpenERP SA ().
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public Lice
-along with this program. If not, see .
diff --git a/addons/pad/__init__.py b/addons/pad/__init__.py
index 663cac2cbf0..ee80bcaf8d0 100644
--- a/addons/pad/__init__.py
+++ b/addons/pad/__init__.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
+import pad
import res_company
-import ir_attachment
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/__openerp__.py b/addons/pad/__openerp__.py
index 267f595c7e5..bc4159089d7 100644
--- a/addons/pad/__openerp__.py
+++ b/addons/pad/__openerp__.py
@@ -25,6 +25,7 @@ Lets the company customize which Pad installation should be used to link to new
"static/src/xml/*.xml",
],
'images': ['static/src/img/pad_link_companies.jpeg'],
+ "css": ['static/src/css/etherpad.css',],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/ir_attachment.py b/addons/pad/ir_attachment.py
deleted file mode 100644
index ba8c88632dd..00000000000
--- a/addons/pad/ir_attachment.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- coding: utf-8 -*-
-from osv import fields, osv
-import random
-import string
-
-class ir_attachment(osv.osv):
- _inherit = 'ir.attachment'
-
- def pad_generate_url(self, cr, uid, model, id):
- pad_url_template = self.pool.get('res.users').browse(cr,uid,[uid])[0].company_id.pad_url_template
- s = string.ascii_uppercase + string.digits
- salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(8)])
- template_vars = {
- 'db' : cr.dbname,
- 'model' : model,
- 'id' : id,
- 'salt' : salt,
- 'name' : '',
- }
- return pad_url_template % template_vars
-
- def pad_get(self, cr, uid, model, id):
- attachment = self.search(cr, uid, [('res_model', '=', model), ('res_id', '=', id), ('type', '=', 'url'), ('name', '=', 'Pad')])
- if attachment:
- return self.read(cr, uid, attachment)[0]['url']
- else:
- url = self.pad_generate_url(cr, uid, model, id)
- self.create(cr, uid, {
- 'res_model' : model,
- 'res_id' : id,
- 'type' : 'url',
- 'name' : 'Pad',
- 'url' : url,
- })
- return url
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/pad.py b/addons/pad/pad.py
new file mode 100644
index 00000000000..40569fcd589
--- /dev/null
+++ b/addons/pad/pad.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+from osv import fields, osv
+import random
+import string
+import urllib2
+from tools.translate import _
+
+class pad_common(osv.osv_memory):
+ _name = 'pad.common'
+ _pad_fields = []
+ def pad_generate_url(self, cr, uid, context=None):
+ pad_url_template = self.pool.get('res.users').browse(cr,uid, uid, context).company_id.pad_url_template
+ s = string.ascii_uppercase + string.digits
+ salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(8)])
+ template_vars = {
+ 'db' : cr.dbname,
+ 'model' : self._name,
+ 'salt' : salt,
+ }
+ url = pad_url_template % template_vars
+ return url
+
+ def copy(self, cr, uid, id, default=None, context=None):
+ if not default:
+ default = {}
+ update = [(field,self.pad_generate_url(cr, uid, context)) for field in self._pad_fields]
+ default.update(update)
+ return super(pad_common, self).copy(cr, uid, id, default, context)
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/res_company.py b/addons/pad/res_company.py
index 0c1dc7c4929..bd955cd0481 100644
--- a/addons/pad/res_company.py
+++ b/addons/pad/res_company.py
@@ -1,14 +1,15 @@
# -*- coding: utf-8 -*-
from osv import fields, osv
+DEFAULT_PAD_TEMPLATE = 'http://beta.etherpad.org/p/%(db)s-%(model)s-%(salt)s'
+
class company_pad(osv.osv):
_inherit = 'res.company'
_columns = {
- 'pad_url_template': fields.char('Pad URL Template', size=128, required=True,
- help="Template used to generate pad URL."),
+ 'pad_url_template': fields.char('Pad URL Template', size=128, required=True, help="Template used to generate pad URL."),
}
_defaults = {
- 'pad_url_template': 'http://ietherpad.com/%(db)s-%(model)s-%(id)d-%(salt)s-%(name)s'
+ 'pad_url_template': DEFAULT_PAD_TEMPLATE,
}
diff --git a/addons/pad/res_company.xml b/addons/pad/res_company.xml
index 9b1c0656470..12f14b0f5bd 100644
--- a/addons/pad/res_company.xml
+++ b/addons/pad/res_company.xml
@@ -8,7 +8,7 @@
-
+
diff --git a/addons/pad/static/src/css/etherpad.css b/addons/pad/static/src/css/etherpad.css
new file mode 100644
index 00000000000..a0240afcab7
--- /dev/null
+++ b/addons/pad/static/src/css/etherpad.css
@@ -0,0 +1,70 @@
+.oe_etherpad_head{
+ width: 100%;
+ display: block;
+ padding-left:3px;
+ cursor:pointer;
+}
+.oe_etherpad_fullscreen div.oe_etherpad_head .oe_normal {
+ display: none;
+}
+.oe_etherpad_normal div.oe_etherpad_head .oe_fullscreen {
+ display: none;
+}
+.oe_etherpad_fullscreen {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: white;
+ z-index:10001 !important;
+}
+.etherpad_default{
+ width: 100%;
+ height: 450px;
+}
+.oe_etherpad_fullscreen .etherpad_default{
+ height: 100%
+}
+
+.etherpad_body{
+ overflow:hidden;
+}
+
+.etherpad_readonly{
+ width: 100%;
+ height: 450px;
+ overflow:auto;
+}
+.etherpad_readonly ul,.etherpad_readonly ol{
+ -webkit-margin-before: 1em;
+ -webkit-margin-after: 1em;
+ -webkit-margin-start: 0px;
+ -webkit-margin-end: 0px;
+ -webkit-padding-start: 40px !important;
+}
+.etherpad_readonly ul li{
+ list-style-type: disc;
+}
+.etherpad_readonly ol li{
+ list-style-type: decimal;
+}
+.etherpad_readonly .indent li{
+ list-style-type: none !important;
+}
+
+.etherpad_readonly{
+ font-family: arial, sans-serif;
+ font-size: 13px;
+ line-height: 17px;
+}
+
+.etherpad_readonly ul.indent { list-style-type: none !important; }
+.etherpad_readonly ol li{ list-style-type: decimal !important; }
+.etherpad_readonly ol ol li{ list-style-type: lower-latin !important; }
+.etherpad_readonly ol ol ol li{ list-style-type: lower-roman !important; }
+.etherpad_readonly ol ol ol ol li{ list-style-type: decimal !important; }
+.etherpad_readonly ol ol ol ol ol li{ list-style-type: lower-latin !important; }
+.etherpad_readonly ol ol ol ol ol ol li{ list-style-type: lower-roman !important; }
+.etherpad_readonly ol ol ol ol ol ol ol li{ list-style-type: decimal !important; }
+.etherpad_readonly ol ol ol ol ol ol ol ol li{ list-style-type: lower-latin !important; }
diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js
index 2e5f8820ac4..6384eb72da8 100644
--- a/addons/pad/static/src/js/pad.js
+++ b/addons/pad/static/src/js/pad.js
@@ -1,18 +1,40 @@
openerp.pad = function(instance) {
-instance.web.Sidebar = instance.web.Sidebar.extend({
- init: function(parent) {
- this._super(parent);
- this.add_items('other',[{ label: "Pad", callback: this.on_add_pad }]);
- },
- on_add_pad: function() {
+instance.web.form.FieldPad = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
+ template: 'FieldPad',
+ initialize_content: function() {
var self = this;
- var view = this.getParent();
- var model = new instance.web.Model('ir.attachment');
- model.call('pad_get', [view.model ,view.datarecord.id],{}).then(function(r) {
- self.do_action({ type: "ir.actions.act_url", url: r });
+ this.$textarea = undefined;
+ this.$element.find('div.oe_etherpad_head').click(function(ev) {
+ self.$element.toggleClass('oe_etherpad_fullscreen').toggleClass('oe_etherpad_normal');
});
- }
+ },
+ set_value: function(value_) {
+ this._super(value_);
+ this.render_value();
+ },
+ render_value: function() {
+ var self = this;
+ var value = this.get('value');
+ if(value !== false) {
+ var url = value.split('\n')[0];
+ if (!this.get("effective_readonly")) {
+ var pad_username = this.session.username;
+ var code = '';
+ this.$element.find('div.oe_etherpad_default').html(code);
+ } else {
+ $.get(url+'/export/html').success(function(data) {
+ self.$element.html(''+data+'
');
+ }).error(function() {
+ self.$element.text('Unable to load pad');
+ });
+ }
+ }
+ },
+});
+
+instance.web.form.widgets = instance.web.form.widgets.extend({
+ 'pad': 'instance.web.form.FieldPad',
});
};
diff --git a/addons/pad/static/src/xml/pad.xml b/addons/pad/static/src/xml/pad.xml
index e922294d03d..e128fb183fb 100644
--- a/addons/pad/static/src/xml/pad.xml
+++ b/addons/pad/static/src/xml/pad.xml
@@ -2,4 +2,17 @@
+
+
+
+
+
+ Fullscreen
+ Return to Record
+
+
+
+
+
+
diff --git a/addons/pad_project/__init__.py b/addons/pad_project/__init__.py
index d6bf9f9551c..098de31a5a4 100644
--- a/addons/pad_project/__init__.py
+++ b/addons/pad_project/__init__.py
@@ -19,6 +19,6 @@
#
##############################################################################
-import models
+import project_task
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/__openerp__.py b/addons/pad_project/__openerp__.py
index 8ca761d2737..18c7d3191d3 100644
--- a/addons/pad_project/__openerp__.py
+++ b/addons/pad_project/__openerp__.py
@@ -20,7 +20,7 @@
##############################################################################
{
- 'name': 'Specifications on PADs',
+ 'name': 'Pad on tasks',
'version': '1.0',
"category": "Project Management",
'description': """
@@ -31,9 +31,9 @@ This module adds a PAD in all project kanban views
'website': 'http://www.openerp.com',
'depends': ['project', 'pad'],
'init_xml': [],
- 'update_xml': ['models/project_task.xml'],
+ 'update_xml': ['project_task.xml'],
'demo_xml': [],
'installable': True,
- 'auto_install': False,
+ 'auto_install': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/models/__init__.py b/addons/pad_project/models/__init__.py
deleted file mode 100644
index 098de31a5a4..00000000000
--- a/addons/pad_project/models/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-
-import project_task
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/models/project_task.py b/addons/pad_project/models/project_task.py
deleted file mode 100644
index c215aed1325..00000000000
--- a/addons/pad_project/models/project_task.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-from tools.translate import _
-from osv import fields, osv
-
-class task(osv.osv):
- _inherit = "project.task"
-
- def pad_get(self, cr, uid, ids, context=None):
- """Get pad action
- """
- url = self.pool.get("ir.attachment").pad_get(cr, uid, self._name, ids[0])
- return {
- 'type': 'ir.actions.act_url',
- 'url': url
- }
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/models/project_task.xml b/addons/pad_project/models/project_task.xml
deleted file mode 100644
index 3c734cf3b97..00000000000
--- a/addons/pad_project/models/project_task.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- project.task.kanban.pad
- project.task
- kanban
-
-
-
- PAD
-
-
-
-
-
diff --git a/addons/pad_project/project_task.py b/addons/pad_project/project_task.py
new file mode 100644
index 00000000000..46c2c54cd46
--- /dev/null
+++ b/addons/pad_project/project_task.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+from tools.translate import _
+from osv import fields, osv
+
+class task(osv.osv):
+ _name = "project.task"
+ _inherit = ["project.task",'pad.common']
+ _pad_fields = ['description_pad']
+ _columns = {
+ 'description_pad': fields.char('Description PAD', size=250)
+ }
+ _defaults = {
+ 'description_pad': lambda self, cr, uid, context: self.pad_generate_url(cr, uid, context),
+ }
diff --git a/addons/pad_project/project_task.xml b/addons/pad_project/project_task.xml
new file mode 100644
index 00000000000..d18f43a92f4
--- /dev/null
+++ b/addons/pad_project/project_task.xml
@@ -0,0 +1,15 @@
+
+
+
+ project.task.form.pad
+ project.task
+ form
+
+
+
+
+
+
+
+
+
diff --git a/addons/plugin_outlook/plugin_outlook.xml b/addons/plugin_outlook/plugin_outlook.xml
index 811661bf127..04e5dca32de 100644
--- a/addons/plugin_outlook/plugin_outlook.xml
+++ b/addons/plugin_outlook/plugin_outlook.xml
@@ -11,9 +11,6 @@
-
-
-
@@ -29,7 +26,7 @@
- Install Outlook Plug-In
+
diff --git a/addons/plugin_thunderbird/plugin_thunderbird.xml b/addons/plugin_thunderbird/plugin_thunderbird.xml
index 69e83bf6df2..1adb4fa5eda 100644
--- a/addons/plugin_thunderbird/plugin_thunderbird.xml
+++ b/addons/plugin_thunderbird/plugin_thunderbird.xml
@@ -11,9 +11,6 @@
-
-
-
@@ -35,7 +32,7 @@
- Install Thunderbird Plug-In
+
diff --git a/addons/point_of_sale/__openerp__.py b/addons/point_of_sale/__openerp__.py
index 4c0bb14cc10..96d344b197b 100644
--- a/addons/point_of_sale/__openerp__.py
+++ b/addons/point_of_sale/__openerp__.py
@@ -25,6 +25,7 @@
'version': '1.0.1',
'category': 'Point Of Sale',
"sequence": 6,
+ "summary": "Touchscreen to Manage your Shop",
'description': """
This module provides a quick and easy sale process.
===================================================
diff --git a/addons/point_of_sale/i18n/point_of_sale.pot b/addons/point_of_sale/i18n/point_of_sale.pot
index b0ff45bb671..0246ca65227 100644
--- a/addons/point_of_sale/i18n/point_of_sale.pot
+++ b/addons/point_of_sale/i18n/point_of_sale.pot
@@ -155,7 +155,7 @@ msgstr ""
#. module: point_of_sale
#: report:pos.lines:0
-msgid "VAT"
+msgid "Tax"
msgstr ""
#. module: point_of_sale
diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml
index f3b491116b7..6b1b9132344 100644
--- a/addons/point_of_sale/point_of_sale_view.xml
+++ b/addons/point_of_sale/point_of_sale_view.xml
@@ -1,14 +1,15 @@
-
- VAT
+ Tax
Quantity
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index e4158a88ae0..4fe51dc67f6 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -314,18 +314,18 @@
- VAT
+ Tax
Quantity
@@ -236,7 +236,7 @@
Description
- VAT
+ Tax
Quantity
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index aa30f023ae8..3f7f7efa43b 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -1,6 +1,16 @@
+
-
+
+
+
+
+
@@ -146,10 +156,10 @@
-
+
-
-
+
+
@@ -174,7 +184,6 @@
-
@@ -197,7 +206,7 @@
@@ -263,6 +272,8 @@
+
+
@@ -297,7 +308,7 @@
-
+
diff --git a/addons/sale/stock_view.xml b/addons/sale/stock_view.xml
index daef529b97b..928eebafcae 100644
--- a/addons/sale/stock_view.xml
+++ b/addons/sale/stock_view.xml
@@ -7,7 +7,7 @@
form
-
+
diff --git a/addons/sale_margin/sale_margin_view.xml b/addons/sale_margin/sale_margin_view.xml
index 4696eec6eb2..30c2a0dea14 100644
--- a/addons/sale_margin/sale_margin_view.xml
+++ b/addons/sale_margin/sale_margin_view.xml
@@ -8,8 +8,13 @@
sale.order
-
-
+
+
+
+
+
+
+
diff --git a/addons/sale_mrp/sale_mrp.py b/addons/sale_mrp/sale_mrp.py
index 840c33770a7..7397edbec2b 100644
--- a/addons/sale_mrp/sale_mrp.py
+++ b/addons/sale_mrp/sale_mrp.py
@@ -70,8 +70,8 @@ class mrp_production(osv.osv):
return res
_columns = {
- 'sale_name': fields.function(_ref_calc, multi='sale_name', type='char', string='Sales Name', help='Indicate the name of sales order.'),
- 'sale_ref': fields.function(_ref_calc, multi='sale_name', type='char', string='Sales Reference', help='Indicate the Customer Reference from sales order.'),
+ 'sale_name': fields.function(_ref_calc, multi='sale_name', type='char', string='Sale Name', help='Indicate the name of sales order.'),
+ 'sale_ref': fields.function(_ref_calc, multi='sale_name', type='char', string='Sale Reference', help='Indicate the Customer Reference from sales order.'),
}
mrp_production()
diff --git a/addons/sale_mrp/sale_mrp_view.xml b/addons/sale_mrp/sale_mrp_view.xml
index fbf2e7a9327..882663680c5 100644
--- a/addons/sale_mrp/sale_mrp_view.xml
+++ b/addons/sale_mrp/sale_mrp_view.xml
@@ -8,10 +8,12 @@
form
-
-
+
+
+
+
diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py
index 50bcb23df7b..2eaaa1ffb69 100644
--- a/addons/stock/__openerp__.py
+++ b/addons/stock/__openerp__.py
@@ -23,6 +23,7 @@
"name" : "Warehouse Management",
"version" : "1.1",
"author" : "OpenERP SA",
+ "summary": "Incoming Shipments, Deliveries, Inventory, Stock",
"description" : """
OpenERP Inventory Management module can manage multi-warehouses, multi and structured stock locations.
======================================================================================================
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index ceed0808ef4..e90a2bb8162 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -2,15 +2,17 @@
-
+
+
+
+ parent="stock.menu_stock_product" sequence="0"/>
@@ -20,19 +22,19 @@
parent="stock.menu_stock_configuration" sequence="45" groups="base.group_no_one"/>
+ parent="stock.menu_product_in_config_stock" sequence="0"/>
-
-
-
+
+
stock.inventory.line.tree
@@ -116,8 +118,8 @@
@@ -204,7 +206,7 @@
stock.inventory
form
-
+
Periodical Inventories are used to count the number of products available per location. You can use it once a year when you do the general inventory or whenever you need it, to correct the current stock level of a product.
@@ -275,9 +277,9 @@
child_ids
-
-
-
+
+
+
@@ -291,7 +293,7 @@
-
+
@@ -387,7 +389,7 @@
tree
-
+
@@ -408,7 +410,7 @@
-
+
@@ -426,7 +428,7 @@
stock.production.lot
form
-
+
{}
This is the list of all the production lots (serial numbers) you recorded. When you select a lot, you can get the upstream or downstream traceability of the products contained in lot. By default, the list is filtred on the serial numbers that are available in your warehouse but you can uncheck the 'Available' button to get all the lots you produced, received or delivered to customers.
@@ -444,8 +446,8 @@
move_history_ids
-
-
+
+
@@ -468,8 +470,8 @@
move_history_ids2
-
-
+
+
@@ -569,11 +571,11 @@
+ string="Internal" domain="[('usage', '=', 'internal')]" help="Internal Locations"/>
+ string="Customer" domain="[('usage', '=', 'customer')]" help="Customer Locations"/>
+ string="Supplier" domain="[('usage', '=', 'supplier')]" help="Supplier Locations"/>
@@ -737,7 +739,7 @@
-
+
@@ -782,7 +784,7 @@
string="Split in Serial Number"
groups="stock.group_production_lot"
type="action" icon="terp-stock_effects-object-colorize"
- states="draft,waiting,confirmed,assigned" />
+ states="draft,waiting,confirmed,assigned"/>
-
+
@@ -860,7 +862,7 @@
-
+
@@ -892,7 +894,7 @@
-
+
@@ -907,7 +909,7 @@
-
+
@@ -971,7 +973,7 @@
-
+
@@ -1015,13 +1017,13 @@
-
+
-
+
-
-
+
+
@@ -1088,7 +1090,7 @@
-
+
@@ -1116,23 +1118,23 @@
-
+
-
+
-
+
-
+
-
-
+
+
@@ -1190,7 +1192,7 @@
string="Scrap Products" type="action"
icon="gtk-convert" context="{'scrap': True}"
states="draft,waiting,confirmed,assigned"
- />
+ />
-
@@ -1266,7 +1268,7 @@
-
+
@@ -1327,7 +1329,7 @@
-
+
@@ -1359,13 +1361,13 @@
stock.move.tree2
stock.move
tree
-
+
-
+
-
+
-
+
diff --git a/addons/survey/survey_view.xml b/addons/survey/survey_view.xml
index 20f6f42a929..fb4b232f512 100644
--- a/addons/survey/survey_view.xml
+++ b/addons/survey/survey_view.xml
@@ -1,14 +1,16 @@
-
-
-
-
-
+
+
+
+
+
+
+
@@ -269,7 +271,7 @@
-
+
survey_search
survey
search
@@ -295,7 +297,7 @@
-
+
event.survey.kanban
survey
@@ -750,7 +752,7 @@
-
+
survey_question_search
survey.question
search
diff --git a/addons/wiki/wiki_view.xml b/addons/wiki/wiki_view.xml
index 700585122d3..b0f0ab0198e 100644
--- a/addons/wiki/wiki_view.xml
+++ b/addons/wiki/wiki_view.xml
@@ -1,15 +1,18 @@
-
-
+
+
-
+
+
+
@@ -38,7 +41,7 @@
+ attrs="{'required':[('method','=','page')], 'readonly':[('method','!=','page')]}"/>
@@ -61,7 +64,7 @@
name="open_wiki_page"
string="Open Wiki Page"
type="object"
- icon="gtk-ok" />
+ icon="gtk-ok"/>
@@ -131,7 +134,7 @@
-
+
@@ -155,7 +158,7 @@
-
+
@@ -203,7 +206,7 @@
+ action="action_wiki"/>
@@ -258,7 +261,7 @@
tree,form
-
- Wiki Pages
+ Sales FAQ
wiki.wiki
form
tree,form