').html(render_res).appendTo(self.$element.find('div.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}
+ );
+ self.thread_list.push(thread);
+ return thread.appendTo(self.$element.find('div.oe_mail_wall_thread:last'));
+ });
+ // update TODO
+ this.comments_structure['root_ids'] = _.union(this.comments_structure['root_ids'], this.comments_structure['new_root_ids']);
+ 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
+ * - 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 () {
+ var self = this;
+ var model_to_root = {};
+ var fetch_domain = [];
+ _(this.comments_structure['model_to_root_ids']).each(function (sc_model, model_name) {
+ fetch_domain.push('|', ['model', '!=', model_name], '!', ['id', 'child_of', sc_model]);
+ });
+ return fetch_domain;
+ },
+
+ /** Display update: show more button */
+ do_update_show_more: function (new_value) {
+ if (new_value != undefined) this.display_show_more = new_value;
+ if (this.display_show_more) this.$element.find('div.oe_mail_wall_more:last').show();
+ else this.$element.find('div.oe_mail_wall_more:last').hide();
+ },
+
+ /** Action: Shows more discussions */
+ do_more: function () {
+ 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('textarea.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'));
+ },
+ });
+};
+
+// 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
new file mode 100644
index 00000000000..0f49902b6b3
--- /dev/null
+++ b/addons/mail/static/src/xml/mail.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
History and Comments
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![User img]()
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ on
+
+ Reply
+
+ Delete
+
+
+ Hide
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index af8baa314de..dd07cbce9b2 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -200,13 +200,8 @@ class mail_compose_message(osv.osv_memory):
body = mail.body_html if mail.subtype == 'html' else mail.body_text
- # 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
-
+ # Get model, and check whether it is OpenChatter enabled, aka inherit from mail.thread
if context.get('mail.compose.message.mode') == 'mass_mail':
- # Mass mailing: must render the template patterns
if context.get('active_ids') and context.get('active_model'):
active_ids = context['active_ids']
active_model = context['active_model']
@@ -214,7 +209,22 @@ class mail_compose_message(osv.osv_memory):
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))
+ else:
+ active_model = mail.model
+ active_ids = [int(mail.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
+ 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)
@@ -223,21 +233,33 @@ class mail_compose_message(osv.osv_memory):
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)
-
+
# in mass-mailing mode we only schedule the mail for sending, it will be
# processed as soon as the mail scheduler runs.
- 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)
+ 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,
+ 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)
else:
# normal mode - no mass-mailing
- msg_id = 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)
+ 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)
+ 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)]
# 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_id], context=context)
+ mail_message.send(cr, uid, msg_ids, context=context)
return {'type': 'ir.actions.act_window_close'}
diff --git a/addons/marketing/i18n/cs.po b/addons/marketing/i18n/cs.po
new file mode 100644
index 00000000000..85d7867b15c
--- /dev/null
+++ b/addons/marketing/i18n/cs.po
@@ -0,0 +1,28 @@
+# Czech 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:36+0000\n"
+"PO-Revision-Date: 2012-04-06 05:18+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: marketing
+#: model:res.groups,name:marketing.group_marketing_manager
+msgid "Manager"
+msgstr "Vedoucí"
+
+#. module: marketing
+#: model:res.groups,name:marketing.group_marketing_user
+msgid "User"
+msgstr "Uživatel"
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 1f70f55e505..9ff3a648af9 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -130,6 +130,7 @@ class mrp_bom(osv.osv):
"""
_name = 'mrp.bom'
_description = 'Bill of Material'
+ _inherit = ['mail.thread']
def _child_compute(self, cr, uid, ids, name, arg, context=None):
""" Gets child bom.
@@ -358,6 +359,18 @@ class mrp_bom(osv.osv):
default.update({'name': bom_data['name'] + ' ' + _('Copy'), 'bom_id':False})
return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context)
+ def create(self, cr, uid, vals, context=None):
+ obj_id = super(mrp_bom, self).create(cr, uid, vals, context=context)
+ self.create_send_note(cr, uid, [obj_id], context=context)
+ return obj_id
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ prod_obj = self.pool.get('product.product')
+ for obj in self.browse(cr, uid, ids, context=context):
+ for prod in prod_obj.browse(cr, uid, [obj.product_id], context=context):
+ self.message_append_note(cr, uid, [obj.id], body=_("Bill of Material has been created for %s product.") % (prod.id.name_template), context=context)
+ return True
+
mrp_bom()
class mrp_bom_revision(osv.osv):
@@ -393,6 +406,7 @@ class mrp_production(osv.osv):
_name = 'mrp.production'
_description = 'Manufacturing Order'
_date_name = 'date_planned'
+ _inherit = ['ir.needaction_mixin', 'mail.thread']
def _production_calc(self, cr, uid, ids, prop, unknow_none, context=None):
""" Calculates total hours and total no. of cycles for a production order.
@@ -497,6 +511,11 @@ class mrp_production(osv.osv):
(_check_qty, 'Order quantity cannot be negative or zero!', ['product_qty']),
]
+ def create(self, cr, uid, vals, context=None):
+ obj_id = super(mrp_production, self).create(cr, uid, vals, context=context)
+ self.create_send_note(cr, uid, [obj_id], context=context)
+ return obj_id
+
def unlink(self, cr, uid, ids, context=None):
for production in self.browse(cr, uid, ids, context=context):
if production.state not in ('draft', 'cancel'):
@@ -629,9 +648,10 @@ class mrp_production(osv.osv):
move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids])
move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines])
self.write(cr, uid, ids, {'state': 'cancel'})
+ self.action_cancel_send_note(cr, uid, ids, context)
return True
- def action_ready(self, cr, uid, ids):
+ def action_ready(self, cr, uid, ids, context=None):
""" Changes the production state to Ready and location id of stock move.
@return: True
"""
@@ -643,18 +663,18 @@ class mrp_production(osv.osv):
if production.move_prod_id:
move_obj.write(cr, uid, [production.move_prod_id.id],
{'location_id': production.location_dest_id.id})
-
- message = _("Manufacturing order '%s' is ready to produce.") % ( name,)
- self.log(cr, uid, production_id, message)
+ self.action_ready_send_note(cr, uid, [production_id], context)
return True
- def action_production_end(self, cr, uid, ids):
+ def action_production_end(self, cr, uid, ids, context=None):
""" Changes production state to Finish and writes finished date.
@return: True
"""
for production in self.browse(cr, uid, ids):
self._costs_generate(cr, uid, production)
- return self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
+ write_res = self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
+ self.action_done_send_note(cr, uid, ids, context)
+ return write_res
def test_production_done(self, cr, uid, ids):
""" Tests whether production is done or not.
@@ -698,7 +718,6 @@ class mrp_production(osv.osv):
if (produced_product.scrapped) or (produced_product.product_id.id <> production.product_id.id):
continue
produced_qty += produced_product.product_qty
-
if production_mode in ['consume','consume_produce']:
consumed_data = {}
@@ -819,11 +838,12 @@ class mrp_production(osv.osv):
} )
return amount
- def action_in_production(self, cr, uid, ids):
+ def action_in_production(self, cr, uid, ids, context=None):
""" Changes state to In Production and writes starting date.
@return: True
"""
self.write(cr, uid, ids, {'state': 'in_production', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
+ self.action_in_production_send_note(cr, uid, ids, context)
return True
def test_if_product(self, cr, uid, ids):
@@ -997,11 +1017,7 @@ class mrp_production(osv.osv):
wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
production.write({'state':'confirmed'}, context=context)
- message = _("Manufacturing order '%s' is scheduled for the %s.") % (
- production.name,
- datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y'),
- )
- self.log(cr, uid, production.id, message)
+ self.action_confirm_send_note(cr, uid, [production.id], context);
return shipment_id
def force_production(self, cr, uid, ids, *args):
@@ -1012,6 +1028,55 @@ class mrp_production(osv.osv):
pick_obj = self.pool.get('stock.picking')
pick_obj.force_assign(cr, uid, [prod.picking_id.id for prod in self.browse(cr, uid, ids)])
return True
+
+ # ---------------------------------------------------
+ # OpenChatter methods and notifications
+ # ---------------------------------------------------
+
+ def get_needaction_user_ids(self, cr, uid, ids, context=None):
+ result = dict.fromkeys(ids, [])
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.state == 'draft' and obj.user_id:
+ result[obj.id] = [obj.user_id.id]
+ return result
+
+ def message_get_subscribers(self, cr, uid, ids, context=None):
+ sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.user_id:
+ sub_ids.append(obj.user_id.id)
+ return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ self.message_append_note(cr, uid, ids, body=_("Manufacturing order has been created."), context=context)
+ return True
+
+ def action_cancel_send_note(self, cr, uid, ids, context=None):
+ message = _("Manufacturing order has been canceled.")
+ self.message_append_note(cr, uid, ids, body=message, context=context)
+ return True
+
+ def action_ready_send_note(self, cr, uid, ids, context=None):
+ message = _("Manufacturing order is ready to produce.")
+ self.message_append_note(cr, uid, ids, body=message, context=context)
+ return True
+
+ def action_in_production_send_note(self, cr, uid, ids, context=None):
+ message = _("Manufacturing order is in production.")
+ self.message_append_note(cr, uid, ids, body=message, context=context)
+ return True
+
+ def action_done_send_note(self, cr, uid, ids, context=None):
+ message = _("Manufacturing order has been done.")
+ self.message_append_note(cr, uid, ids, body=message, context=context)
+ return True
+
+ def action_confirm_send_note(self, cr, uid, ids, context=None):
+ for obj in self.browse(cr, uid, ids, context=context):
+ message = _("Manufacturing order has been confirmed and is scheduled for the %s.") % (obj.date_planned)
+ self.message_append_note(cr, uid, [obj.id], body=message, context=context)
+ return True
+
mrp_production()
@@ -1019,6 +1084,7 @@ class mrp_production_workcenter_line(osv.osv):
_name = 'mrp.production.workcenter.line'
_description = 'Work Order'
_order = 'sequence'
+ _inherit = ['mail.thread']
_columns = {
'name': fields.char('Work Order', size=64, required=True),
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index 961d42cee2b..986e1b2f754 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -412,6 +412,8 @@
+
+
@@ -646,6 +648,7 @@
+
@@ -775,7 +778,6 @@
-
@@ -785,6 +787,7 @@
+
diff --git a/addons/mrp/wizard/change_production_qty.py b/addons/mrp/wizard/change_production_qty.py
index c41213d93b8..59370e0ff2f 100644
--- a/addons/mrp/wizard/change_production_qty.py
+++ b/addons/mrp/wizard/change_production_qty.py
@@ -70,7 +70,7 @@ class change_production_qty(osv.osv_memory):
bom_obj = self.pool.get('mrp.bom')
for wiz_qty in self.browse(cr, uid, ids, context=context):
prod = prod_obj.browse(cr, uid, record_id, context=context)
- prod_obj.write(cr, uid,prod.id, {'product_qty': wiz_qty.product_qty})
+ prod_obj.write(cr, uid, [prod.id], {'product_qty': wiz_qty.product_qty})
prod_obj.action_compute(cr, uid, [prod.id])
move_lines_obj = self.pool.get('stock.move')
diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py
index fbf307e860e..78deb68e5e7 100644
--- a/addons/mrp_operations/mrp_operations.py
+++ b/addons/mrp_operations/mrp_operations.py
@@ -156,22 +156,24 @@ class mrp_production_workcenter_line(osv.osv):
prod_obj.write(cr, uid, [prod.production_id.id], {'date_start':dstart}, context=context, mini=False)
return result
- def action_draft(self, cr, uid, ids):
+ def action_draft(self, cr, uid, ids, context=None):
""" Sets state to draft.
@return: True
"""
self.write(cr, uid, ids, {'state':'draft'})
+ self.action_draft_send_note(cr, uid, ids, context=context)
return True
- def action_start_working(self, cr, uid, ids):
+ def action_start_working(self, cr, uid, ids, context=None):
""" Sets state to start working and writes starting date.
@return: True
"""
self.modify_production_order_state(cr, uid, ids, 'start')
self.write(cr, uid, ids, {'state':'startworking', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
+ self.action_start_send_note(cr, uid, ids, context=context)
return True
- def action_done(self, cr, uid, ids):
+ def action_done(self, cr, uid, ids, context=None):
""" Sets state to done, writes finish date and calculates delay.
@return: True
"""
@@ -185,28 +187,76 @@ class mrp_production_workcenter_line(osv.osv):
delay += (date_finished-date_start).seconds / float(60*60)
self.write(cr, uid, ids, {'state':'done', 'date_finished': date_now,'delay':delay})
+ self.action_done_send_note(cr, uid, ids, context=context)
self.modify_production_order_state(cr,uid,ids,'done')
return True
- def action_cancel(self, cr, uid, ids):
+ def action_cancel(self, cr, uid, ids, context=None):
""" Sets state to cancel.
@return: True
"""
self.write(cr, uid, ids, {'state':'cancel'})
+ self.action_cancel_send_note(cr, uid, ids, context=context)
return True
- def action_pause(self, cr, uid, ids):
+ def action_pause(self, cr, uid, ids, context=None):
""" Sets state to pause.
@return: True
"""
self.write(cr, uid, ids, {'state':'pause'})
+ self.action_pending_send_note(cr, uid, ids, context=context)
return True
- def action_resume(self, cr, uid, ids):
+ def action_resume(self, cr, uid, ids, context=None):
""" Sets state to startworking.
@return: True
"""
self.write(cr, uid, ids, {'state':'startworking'})
+ self.action_start_send_note(cr, uid, ids, context=context)
+ return True
+
+ # -------------------------------------------------------
+ # OpenChatter methods and notifications
+ # -------------------------------------------------------
+
+ def action_draft_send_note(self, cr, uid, ids, context=None):
+ prod_obj = self.pool.get('mrp.production')
+ for workorder in self.browse(cr, uid, ids):
+ for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
+ message = _("Work order has been created for production order %s.") % (prod.id.name)
+ self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
+ return True
+
+ def action_start_send_note(self, cr, uid, ids, context=None):
+ prod_obj = self.pool.get('mrp.production')
+ for workorder in self.browse(cr, uid, ids):
+ for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
+ message = _("Work order has been started for production order %s.") % (prod.id.name)
+ self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
+ return True
+
+ def action_done_send_note(self, cr, uid, ids, context=None):
+ prod_obj = self.pool.get('mrp.production')
+ for workorder in self.browse(cr, uid, ids):
+ for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
+ message = _("Work order has been done for production order %s.") % (prod.id.name)
+ self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
+ return True
+
+ def action_pending_send_note(self, cr, uid, ids, context=None):
+ prod_obj = self.pool.get('mrp.production')
+ for workorder in self.browse(cr, uid, ids):
+ for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
+ message = _("Work order is pending for production order %s.") % (prod.id.name)
+ self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
+ return True
+
+ def action_cancel_send_note(self, cr, uid, ids, context=None):
+ prod_obj = self.pool.get('mrp.production')
+ for workorder in self.browse(cr, uid, ids):
+ for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
+ message = _("Work order has been cancelled for production order %s.") % (prod.id.name)
+ self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
return True
mrp_production_workcenter_line()
diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml
index 00b4947122e..b588ab53b8f 100644
--- a/addons/mrp_operations/mrp_operations_view.xml
+++ b/addons/mrp_operations/mrp_operations_view.xml
@@ -118,6 +118,7 @@
+
diff --git a/addons/pad/i18n/cs.po b/addons/pad/i18n/cs.po
new file mode 100644
index 00000000000..16f486af859
--- /dev/null
+++ b/addons/pad/i18n/cs.po
@@ -0,0 +1,58 @@
+# Czech 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 01:37+0100\n"
+"PO-Revision-Date: 2012-04-06 06:59+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: pad
+#: sql_constraint:res.company:0
+msgid "The company name must be unique !"
+msgstr "Jméno společnosti musí být jedinečné !"
+
+#. module: pad
+#: help:res.company,pad_url_template:0
+msgid "Template used to generate pad URL."
+msgstr "Šablona použitá pro generování URL bloku"
+
+#. module: pad
+#: model:ir.model,name:pad.model_res_company
+msgid "Companies"
+msgstr "Společnosti"
+
+#. module: pad
+#: constraint:res.company:0
+msgid "Error! You can not create recursive companies."
+msgstr "Chyba! Nemůžete vytvořit rekurzivní společnosti."
+
+#. module: pad
+#: model:ir.model,name:pad.model_ir_attachment
+msgid "ir.attachment"
+msgstr "ir.attachment"
+
+#. module: pad
+#: view:res.company:0
+msgid "Pad"
+msgstr "Blok"
+
+#. module: pad
+#: field:res.company,pad_url_template:0
+msgid "Pad URL Template"
+msgstr "Šablona URL bloku"
+
+#. openerp-web
+#: /home/odo/repositories/addons/trunk/pad/static/src/xml/pad.xml:9
+msgid "Add Pad"
+msgstr "Přidat blok"
diff --git a/addons/pad_project/i18n/ar.po b/addons/pad_project/i18n/ar.po
new file mode 100644
index 00000000000..cfb855158a6
--- /dev/null
+++ b/addons/pad_project/i18n/ar.po
@@ -0,0 +1,38 @@
+# Arabic 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:36+0000\n"
+"PO-Revision-Date: 2012-04-06 07:58+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Arabic \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: pad_project
+#: constraint:project.task:0
+msgid "Error ! Task end-date must be greater then task start-date"
+msgstr "خطأ ! يجب ان يكون تاريخ نهاية المهمة بعد من تاريخ البداية"
+
+#. module: pad_project
+#: model:ir.model,name:pad_project.model_project_task
+msgid "Task"
+msgstr "مهمة"
+
+#. module: pad_project
+#: view:project.task:0
+msgid "Pad"
+msgstr ""
+
+#. module: pad_project
+#: constraint:project.task:0
+msgid "Error ! You cannot create recursive tasks."
+msgstr "خطأ ! لا يمكنك انشاء مهام متداخلة."
diff --git a/addons/pad_project/i18n/cs.po b/addons/pad_project/i18n/cs.po
new file mode 100644
index 00000000000..1b47ef0abc0
--- /dev/null
+++ b/addons/pad_project/i18n/cs.po
@@ -0,0 +1,38 @@
+# Czech 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:36+0000\n"
+"PO-Revision-Date: 2012-04-06 06:58+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: pad_project
+#: constraint:project.task:0
+msgid "Error ! Task end-date must be greater then task start-date"
+msgstr "Chyba ! Datum ukončení úkolu musí být větší než počáteční datum"
+
+#. module: pad_project
+#: model:ir.model,name:pad_project.model_project_task
+msgid "Task"
+msgstr "Úkol"
+
+#. module: pad_project
+#: view:project.task:0
+msgid "Pad"
+msgstr "Blok"
+
+#. module: pad_project
+#: constraint:project.task:0
+msgid "Error ! You cannot create recursive tasks."
+msgstr "Chyba ! Nemůžete vytvořit rekurzivní úkoly."
diff --git a/addons/plugin/i18n/ar.po b/addons/plugin/i18n/ar.po
new file mode 100644
index 00000000000..4047918f385
--- /dev/null
+++ b/addons/plugin/i18n/ar.po
@@ -0,0 +1,23 @@
+# Arabic 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:36+0000\n"
+"PO-Revision-Date: 2012-04-06 07:59+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Arabic \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: plugin
+#: model:ir.model,name:plugin.model_plugin_handler
+msgid "plugin.handler"
+msgstr "plugin.handler"
diff --git a/addons/plugin/i18n/cs.po b/addons/plugin/i18n/cs.po
new file mode 100644
index 00000000000..2991dd9970a
--- /dev/null
+++ b/addons/plugin/i18n/cs.po
@@ -0,0 +1,23 @@
+# Czech 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:36+0000\n"
+"PO-Revision-Date: 2012-04-06 06:59+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:56+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: plugin
+#: model:ir.model,name:plugin.model_plugin_handler
+msgid "plugin.handler"
+msgstr "plugin.handler"
diff --git a/addons/plugin_thunderbird/i18n/cs.po b/addons/plugin_thunderbird/i18n/cs.po
index 1d669ea3dc6..8918a097082 100644
--- a/addons/plugin_thunderbird/i18n/cs.po
+++ b/addons/plugin_thunderbird/i18n/cs.po
@@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-02-09 00:36+0000\n"
-"PO-Revision-Date: 2010-01-25 11:49+0000\n"
-"Last-Translator: Kuvaly [LCT] \n"
+"PO-Revision-Date: 2012-04-06 06:56+0000\n"
+"Last-Translator: Jiří Hajda \n"
"Language-Team: Czech \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-10 04:49+0000\n"
-"X-Generator: Launchpad (build 14771)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
#. module: plugin_thunderbird
#: field:plugin_thunderbird.installer,pdf_file:0
msgid "Installation Manual"
-msgstr ""
+msgstr "Instalační příručka"
#. module: plugin_thunderbird
#: field:plugin_thunderbird.installer,description:0
@@ -30,23 +30,23 @@ msgstr "Popis"
#. module: plugin_thunderbird
#: view:plugin_thunderbird.installer:0
msgid "title"
-msgstr ""
+msgstr "nadpis"
#. module: plugin_thunderbird
#: model:ir.model,name:plugin_thunderbird.model_plugin_thunderbird_installer
msgid "plugin_thunderbird.installer"
-msgstr ""
+msgstr "plugin_thunderbird.installer"
#. module: plugin_thunderbird
#: field:plugin_thunderbird.installer,config_logo:0
msgid "Image"
-msgstr ""
+msgstr "Obrázek"
#. module: plugin_thunderbird
#: field:plugin_thunderbird.installer,plugin_file:0
#: field:plugin_thunderbird.installer,thunderbird:0
msgid "Thunderbird Plug-in"
-msgstr ""
+msgstr "Doplněk Thunderbirdu"
#. module: plugin_thunderbird
#: view:plugin_thunderbird.installer:0
@@ -54,6 +54,8 @@ msgid ""
"This plug-in allows you to link your e-mail to OpenERP's documents. You can "
"attach it to any existing one in OpenERP or create a new one."
msgstr ""
+"Doplněk vám umožní spojit váš email k dokumentům OpenERP. Můžete jej "
+"připojit k jakémukoliv existujícímu v OpenERP nebo vytvořit nový."
#. module: plugin_thunderbird
#: help:plugin_thunderbird.installer,thunderbird:0
@@ -61,27 +63,28 @@ msgid ""
"Allows you to select an object that you would like to add to your email and "
"its attachments."
msgstr ""
+"Umožní vám vybrat objekt, který chcete přidat do vašeho emailu a jeho příloh."
#. module: plugin_thunderbird
#: help:plugin_thunderbird.installer,pdf_file:0
msgid "The documentation file :- how to install Thunderbird Plug-in."
-msgstr ""
+msgstr "Dokumentační soubor :- jak instalovat doplněk Thunderbirdu"
#. module: plugin_thunderbird
#: view:plugin_thunderbird.installer:0
msgid "_Close"
-msgstr ""
+msgstr "_Zavřít"
#. module: plugin_thunderbird
#: view:plugin_thunderbird.installer:0
msgid "Installation and Configuration Steps"
-msgstr ""
+msgstr "Kroky instalace a nastavení"
#. module: plugin_thunderbird
#: field:plugin_thunderbird.installer,name:0
#: field:plugin_thunderbird.installer,pdf_name:0
msgid "File name"
-msgstr ""
+msgstr "Název souboru"
#. module: plugin_thunderbird
#: help:plugin_thunderbird.installer,plugin_file:0
@@ -89,10 +92,12 @@ msgid ""
"Thunderbird plug-in file. Save as this file and install this plug-in in "
"thunderbird."
msgstr ""
+"Soubor doplňku Thunderbirdu. Uložit toto jako soubor a nainstalujte tento "
+"doplněk do thunderbirdu."
#. module: plugin_thunderbird
#: model:ir.actions.act_window,name:plugin_thunderbird.action_thunderbird_installer
#: model:ir.ui.menu,name:plugin_thunderbird.menu_base_config_plugins_thunderbird
#: view:plugin_thunderbird.installer:0
msgid "Install Thunderbird Plug-In"
-msgstr ""
+msgstr "Instalovat doplněk Thunderbirdu"
diff --git a/addons/portal/i18n/cs.po b/addons/portal/i18n/cs.po
index 86605d948f3..3aacc86a971 100644
--- a/addons/portal/i18n/cs.po
+++ b/addons/portal/i18n/cs.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
-"PO-Revision-Date: 2012-02-03 13:07+0000\n"
+"PO-Revision-Date: 2012-04-06 06:51+0000\n"
"Last-Translator: Jiří Hajda \n"
"Language-Team: Czech \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 07:09+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
"X-Poedit-Language: Czech\n"
#. module: portal
@@ -57,6 +57,8 @@ msgid ""
"Portal managers have access to the portal definitions, and can easily "
"configure the users, access rights and menus of portal users."
msgstr ""
+"Vedoucí portálu mají přístup k definici portálu a mohou snadno nastavit "
+"uživatel, přístupová práva a nabídky uživatelů portálu."
#. module: portal
#: help:res.portal,override_menu:0
@@ -99,6 +101,7 @@ msgstr "URL, kde uživatelé portálu se mohou připojit k serveru"
#: model:res.groups,comment:portal.group_portal_officer
msgid "Portal officers can create new portal users with the portal wizard."
msgstr ""
+"Úředníci portálu mohou vytvářet uživatele portálu pomocí průvodce portálu."
#. module: portal
#: help:res.portal.wizard,message:0
@@ -144,7 +147,7 @@ msgstr "Uživatelské jméno"
#. module: portal
#: help:res.portal,group_id:0
msgid "The group corresponding to this portal"
-msgstr ""
+msgstr "Skupina odpovídající tomuto portálu"
#. module: portal
#: model:ir.model,name:portal.model_res_portal_widget
@@ -369,7 +372,7 @@ msgstr ""
#. module: portal
#: model:res.groups,name:portal.group_portal_manager
msgid "Manager"
-msgstr ""
+msgstr "Vedoucí"
#. module: portal
#: help:res.portal.wizard.user,name:0
@@ -413,4 +416,4 @@ msgstr "Průvodce sdílením"
#. module: portal
#: model:res.groups,name:portal.group_portal_officer
msgid "Officer"
-msgstr ""
+msgstr "Úředník"
diff --git a/addons/product/product.py b/addons/product/product.py
index 0d5fa31ac11..70f6a0683d6 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -259,7 +259,7 @@ class product_template(osv.osv):
_description = "Product Template"
def _get_main_product_supplier(self, cr, uid, product, context=None):
- """Determines the main (best) product supplier for ``product``,
+ """Determines the main (best) product supplier for ``product``,
returning the corresponding ``supplierinfo`` record, or False
if none were found. The default strategy is to select the
supplier with the highest priority (i.e. smallest sequence).
@@ -503,6 +503,7 @@ class product_product(osv.osv):
_description = "Product"
_table = "product_product"
_inherits = {'product.template': 'product_tmpl_id'}
+ _inherit = ['mail.thread']
_order = 'default_code,name_template'
_columns = {
'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'),
@@ -526,7 +527,15 @@ class product_product(osv.osv):
'color': fields.integer('Color Index'),
'product_image': fields.binary('Image'),
}
-
+
+ def create(self, cr, uid, vals, context=None):
+ obj_id = super(product_product, self).create(cr, uid, vals, context=context)
+ self.create_send_note(cr, uid, [obj_id], context=context)
+ return obj_id
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ return self.message_append_note(cr, uid, ids, body=_("Product has been created."), context=context)
+
def unlink(self, cr, uid, ids, context=None):
unlink_ids = []
unlink_product_tmpl_ids = []
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index c99de86c5da..2a12fc9ad08 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -69,27 +69,26 @@
+
diff --git a/addons/project/project.py b/addons/project/project.py
index af21e679f30..0335b7cb540 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -53,6 +53,7 @@ class project(osv.osv):
_name = "project.project"
_description = "Project"
_inherits = {'account.analytic.account': "analytic_account_id"}
+ _inherit = ['ir.needaction_mixin', 'mail.thread']
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
if user == 1:
@@ -224,9 +225,7 @@ class project(osv.osv):
task_ids = task_obj.search(cr, uid, [('project_id', 'in', ids), ('state', 'not in', ('cancelled', 'done'))])
task_obj.write(cr, uid, task_ids, {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
self.write(cr, uid, ids, {'state':'close'}, context=context)
- for (id, name) in self.name_get(cr, uid, ids):
- message = _("The project '%s' has been closed.") % name
- self.log(cr, uid, id, message)
+ self.set_close_send_note(cr, uid, ids, context=context)
return True
def set_cancel(self, cr, uid, ids, context=None):
@@ -234,23 +233,24 @@ class project(osv.osv):
task_ids = task_obj.search(cr, uid, [('project_id', 'in', ids), ('state', '!=', 'done')])
task_obj.write(cr, uid, task_ids, {'state': 'cancelled', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
self.write(cr, uid, ids, {'state':'cancelled'}, context=context)
+ self.set_cancel_send_note(cr, uid, ids, context=context)
return True
def set_pending(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'pending'}, context=context)
+ self.set_pending_send_note(cr, uid, ids, context=context)
return True
def set_open(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'open'}, context=context)
+ self.set_open_send_note(cr, uid, ids, context=context)
return True
def reset_project(self, cr, uid, ids, context=None):
res = self.setActive(cr, uid, ids, value=True, context=context)
- for (id, name) in self.name_get(cr, uid, ids):
- message = _("The project '%s' has been opened.") % name
- self.log(cr, uid, id, message)
+ self.set_open_send_note(cr, uid, ids, context=context)
return res
-
+
def map_tasks(self, cr, uid, old_project_id, new_project_id, context=None):
""" copy and map tasks from old to new project """
if context is None:
@@ -260,7 +260,7 @@ class project(osv.osv):
proj = self.browse(cr, uid, old_project_id, context=context)
for task in proj.tasks:
map_task_id[task.id] = task_obj.copy(cr, uid, task.id, {}, context=context)
- self.write(cr, uid, new_project_id, {'tasks':[(6,0, map_task_id.values())]})
+ self.write(cr, uid, [new_project_id], {'tasks':[(6,0, map_task_id.values())]})
task_obj.duplicate_task(cr, uid, map_task_id, context=context)
return True
@@ -442,6 +442,50 @@ def Project():
'user_id': int(p.booked_resource[0].name[5:]),
}, context=context)
return True
+
+ # ------------------------------------------------
+ # OpenChatter methods and notifications
+ # ------------------------------------------------
+
+ def get_needaction_user_ids(self, cr, uid, ids, context=None):
+ result = dict.fromkeys(ids)
+ for obj in self.browse(cr, uid, ids, context=context):
+ result[obj.id] = []
+ if obj.state == 'draft' and obj.user_id:
+ result[obj.id] = [obj.user_id.id]
+ return result
+
+ def message_get_subscribers(self, cr, uid, ids, context=None):
+ sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.user_id:
+ sub_ids.append(obj.user_id.id)
+ return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
+
+ def create(self, cr, uid, vals, context=None):
+ obj_id = super(project, self).create(cr, uid, vals, context=context)
+ self.create_send_note(cr, uid, [obj_id], context=context)
+ return obj_id
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ return self.message_append_note(cr, uid, ids, body=_("Project has been created."), context=context)
+
+ def set_open_send_note(self, cr, uid, ids, context=None):
+ message = _("Project has been opened.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
+ def set_pending_send_note(self, cr, uid, ids, context=None):
+ message = _("Project is now pending.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
+ def set_cancel_send_note(self, cr, uid, ids, context=None):
+ message = _("Project has been cancelled.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
+ def set_close_send_note(self, cr, uid, ids, context=None):
+ message = _("Project has been closed.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
project()
class users(osv.osv):
@@ -456,6 +500,7 @@ class task(osv.osv):
_description = "Task"
_log_create = True
_date_name = "date_start"
+ _inherit = ['ir.needaction_mixin', 'mail.thread']
def _resolve_project_id_from_context(self, cr, uid, context=None):
@@ -844,8 +889,7 @@ class task(osv.osv):
if not task.date_end:
vals.update({ 'date_end':time.strftime('%Y-%m-%d %H:%M:%S')})
self.write(cr, uid, [task.id],vals, context=context)
- message = _("The task '%s' is done") % (task.name,)
- self.log(cr, uid, task.id, message)
+ self.do_close_send_note(cr, uid, [task.id], context)
return True
def do_reopen(self, cr, uid, ids, context=None):
@@ -865,6 +909,7 @@ class task(osv.osv):
}, context=context)
self.write(cr, uid, [task.id], {'state': 'open'}, context=context)
+ self.do_open_send_note(cr, uid, [task.id], context)
return True
def do_cancel(self, cr, uid, ids, context={}):
@@ -883,9 +928,8 @@ class task(osv.osv):
'ref_doc1': 'project.task,%d' % task.id,
'ref_doc2': 'project.project,%d' % project.id,
}, context=context)
- message = _("The task '%s' is cancelled.") % (task.name,)
- self.log(cr, uid, task.id, message)
self.write(cr, uid, [task.id], {'state': 'cancelled', 'remaining_hours':0.0}, context=context)
+ self.do_cancel_send_note(cr, uid, [task.id], context)
return True
def do_open(self, cr, uid, ids, context={}):
@@ -896,12 +940,12 @@ class task(osv.osv):
if not t.date_start:
data['date_start'] = time.strftime('%Y-%m-%d %H:%M:%S')
self.write(cr, uid, [t.id], data, context=context)
- message = _("The task '%s' is opened.") % (t.name,)
- self.log(cr, uid, t.id, message)
+ self.do_open_send_note(cr, uid, [t.id], context)
return True
def do_draft(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'draft'}, context=context)
+ self.do_draft_send_note(cr, uid, ids, context)
return True
@@ -912,7 +956,7 @@ class task(osv.osv):
for attachment_id in attachment_ids:
new_attachment_ids.append(attachment.copy(cr, uid, attachment_id, default={'res_id': delegated_task_id}, context=context))
return new_attachment_ids
-
+
def do_delegate(self, cr, uid, ids, delegate_data={}, context=None):
"""
@@ -940,20 +984,16 @@ class task(osv.osv):
'name': newname,
}, context=context)
if delegate_data['state'] == 'pending':
- self.do_pending(cr, uid, task.id, context=context)
+ self.do_pending(cr, uid, [task.id], context=context)
elif delegate_data['state'] == 'done':
- self.do_close(cr, uid, task.id, context=context)
-
- message = _("The task '%s' has been delegated to %s.") % (delegate_data['name'], delegate_data['user_id'][1])
- self.log(cr, uid, task.id, message)
+ self.do_close(cr, uid, [task.id], context=context)
+ self.do_delegation_send_note(cr, uid, [task.id], context)
delegated_tasks[task.id] = delegated_task_id
return delegated_tasks
def do_pending(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'pending'}, context=context)
- for (id, name) in self.name_get(cr, uid, ids):
- message = _("The task '%s' is pending.") % name
- self.log(cr, uid, id, message)
+ self.do_pending_send_note(cr, uid, ids, context)
return True
def set_remaining_time(self, cr, uid, ids, remaining_time=1.0, context=None):
@@ -984,7 +1024,7 @@ class task(osv.osv):
def set_kanban_state_done(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'done'}, context=context)
- def _change_type(self, cr, uid, ids, next, *args):
+ def _change_type(self, cr, uid, ids, next, context=None):
"""
go to the next stage
if next is False, go to previous stage
@@ -1005,13 +1045,14 @@ class task(osv.osv):
elif typeid and typeid in sorted_types and sorted_types.index(typeid) != len(sorted_types)-1:
index = sorted_types.index(typeid)
self.write(cr, uid, task.id, {'type_id': sorted_types[index+1]})
+ self.state_change_send_note(cr, uid, [task.id], context)
return True
- def next_type(self, cr, uid, ids, *args):
- return self._change_type(cr, uid, ids, True, *args)
+ def next_type(self, cr, uid, ids, context=None):
+ return self._change_type(cr, uid, ids, True, context=context)
- def prev_type(self, cr, uid, ids, *args):
- return self._change_type(cr, uid, ids, False, *args)
+ def prev_type(self, cr, uid, ids, context=None):
+ return self._change_type(cr, uid, ids, False, context=context)
def _store_history(self, cr, uid, ids, context=None):
for task in self.browse(cr, uid, ids, context=context):
@@ -1028,9 +1069,10 @@ class task(osv.osv):
return True
def create(self, cr, uid, vals, context=None):
- result = super(task, self).create(cr, uid, vals, context=context)
- self._store_history(cr, uid, [result], context=context)
- return result
+ task_id = super(task, self).create(cr, uid, vals, context=context)
+ self._store_history(cr, uid, [task_id], context=context)
+ self.create_send_note(cr, uid, [task_id], context=context)
+ return task_id
# Overridden to reset the kanban_state to normal whenever
# the stage (type_id) of the task changes.
@@ -1041,13 +1083,14 @@ class task(osv.osv):
new_stage = vals.get('type_id')
vals_reset_kstate = dict(vals, kanban_state='normal')
for t in self.browse(cr, uid, ids, context=context):
- write_vals = vals_reset_kstate if t.type_id != new_stage else vals
+ write_vals = vals_reset_kstate if t.type_id != new_stage else vals
super(task,self).write(cr, uid, [t.id], write_vals, context=context)
result = True
else:
result = super(task,self).write(cr, uid, ids, vals, context=context)
if ('type_id' in vals) or ('remaining_hours' in vals) or ('user_id' in vals) or ('state' in vals) or ('kanban_state' in vals):
self._store_history(cr, uid, ids, context=context)
+ self.state_change_send_note(cr, uid, ids, context)
return result
def unlink(self, cr, uid, ids, context=None):
@@ -1083,6 +1126,62 @@ class task(osv.osv):
result += "\n"
return result
+
+ # ---------------------------------------------------
+ # OpenChatter methods and notifications
+ # ---------------------------------------------------
+
+ def get_needaction_user_ids(self, cr, uid, ids, context=None):
+ result = dict.fromkeys(ids, [])
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.state == 'draft' and obj.user_id:
+ result[obj.id] = [obj.user_id.id]
+ return result
+
+ def message_get_subscribers(self, cr, uid, ids, context=None):
+ sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.user_id:
+ sub_ids.append(obj.user_id.id)
+ if obj.manager_id:
+ sub_ids.append(obj.manager_id.id)
+ return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ return self.message_append_note(cr, uid, ids, body=_("Task has been created."), context=context)
+
+ def do_pending_send_note(self, cr, uid, ids, context=None):
+ if not isinstance(ids,list): ids = [ids]
+ msg = _('Task is now pending.')
+ return self.message_append_note(cr, uid, ids, body=msg, context=context)
+
+ def do_open_send_note(self, cr, uid, ids, context=None):
+ msg = _('Task has been opened.')
+ return self.message_append_note(cr, uid, ids, body=msg, context=context)
+
+ def do_cancel_send_note(self, cr, uid, ids, context=None):
+ msg = _('Task has been canceled.')
+ return self.message_append_note(cr, uid, ids, body=msg, context=context)
+
+ def do_close_send_note(self, cr, uid, ids, context=None):
+ msg = _('Task has been closed.')
+ return self.message_append_note(cr, uid, ids, body=msg, context=context)
+
+ def do_draft_send_note(self, cr, uid, ids, context=None):
+ msg = _('Task has been renewed.')
+ return self.message_append_note(cr, uid, ids, body=msg, context=context)
+
+ def do_delegation_send_note(self, cr, uid, ids, context=None):
+ for task in self.browse(cr, uid, ids, context=context):
+ msg = _('Task has been delegated to %s.') % (task.user_id.name)
+ self.message_append_note(cr, uid, [task.id], body=msg, context=context)
+ return True
+
+ def state_change_send_note(self, cr, uid, ids, context=None):
+ for task in self.browse(cr, uid, ids, context=context):
+ msg = _('Stage changed to %s') % (task.type_id.name)
+ self.message_append_note(cr, uid, [task.id], body=msg, context=context)
+ return True
task()
@@ -1178,7 +1277,7 @@ class project_task_history(osv.osv):
for history in self.browse(cr, uid, ids, context=context):
cr.execute('''select
id
- from
+ from
project_task_history
where
task_id=%s and
@@ -1234,4 +1333,3 @@ class project_task_history_cumulative(osv.osv):
)
""")
project_task_history_cumulative()
-
diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml
index 28d451b9ee0..2f8c9e9638a 100644
--- a/addons/project/project_demo.xml
+++ b/addons/project/project_demo.xml
@@ -190,7 +190,7 @@
-
+
@@ -202,7 +202,7 @@
-
+
@@ -214,7 +214,7 @@
-
+
@@ -249,7 +249,7 @@
Test on Runbot
-
+
@@ -260,7 +260,7 @@
Deploy and Review on Customer System
-
+
@@ -328,7 +328,7 @@
BoM, After sales returns, interventions. Traceability.
Specific adaptation to MRP
-
+
16.0
@@ -338,7 +338,7 @@
Data importation + Doc
-
+
16.0
@@ -348,7 +348,7 @@
Modifications asked by the customer.
-
+
16.0
@@ -380,7 +380,7 @@
Analysis, Data Importation
-
+
20
@@ -391,7 +391,7 @@
Parameters
-
+
20
@@ -405,8 +405,9 @@
-
-
+
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 95538513f0c..7010031001c 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -96,6 +96,7 @@
+
@@ -290,12 +291,7 @@
-
-
-
-
-
-
+
@@ -308,6 +304,7 @@
+
diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py
index 408ef10cb78..e61af235d42 100644
--- a/addons/project_issue/project_issue.py
+++ b/addons/project_issue/project_issue.py
@@ -46,45 +46,7 @@ class project_issue(crm.crm_case, osv.osv):
_name = "project.issue"
_description = "Project Issue"
_order = "priority, create_date desc"
- _inherit = ['mail.thread']
-
- def write(self, cr, uid, ids, vals, context=None):
- #Update last action date everytime the user change the stage, the state or send a new email
- logged_fields = ['type_id', 'state', 'message_ids']
- if any([field in vals for field in logged_fields]):
- vals['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
- return super(project_issue, self).write(cr, uid, ids, vals, context)
-
- def case_open(self, cr, uid, ids, *args):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case's Ids
- @param *args: Give Tuple Value
- """
-
- res = super(project_issue, self).case_open(cr, uid, ids, *args)
- self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'), 'user_id' : uid})
- for (id, name) in self.name_get(cr, uid, ids):
- message = _("Issue '%s' has been opened.") % name
- self.log(cr, uid, id, message)
- return res
-
- def case_close(self, cr, uid, ids, *args):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case's Ids
- @param *args: Give Tuple Value
- """
-
- res = super(project_issue, self).case_close(cr, uid, ids, *args)
- for (id, name) in self.name_get(cr, uid, ids):
- message = _("Issue '%s' has been closed.") % name
- self.log(cr, uid, id, message)
- return res
+ _inherit = ['ir.needaction_mixin', 'mail.thread']
def _compute_day(self, cr, uid, ids, fields, args, context=None):
"""
@@ -112,7 +74,8 @@ class project_issue(crm.crm_case, osv.osv):
ans = date_open - date_create
date_until = issue.date_open
#Calculating no. of working hours to open the issue
- hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
+ if issue.project_id.resource_calendar_id:
+ hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
date_create,
date_open)
elif field in ['working_hours_close','day_close']:
@@ -121,7 +84,8 @@ class project_issue(crm.crm_case, osv.osv):
date_until = issue.date_closed
ans = date_close - date_create
#Calculating no. of working hours to close the issue
- hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
+ if issue.project_id.resource_calendar_id:
+ hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
date_create,
date_close)
elif field in ['days_since_creation']:
@@ -166,6 +130,25 @@ class project_issue(crm.crm_case, osv.osv):
return res
+ def _hours_get(self, cr, uid, ids, field_names, args, context=None):
+ task_pool = self.pool.get('project.task')
+ res = {}
+ for issue in self.browse(cr, uid, ids, context=context):
+ progress = 0.0
+ if issue.task_id:
+ progress = task_pool._hours_get(cr, uid, [issue.task_id.id], field_names, args, context=context)[issue.task_id.id]['progress']
+ res[issue.id] = {'progress' : progress}
+ return res
+
+ def _get_project(self, cr, uid, context=None):
+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
+ if user.context_project_id:
+ return user.context_project_id.id
+ return False
+
+ def on_change_project(self, cr, uid, ids, project_id, context=None):
+ return {}
+
def _get_issue_task(self, cr, uid, ids, context=None):
issues = []
issue_pool = self.pool.get('project.issue')
@@ -181,16 +164,6 @@ class project_issue(crm.crm_case, osv.osv):
issues += issue_pool.search(cr, uid, [('task_id','=',work.task_id.id)])
return issues
- def _hours_get(self, cr, uid, ids, field_names, args, context=None):
- task_pool = self.pool.get('project.task')
- res = {}
- for issue in self.browse(cr, uid, ids, context=context):
- progress = 0.0
- if issue.task_id:
- progress = task_pool._hours_get(cr, uid, [issue.task_id.id], field_names, args, context=context)[issue.task_id.id]['progress']
- res[issue.id] = {'progress' : progress}
- return res
-
_columns = {
'id': fields.integer('ID', readonly=True),
'name': fields.char('Issue', size=128, required=True),
@@ -249,15 +222,6 @@ class project_issue(crm.crm_case, osv.osv):
}),
}
- def _get_project(self, cr, uid, context=None):
- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
- if user.context_project_id:
- return user.context_project_id.id
- return False
-
- def on_change_project(self, cr, uid, ids, project_id, context=None):
- return {}
-
_defaults = {
'active': 1,
@@ -287,14 +251,13 @@ class project_issue(crm.crm_case, osv.osv):
return self.set_priority(cr, uid, ids, '3')
def convert_issue_task(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+
case_obj = self.pool.get('project.issue')
data_obj = self.pool.get('ir.model.data')
task_obj = self.pool.get('project.task')
-
-
- if context is None:
- context = {}
-
+
result = data_obj._get_id(cr, uid, 'project', 'view_task_search_form')
res = data_obj.read(cr, uid, result, ['res_id'])
id2 = data_obj._get_id(cr, uid, 'project', 'view_task_form2')
@@ -316,12 +279,13 @@ class project_issue(crm.crm_case, osv.osv):
'user_id': bug.user_id.id,
'planned_hours': 0.0,
})
-
vals = {
'task_id': new_task_id,
'state':'pending'
}
- case_obj.write(cr, uid, [bug.id], vals)
+ self.convert_to_task_send_note(cr, uid, [bug.id], context=context)
+ case_obj.write(cr, uid, [bug.id], vals, context=context)
+ self.case_pending_send_note(cr, uid, [bug.id], context=context)
return {
'name': _('Tasks'),
@@ -353,28 +317,38 @@ class project_issue(crm.crm_case, osv.osv):
def convert_to_bug(self, cr, uid, ids, context=None):
return self._convert(cr, uid, ids, 'bug_categ', context=context)
- def next_type(self, cr, uid, ids, *args):
+ def next_type(self, cr, uid, ids, context=None):
for task in self.browse(cr, uid, ids):
typeid = task.type_id.id
types = map(lambda x:x.id, task.project_id.type_ids or [])
if types:
if not typeid:
- self.write(cr, uid, task.id, {'type_id': types[0]})
+ self.write(cr, uid, [task.id], {'type_id': types[0]})
elif typeid and typeid in types and types.index(typeid) != len(types)-1 :
index = types.index(typeid)
- self.write(cr, uid, task.id, {'type_id': types[index+1]})
+ self.write(cr, uid, [task.id], {'type_id': types[index+1]})
return True
- def prev_type(self, cr, uid, ids, *args):
+ def prev_type(self, cr, uid, ids, context=None):
for task in self.browse(cr, uid, ids):
typeid = task.type_id.id
types = map(lambda x:x.id, task.project_id and task.project_id.type_ids or [])
if types:
if typeid and typeid in types:
index = types.index(typeid)
- self.write(cr, uid, task.id, {'type_id': index and types[index-1] or False})
+ self.write(cr, uid, [task.id], {'type_id': index and types[index-1] or False})
return True
+ def write(self, cr, uid, ids, vals, context=None):
+ #Update last action date every time the user change the stage, the state or send a new email
+ logged_fields = ['type_id', 'state', 'message_ids']
+ if any([field in vals for field in logged_fields]):
+ vals['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
+ if vals.get('type_id', False):
+ stage = self.pool.get('project.task.type').browse(cr, uid, vals['type_id'], context=context)
+ self.message_append_note(cr, uid, ids, body=_("Stage changed to %s.") % stage.name, context=context)
+ return super(project_issue, self).write(cr, uid, ids, vals, context)
+
def onchange_task_id(self, cr, uid, ids, task_id, context=None):
result = {}
if not task_id:
@@ -382,14 +356,24 @@ class project_issue(crm.crm_case, osv.osv):
task = self.pool.get('project.task').browse(cr, uid, task_id, context=context)
return {'value':{'user_id': task.user_id.id,}}
- def case_escalate(self, cr, uid, ids, *args):
- """Escalates case to top level
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of case Ids
- @param *args: Tuple Value for additional Params
+ def case_reset(self, cr, uid, ids, context=None):
+ """Resets case as draft
"""
+ res = super(project_issue, self).case_reset(cr, uid, ids, context)
+ self.write(cr, uid, ids, {'date_open': False, 'date_closed': False})
+ return res
+
+ def create(self, cr, uid, vals, context=None):
+ obj_id = super(project_issue, self).create(cr, uid, vals, context=context)
+ self.create_send_note(cr, uid, [obj_id], context=context)
+ return obj_id
+
+ def case_open(self, cr, uid, ids, context=None):
+ res = super(project_issue, self).case_open(cr, uid, ids, context)
+ self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'), 'user_id' : uid})
+ return res
+
+ def case_escalate(self, cr, uid, ids, context=None):
cases = self.browse(cr, uid, ids)
for case in cases:
data = {'state' : 'draft'}
@@ -402,7 +386,7 @@ class project_issue(crm.crm_case, osv.osv):
else:
raise osv.except_osv(_('Warning !'), _('You cannot escalate this issue.\nThe relevant Project has not configured the Escalation Project!'))
self.write(cr, uid, [case.id], data)
- self.message_append(cr, uid, cases, _('Escalate'))
+ self.case_escalate_send_note(cr, uid, [case.id], context)
return True
def message_new(self, cr, uid, msg, custom_values=None, context=None):
@@ -434,7 +418,6 @@ class project_issue(crm.crm_case, osv.osv):
return res_id
def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None):
-
if vals is None:
vals = {}
@@ -479,6 +462,45 @@ class project_issue(crm.crm_case, osv.osv):
default['name'] = issue['name'] + _(' (copy)')
return super(project_issue, self).copy(cr, uid, id, default=default,
context=context)
+
+ # -------------------------------------------------------
+ # OpenChatter methods and notifications
+ # -------------------------------------------------------
+
+ def get_needaction_user_ids(self, cr, uid, ids, context=None):
+ result = dict.fromkeys(ids, [])
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.state == 'draft' and obj.user_id:
+ result[obj.id] = [obj.user_id.id]
+ return result
+
+ def message_get_subscribers(self, cr, uid, ids, context=None):
+ sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.user_id:
+ sub_ids.append(obj.user_id.id)
+ return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
+
+ def case_get_note_msg_prefix(self, cr, uid, id, context=None):
+ return 'Project issue '
+
+ def convert_to_task_send_note(self, cr, uid, ids, context=None):
+ message = _("Project issue has been converted in to task.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ message = _("Project issue has been created.")
+ return self.message_append_note(cr, uid, ids, body=message, context=context)
+
+ def case_escalate_send_note(self, cr, uid, ids, context=None):
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.project_id:
+ message = _("has been escalated to '%s'.") % (obj.project_id.name)
+ obj.message_append_note(body=message, context=context)
+ else:
+ message = _("has been escalated.")
+ obj.message_append_note(body=message, context=context)
+ return True
project_issue()
@@ -490,11 +512,11 @@ class project(osv.osv):
}
def _check_escalation(self, cr, uid, ids, context=None):
- project_obj = self.browse(cr, uid, ids[0], context=context)
- if project_obj.project_escalation_id:
- if project_obj.project_escalation_id.id == project_obj.id:
- return False
- return True
+ project_obj = self.browse(cr, uid, ids[0], context=context)
+ if project_obj.project_escalation_id:
+ if project_obj.project_escalation_id.id == project_obj.id:
+ return False
+ return True
_constraints = [
(_check_escalation, 'Error! You cannot assign escalation to the same project!', ['project_escalation_id'])
diff --git a/addons/project_issue/project_issue_menu.xml b/addons/project_issue/project_issue_menu.xml
index ea52d4c06d9..dd61992a555 100644
--- a/addons/project_issue/project_issue_menu.xml
+++ b/addons/project_issue/project_issue_menu.xml
@@ -1,6 +1,7 @@
+
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml
index df0797da6bb..cb532f4af38 100644
--- a/addons/project_issue/project_issue_view.xml
+++ b/addons/project_issue/project_issue_view.xml
@@ -54,7 +54,12 @@
-
+
+
+
+
@@ -91,41 +96,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -133,13 +106,14 @@
-
-
-
-
+
+
+
+
+
diff --git a/addons/project_mailgate/i18n/cs.po b/addons/project_mailgate/i18n/cs.po
new file mode 100644
index 00000000000..4f6517861e1
--- /dev/null
+++ b/addons/project_mailgate/i18n/cs.po
@@ -0,0 +1,78 @@
+# Czech 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:37+0000\n"
+"PO-Revision-Date: 2012-04-06 06:41+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: project_mailgate
+#: view:project.task:0
+msgid "History Information"
+msgstr "Informace historie"
+
+#. module: project_mailgate
+#: model:ir.model,name:project_mailgate.model_project_task
+msgid "Task"
+msgstr "Úkol"
+
+#. module: project_mailgate
+#: constraint:project.task:0
+msgid "Error ! You cannot create recursive tasks."
+msgstr "Chyba ! Nemůžete vytvořit rekurzivní úkoly."
+
+#. module: project_mailgate
+#: field:project.task,message_ids:0
+msgid "Messages"
+msgstr "Zprávy"
+
+#. module: project_mailgate
+#: code:addons/project_mailgate/project_mailgate.py:90
+#, python-format
+msgid "Draft"
+msgstr "Koncept"
+
+#. module: project_mailgate
+#: constraint:project.task:0
+msgid "Error ! Task end-date must be greater then task start-date"
+msgstr "Chyba ! Datum ukončení úkolu musí být větší než počáteční datum"
+
+#. module: project_mailgate
+#: code:addons/project_mailgate/project_mailgate.py:116
+#, python-format
+msgid "Cancel"
+msgstr "Zrušit"
+
+#. module: project_mailgate
+#: code:addons/project_mailgate/project_mailgate.py:110
+#, python-format
+msgid "Done"
+msgstr "Dokončené"
+
+#. module: project_mailgate
+#: code:addons/project_mailgate/project_mailgate.py:96
+#, python-format
+msgid "Open"
+msgstr "Otevřené"
+
+#. module: project_mailgate
+#: code:addons/project_mailgate/project_mailgate.py:102
+#, python-format
+msgid "Pending"
+msgstr "Čekající"
+
+#. module: project_mailgate
+#: view:project.task:0
+msgid "History"
+msgstr "Historie"
diff --git a/addons/project_mrp/i18n/cs.po b/addons/project_mrp/i18n/cs.po
index 965536190b6..7764b0cb120 100644
--- a/addons/project_mrp/i18n/cs.po
+++ b/addons/project_mrp/i18n/cs.po
@@ -7,20 +7,20 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2011-09-05 06:12+0000\n"
+"PO-Revision-Date: 2012-04-06 04:53+0000\n"
"Last-Translator: Jiří Hajda \n"
"Language-Team: Czech \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:35+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
"X-Poedit-Language: Czech\n"
#. module: project_mrp
#: sql_constraint:sale.order:0
msgid "Order Reference must be unique per Company!"
-msgstr ""
+msgstr "Odkaz obědnávky musí být jedinečný na společnost!"
#. module: project_mrp
#: model:process.node,note:project_mrp.process_node_procuretasktask0
@@ -35,12 +35,12 @@ msgstr "Úloha zásobování"
#. module: project_mrp
#: model:ir.model,name:project_mrp.model_sale_order
msgid "Sales Order"
-msgstr ""
+msgstr "Prodejní objednávka"
#. module: project_mrp
#: field:procurement.order,sale_line_id:0
msgid "Sale order line"
-msgstr ""
+msgstr "Řádek prodejní objednávky"
#. module: project_mrp
#: model:process.transition,note:project_mrp.process_transition_createtask0
@@ -55,7 +55,7 @@ msgstr "pokud je typ 'služba', pak vytvoří úkol."
#. module: project_mrp
#: constraint:project.task:0
msgid "Error ! Task end-date must be greater then task start-date"
-msgstr ""
+msgstr "Chyba ! Datum ukončení úkolu musí být větší než počáteční datum"
#. module: project_mrp
#: model:process.node,name:project_mrp.process_node_saleordertask0
@@ -125,7 +125,7 @@ msgstr "V případě, kdy prodáváte služby pomocí prodejního příkazu"
#. module: project_mrp
#: field:project.task,sale_line_id:0
msgid "Sale Order Line"
-msgstr ""
+msgstr "Řádek prodejní objednávky"
#~ msgid "Procurement and Project Management integration"
#~ msgstr "Integrace zásobování a projektového řízení"
diff --git a/addons/project_retro_planning/i18n/cs.po b/addons/project_retro_planning/i18n/cs.po
index 94c289695c0..3949bbf8f3f 100644
--- a/addons/project_retro_planning/i18n/cs.po
+++ b/addons/project_retro_planning/i18n/cs.po
@@ -7,29 +7,29 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2009-11-17 10:19+0000\n"
-"Last-Translator: Kuvaly [LCT] \n"
+"PO-Revision-Date: 2012-04-06 04:52+0000\n"
+"Last-Translator: Jiří Hajda \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:51+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
#. module: project_retro_planning
#: model:ir.model,name:project_retro_planning.model_project_project
msgid "Project"
-msgstr ""
+msgstr "Projekt"
#. module: project_retro_planning
#: constraint:project.project:0
msgid "Error! project start-date must be lower then project end-date."
-msgstr ""
+msgstr "Chyba! Počáteční datum projektu musí být menší než datum ukončení."
#. module: project_retro_planning
#: constraint:project.project:0
msgid "Error! You cannot assign escalation to the same project!"
-msgstr ""
+msgstr "Chyba! Nemůžete přiřadit stupňování ke stejnému projektu!"
#~ msgid "Project Retro planning"
#~ msgstr "Projekt retro plánování"
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 79d71f2c2cc..e0c64b5d2a1 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -220,9 +220,16 @@ class purchase_order(osv.osv):
('name_uniq', 'unique(name, company_id)', 'Order Reference must be unique per Company!'),
]
_name = "purchase.order"
+ _inherit = ['ir.needaction_mixin', 'mail.thread']
_description = "Purchase Order"
_order = "name desc"
-
+
+ def create(self, cr, uid, vals, context=None):
+ order = super(purchase_order, self).create(cr, uid, vals, context=context)
+ if order:
+ self.create_send_note(cr, uid, [order], context=context)
+ return order
+
def unlink(self, cr, uid, ids, context=None):
purchase_orders = self.read(cr, uid, ids, ['state'], context=context)
unlink_ids = []
@@ -289,6 +296,7 @@ class purchase_order(osv.osv):
self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context)
for id in ids:
self.write(cr, uid, [id], {'state' : 'confirmed', 'validator' : uid})
+ self.confirm_send_note(cr, uid, ids, context)
return True
def _prepare_inv_line(self, cr, uid, account_id, order_line, context=None):
@@ -388,8 +396,15 @@ class purchase_order(osv.osv):
# Link this new invoice to related purchase order
order.write({'invoice_ids': [(4, inv_id)]}, context=context)
res = inv_id
+ if res:
+ self.invoice_send_note(cr, uid, ids, res, context)
return res
-
+
+ def invoice_done(self, cr, uid, ids, context=None):
+ self.write(cr, uid, ids, {'state':'approved'}, context=context)
+ self.invoice_done_send_note(cr, uid, ids, context=context)
+ return True
+
def has_stockable_product(self,cr, uid, ids, *args):
for order in self.browse(cr, uid, ids):
for order_line in order.order_line:
@@ -502,8 +517,15 @@ class purchase_order(osv.osv):
# In case of multiple (split) pickings, we should return the ID of the critical one, i.e. the
# one that should trigger the advancement of the purchase workflow.
# By default we will consider the first one as most important, but this behavior can be overridden.
+ if picking_ids:
+ self.shipment_send_note(cr, uid, ids, picking_ids[0], context=context)
return picking_ids[0] if picking_ids else False
+ def picking_done(self, cr, uid, ids, context=None):
+ self.write(cr, uid, ids, {'shipped':1,'state':'approved'}, context=context)
+ self.shipment_done_send_note(cr, uid, ids, context=context)
+ return True
+
def copy(self, cr, uid, id, default=None, context=None):
if not default:
default = {}
@@ -627,6 +649,46 @@ class purchase_order(osv.osv):
wf_service.trg_redirect(uid, 'purchase.order', old_id, neworder_id, cr)
wf_service.trg_validate(uid, 'purchase.order', old_id, 'purchase_cancel', cr)
return orders_info
+
+ # --------------------------------------
+ # OpenChatter methods and notifications
+ # --------------------------------------
+
+ def get_needaction_user_ids(self, cr, uid, ids, context=None):
+ result = dict.fromkeys(ids, [])
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.state == 'approved':
+ result[obj.id] = [obj.validator.id]
+ return result
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ return self.message_append_note(cr, uid, ids, body=_("Request for quotation created."), context=context)
+
+ def confirm_send_note(self, cr, uid, ids, context=None):
+ for obj in self.browse(cr, uid, ids, context=context):
+ self.message_subscribe(cr, uid, [obj.id], [obj.validator.id], context=context)
+ self.message_append_note(cr, uid, [obj.id], body=_("Quotation for %s converted to a Purchase Order of %s %s.") % (obj.partner_id.name, obj.amount_total, obj.pricelist_id.currency_id.symbol), context=context)
+
+ def shipment_send_note(self, cr, uid, ids, picking_id, context=None):
+ for order in self.browse(cr, uid, ids, context=context):
+ for picking in (pck for pck in order.picking_ids if pck.id == picking_id):
+ pck_date = datetime.strptime(picking.min_date, '%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y')
+ self.message_append_note(cr, uid, [order.id], body=_("Shipment %s scheduled for %s.") % (picking.name, pck_date), context=context)
+
+ def invoice_send_note(self, cr, uid, ids, invoice_id, context=None):
+ for order in self.browse(cr, uid, ids, context=context):
+ for invoice in (inv for inv in order.invoice_ids if inv.id == invoice_id):
+ self.message_append_note(cr, uid, [order.id], body=_("Draft Invoice of %s %s is waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), context=context)
+
+ def shipment_done_send_note(self, cr, uid, ids, context=None):
+ self.message_append_note(cr, uid, ids, body=_("""Shipment received."""), context=context)
+
+ def invoice_done_send_note(self, cr, uid, ids, context=None):
+ self.message_append_note(cr, uid, ids, body=_("Invoice paid."), context=context)
+
+ def cancel_send_note(self, cr, uid, ids, context=None):
+ for obj in self.browse(cr, uid, ids, context=context):
+ self.message_append_note(cr, uid, [obj.id], body=_("Purchase Order for %s cancelled.") % (obj.partner_id.name), context=context)
purchase_order()
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index 4d761f2742e..b1511139102 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -206,6 +206,7 @@
+
diff --git a/addons/purchase/purchase_workflow.xml b/addons/purchase/purchase_workflow.xml
index c978712c0a1..b26363a02f2 100644
--- a/addons/purchase/purchase_workflow.xml
+++ b/addons/purchase/purchase_workflow.xml
@@ -55,7 +55,7 @@
invoice_done
- write({'state':'approved'})
+ invoice_done()
function
@@ -72,7 +72,7 @@
picking_done
- write({'shipped':1,'state':'approved'})
+ picking_done()
function
subflow.delivery_done
diff --git a/addons/purchase_analytic_plans/i18n/cs.po b/addons/purchase_analytic_plans/i18n/cs.po
index 40fabb0ea94..36968f51af3 100644
--- a/addons/purchase_analytic_plans/i18n/cs.po
+++ b/addons/purchase_analytic_plans/i18n/cs.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2009-11-17 10:15+0000\n"
-"Last-Translator: Kuvaly [LCT] \n"
+"PO-Revision-Date: 2012-04-06 04:51+0000\n"
+"Last-Translator: Jiří Hajda \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 05:58+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
#. module: purchase_analytic_plans
#: field:purchase.order.line,analytics_id:0
@@ -24,17 +24,17 @@ msgstr "Analytická distribuce"
#. module: purchase_analytic_plans
#: sql_constraint:purchase.order:0
msgid "Order Reference must be unique per Company!"
-msgstr ""
+msgstr "Odkaz obědnávky musí být jedinečný na společnost!"
#. module: purchase_analytic_plans
#: model:ir.model,name:purchase_analytic_plans.model_purchase_order_line
msgid "Purchase Order Line"
-msgstr ""
+msgstr "Řádek nákupní objednávky"
#. module: purchase_analytic_plans
#: model:ir.model,name:purchase_analytic_plans.model_purchase_order
msgid "Purchase Order"
-msgstr ""
+msgstr "Nákupní objednávka"
#~ msgid "Invalid XML for View Architecture!"
#~ msgstr "Invalidní XML pro zobrazení architektury!"
diff --git a/addons/resource/i18n/cs.po b/addons/resource/i18n/cs.po
index 469162aa292..997d85063a0 100644
--- a/addons/resource/i18n/cs.po
+++ b/addons/resource/i18n/cs.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2011-09-06 06:16+0000\n"
+"PO-Revision-Date: 2012-04-06 05:18+0000\n"
"Last-Translator: Jiří Hajda \n"
"Language-Team: Czech \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:57+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
"X-Poedit-Language: Czech\n"
#. module: resource
@@ -94,6 +94,7 @@ msgstr "Zdroje"
#, python-format
msgid "Make sure the Working time has been configured with proper week days!"
msgstr ""
+"Ujistěte se, že pracovní doba byla nastavena se správnými dny v týdnu!"
#. module: resource
#: field:resource.calendar,manager:0
@@ -249,6 +250,8 @@ msgid ""
"Define working hours and time table that could be scheduled to your project "
"members"
msgstr ""
+"Určuje pracovní hodiny a časovou tabulku, která může být naplánována vašim "
+"členům projektu"
#. module: resource
#: help:resource.resource,user_id:0
@@ -263,7 +266,7 @@ msgstr "Určit plánování zdroje"
#. module: resource
#: view:resource.calendar.leaves:0
msgid "Starting Date of Leave"
-msgstr ""
+msgstr "Počáteční datum uvolnění"
#. module: resource
#: field:resource.resource,code:0
@@ -335,7 +338,7 @@ msgstr "(dovolená)"
#: code:addons/resource/resource.py:392
#, python-format
msgid "Configuration Error!"
-msgstr ""
+msgstr "Chyba nastavení!"
#. module: resource
#: selection:resource.resource,resource_type:0
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 2b9032d87f8..5ba6824fe19 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -48,7 +48,9 @@ sale_shop()
class sale_order(osv.osv):
_name = "sale.order"
+ _inherit = ['ir.needaction_mixin', 'mail.thread']
_description = "Sales Order"
+
def copy(self, cr, uid, id, default=None, context=None):
if not default:
@@ -307,7 +309,7 @@ class sale_order(osv.osv):
v['pricelist_id'] = shop.pricelist_id.id
return {'value': v}
- def action_cancel_draft(self, cr, uid, ids, *args):
+ def action_cancel_draft(self, cr, uid, ids, context=None):
if not len(ids):
return False
cr.execute('select id from sale_order_line where order_id IN %s and state=%s', (tuple(ids), 'cancel'))
@@ -319,9 +321,7 @@ class sale_order(osv.osv):
# Deleting the existing instance of workflow for SO
wf_service.trg_delete(uid, 'sale.order', inv_id, cr)
wf_service.trg_create(uid, 'sale.order', inv_id, cr)
- for (id,name) in self.name_get(cr, uid, ids):
- message = _("The sales order '%s' has been set in draft state.") %(name,)
- self.log(cr, uid, id, message)
+ self.action_cancel_draft_send_note(cr, uid, ids, context=context)
return True
def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, order_lines, context={}):
@@ -388,7 +388,10 @@ class sale_order(osv.osv):
vals.update({'invoice_quantity': 'order'})
if vals['order_policy'] == 'picking':
vals.update({'invoice_quantity': 'procurement'})
- return super(sale_order, self).create(cr, uid, vals, context=context)
+ order = super(sale_order, self).create(cr, uid, vals, context=context)
+ if order:
+ self.create_send_note(cr, uid, [order], context=context)
+ return order
def button_dummy(self, cr, uid, ids, context=None):
return True
@@ -551,6 +554,8 @@ class sale_order(osv.osv):
if order.order_policy == 'picking':
picking_obj.write(cr, uid, map(lambda x: x.id, order.picking_ids), {'invoice_state': 'invoiced'})
cr.execute('insert into sale_order_invoice_rel (order_id,invoice_id) values (%s,%s)', (order.id, res))
+ if res:
+ self.invoice_send_note(cr, uid, ids, res, context)
return res
def action_invoice_cancel(self, cr, uid, ids, context=None):
@@ -635,8 +640,7 @@ class sale_order(osv.osv):
wf_service.trg_validate(uid, 'account.invoice', inv, 'invoice_cancel', cr)
sale_order_line_obj.write(cr, uid, [l.id for l in sale.order_line],
{'state': 'cancel'})
- message = _("The sales order '%s' has been cancelled.") % (sale.name,)
- self.log(cr, uid, sale.id, message)
+ self.cancel_send_note(cr, uid, [sale.id], context=None)
self.write(cr, uid, ids, {'state': 'cancel'})
return True
@@ -649,8 +653,7 @@ class sale_order(osv.osv):
else:
self.write(cr, uid, [o.id], {'state': 'progress', 'date_confirm': fields.date.context_today(self, cr, uid, context=context)})
self.pool.get('sale.order.line').button_confirm(cr, uid, [x.id for x in o.order_line])
- message = _("The quotation '%s' has been converted to a sales order.") % (o.name,)
- self.log(cr, uid, o.id, message)
+ self.confirm_send_note(cr, uid, ids, context)
return True
def procurement_lines_get(self, cr, uid, ids, *args):
@@ -835,6 +838,8 @@ class sale_order(osv.osv):
wf_service = netsvc.LocalService("workflow")
if picking_id:
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
+ self.delivery_send_note(cr, uid, [order.id], picking_id, context)
+
for proc_id in proc_ids:
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
@@ -873,7 +878,9 @@ class sale_order(osv.osv):
towrite.append(line.id)
if towrite:
self.pool.get('sale.order.line').write(cr, uid, towrite, {'state': 'done'}, context=context)
- self.write(cr, uid, [order.id], val)
+ res = self.write(cr, uid, [order.id], val)
+ if res:
+ self.delivery_end_send_note(cr, uid, [order.id], context=context)
return True
def _log_event(self, cr, uid, ids, factor=0.7, name='Open Order'):
@@ -905,6 +912,52 @@ class sale_order(osv.osv):
if order_line.product_id and order_line.product_id.product_tmpl_id.type in ('product', 'consu'):
return True
return False
+
+ # ------------------------------------------------
+ # OpenChatter methods and notifications
+ # ------------------------------------------------
+
+ def get_needaction_user_ids(self, cr, uid, ids, context=None):
+ result = dict.fromkeys(ids, [])
+ for obj in self.browse(cr, uid, ids, context=context):
+ if (obj.state == 'manual' or obj.state == 'progress'):
+ result[obj.id] = [obj.user_id.id]
+ return result
+
+ def create_send_note(self, cr, uid, ids, context=None):
+ for obj in self.browse(cr, uid, ids, context=context):
+ self.message_subscribe(cr, uid, [obj.id], [obj.user_id.id], context=context)
+ self.message_append_note(cr, uid, [obj.id], body=_("Quotation for %s has been created.") % (obj.partner_id.name), context=context)
+
+ def confirm_send_note(self, cr, uid, ids, context=None):
+ for obj in self.browse(cr, uid, ids, context=context):
+ self.message_append_note(cr, uid, [obj.id], body=_("Quotation for %s converted to Sale Order of %s %s.") % (obj.partner_id.name, obj.amount_total, obj.pricelist_id.currency_id.symbol), context=context)
+
+ def cancel_send_note(self, cr, uid, ids, context=None):
+ for obj in self.browse(cr, uid, ids, context=context):
+ self.message_append_note(cr, uid, [obj.id], body=_("Sale Order for %s cancelled.") % (obj.partner_id.name), context=context)
+
+ def delivery_send_note(self, cr, uid, ids, picking_id, context=None):
+ for order in self.browse(cr, uid, ids, context=context):
+ for picking in (pck for pck in order.picking_ids if pck.id == picking_id):
+ pck_date = datetime.strptime(picking.min_date, '%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y')
+ self.message_append_note(cr, uid, [order.id], body=_("Delivery Order %s scheduled for %s.") % (picking.name, pck_date), context=context)
+
+ def delivery_end_send_note(self, cr, uid, ids, context=None):
+ self.message_append_note(cr, uid, ids, body=_("Order delivered."), context=context)
+
+ def invoice_paid_send_note(self, cr, uid, ids, context=None):
+ self.message_append_note(cr, uid, ids, body=_("Invoice paid."), context=context)
+
+ def invoice_send_note(self, cr, uid, ids, invoice_id, context=None):
+ for order in self.browse(cr, uid, ids, context=context):
+ for invoice in (inv for inv in order.invoice_ids if inv.id == invoice_id):
+ self.message_append_note(cr, uid, [order.id], body=_("Draft Invoice of %s %s waiting for validation.") % (invoice.amount_total, invoice.currency_id.symbol), context=context)
+
+ def action_cancel_draft_send_note(self, cr, uid, ids, context=None):
+ return self.message_append_note(cr, uid, ids, body='Sale order has been set in draft.', context=context)
+
+
sale_order()
# TODO add a field price_unit_uos
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index f3a810f9692..fa39793f939 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -225,17 +225,12 @@
-
+
-
-
-
-
-
@@ -246,6 +241,7 @@
+
diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py
index b51fd9bcb93..94cae45519d 100644
--- a/addons/sale/wizard/sale_make_invoice_advance.py
+++ b/addons/sale/wizard/sale_make_invoice_advance.py
@@ -105,7 +105,7 @@ class sale_advance_payment_inv(osv.osv_memory):
for inv in sale.invoice_ids:
ids_inv.append(inv.id)
ids_inv.append(inv_id)
- obj_sale.write(cr, uid, sale.id, {'invoice_ids': [(6, 0, ids_inv)]})
+ obj_sale.write(cr, uid, [sale.id], {'invoice_ids': [(6, 0, ids_inv)]})
list_inv.append(inv_id)
#
# If invoice on picking: add the cost on the SO
diff --git a/addons/sale_analytic_plans/i18n/cs.po b/addons/sale_analytic_plans/i18n/cs.po
index 09bbc0497a5..de13b709c5d 100644
--- a/addons/sale_analytic_plans/i18n/cs.po
+++ b/addons/sale_analytic_plans/i18n/cs.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2010-08-03 06:36+0000\n"
-"Last-Translator: Konki \n"
+"PO-Revision-Date: 2012-04-06 04:50+0000\n"
+"Last-Translator: Jiří Hajda \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:43+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
#. module: sale_analytic_plans
#: field:sale.order.line,analytics_id:0
@@ -24,7 +24,7 @@ msgstr "Analytická distribuce"
#. module: sale_analytic_plans
#: model:ir.model,name:sale_analytic_plans.model_sale_order_line
msgid "Sales Order Line"
-msgstr ""
+msgstr "Řádek prodejní objednávky"
#~ msgid "Invalid XML for View Architecture!"
#~ msgstr "Neplatný XML pro View Architecture!"
diff --git a/addons/sale_crm/i18n/cs.po b/addons/sale_crm/i18n/cs.po
index a86992afcd4..e799b92548d 100644
--- a/addons/sale_crm/i18n/cs.po
+++ b/addons/sale_crm/i18n/cs.po
@@ -7,31 +7,31 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2011-07-15 18:59+0000\n"
+"PO-Revision-Date: 2012-04-06 05:16+0000\n"
"Last-Translator: Jiří Hajda \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:14+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
"X-Poedit-Language: Czech\n"
#. module: sale_crm
#: field:sale.order,categ_id:0
msgid "Category"
-msgstr ""
+msgstr "Kategorie"
#. module: sale_crm
#: sql_constraint:sale.order:0
msgid "Order Reference must be unique per Company!"
-msgstr ""
+msgstr "Odkaz obědnávky musí být jedinečný na společnost!"
#. module: sale_crm
#: code:addons/sale_crm/wizard/crm_make_sale.py:112
#, python-format
msgid "Converted to Sales Quotation(%s)."
-msgstr ""
+msgstr "Převedeno na prodejní ocenění(%s)."
#. module: sale_crm
#: view:crm.make.sale:0
@@ -63,7 +63,7 @@ msgstr "_Vytvořit"
#. module: sale_crm
#: view:sale.order:0
msgid "My Sales Team(s)"
-msgstr ""
+msgstr "Můj prodejní tým"
#. module: sale_crm
#: help:crm.make.sale,close:0
@@ -76,7 +76,7 @@ msgstr ""
#. module: sale_crm
#: view:board.board:0
msgid "My Opportunities"
-msgstr ""
+msgstr "Moje příležitosti"
#. module: sale_crm
#: view:crm.lead:0
@@ -107,7 +107,7 @@ msgstr "Užavřít příležitost"
#. module: sale_crm
#: view:board.board:0
msgid "My Planned Revenues by Stage"
-msgstr ""
+msgstr "Moje plánované výnosy podle fáze"
#. module: sale_crm
#: code:addons/sale_crm/wizard/crm_make_sale.py:110
diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py
index fe79815fbee..3923336eb5b 100644
--- a/addons/sale_crm/wizard/crm_make_sale.py
+++ b/addons/sale_crm/wizard/crm_make_sale.py
@@ -105,9 +105,8 @@ class crm_make_sale(osv.osv_memory):
sale_order = sale_obj.browse(cr, uid, new_id, context=context)
case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
new_ids.append(new_id)
- message = _("Opportunity '%s' is converted to Quotation.") % (case.name)
- self.log(cr, uid, case.id, message)
- case_obj.message_append(cr, uid, [case], _("Converted to Sales Quotation(%s).") % (sale_order.name), context=context)
+ message = _("Opportunity has been converted to the quotation %s.") % (sale_order.name)
+ case.message_append_note(body=message)
if make.close:
case_obj.case_close(cr, uid, data)
diff --git a/addons/sale_order_dates/sale_order_dates_view.xml b/addons/sale_order_dates/sale_order_dates_view.xml
index c6544d5238f..672a1cadd0e 100644
--- a/addons/sale_order_dates/sale_order_dates_view.xml
+++ b/addons/sale_order_dates/sale_order_dates_view.xml
@@ -8,15 +8,16 @@
form
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/addons/share/static/src/css/share.css b/addons/share/static/src/css/share.css
index 8b137891791..379b3fbb86b 100644
--- a/addons/share/static/src/css/share.css
+++ b/addons/share/static/src/css/share.css
@@ -1 +1,8 @@
+button.oe-share-mail {
+ width: 120px;
+ display: none;
+}
+a.oe-share_link, a.oe-share {
+ display: none;
+}
diff --git a/addons/share/static/src/js/share.js b/addons/share/static/src/js/share.js
index a4dfba12e28..3563a4bb859 100644
--- a/addons/share/static/src/js/share.js
+++ b/addons/share/static/src/js/share.js
@@ -1,23 +1,29 @@
openerp.share = function(session) {
-function launch_wizard(self, view, user_type) {
+ var has_action_id = false;
+
+ function launch_wizard(self, view, user_type, invite) {
var action = view.getParent().action;
var Share = new session.web.DataSet(self, 'share.wizard', view.dataset.get_context());
var domain = new session.web.CompoundDomain(view.dataset.domain);
if (view.fields_view.type == 'form') {
domain = new session.web.CompoundDomain(domain, [['id', '=', view.datarecord.id]]);
}
+ if (view.fields_view.type == 'form') rec_name = view.datarecord.name;
+ else rec_name = '';
self.rpc('/web/session/eval_domain_and_context', {
domains: [domain],
contexts: [view.dataset.context]
}, function (result) {
Share.create({
name: action.name,
+ record_name: rec_name,
domain: result.domain,
action_id: action.id,
user_type: user_type || 'embedded',
view_type: view.fields_view.type,
+ invite: invite || false,
}, function(result) {
var share_id = result.result;
var step1 = Share.call('go_step_1', [[share_id],], function(result) {
@@ -26,63 +32,90 @@ function launch_wizard(self, view, user_type) {
});
});
});
-}
-
-function has_share(yes, no) {
- if (!session.connection.share_flag) {
- session.connection.share_flag = $.Deferred(function() {
- var func = new session.web.Model("share.wizard").get_func("has_share");
- func(session.connection.uid).pipe(function(res) {
- if(res) {
- session.connection.share_flag.resolve();
- } else {
- session.connection.share_flag.reject();
- }
- });
- });
}
- session.connection.share_flag.done(yes).fail(no);
-}
-session.web.Sidebar = session.web.Sidebar.extend({
- add_default_sections: function() {
- this._super();
- var self = this;
- has_share(function() {
- self.add_items('other', [{
- label: 'Share',
- callback: self.on_sidebar_click_share,
- classname: 'oe-share',
- }]);
- });
- },
- on_sidebar_click_share: function(item) {
- var view = this.getParent()
- launch_wizard(this, view);
- },
-});
+ function has_share(yes, no) {
+ if (!session.connection.share_flag) {
+ session.connection.share_flag = $.Deferred(function() {
+ var func = new session.web.Model("share.wizard").get_func("has_share");
+ func(session.connection.uid).pipe(function(res) {
+ if(res) {
+ session.connection.share_flag.resolve();
+ } else {
+ session.connection.share_flag.reject();
+ }
+ });
+ });
+ }
+ session.connection.share_flag.done(yes).fail(no);
+ }
-session.web.ViewManagerAction.include({
- start: function() {
- var self = this;
- has_share(function() {
- self.$element.find('a.oe-share_link').click(self.on_click_share_link);
- self.$element.find('a.oe-share').click(self.on_click_share);
- }, function() {
- self.$element.find('a.oe-share_link').remove();
- self.$element.find('a.oe-share').remove();
- });
- return this._super.apply(this, arguments);
- },
- on_click_share_link: function(e) {
- e.preventDefault();
- launch_wizard(this, this.views[this.active_view].controller);
- },
- on_click_share: function(e) {
- e.preventDefault();
- launch_wizard(this, this.views[this.active_view].controller, 'emails');
- },
-});
+ session.web.Sidebar = session.web.Sidebar.extend({
+ add_default_sections: function() {
+ this._super();
+ var self = this;
+ has_share(function() {
+ self.add_items('other', [{
+ label: 'Share',
+ callback: self.on_sidebar_click_share,
+ classname: 'oe-share',
+ }]);
+ });
+ },
+ on_sidebar_click_share: function(item) {
+ var view = this.getParent()
+ launch_wizard(this, view);
+ },
+ });
+ session.mail.RecordThread.include( {
+ start: function() {
+ start_res = this._super.apply(this, arguments);
+ if (has_action_id) {
+ this.$element.find('button.oe-share-mail').show();
+ }
+ return start_res;
+ }
+ });
+
+ session.web.ViewManagerAction.include({
+ start: function() {
+ var self = this;
+ this.check_if_action_is_defined();
+ has_share(function() {
+ self.$element.find('a.oe-share_link').click(self.on_click_share_link);
+ self.$element.find('a.oe-share').click(self.on_click_share);
+ self.$element.delegate('button.oe-share-mail', 'click', self.on_click_share_mail);
+ }, function() {
+ self.$element.find('a.oe-share_link').remove();
+ self.$element.find('a.oe-share').remove();
+ });
+ return this._super.apply(this, arguments);
+ },
+
+ check_if_action_is_defined: function() {
+ if (this.action && this.action.id) {
+ has_action_id = true;
+ this.$element.find('a.oe-share_link').show();
+ this.$element.find('a.oe-share').show();
+ }
+ else {
+ has_action_id = false;
+ }
+ },
+
+ on_click_share_link: function(e) {
+ e.preventDefault();
+ launch_wizard(this, this.views[this.active_view].controller, 'embedded', false);
+ },
+ on_click_share: function(e) {
+ e.preventDefault();
+ launch_wizard(this, this.views[this.active_view].controller, 'emails', false);
+ },
+ on_click_share_mail: function(e) {
+ e.preventDefault();
+ launch_wizard(this, this.views[this.active_view].controller, 'emails', true);
+ },
+ });
};
diff --git a/addons/share/static/src/xml/share.xml b/addons/share/static/src/xml/share.xml
index 532e8c74c9d..d79c2d8501e 100644
--- a/addons/share/static/src/xml/share.xml
+++ b/addons/share/static/src/xml/share.xml
@@ -10,4 +10,11 @@
+
+
+
+
+
+
+
diff --git a/addons/share/wizard/share_wizard.py b/addons/share/wizard/share_wizard.py
index 09fb43ca361..854f021bf67 100644
--- a/addons/share/wizard/share_wizard.py
+++ b/addons/share/wizard/share_wizard.py
@@ -165,12 +165,17 @@ class share_wizard(osv.osv_memory):
'user_type': fields.selection(lambda s, *a, **k: s._user_type_selection(*a, **k),'Sharing method', required=True,
help="Select the type of user(s) you would like to share data with."),
'new_users': fields.text("Emails"),
+ 'email_1': fields.char('New user email', size=64),
+ 'email_2': fields.char('New user email', size=64),
+ 'email_3': fields.char('New user email', size=64),
+ 'invite': fields.boolean('Invite users to OpenSocial record'),
'access_mode': fields.selection([('readonly','Can view'),('readwrite','Can edit')],'Access Mode', required=True,
help="Access rights to be granted on the shared documents."),
'result_line_ids': fields.one2many('share.wizard.result.line', 'share_wizard_id', 'Summary', readonly=True),
'share_root_url': fields.function(_share_root_url, string='Share Access URL', type='char', size=512, readonly=True,
help='Main access page for users that are granted shared access'),
'name': fields.char('Share Title', size=64, required=True, help="Title for the share (displayed to users as menu and shortcut name)"),
+ 'record_name': fields.char('Record name', size=128, help="Name of the shared record, if sharing a precise record"),
'message': fields.text("Personal Message", help="An optional personal message, to be included in the e-mail notification."),
'embed_code': fields.function(_embed_code, type='text'),
@@ -181,6 +186,7 @@ class share_wizard(osv.osv_memory):
_defaults = {
'view_type': 'page',
'user_type' : 'embedded',
+ 'invite': False,
'domain': lambda self, cr, uid, context, *a: context.get('domain', '[]'),
'action_id': lambda self, cr, uid, context, *a: context.get('action_id'),
'access_mode': 'readonly',
@@ -192,8 +198,8 @@ class share_wizard(osv.osv_memory):
return bool(self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email)
def go_step_1(self, cr, uid, ids, context=None):
- user_type = self.browse(cr,uid,ids,context)[0].user_type
- if user_type == 'emails' and not self.has_email(cr, uid, context=context):
+ wizard_data = self.browse(cr,uid,ids,context)[0]
+ if wizard_data.user_type == 'emails' and not self.has_email(cr, uid, context=context):
raise osv.except_osv(_('No e-mail address configured'),
_('You must configure your e-mail address in the user preferences before using the Share button.'))
model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'share', 'action_share_wizard_step1')
@@ -223,12 +229,18 @@ class share_wizard(osv.osv_memory):
created_ids = []
existing_ids = []
if wizard_data.user_type == 'emails':
- for new_user in (wizard_data.new_users or '').split('\n'):
+ # get new user list from email data
+ new_users = (wizard_data.new_users or '').split('\n')
+ new_users += [wizard_data.email_1 or '', wizard_data.email_2 or '', wizard_data.email_3 or '']
+ for new_user in new_users:
# Ignore blank lines
new_user = new_user.strip()
if not new_user: continue
# Ignore the user if it already exists.
- existing = user_obj.search(cr, UID_ROOT, [('login', '=', new_user)])
+ if not wizard_data.invite:
+ existing = user_obj.search(cr, UID_ROOT, [('login', '=', new_user)])
+ else:
+ existing = user_obj.search(cr, UID_ROOT, [('user_email', '=', new_user)])
existing_ids.extend(existing)
if existing:
new_line = { 'user_id': existing[0],
@@ -243,6 +255,7 @@ class share_wizard(osv.osv_memory):
'user_email': new_user,
'groups_id': [(6,0,[group_id])],
'share': True,
+ 'message_email_pref': 'all',
'company_id': current_user.company_id.id
}, context)
new_line = { 'user_id': user_id,
@@ -643,7 +656,7 @@ class share_wizard(osv.osv_memory):
_('You must be a member of the Share/User group to use the share wizard'),
context=context)
if wizard_data.user_type == 'emails':
- self._assert(wizard_data.new_users,
+ self._assert((wizard_data.new_users or wizard_data.email_1 or wizard_data.email_2 or wizard_data.email_3),
_('Please indicate the emails of the persons to share with, one per line'),
context=context)
@@ -667,21 +680,21 @@ class share_wizard(osv.osv_memory):
if new_ids:
# new users need a new shortcut AND a home action
self._setup_action_and_shortcut(cr, uid, wizard_data, new_ids, make_home=True, context=context)
- return group_id
+ return group_id, new_ids, existing_ids
def go_step_2(self, cr, uid, ids, context=None):
wizard_data = self.browse(cr, uid, ids[0], context=context)
self._check_preconditions(cr, uid, wizard_data, context=context)
# Create shared group and users
- group_id = self._create_share_users_group(cr, uid, wizard_data, context=context)
+ group_id, new_ids, existing_ids = self._create_share_users_group(cr, uid, wizard_data, context=context)
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
model_obj = self.pool.get('ir.model')
model_id = model_obj.search(cr, uid, [('model','=', wizard_data.action_id.res_model)])[0]
model = model_obj.browse(cr, uid, model_id, context=context)
-
+
# ACCESS RIGHTS
# We have several classes of objects that should receive different access rights:
# Let:
@@ -731,68 +744,141 @@ class share_wizard(osv.osv_memory):
# refresh wizard_data
wizard_data = self.browse(cr, uid, ids[0], context=context)
+
+ # EMAILS AND NOTIFICATIONS
+ # A. Not invite: as before
+ # -> send emails to destination users
+ # B. Invite (OpenSocial)
+ # -> subscribe all users (existing and new) to the record
+ # -> send a notification with a summary to the current record
+ # -> send a notification to all users; users allowing to receive
+ # emails in preferences will receive it
+ # new users by default receive all notifications by email
+
+ # A.
+ if not wizard_data.invite:
+ self.send_emails(cr, uid, wizard_data, context=context)
+ # B.
+ else:
+ # Invite (OpenSocial): automatically subscribe users to the record
+ res_id = 0
+ for cond in safe_eval(main_domain):
+ if cond[0] == 'id':
+ res_id = cond[2]
+ # Record id not found: issue
+ if res_id <= 0:
+ raise osv.except_osv(_('Record id not found'), _('The share engine has not been able to fetch a record_id for your invitation.'))
+ self.pool.get(model.model).message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context)
+ self.send_invite_email(cr, uid, wizard_data, context=context)
+ self.send_invite_note(cr, uid, model.model, res_id, wizard_data, context=context)
+
+ # CLOSE
+ # A. Not invite: as before
+ # B. Invite: skip summary screen, get back to the record
+
+ # A.
+ if not wizard_data.invite:
+ dummy, step2_form_view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'share', 'share_step2_form')
+ return {
+ 'name': _('Shared access created!'),
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'share.wizard',
+ 'view_id': False,
+ 'res_id': ids[0],
+ 'views': [(step2_form_view_id, 'form'), (False, 'tree'), (False, 'calendar'), (False, 'graph')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new'
+ }
+ # B.
+ else:
+ return {
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': model.model,
+ 'view_id': False,
+ 'res_id': res_id,
+ 'views': [(False, 'form'), (False, 'tree'), (False, 'calendar'), (False, 'graph')],
+ 'type': 'ir.actions.act_window',
+ }
+
- # send the confirmation emails:
- self.send_emails(cr, uid, wizard_data, context=context)
-
- dummy, step2_form_view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'share', 'share_step2_form')
- return {
- 'name': _('Shared access created!'),
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'share.wizard',
- 'view_id': False,
- 'res_id': ids[0],
- 'views': [(step2_form_view_id, 'form'), (False, 'tree'), (False, 'calendar'), (False, 'graph')],
- 'type': 'ir.actions.act_window',
- 'target': 'new'
- }
-
+ def send_invite_note(self, cr, uid, model_name, res_id, wizard_data, context=None):
+ subject = _('Invitation')
+ body = 'has been shared with'
+ tmp_idx = 0
+ for result_line in wizard_data.result_line_ids:
+ body += ' @%s' % (result_line.user_id.login)
+ if tmp_idx < len(wizard_data.result_line_ids)-2:
+ body += ','
+ elif tmp_idx == len(wizard_data.result_line_ids)-2:
+ body += ' and'
+ body += '.'
+ return self.pool.get(model_name).message_append_note(cr, uid, [res_id], _('System Notification'), body, context=context)
+
+ def send_invite_email(self, cr, uid, wizard_data, context=None):
+ message_obj = self.pool.get('mail.message')
+ notification_obj = self.pool.get('mail.notification')
+ user = self.pool.get('res.users').browse(cr, UID_ROOT, uid)
+ if not user.user_email:
+ raise osv.except_osv(_('Email required'), _('The current user must have an email address configured in User Preferences to be able to send outgoing emails.'))
+
+ # TODO: also send an HTML version of this mail
+ for result_line in wizard_data.result_line_ids:
+ email_to = result_line.user_id.user_email
+ if not email_to:
+ continue
+ subject = _('Invitation to collaborate about %s') % (wizard_data.record_name)
+ body = _("Hello,\n\n")
+ body += _("I have shared %s (%s) with you!\n\n") % (wizard_data.record_name, wizard_data.name)
+ if wizard_data.message:
+ body += "%s\n\n" % (wizard_data.message)
+ if result_line.newly_created:
+ body += _("The documents are not attached, you can view them online directly on my OpenERP server at:\n %s\n\n") % (result_line.share_url)
+ body += _("These are your credentials to access this protected area:\n")
+ body += "%s: %s" % (_("Username"), result_line.user_id.login) + "\n"
+ body += "%s: %s" % (_("Password"), result_line.password) + "\n"
+ body += "%s: %s" % (_("Database"), cr.dbname) + "\n"
+ body += _("The documents have been automatically added to your subscriptions.\n\n")
+ body += '%s\n\n' % ((user.signature or ''))
+ body += "--\n"
+ body += _("OpenERP is a powerful and user-friendly suite of Business Applications (CRM, Sales, HR, etc.)\n"
+ "It is open source and can be found on http://www.openerp.com.")
+ msg_id = message_obj.schedule_with_attach(cr, uid, user.user_email, [email_to], subject, body, model='', context=context)
+ notification_obj.create(cr, uid, {'user_id': result_line.user_id.id, 'message_id': msg_id}, context=context)
+
def send_emails(self, cr, uid, wizard_data, context=None):
self._logger.info('Sending share notifications by email...')
mail_message = self.pool.get('mail.message')
user = self.pool.get('res.users').browse(cr, UID_ROOT, uid)
-
+ if not user.user_email:
+ raise osv.except_osv(_('Email required'), _('The current user must have an email address configured in User Preferences to be able to send outgoing emails.'))
+
# TODO: also send an HTML version of this mail
msg_ids = []
for result_line in wizard_data.result_line_ids:
email_to = result_line.user_id.user_email
if not email_to:
continue
- if not user.user_email:
- raise osv.except_osv(_('Email required'), _('The current user must have an email address configured in User Preferences to be able to send outgoing emails.'))
subject = wizard_data.name
- body = _("Hello,")
- body += "\n\n"
- body += _("I've shared %s with you!") % wizard_data.name
- body += "\n\n"
- body += _("The documents are not attached, you can view them online directly on my OpenERP server at:")
- body += "\n " + result_line.share_url
- body += "\n\n"
+ body = _("Hello,\n\n")
+ body += _("I've shared %s with you!\n\n") % wizard_data.name
+ body += _("The documents are not attached, you can view them online directly on my OpenERP server at:\n %s\n\n") % (result_line.share_url)
if wizard_data.message:
- body += wizard_data.message
- body += "\n\n"
+ body += '%s\n\n' % (wizard_data.message)
if result_line.newly_created:
body += _("These are your credentials to access this protected area:\n")
- body += "%s: %s" % (_("Username"), result_line.user_id.login) + "\n"
- body += "%s: %s" % (_("Password"), result_line.password) + "\n"
- body += "%s: %s" % (_("Database"), cr.dbname) + "\n"
+ body += "%s: %s\n" % (_("Username"), result_line.user_id.login)
+ body += "%s: %s\n" % (_("Password"), result_line.password)
+ body += "%s: %s\n" % (_("Database"), cr.dbname)
else:
body += _("The documents have been automatically added to your current OpenERP documents.\n")
body += _("You may use your current login (%s) and password to view them.\n") % result_line.user_id.login
- body += "\n\n"
- body += (user.signature or '')
- body += "\n\n"
+ body += "\n\n%s\n\n" % ( (user.signature or '') )
body += "--\n"
body += _("OpenERP is a powerful and user-friendly suite of Business Applications (CRM, Sales, HR, etc.)\n"
"It is open source and can be found on http://www.openerp.com.")
- msg_ids.append(mail_message.schedule_with_attach(cr, uid,
- user.user_email,
- [email_to],
- subject,
- body,
- model='share.wizard',
- context=context))
+ msg_ids.append(mail_message.schedule_with_attach(cr, uid, user.user_email, [email_to], subject, body, model='share.wizard', context=context))
# force direct delivery, as users expect instant notification
mail_message.send(cr, uid, msg_ids, context=context)
self._logger.info('%d share notification(s) sent.', len(msg_ids))
diff --git a/addons/share/wizard/share_wizard_view.xml b/addons/share/wizard/share_wizard_view.xml
index 29bd5e59f01..77d9213f315 100644
--- a/addons/share/wizard/share_wizard_view.xml
+++ b/addons/share/wizard/share_wizard_view.xml
@@ -30,16 +30,23 @@
@@ -1222,6 +1223,7 @@
+
diff --git a/addons/stock/wizard/stock_change_product_qty.py b/addons/stock/wizard/stock_change_product_qty.py
index 9d3de5692f0..162aea77f86 100644
--- a/addons/stock/wizard/stock_change_product_qty.py
+++ b/addons/stock/wizard/stock_change_product_qty.py
@@ -26,6 +26,7 @@ import tools
class stock_change_product_qty(osv.osv_memory):
_name = "stock.change.product.qty"
+ _inherit = ['mail.thread']
_description = "Change Product Quantity"
_columns = {
'product_id' : fields.many2one('product.product', 'Product'),
@@ -98,9 +99,24 @@ class stock_change_product_qty(osv.osv_memory):
inventry_obj.action_confirm(cr, uid, [inventory_id], context=context)
inventry_obj.action_done(cr, uid, [inventory_id], context=context)
-
+ self.change_product_qty_send_note(cr, uid, [data.id], context)
return {}
+ def change_product_qty_send_note (self, cr, uid, ids, context=None):
+ prod_obj = self.pool.get('product.product')
+ location_obj = self.pool.get('stock.location')
+ prod_temp_obj = self.pool.get('product.template')
+ uom_obj = self.pool.get('product.uom')
+
+ for data in self.browse(cr, uid, ids, context=context):
+ for location in location_obj.browse(cr, uid, [data.location_id.id], context=context):
+ location_name = location.name
+ for prod in prod_obj.browse(cr, uid, [data.product_id.id], context=context):
+ for prod_temp in prod_temp_obj.browse(cr, uid, [prod.product_tmpl_id.id], context=context):
+ for uom in uom_obj.browse(cr, uid, [prod_temp.uom_id.id], context=context):
+ message = _("Quantity has been changed to %s %s for %s location.") % (data.new_quantity,uom.name,location_name)
+ prod_obj.message_append_note(cr, uid, [prod.id], body=message, context=context)
+
stock_change_product_qty()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock_invoice_directly/i18n/cs.po b/addons/stock_invoice_directly/i18n/cs.po
index 26e21813723..8df36e22bae 100644
--- a/addons/stock_invoice_directly/i18n/cs.po
+++ b/addons/stock_invoice_directly/i18n/cs.po
@@ -7,19 +7,19 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2009-11-17 10:52+0000\n"
-"Last-Translator: Kuvaly [LCT] \n"
+"PO-Revision-Date: 2012-04-06 04:48+0000\n"
+"Last-Translator: Jiří Hajda \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:51+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
#. module: stock_invoice_directly
#: model:ir.model,name:stock_invoice_directly.model_stock_partial_picking
msgid "Partial Picking Processing Wizard"
-msgstr ""
+msgstr "Průvodce zpracování částečného navádění"
#~ msgid "Invoice Picking Directly"
#~ msgstr "Přímé vybírání faktur"
diff --git a/addons/stock_no_autopicking/i18n/cs.po b/addons/stock_no_autopicking/i18n/cs.po
index 453e602407d..9442838c14c 100644
--- a/addons/stock_no_autopicking/i18n/cs.po
+++ b/addons/stock_no_autopicking/i18n/cs.po
@@ -7,24 +7,24 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
-"PO-Revision-Date: 2009-11-17 10:53+0000\n"
-"Last-Translator: Kuvaly [LCT] \n"
+"PO-Revision-Date: 2012-04-06 05:15+0000\n"
+"Last-Translator: Jiří Hajda \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:44+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
#. module: stock_no_autopicking
#: model:ir.model,name:stock_no_autopicking.model_product_product
msgid "Product"
-msgstr ""
+msgstr "Výrobek"
#. module: stock_no_autopicking
#: model:ir.model,name:stock_no_autopicking.model_mrp_production
msgid "Manufacturing Order"
-msgstr ""
+msgstr "Výrobní příkaz"
#. module: stock_no_autopicking
#: field:product.product,auto_pick:0
@@ -34,22 +34,22 @@ msgstr "Auto výběr"
#. module: stock_no_autopicking
#: help:product.product,auto_pick:0
msgid "Auto picking for raw materials of production orders."
-msgstr ""
+msgstr "Automatické navádění pro hrubý materiál výrobních příkazů."
#. module: stock_no_autopicking
#: constraint:product.product:0
msgid "Error: Invalid ean code"
-msgstr ""
+msgstr "Chyba: Neplatný kód ean"
#. module: stock_no_autopicking
#: sql_constraint:mrp.production:0
msgid "Reference must be unique per Company!"
-msgstr ""
+msgstr "Odkaz musí být jedinečný na společnost"
#. module: stock_no_autopicking
#: constraint:mrp.production:0
msgid "Order quantity cannot be negative or zero!"
-msgstr ""
+msgstr "Objednané množství nesmí být záporné nebo nulové!"
#~ msgid "Invalid XML for View Architecture!"
#~ msgstr "Invalidní XML pro zobrazení architektury!"
diff --git a/addons/web_livechat/i18n/cs.po b/addons/web_livechat/i18n/cs.po
new file mode 100644
index 00000000000..bb1aa79d289
--- /dev/null
+++ b/addons/web_livechat/i18n/cs.po
@@ -0,0 +1,28 @@
+# Czech 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 01:37+0100\n"
+"PO-Revision-Date: 2012-04-06 04:48+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: web_livechat
+#: sql_constraint:publisher_warranty.contract:0
+msgid "That contract is already registered in the system."
+msgstr "Tato smlouva je již v systému registrována."
+
+#. module: web_livechat
+#: model:ir.model,name:web_livechat.model_publisher_warranty_contract
+msgid "publisher_warranty.contract"
+msgstr "publisher_warranty.contract"
diff --git a/addons/web_uservoice/i18n/cs.po b/addons/web_uservoice/i18n/cs.po
new file mode 100644
index 00000000000..44c6db7c35e
--- /dev/null
+++ b/addons/web_uservoice/i18n/cs.po
@@ -0,0 +1,23 @@
+# Czech 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 01:37+0100\n"
+"PO-Revision-Date: 2012-04-06 04:46+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. openerp-web
+#: /home/odo/repositories/addons/trunk/web_uservoice/static/src/xml/web_uservoice.xml:6
+msgid "feedback"
+msgstr "zpětná vazba"
diff --git a/addons/wiki/i18n/cs.po b/addons/wiki/i18n/cs.po
index fee7fa45d0c..fb63420ede4 100644
--- a/addons/wiki/i18n/cs.po
+++ b/addons/wiki/i18n/cs.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
-"PO-Revision-Date: 2011-09-05 06:39+0000\n"
+"PO-Revision-Date: 2012-04-06 04:44+0000\n"
"Last-Translator: Jiří Hajda \n"
"Language-Team: Czech \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-02-09 06:46+0000\n"
-"X-Generator: Launchpad (build 14763)\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
"X-Poedit-Language: Czech\n"
#. module: wiki
@@ -98,7 +98,7 @@ msgstr "Rodičovská nabídka"
#: code:addons/wiki/wizard/wiki_make_index.py:52
#, python-format
msgid "There is no section in this Page"
-msgstr ""
+msgstr "Na této stránce není žádná sekce"
#. module: wiki
#: field:wiki.groups,name:0 view:wiki.wiki:0 field:wiki.wiki,group_id:0
diff --git a/addons/wiki_faq/i18n/cs.po b/addons/wiki_faq/i18n/cs.po
new file mode 100644
index 00000000000..fde36d8fde9
--- /dev/null
+++ b/addons/wiki_faq/i18n/cs.po
@@ -0,0 +1,32 @@
+# Czech 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: 2011-01-11 11:16+0000\n"
+"PO-Revision-Date: 2012-04-06 04:46+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: wiki_faq
+#: model:ir.module.module,description:wiki_faq.module_meta_information
+msgid ""
+"This module provides a wiki FAQ Template\n"
+" "
+msgstr ""
+"Tento modul poskytuje šablonu wiki FAQ\n"
+" "
+
+#. module: wiki_faq
+#: model:ir.module.module,shortdesc:wiki_faq.module_meta_information
+msgid "Document Management - Wiki - FAQ"
+msgstr "Správa dokumentů - Wiki - FAQ"
diff --git a/addons/wiki_quality_manual/i18n/cs.po b/addons/wiki_quality_manual/i18n/cs.po
new file mode 100644
index 00000000000..86cf27747ec
--- /dev/null
+++ b/addons/wiki_quality_manual/i18n/cs.po
@@ -0,0 +1,32 @@
+# Czech 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: 2011-01-11 11:16+0000\n"
+"PO-Revision-Date: 2012-04-06 04:47+0000\n"
+"Last-Translator: Jiří Hajda \n"
+"Language-Team: Czech \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2012-04-07 04:55+0000\n"
+"X-Generator: Launchpad (build 15060)\n"
+
+#. module: wiki_quality_manual
+#: model:ir.module.module,description:wiki_quality_manual.module_meta_information
+msgid ""
+"Quality Manual Template\n"
+" "
+msgstr ""
+"Šablona příručky kvality\n"
+" "
+
+#. module: wiki_quality_manual
+#: model:ir.module.module,shortdesc:wiki_quality_manual.module_meta_information
+msgid "Document Management - Wiki - Quality Manual"
+msgstr "Správa dokumentů - Wiki - Příručka kvality"