From 3657e4bd821e60544880985a5d48a5bc4419d803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 31 Jan 2012 16:50:00 +0100 Subject: [PATCH 0001/1161] [ADD] Added empty files for mail_group and mail_group views. Added css file for kanban view. Modified init and openerp files accordingly. bzr revid: tde@openerp.com-20120131155000-cmzd88d0rkso8sl1 --- addons/mail/__init__.py | 1 + addons/mail/__openerp__.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py index 4787883ef9c..c7fffb3a338 100644 --- a/addons/mail/__init__.py +++ b/addons/mail/__init__.py @@ -21,6 +21,7 @@ import mail_message import mail_thread +import mail_group import res_partner import wizard diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py index 8085d301364..5e52e103852 100644 --- a/addons/mail/__openerp__.py +++ b/addons/mail/__openerp__.py @@ -58,6 +58,7 @@ The main features are: 'data': [ "wizard/mail_compose_message_view.xml", "mail_message_view.xml", + "mail_group_view.xml", "mail_thread_view.xml", "res_partner_view.xml", 'security/ir.model.access.csv', @@ -67,5 +68,6 @@ The main features are: 'auto_install': False, 'certificate': '001056784984222247309', 'images': ['images/customer_history.jpeg','images/messages_form.jpeg','images/messages_list.jpeg'], + 'css': ['static/src/css/mail_group.css'], } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From a0a89fd37b24553776fa451466a922e727915571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 31 Jan 2012 16:52:57 +0100 Subject: [PATCH 0002/1161] [ADD] Really added files I was pretending to add in previous revision bzr revid: tde@openerp.com-20120131155257-skq6lu8g0mptm19h --- addons/mail/mail_group.py | 20 +++++++ addons/mail/mail_group_view.xml | 4 ++ addons/mail/static/src/css/mail_group.css | 68 +++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 addons/mail/mail_group.py create mode 100644 addons/mail/mail_group_view.xml create mode 100644 addons/mail/static/src/css/mail_group.css diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py new file mode 100644 index 00000000000..5dfeb073de6 --- /dev/null +++ b/addons/mail/mail_group.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2011 OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see +# +############################################################################## \ No newline at end of file diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml new file mode 100644 index 00000000000..b2839b2cc0a --- /dev/null +++ b/addons/mail/mail_group_view.xml @@ -0,0 +1,4 @@ + + + + diff --git a/addons/mail/static/src/css/mail_group.css b/addons/mail/static/src/css/mail_group.css new file mode 100644 index 00000000000..a65f766210e --- /dev/null +++ b/addons/mail/static/src/css/mail_group.css @@ -0,0 +1,68 @@ +.oe_group_vignette { + padding: 8px 0; + min-height: 100px; +} + +.oe_group_image, .oe_group_details { + display: inline-block; + vertical-align: top; +} + +.oe_group_image { + width: 100px; + height: 100px; + text-align: center; + overflow: hidden; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + -o-border-radius: 3px; + -ms-border-radius: 3px; + border-radius: 3px; + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + -o-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + -box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); +} + +.oe_group_picture { + width: 100px; + height: auto; + clip: rect(10px, 100px, 110px, 0px); +} + +.oe_group_picture_wide { + height: 100px; + width: auto; + clip: rect(0px, 115px, 100px, 15px); +} + +.oe_group_details { + width: 220px; + font-size: 13px; + padding: 2px 5px; + color: #4c4c4c; + min-height: 120px; +} + +.oe_group_details h4 { + margin: 0; + font-size: 13px; +} + +.oe_group_details h4 a { + color: #4c4c4c; +} + +.oe_group_details h4 a:hover { + text-decoration: underline; +} + +.oe_group_details ul { + margin: 3px 0 5px; + padding: 0; + list-style: none; +} + +.oe_group_details li { + margin: 2px 0; +} From f4551851fd7a3905782b4e81b81878d867cb2ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 31 Jan 2012 16:54:12 +0100 Subject: [PATCH 0003/1161] [IMP] Added group and subscription models. Added subscription mechanism when searching for tweets. Added views. bzr revid: tde@openerp.com-20120131155412-r16jr1nhwd9k4srv --- addons/mail/mail_group.py | 132 +++++++++++++++++++++++- addons/mail/mail_group_view.xml | 176 +++++++++++++++++++++++++++++++- addons/mail/mail_message.py | 81 ++++++++++++++- 3 files changed, 384 insertions(+), 5 deletions(-) diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py index 5dfeb073de6..996f9f174ae 100644 --- a/addons/mail/mail_group.py +++ b/addons/mail/mail_group.py @@ -17,4 +17,134 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see # -############################################################################## \ No newline at end of file +############################################################################## + +import tools +from osv import osv +from osv import fields +from tools.translate import _ + +class mail_group(osv.osv): + """ + A mail group is a collection of users sharing messages. Mail groups are different from user groups + because they don't have a specific field holding users. Group users are users that follow + the mail group, using the subscription/follow mechanism of Chatter. + """ + + _name = 'mail.group' + _inherits = {'res.groups': 'group_id'} + + def action_group_join(self, cr, uid, ids, context={}): + sub_obj = self.pool.get('mail.subscription') + menu_values = {'res_model': 'mail.group', 'user_id': uid} + for id in ids: + menu_values['res_id'] = id + sub_id = sub_obj.create(cr, uid, menu_values, context=context) + + for group in self.browse(cr, uid, ids, context): + self.write(cr, uid, group.id, { + 'users': [(4, uid)] + }) + + return True + + _columns = { + 'group_id': fields.many2one('res.groups', required=True, ondelete='cascade', + string='Group', + help='The group extended by this portal'), + #'name': fields.char('Name', size=64, required=True), + 'description': fields.text('Description'), + 'responsible_id': fields.many2one('res.users', string='Responsible', + ondelete='set null', required=True), + 'public': fields.boolean('Public', help='This group is visible by non members') + } + + _defaults = { + 'public': True, + } + + + def create(self, cr, uid, values, context=None): + """ extend create() to automatically create a menu for the group """ + if context is None: context = {} + # create group + group_id = super(mail_group, self).create(cr, uid, values, context) + # create menu + self._create_menu(cr, uid, [group_id], context) + return group_id + + def _create_menu(self, cr, uid, ids, context=None): + """ create a menu for the given groups """ + menu_obj = self.pool.get('ir.ui.menu') + ir_data = self.pool.get('ir.model.data') + act_win_obj = self.pool.get('ir.actions.act_window') + menu_root = self._get_res_xml_id(cr, uid, 'mail', 'mg_groups') + + for group in self.browse(cr, uid, ids, context): + # create an ir.action.act_window action + act_values = { + 'name': '%s' % group.name, + 'res_model': 'mail.message', + 'domain': '["&", ("res_model", "=", "mail.group"), ("res_id", "=", %s)]' % group.id, + } + act_id = act_win_obj.create(cr, uid, act_values, context) + # create a menuitem under 'mail.mg_groups' + menu_values = { + 'name': _('%s') % group.name, + 'parent_id': menu_root, + 'action': 'ir.actions.act_window,%s' % (act_id), + 'groups_id': [(6, 0, [group.group_id.id])], + } + menu_id = menu_obj.create(cr, uid, menu_values, context) + # create data + data_values = { + 'name': _('%s') % group.name, + 'model': 'ir.ui.menu', + 'module': 'portal', + 'res_id': menu_id, + 'noupdate': 'True'} + data_id = ir_data.create(cr, uid, data_values, context) + return True + + def _assign_menu(self, cr, uid, ids, context=None): + """ assign groups (ids) menu to the users joigning the groups""" + user_obj = self.pool.get('res.users') + for p in self.browse(cr, uid, ids, context): + # user menu action = portal menu action if set in portal + if p.menu_action_id: + user_ids = [u.id for u in p.users if u.id != 1] + user_values = {'menu_id': p.menu_action_id.id} + user_obj.write(cr, uid, user_ids, user_values, context) + + def _get_res_xml_id(self, cr, uid, module, xml_id): + """ return the resource id associated to the given xml_id """ + data_obj = self.pool.get('ir.model.data') + data_id = data_obj._get_id(cr, uid, module, xml_id) + return data_obj.browse(cr, uid, data_id).res_id + + +mail_group() + + +class mail_subscription(osv.osv): + """ + mail_subscription holds the data related to the follow mechanism inside OpenERP. + A subscription can be of following: + - res_model: model of the followed objects + - res_id: ID of resource OR + - res_domain: a domain filtering followed objects + """ + + _name = 'mail.subscription' + _rec_name = 'id' + _columns = { + 'res_model': fields.char('Related Document model', size=128, select=1), + 'res_id': fields.integer('Related Document ID', select=1), + 'res_domain': fields.char('res_domain', size=256), + 'user_id': fields.integer('Related User ID', select=1), + } + + _defaults = { + } + +mail_subscription() diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index b2839b2cc0a..3532eed5871 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -1,4 +1,178 @@ + - + + + mail.message.tree_tweet + mail.message + tree + 15 + + + + + + + + + + + + mail.message.form_tweet + mail.message + form + 15 + +
+ + + + + + + + + + + + +
+ + + + mail.message.search_tweet + mail.message + search + + + + + + + + + + mail.group.kanban + mail.group + kanban + + + + + +
+
+ + prout +
+
+

+
    +
  • +
  • Join
  • +
  • Joined
  • +
+
+ +
+
+
+
+
+
+ + + + mail.group.form + mail.group + form + + +
+ + + + + + + + + + + + + +
+ + + + Groups + mail.group + form + kanban,tree,form + + + + Messages + mail.message + form + tree,form + {'filter_search': True, 'tree_view_ref': 'mail.view_tweet_tree', 'form_view_ref': 'mail.view_tweet_form'} + + + + + Messages + mail.message + form + tree,form + {'filter_search': True, 'tree_view_ref': 'mail.view_tweet_tree', 'form_view_ref': 'mail.view_tweet_form'} + + [('user_id', '=', uid)] + + + + Subscriptions + mail.subscription + form + tree,form + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 1693397f6fa..825e3f3c7c6 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -71,8 +71,8 @@ class mail_message_common(osv.osv_memory): _rec_name = 'subject' _columns = { 'subject': fields.char('Subject', size=512, required=True), - 'model': fields.char('Related Document model', size=128, select=1, readonly=1), - 'res_id': fields.integer('Related Document ID', select=1, readonly=1), + 'model': fields.char('Related Document model', size=128, select=1), # was rfeadonly + 'res_id': fields.integer('Related Document ID', select=1), # was rfeadonly 'date': fields.datetime('Date'), 'email_from': fields.char('From', size=128, help='Message sender, taken from user preferences. If empty, this is not a mail but a message.'), 'email_to': fields.char('To', size=256, help='Message recipients'), @@ -163,7 +163,7 @@ class mail_message(osv.osv): _columns = { 'partner_id': fields.many2one('res.partner', 'Related partner'), - 'user_id': fields.many2one('res.users', 'Related user', readonly=1), + #'user_id': fields.many2one('res.users', 'Related user', readonly=1), 'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id', 'Attachments'), 'display_text': fields.function(_get_display_text, method=True, type='text', size="512", string='Display Text'), 'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1), @@ -176,12 +176,87 @@ class mail_message(osv.osv): ], 'State', readonly=True), 'auto_delete': fields.boolean('Auto Delete', help="Permanently delete this email after sending it, to save space"), 'original': fields.binary('Original', help="Original version of the message, as it was sent on the network", readonly=1), + # tde add/modif + 'user_id': fields.many2one('res.users', 'Related user', readonly=1), + 'type': fields.selection([ + ('tweet', 'Tweet'), + ('status', 'Status'), + ], 'Type'), + 'need_action': fields.boolean('Need action'), } _defaults = { 'state': 'received', } + # thib add + def create(self, cr, uid, vals, context=None): + print vals + return super(mail_message, self).create(cr, uid, vals, context) + + def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): + if not context or not context.has_key('filter_search'): + return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count) + + # get subscriptions + sub_obj = self.pool.get('mail.subscription') + sub_ids = sub_obj.search(cr, uid, [('user_id', '=', uid)]) + subs = sub_obj.browse(cr, uid, sub_ids) + + # stock tweets to find + res_model_ids_dict = {} + res_model_all_list = [] + + # check all subscriptions + for sub in subs: + if sub.res_model and sub.res_id == 0 and sub.res_domain == False: + print "s-1" + if sub.res_model not in res_model_all_list: + res_model_all_list.append(sub.res_model) + elif sub.res_model and sub.res_id: + print "s-2" + if res_model_ids_dict.has_key(sub.res_model): + res_model_ids_dict[sub.res_model].append(sub.res_id) + else: + res_model_ids_dict[sub.res_model] = [sub.res_id] + elif sub.res_model and sub.res_domain: + print "s-3" + res_obj = self.pool.get(sub.res_model) + print sub.res_domain + #res_ids = res_obj.search(cr, uid, [('id', 'in', [1,2])]) + res_ids = res_obj.search(cr, uid, eval(sub.res_domain)) + if res_model_ids_dict.has_key(sub.res_model): + res_model_ids_dict[sub.res_model] += res_ids + else: + res_model_ids_dict[sub.res_model] = res_ids + print 'cacaprout' + else: + print 'erreur !!!' + print sub + + # add fully-followed domains + args.append('|') + args.append(['model', 'in', res_model_all_list]) + + # add partially-followed domains + for x in range(0, len(res_model_ids_dict.keys())-1): + args.append('|') + + for res_model in res_model_ids_dict.keys(): + if res_model not in res_model_all_list: + args.append('&') + args.append(['model', '=', res_model]) + args.append(['res_id', 'in', res_model_ids_dict[res_model]]) + + if context and context.has_key('filter_search'): + pass + else: + args = [] + print args + return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit,order=order, context=context, count=count) + + # end thib add + def init(self, cr): cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'mail_message_model_res_id_idx'""") if not cr.fetchone(): From b15ec8334bc641877e96957a064ca3b435248429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 31 Jan 2012 16:57:48 +0100 Subject: [PATCH 0004/1161] [FIX] Fixed missing fields for search. bzr revid: tde@openerp.com-20120131155748-1ossao3j32wd8bal --- addons/mail/mail_group_view.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index 3532eed5871..755583cc136 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -13,6 +13,8 @@ + + From 2107ef2017ffa97b2029b2fb682895be4ff9d08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 1 Feb 2012 12:02:34 +0100 Subject: [PATCH 0005/1161] [FIX] Wrong field name in message tree view bzr revid: tde@openerp.com-20120201110234-a3vkrrtp70bc7wob --- addons/mail/mail_group_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index 755583cc136..d6b852a2cbe 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -13,7 +13,7 @@ - + From 991d9b784399ab0efa602dfba5f6e5beee445356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 1 Feb 2012 16:42:13 +0100 Subject: [PATCH 0006/1161] [FIX] spelling error bzr revid: tde@openerp.com-20120201154213-utvgy12zt49c7jcq --- addons/mail/mail_group_view.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index d6b852a2cbe..ee92758d5f9 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -116,7 +116,7 @@ - + Groups mail.group form @@ -150,22 +150,24 @@ - + - + - + + + - - + - + + + - + - - - + - + + + + + \ No newline at end of file diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 23c131ec66b..c1e8f7aa098 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -82,7 +82,7 @@ class mail_thread(osv.osv): }) return super(mail_thread, self).copy(cr, uid, id, default, context=context) - def message_append(self, cr, uid, threads, subject, body_text=None, email_to=False, + def message_append(self, cr, uid, threads, subject, body_text=None, type='email', email_to=False, email_from=False, email_cc=None, email_bcc=None, reply_to=None, email_date=None, message_id=False, references=None, attachments=None, body_html=None, subtype=None, headers=None, @@ -166,7 +166,8 @@ class mail_thread(osv.osv): 'message_id': message_id, 'body_text': body_text or (hasattr(thread, 'description') and thread.description or False), 'attachment_ids': [(6, 0, to_attach)], - 'state' : 'received', + 'state': 'received', + 'type': type, } if email_from: @@ -215,9 +216,12 @@ class mail_thread(osv.osv): to determine the model of the thread to update (instead of the current model). """ + # 6.2 Social feature: add default email type for old API + if not 'type' in msg_dict: msg_dict['type'] = 'email' return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), body_text = msg_dict.get('body_text'), + type = msg_dict.get('type'), email_to = msg_dict.get('to'), email_from = msg_dict.get('from'), email_cc = msg_dict.get('cc'), @@ -235,8 +239,15 @@ class mail_thread(osv.osv): context = context) # Message loading - def message_load(self): - pass + def message_load(self, cr, uid, ids, context=None): + """ Social feature added this method + loading message: search in mail.messages where res_id = ids, (res_)model = current model """ + msg_obj = self.pool.get('mail.message') + msg_ids = [] + for id in ids: + msg_ids += msg_obj.search(cr, uid, ['&', ('res_id', '=', id), ('model', '=', self._name)], context=context) + msgs = msg_obj.browse(cr, uid, ids) + return msgs #------------------------------------------------------ # Email specific @@ -484,8 +495,8 @@ class mail_thread(osv.osv): #------------------------------------------------------ # Note specific #------------------------------------------------------ - def message_append_note(self, context, type='notification'): - pass + def message_append_note(self, cr, uid, ids, subject, body, type='notification', context=None): + return self.message_append(cr, uid, ids, subject, body_text=body, type=type, context=context) #------------------------------------------------------ # Subscription mechanism From a83847d6f74f832fa9c49a70cf9560f51c281007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 2 Feb 2012 11:35:01 +0100 Subject: [PATCH 0012/1161] [ADD] Implementation of subscription mechanism methods bzr revid: tde@openerp.com-20120202103501-0tt9epmzkfcuf8xz --- addons/mail/mail_thread.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index c1e8f7aa098..8d5a05fb2bb 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -501,16 +501,27 @@ class mail_thread(osv.osv): #------------------------------------------------------ # Subscription mechanism #------------------------------------------------------ - def message_get_subscribers(self): - pass - - def message_subscribe(self): - pass - - def message_unsubscribe(self): - pass - + def message_get_subscribers(self, cr, uid, ids, context=None): + subscription_obj = self.pool.get('mail.subscription') + for id in ids: + sub_ids = subscription_obj.search(cr, uid, ['res_model': self._name, 'res_id': id], context=context) + subs = subscription_obj.browse(cr, uid, sub_ids, context=context) + return subs + def message_subscribe(self, cr, uid, ids, context=None): + subscription_obj = self.pool.get('mail.subscription') + subscriber_id = uid # TODO + for id in ids: + subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': subscriber_id}, context=context) + return True + def message_unsubscribe(self, cr, uid, ids, context=None): + subscription_obj = self.pool.get('mail.subscription') + subscriber_id = uid # TODO + sub_ids = [] + for id in ids: + sub_ids += subscription_obj.search(cr, uid, ['res_model': self._name, 'res_id': id, 'user_id': subscriber_id], context=context) + subscription_obj.unlink(cr, uid, ids, context=context) + return True # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 109647a109de0f0c45329570ff1b5e863359717e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 2 Feb 2012 12:26:57 +0100 Subject: [PATCH 0013/1161] [IMP] Added push of messages when creating one. Fixed bugs in mail_thread subscription mechanism. Added list views for subscriptions and notifications. Subscription is now unread by default. bzr revid: tde@openerp.com-20120202112657-zj406ck98n06imo9 --- addons/mail/mail_message.py | 20 +++++++++++--- addons/mail/mail_subscription.py | 5 ++-- addons/mail/mail_subscription_view.xml | 36 ++++++++++++++++++++++++++ addons/mail/mail_thread.py | 4 +-- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 877ffd972b6..dfd2fe00b92 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -71,8 +71,8 @@ class mail_message_common(osv.osv_memory): _rec_name = 'subject' _columns = { 'subject': fields.char('Subject', size=512, required=True), - 'model': fields.char('Related Document model', size=128, select=1), # was rfeadonly - 'res_id': fields.integer('Related Document ID', select=1), # was rfeadonly + 'model': fields.char('Related Document model', size=128, select=1), # was readonly + 'res_id': fields.integer('Related Document ID', select=1), # was readonly 'date': fields.datetime('Date'), 'email_from': fields.char('From', size=128, help='Message sender, taken from user preferences. If empty, this is not a mail but a message.'), 'email_to': fields.char('To', size=256, help='Message recipients'), @@ -191,11 +191,23 @@ class mail_message(osv.osv): } #------------------------------------------------------ - # Note specific api + # Generic api #------------------------------------------------------ def create(self, cr, uid, vals, context=None): - return super(mail_message, self).create(cr, uid, vals, context) + msg_id = super(mail_message, self).create(cr, uid, vals, context) + # push the message to suscribed users + subscription_obj = self.pool.get('mail.subscription') + notification_obj = self.pool.get('mail.notification') + sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', vals['model']), ('user_id', '=', uid)], context=context) + subs = subscription_obj.browse(cr, uid, sub_ids, context=context) + for sub in subs: + notification_obj.create(cr, uid, {'user_id': sub.user_id, 'message_id': msg_id}, context=context) + return msg_id + + #------------------------------------------------------ + # Note specific api + #------------------------------------------------------ def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): if not context or not context.has_key('filter_search'): diff --git a/addons/mail/mail_subscription.py b/addons/mail/mail_subscription.py index f250ddc42e6..89750c47f5f 100644 --- a/addons/mail/mail_subscription.py +++ b/addons/mail/mail_subscription.py @@ -30,7 +30,7 @@ class mail_subscription(osv.osv): A subscription can be of following: - res_model: model of the followed objects - res_id: ID of resource OR - - res_domain: a domain filtering followed objects + - res_domain: a domain filtering followed objects - currently removed """ _name = 'mail.subscription' @@ -38,7 +38,7 @@ class mail_subscription(osv.osv): _columns = { 'res_model': fields.char('Related Document model', size=128, select=1), 'res_id': fields.integer('Related Document ID', select=1), - 'res_domain': fields.char('res_domain', size=256), + #'res_domain': fields.char('res_domain', size=256), 'user_id': fields.integer('Related User ID', select=1), } @@ -63,6 +63,7 @@ class mail_notification(osv.osv): } _defaults = { + 'read': False, } mail_notification() diff --git a/addons/mail/mail_subscription_view.xml b/addons/mail/mail_subscription_view.xml index 75f0408f341..2850cd206a1 100644 --- a/addons/mail/mail_subscription_view.xml +++ b/addons/mail/mail_subscription_view.xml @@ -2,6 +2,42 @@ + + + + mail.subscription.tree + mail.subscription + tree + 10 + + + + + + + + + + + + + mail.notification.tree + mail.notification + tree + 10 + + + + + + + + + Subscriptions mail.subscription diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 8d5a05fb2bb..e9df98ee955 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -504,7 +504,7 @@ class mail_thread(osv.osv): def message_get_subscribers(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') for id in ids: - sub_ids = subscription_obj.search(cr, uid, ['res_model': self._name, 'res_id': id], context=context) + sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', '=', id)], context=context) subs = subscription_obj.browse(cr, uid, sub_ids, context=context) return subs @@ -520,7 +520,7 @@ class mail_thread(osv.osv): subscriber_id = uid # TODO sub_ids = [] for id in ids: - sub_ids += subscription_obj.search(cr, uid, ['res_model': self._name, 'res_id': id, 'user_id': subscriber_id], context=context) + sub_ids += subscription_obj.search(cr, uid, ['&', '&', ('res_model', '=', self._name), ('res_id', '=', id), ('user_id', '=', subscriber_id)], context=context) subscription_obj.unlink(cr, uid, ids, context=context) return True From 1b9b26693ccc932c820df7cc1ccbe56dfc490fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 2 Feb 2012 15:18:43 +0100 Subject: [PATCH 0014/1161] [ADD] Added first not-working draft for widget. Cleaned message search function. bzr revid: tde@openerp.com-20120202141843-4jq49mbd7a6ecq4b --- addons/mail/__openerp__.py | 16 +++- addons/mail/mail_message.py | 117 +++++++++++++++------------- addons/mail/static/src/js/mail.js | 53 +++++++------ addons/mail/static/src/xml/mail.xml | 17 ++++ 4 files changed, 126 insertions(+), 77 deletions(-) create mode 100644 addons/mail/static/src/xml/mail.xml diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py index ed28c5be365..ec079463230 100644 --- a/addons/mail/__openerp__.py +++ b/addons/mail/__openerp__.py @@ -68,7 +68,19 @@ The main features are: 'installable': True, 'auto_install': False, 'certificate': '001056784984222247309', - 'images': ['images/customer_history.jpeg','images/messages_form.jpeg','images/messages_list.jpeg'], - 'css': ['static/src/css/mail_group.css'], + 'images': [ + 'images/customer_history.jpeg', + 'images/messages_form.jpeg', + 'images/messages_list.jpeg', + ], + 'css': [ + 'static/src/css/mail_group.css', + ], + 'js': [ + 'static/src/js/mail.js', + ], + 'qweb': [ + 'static/src/xml/mail.xml', + ], } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index dfd2fe00b92..b13d9a3d389 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -205,70 +205,81 @@ class mail_message(osv.osv): notification_obj.create(cr, uid, {'user_id': sub.user_id, 'message_id': msg_id}, context=context) return msg_id + def get_pushed_messages(self, cr, uid, context=None): + """Wall: get messages to display""" + notification_obj = self.pool.get('mail.notification') + notification_ids = notification_obj.search(cr, uid, [('user_id', '=', uid)], context=context) + notifications = notification_obj.browse(cr, uid, notification_ids, context=context) + + # TODO / REMARK: classify based on res_model / res_id to have a 1_level hierarchy ? + + return notifications + + #------------------------------------------------------ # Note specific api #------------------------------------------------------ - def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): - if not context or not context.has_key('filter_search'): - return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count) + #def tmp_backup(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): + #if not context or not context.has_key('filter_search'): + #return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count) - # get subscriptions - sub_obj = self.pool.get('mail.subscription') - sub_ids = sub_obj.search(cr, uid, [('user_id', '=', uid)]) - subs = sub_obj.browse(cr, uid, sub_ids) + ## get subscriptions + #sub_obj = self.pool.get('mail.subscription') + #sub_ids = sub_obj.search(cr, uid, [('user_id', '=', uid)]) + #subs = sub_obj.browse(cr, uid, sub_ids) - # stock tweets to find - res_model_ids_dict = {} - res_model_all_list = [] + ## stock tweets to find + #res_model_ids_dict = {} + #res_model_all_list = [] - # check all subscriptions - for sub in subs: - if sub.res_model and sub.res_id == 0 and sub.res_domain == False: - print "s-1" - if sub.res_model not in res_model_all_list: - res_model_all_list.append(sub.res_model) - elif sub.res_model and sub.res_id: - print "s-2" - if res_model_ids_dict.has_key(sub.res_model): - res_model_ids_dict[sub.res_model].append(sub.res_id) - else: - res_model_ids_dict[sub.res_model] = [sub.res_id] - elif sub.res_model and sub.res_domain: - print "s-3" - res_obj = self.pool.get(sub.res_model) - print sub.res_domain - #res_ids = res_obj.search(cr, uid, [('id', 'in', [1,2])]) - res_ids = res_obj.search(cr, uid, eval(sub.res_domain)) - if res_model_ids_dict.has_key(sub.res_model): - res_model_ids_dict[sub.res_model] += res_ids - else: - res_model_ids_dict[sub.res_model] = res_ids - print 'cacaprout' - else: - print 'erreur !!!' - print sub + ## check all subscriptions + #for sub in subs: + #if sub.res_model and sub.res_id == 0 and sub.res_domain == False: + #print "s-1" + #if sub.res_model not in res_model_all_list: + #res_model_all_list.append(sub.res_model) + #elif sub.res_model and sub.res_id: + #print "s-2" + #if res_model_ids_dict.has_key(sub.res_model): + #res_model_ids_dict[sub.res_model].append(sub.res_id) + #else: + #res_model_ids_dict[sub.res_model] = [sub.res_id] + #elif sub.res_model and sub.res_domain: + #print "s-3" + #res_obj = self.pool.get(sub.res_model) + #print sub.res_domain + ##res_ids = res_obj.search(cr, uid, [('id', 'in', [1,2])]) + #res_ids = res_obj.search(cr, uid, eval(sub.res_domain)) + #if res_model_ids_dict.has_key(sub.res_model): + #res_model_ids_dict[sub.res_model] += res_ids + #else: + #res_model_ids_dict[sub.res_model] = res_ids + #print 'cacaprout' + #else: + #print 'erreur !!!' + #print sub - # add fully-followed domains - args.append('|') - args.append(['model', 'in', res_model_all_list]) + ## add fully-followed domains + #args.append('|') + #args.append(['model', 'in', res_model_all_list]) - # add partially-followed domains - for x in range(0, len(res_model_ids_dict.keys())-1): - args.append('|') + ## add partially-followed domains + #for x in range(0, len(res_model_ids_dict.keys())-1): + #args.append('|') - for res_model in res_model_ids_dict.keys(): - if res_model not in res_model_all_list: - args.append('&') - args.append(['model', '=', res_model]) - args.append(['res_id', 'in', res_model_ids_dict[res_model]]) + #for res_model in res_model_ids_dict.keys(): + #if res_model not in res_model_all_list: + #args.append('&') + #args.append(['model', '=', res_model]) + #args.append(['res_id', 'in', res_model_ids_dict[res_model]]) - if context and context.has_key('filter_search'): - pass - else: - args = [] - print args - return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit,order=order, context=context, count=count) + #if context and context.has_key('filter_search'): + #pass + #else: + #args = [] + #print args + #return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit,order=order, context=context, count=count) #------------------------------------------------------ # E-Mail api diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 2e81741f62a..6e23d813702 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -1,25 +1,34 @@ openerp.mail = function(session) { - -var mail = session.mail = {}; - -mail.Wall = session.web.Widget.extend({ - init: function(parent) { - }, - start: function() { - this.$element - }, -}); - -session.ThreadView - -session.MessgageInput - - - -var w = new session.mail.ThreadView(this); - -w.appendTo($("div.wall")); - - + + var mail = session.mail = {}; + + mail.Wall = session.web.Widget.extend({ + init: function(parent) { + }, + start: function() { +// this.$element + }, + }); + + mail.ThreadView = session.web.Widget.extend({ + template: 'MailTest', + + init: function(parent) { + }, + + start: function() { +// this.$element + }, + }); + + mail.MessgageInput = session.web.Widget.extend({ + }); + + + var tv = new mail.ThreadView(this); +// tv.appendTo($("div.wall")); +// tv.appendTo($("body")); + }; + // 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..005b4b23a79 --- /dev/null +++ b/addons/mail/static/src/xml/mail.xml @@ -0,0 +1,17 @@ + + \ No newline at end of file From babb03a00fcf01534c3b8bde56710c3799c6af2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 3 Feb 2012 09:48:25 +0100 Subject: [PATCH 0015/1161] First draft of javascript work for threadview bzr revid: tde@openerp.com-20120203084825-nyskuc8kxlljox0z --- addons/crm/crm_lead_view.xml | 43 +++++++++++++++++-------------- addons/mail/mail_thread.py | 1 + addons/mail/mail_thread_view.xml | 1 + addons/mail/static/src/js/mail.js | 5 ++-- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 44d83f47634..6218d00f044 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -547,27 +547,30 @@ - + - - - - - -
- +
@@ -25,12 +25,14 @@
-
+
Image
-
-
-
- +
+

+
+
+ +

From b6739df2973dd7743a38165ce6e69c217b50d9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 7 Feb 2012 11:16:57 +0100 Subject: [PATCH 0025/1161] Tmp action button add for res_log testing purpose bzr revid: tde@openerp.com-20120207101657-phoxiwpa5q4g35sk --- addons/mail/mail_group.py | 11 +++++++---- addons/mail/mail_group_view.xml | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py index ff634e58d70..50141bf27a0 100644 --- a/addons/mail/mail_group.py +++ b/addons/mail/mail_group.py @@ -49,11 +49,14 @@ class mail_group(osv.osv): return True - def action_follow(self, cr, uid, ids, context={}): - return self.message_subscribe(cr, uid, ids, context=context) + def action_test(self, cr, uid, ids, context={}): + for o in self.browse(cr, uid, ids): + message = _('You are doing things with the group %s, wooooh !') % (o.name,) + self.log(cr, uid, o.id, message) + return True - def action_unfollow(self, cr, uid, ids, context={}): - return self.message_unsubscribe(cr, uid, ids, context=context) + def action_null(self, cr, uid, ids, context={}): + return True _columns = { #'group_id': fields.many2one('res.groups', required=True, ondelete='cascade', diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index ff489b09734..7ec4e26b25b 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -103,6 +103,9 @@
-
-

- 00000000 - 11111111 - 00000000 - 11111111 - 00000000 - 11111111 - 00000000 - 11111111 -

-
+ + zmeofizepofinzepfoiznepfoizpfozeinfpzoeinfpoznf zfe zef zef ze fz efz efz ef zef ze fz efznf zfe zef zef ze fz efz efz ef zef ze fz efznf zfe zef zef ze fz efz efz ef zef ze fz ef +
Image

-
-
- + zmeofizepofinzepfoiznepfoizpfozeinfpzoeinfpoznf zfe zef zef ze fz efz efz ef zef ze fz efznf zfe zef zef ze fz efz efz ef zef ze fz efznf zfe zef zef ze fz efz efz ef zef ze fz ef + + + +

From cff98a3aeb4b2308d00dc4b91b283ab79e322c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 8 Feb 2012 16:25:21 +0100 Subject: [PATCH 0027/1161] [IMP] Improved ThreadView widget display; cleaned ThreadView widget js code; added basic access rules; added message_mark_done method to clean a mail.thread of its need_action_user_id; added auto-push of notifications if user requested to perform an action is not following the object; added first draft of messaging mechanism in hr_holidays bzr revid: tde@openerp.com-20120208152521-68i4nekjj8mnuyc8 --- addons/hr_holidays/hr_holidays.py | 21 ++++++++++- addons/hr_holidays/hr_holidays_view.xml | 1 + addons/mail/mail_group.py | 6 --- addons/mail/mail_group_view.xml | 12 ------ addons/mail/mail_message.py | 10 ++++- addons/mail/mail_thread.py | 17 ++++++--- addons/mail/mail_thread_view.xml | 10 +++++ addons/mail/security/ir.model.access.csv | 2 + addons/mail/static/src/css/mail.css | 47 ++++++++++++++++-------- addons/mail/static/src/js/mail.js | 38 +++++++------------ addons/mail/static/src/xml/mail.xml | 44 ++++++++++++---------- 11 files changed, 123 insertions(+), 85 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 3bb7a8e4982..2ddb6e87a3a 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -93,6 +93,7 @@ class hr_holidays(osv.osv): _name = "hr.holidays" _description = "Leave" _order = "type desc, date_from asc" + _inherit = ['mail.thread'] def _employee_get(self, cr, uid, context=None): ids = self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context) @@ -250,8 +251,16 @@ class hr_holidays(osv.osv): obj_emp = self.pool.get('hr.employee') ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)]) manager = ids2 and ids2[0] or False + self.holidays_validate_notificate(cr, uid, ids, context=context) return self.write(cr, uid, ids, {'state':'validate1', 'manager_id': manager}) + def holidays_validate_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids): + self.message_mark_done(cr, uid, [obj.id], context=context) + self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' has been validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) + if obj.holiday_status_id.double_validation: + self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' is waiting for second validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) + def holidays_validate2(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) obj_emp = self.pool.get('hr.employee') @@ -301,13 +310,23 @@ class hr_holidays(osv.osv): wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'validate', cr) wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'second_validate', cr) if holiday_ids: + self.holidays_valid2_notificate(self, cr, uid, [holiday_ids], context=context) self.write(cr, uid, holiday_ids, {'manager_id2': manager}) return True + + def holidays_valid2_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids): + self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' has been double validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) def holidays_confirm(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) + self.holidays_confirm_notificate(cr, uid, ids, context=context) return self.write(cr, uid, ids, {'state':'confirm'}) - + + def holidays_confirm_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids): + self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' has been confirmed and is waiting for validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', need_action_user_id=obj.employee_id.parent_id.user_id.id) + def holidays_refuse(self, cr, uid, ids, approval, context=None): obj_emp = self.pool.get('hr.employee') ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)]) diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml index 22d4d6e567d..2096ae2bc61 100644 --- a/addons/hr_holidays/hr_holidays_view.xml +++ b/addons/hr_holidays/hr_holidays_view.xml @@ -95,6 +95,7 @@ +
+
+
\ No newline at end of file From 9efc4714f26757a127861119e549f7718af3e136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 9 Feb 2012 11:04:47 +0100 Subject: [PATCH 0030/1161] [IMP] Wall: added parameters passing (filtering, message number to display, ..). Added My Wall (all feeds versus my feeds). bzr revid: tde@openerp.com-20120209100447-p8csuqq85jsexrdn --- addons/hr_holidays/hr_holidays.py | 8 ++++---- addons/mail/mail_message.py | 2 +- addons/mail/mail_message_view.xml | 7 +++++++ addons/mail/mail_thread_view.xml | 19 ++++++++++++++----- addons/mail/static/src/js/mail.js | 9 ++++++--- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 2ddb6e87a3a..8fd91c30581 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -257,9 +257,9 @@ class hr_holidays(osv.osv): def holidays_validate_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_mark_done(cr, uid, [obj.id], context=context) - self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' has been validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) + self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) if obj.holiday_status_id.double_validation: - self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' is waiting for second validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) + self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' is waiting for second validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) def holidays_validate2(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) @@ -316,7 +316,7 @@ class hr_holidays(osv.osv): def holidays_valid2_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): - self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' has been double validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) + self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been double validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) def holidays_confirm(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) @@ -325,7 +325,7 @@ class hr_holidays(osv.osv): def holidays_confirm_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): - self.message_append_note(cr, uid, [obj.id], 'System notification', _("The %s request '%s' has been confirmed and is waiting for validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', need_action_user_id=obj.employee_id.parent_id.user_id.id) + self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been confirmed and is waiting for validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', need_action_user_id=obj.employee_id.parent_id.user_id.id) def holidays_refuse(self, cr, uid, ids, approval, context=None): obj_emp = self.pool.get('hr.employee') diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 2ecdad5ceca..28e02401244 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -216,7 +216,7 @@ class mail_message(osv.osv): notification_obj.create(cr, uid, {'user_id': vals['need_action_user_id'], 'message_id': msg_id}, context=context) return msg_id - def get_pushed_messages(self, cr, uid, context=None): + def get_pushed_messages(self, cr, uid, ids, filter_search=False, context=None): """Wall: get messages to display""" notification_obj = self.pool.get('mail.notification') notification_ids = notification_obj.search(cr, uid, [('user_id', '=', uid)], context=context) diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index 4ccf7d44323..0036897d411 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -230,6 +230,13 @@ (w)All Feeds mail.all_feeds + + + + + My Feeds + mail.all_feeds +
diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index 7bd503b0546..d2e557d06d8 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -51,26 +51,35 @@
- + + Feeds + + + + - - - + + My Feeds + + + + (w)All Feeds - + + diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index bd82399b88e..747276121fa 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -95,8 +95,9 @@ openerp.mail = function(session) { // QWeb template to use when rendering the object template: 'WallView', - init: function() { - this._super.apply(this, arguments); + init: function (parent, params) { + this._super(parent); + this.filter_search = params['filter_search']; /* DataSets */ this.ds_msg = new session.web.DataSet(this, 'mail.message'); }, @@ -104,8 +105,9 @@ openerp.mail = function(session) { start: function() { var self = this; this._super.apply(this, arguments); + console.log(this); self.$element.find('button.oe_mail_action_comment').bind('click', function () { self.do_comment(); }); - this.ds_msg.call('get_pushed_messages', []).then( + this.ds_msg.call('get_pushed_messages', [[], self.filter_search]).then( this.proxy('display_records')); }, @@ -114,6 +116,7 @@ openerp.mail = function(session) { }, fetch_messages: function () { + console.log('debug--fetch_messages'); return this.ds_msg.call('get_pushed_messages', []).then( this.proxy('display_records')); }, From 1d09919c1810c575d3c2bd74ef76b54ceca44d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 10 Feb 2012 10:53:48 +0100 Subject: [PATCH 0031/1161] [FIX] Fixed bug with message dict not necessarily containing a 'type' entry bzr revid: tde@openerp.com-20120210095348-z8m7gqpse6hw9byr --- addons/mail/mail_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 28e02401244..58e5833fa49 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -198,7 +198,7 @@ class mail_message(osv.osv): def create(self, cr, uid, vals, context=None): # OpenSocial: notifications do not come from any user but from system - if vals['type'] == 'notification': vals['user_id'] = False + if vals.get('type') == 'notification': vals['user_id'] = False need_action_pushed = False msg_id = super(mail_message, self).create(cr, uid, vals, context) # push the message to suscribed users From 62a33c175a16471db9e9b2ad5555beaca27ddd7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 10 Feb 2012 11:25:37 +0100 Subject: [PATCH 0032/1161] [FIX] Fixed crash when assigning need_action_user_id to unexistent manager_id for holidays validation bzr revid: tde@openerp.com-20120210102537-rrvk58ttasnfmoqq --- addons/hr_holidays/hr_holidays.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 8fd91c30581..a2acea4792d 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -325,7 +325,7 @@ class hr_holidays(osv.osv): def holidays_confirm_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): - self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been confirmed and is waiting for validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', need_action_user_id=obj.employee_id.parent_id.user_id.id) + self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been confirmed and is waiting for validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', need_action_user_id = obj.employee_id.parent_id.user_id.id if obj.employee_id.parent_id else False) def holidays_refuse(self, cr, uid, ids, approval, context=None): obj_emp = self.pool.get('hr.employee') From 5042ba24658d48ffbd500484b6e01c0712f0ada5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 10 Feb 2012 11:52:23 +0100 Subject: [PATCH 0033/1161] [IMP] Cleaned xml, css and js for ThreadView. bzr revid: tde@openerp.com-20120210105223-fv24nic79ycldc2i --- addons/mail/static/src/css/mail.css | 75 ++++++++++++++++++++++------- addons/mail/static/src/js/mail.js | 26 +++++----- addons/mail/static/src/xml/mail.xml | 33 ++++++++----- 3 files changed, 93 insertions(+), 41 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 906bdbff6cf..baf7a98d71f 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -1,43 +1,74 @@ /** ThreadView widget **/ .oe_mail_main { + overflow: auto; + padding: 5px 5px 5px 5px; } +/* 2 columns view */ +.oe_mail_main_left { + float: left; + width: 65%; +} + +.oe_mail_main_right { + float: right; + width: 34%; +} + +/* Left-side CSS */ .oe_mail_actions { - padding-bottom: 10px; + margin-bottom: 10px; } .oe_mail_post_comment { - width: 65%; - padding-bottom: 10px; + margin-bottom: 10px; } -.oe_mail_comments { - width: 65%; +.oe_mail_button_follow, .oe_mail_button_unfollow, .oe_mail_button_getfollowers, .oe_mail_button_hidefollowers { + width: 100px; +} + +.oe_mail_button_comment { + width: 150px; +} + +.oe_mail_action_textarea { + width: 60%; + height: 50px; + padding: 5px; +} + +.oe_mail_action_comment { } .oe_mail_msg { - width: 65%; -/* border: 1px solid #998877; */ - padding: 10px 0px 10px 0px; } -.oe_mail_msg:after { +/*.oe_mail_msg:after { content: ""; display: block; clear: both; +}*/ + +.oe_mail_comment { + white-space: normal; + margin-bottom: 5px; } .oe_mail_msg_image { float: left; - width: 9%; + width: 14%; +} + +.oe_mail_msg_image img { + width: 80%; + margin-left: 10%; } .oe_mail_msg_content { - width: 89%; - margin-left: 10%; -/* border: 1px solid #557722; */ - overflow: hidden; + width: 85%; + margin-left: 15%; } .oe_mail_msg_p { @@ -48,14 +79,24 @@ .oe_mail_msg_body { } -.oe_mail_msg_author { +.oe_mail_msg_author, .oe_mail_msg_author a { color: #4E43E7; } -.oe_mail_msg_need_action { +.oe_mail_msg_need_action, .oe_mail_msg_need_action a { color: #C03000; } -.oe_mail_msg_date { +.oe_mail_msg_date, .oe_mail_msg_date a { color: #4E43E7; } + +/* Right-side CSS */ +.oe_mail_followers_vignette { + float: left; + width: 20%%; +} + +.oe_mail_followers_vignette img { + width: 80%; +} diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 747276121fa..93a333335a8 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -27,15 +27,15 @@ openerp.mail = function(session) { var self = this; this._super.apply(this, arguments); /* bind follow and unfollow buttons */ - self.$element.find('button.oe_mail_action_follow').bind('click', function () { self.do_follow(); }); - self.$element.find('button.oe_mail_action_follow').hide(); - self.$element.find('button.oe_mail_action_unfollow').bind('click', function () { self.do_unfollow(); }); - self.$element.find('button.oe_mail_action_unfollow').hide(); - self.$element.find('button.oe_mail_action_comment').bind('click', function () { self.do_comment(); }); + self.$element.find('button.oe_mail_button_follow').bind('click', function () { self.do_follow(); }); + self.$element.find('button.oe_mail_button_follow').hide(); + self.$element.find('button.oe_mail_button_unfollow').bind('click', function () { self.do_unfollow(); }); + self.$element.find('button.oe_mail_button_unfollow').hide(); + self.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); /* find wich (un)follow buttons to show */ var call_res = this.ds.call('message_is_subscriber', [[this.session.uid]]).then(function (records) { - if (records == true) { self.follow_state = 1; self.$element.find('button.oe_mail_action_unfollow').show(); } - else { self.follow_state = 0; self.$element.find('button.oe_mail_action_follow').show(); } + if (records == true) { self.follow_state = 1; self.$element.find('button.oe_mail_button_unfollow').show(); } + else { self.follow_state = 0; self.$element.find('button.oe_mail_button_follow').show(); } }); }, @@ -56,27 +56,27 @@ openerp.mail = function(session) { }, display_records: function (records) { - this.$element.find('div.oe_mail_comments').empty(); + this.$element.find('div.oe_mail_msg').empty(); var self = this; _(records).each(function (record) { var template = 'ThreadMsgView'; var render_res = session.web.qweb.render(template, { 'record': record, }); - $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_comments')); + $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_msg')); }); // this.timeout = setTimeout(this.proxy('fetch_messages'), 5000); }, do_follow: function () { - this.$element.find('button.oe_mail_action_unfollow').show(); - this.$element.find('button.oe_mail_action_follow').hide(); + this.$element.find('button.oe_mail_button_unfollow').show(); + this.$element.find('button.oe_mail_button_follow').hide(); return this.ds_sub.create({'res_model': this.view.model, 'user_id': this.session.uid, 'res_id': this.view.datarecord.id}).then(); }, do_unfollow: function () { - this.$element.find('button.oe_mail_action_follow').show(); - this.$element.find('button.oe_mail_action_unfollow').hide(); + this.$element.find('button.oe_mail_button_follow').show(); + this.$element.find('button.oe_mail_button_unfollow').hide(); return this.ds.call('message_unsubscribe', [[this.view.datarecord.id]]).then(); }, diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 58e242829b6..72fbf8d0f88 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -3,17 +3,28 @@
OpenSocial
-
- - +
+
+ + +
+
+
+ +
+
+
+
+
-
-
- -
-
+
+ + +
+
+
Image
@@ -23,15 +34,15 @@ OpenERP System Notification
- + - - Need action + - Need action by

- +

From 628989451d3f4ceab62dfdfce110d126b8f0b96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 10 Feb 2012 13:42:53 +0100 Subject: [PATCH 0034/1161] [IMP] Changed mail.subscription.user_id field from integer to many2one bzr revid: tde@openerp.com-20120210124253-mx7vgxhmzpfant62 --- addons/mail/mail_subscription.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_subscription.py b/addons/mail/mail_subscription.py index c5b5407190b..eaf53bc1c17 100644 --- a/addons/mail/mail_subscription.py +++ b/addons/mail/mail_subscription.py @@ -39,7 +39,8 @@ class mail_subscription(osv.osv): select=1, required=True), 'res_id': fields.integer('Related Document ID', select=1), #'res_domain': fields.char('res_domain', size=256), - 'user_id': fields.integer('Related User ID', select=1, required=True), + 'user_id': fields.many2one('res.users', string='Related User ID', + ondelete='cascade', required=True, select=1), } _defaults = { } From a123480d2c123f011265eff253d787cca27fb57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 10 Feb 2012 13:43:48 +0100 Subject: [PATCH 0035/1161] [IMP] Added a 'get followers' button on ThreadWidget. Basic displaying of results added. bzr revid: tde@openerp.com-20120210124348-8s73xmswnfypqhx6 --- addons/mail/mail_thread.py | 7 +++++++ addons/mail/static/src/css/mail.css | 2 +- addons/mail/static/src/js/mail.js | 28 +++++++++++++++++++++++----- addons/mail/static/src/xml/mail.xml | 10 +++++----- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index f582bc50062..68bf4429d18 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -543,6 +543,13 @@ class mail_thread(osv.osv): subs = subscription_obj.browse(cr, uid, sub_ids, context=context) return subs + def message_get_subscribers_web(self, cr, uid, ids, context=None): + subscription_obj = self.pool.get('mail.subscription') + for id in ids: + sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', '=', id)], context=context) + subs = subscription_obj.read(cr, uid, sub_ids, context=context) + return subs + def message_is_subscriber(self, cr, uid, ids, context=None): for subscription in self.message_get_subscribers(cr, uid, ids, context=context): if subscription.user_id == uid: return True diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index baf7a98d71f..0d153ce0c06 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -25,7 +25,7 @@ margin-bottom: 10px; } -.oe_mail_button_follow, .oe_mail_button_unfollow, .oe_mail_button_getfollowers, .oe_mail_button_hidefollowers { +.oe_mail_button_follow, .oe_mail_button_unfollow, .oe_mail_button_followers { width: 100px; } diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 93a333335a8..fa7037bcacb 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -32,6 +32,7 @@ openerp.mail = function(session) { self.$element.find('button.oe_mail_button_unfollow').bind('click', function () { self.do_unfollow(); }); self.$element.find('button.oe_mail_button_unfollow').hide(); self.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); + self.$element.find('button.oe_mail_button_followers').bind('click', function () { self.do_toggle_followers(); }); /* find wich (un)follow buttons to show */ var call_res = this.ds.call('message_is_subscriber', [[this.session.uid]]).then(function (records) { if (records == true) { self.follow_state = 1; self.$element.find('button.oe_mail_button_unfollow').show(); } @@ -47,15 +48,18 @@ openerp.mail = function(session) { set_value: function() { this._super.apply(this, arguments); if (! this.view.datarecord.id) { return; } - return this.fetch_messages(); + return this.fetch_data(); }, - fetch_messages: function () { - return this.ds.call('message_load', [[this.view.datarecord.id]]).then( - this.proxy('display_records')); + fetch_data: function () { + var load_res = this.ds.call('message_load', [[this.view.datarecord.id]]).then( + this.proxy('display_comments')); + var follow_res = this.ds.call('message_get_subscribers_web', [[this.view.datarecord.id]]).then( + this.proxy('display_followers')); + return follow_res; }, - display_records: function (records) { + display_comments: function (records) { this.$element.find('div.oe_mail_msg').empty(); var self = this; _(records).each(function (record) { @@ -68,6 +72,16 @@ openerp.mail = function(session) { // this.timeout = setTimeout(this.proxy('fetch_messages'), 5000); }, + display_followers: function (records) { + this.$element.find('div.oe_mail_followers').empty(); + var self = this; + _(records).each(function (record) { + console.log(record); +//
+ $('
').text(record.user_id[1]).appendTo(self.$element.find('div.oe_mail_followers')); + }); + }, + do_follow: function () { this.$element.find('button.oe_mail_button_unfollow').show(); this.$element.find('button.oe_mail_button_follow').hide(); @@ -85,6 +99,10 @@ openerp.mail = function(session) { return this.ds.call('message_append_note', [[this.view.datarecord.id], 'Reply comment', body_text, type='comment']).then( this.proxy('fetch_messages')); }, + + do_toggle_followers: function () { + this.$element.find('div.oe_mail_followers').toggle(); + }, }); /* Add WallView widget to registry */ diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 72fbf8d0f88..ff8386f32b9 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -18,13 +18,13 @@
- - -
-
+
+ +
+
+
-
Image
From fcbd3d26dca82b0c265abd45504b083e54f9ad9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 16 Feb 2012 14:34:44 +0100 Subject: [PATCH 0036/1161] [IMP] hr: added parent_id in demo data for employees, allowing to test the need_action_user_id feature with hr.holidays with demo data bzr revid: tde@openerp.com-20120216133444-byv4m8vkh8g68uoe --- addons/hr/hr_demo.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/addons/hr/hr_demo.xml b/addons/hr/hr_demo.xml index b6a11f0b111..00b2ab325e4 100644 --- a/addons/hr/hr_demo.xml +++ b/addons/hr/hr_demo.xml @@ -165,6 +165,7 @@ Fabien Pinckaers + Grand-Rosière @@ -177,6 +178,7 @@ Antony Lesuisse + Grand-Rosière @@ -189,6 +191,7 @@ Minh Tran + Grand-Rosière @@ -202,6 +205,7 @@ Nicolas Vanhoren + Grand-Rosière @@ -214,6 +218,7 @@ Stéphane Wirtel + Grand-Rosière @@ -226,6 +231,7 @@ Christophe Simonis + Grand-Rosière @@ -238,6 +244,7 @@ Quentin De Paoli + Grand-Rosière @@ -249,6 +256,7 @@ Fabien Meghazi + Grand-Rosière @@ -260,6 +268,7 @@ Francois Pietquin + Grand-Rosière @@ -272,6 +281,7 @@ Julien Thewys + Grand-Rosière @@ -296,6 +306,7 @@ Valérie Descamps + Grand-Rosière From 8e14b6a70661dc367e20357afb3550bf12798465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 16 Feb 2012 14:43:19 +0100 Subject: [PATCH 0037/1161] [FIX] hr: updated demo data for employee_fp referencing itself as manager bzr revid: tde@openerp.com-20120216134319-8r8ty5h3wbnrkd35 --- addons/hr/hr_demo.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/hr/hr_demo.xml b/addons/hr/hr_demo.xml index 00b2ab325e4..f82e2dac39e 100644 --- a/addons/hr/hr_demo.xml +++ b/addons/hr/hr_demo.xml @@ -165,7 +165,6 @@ Fabien Pinckaers - Grand-Rosière @@ -174,6 +173,10 @@ /9j/4AAQSkZJRgABAQEAZABkAAD/4gv4SUNDX1BST0ZJTEUAAQEAAAvoAAAAAAIAAABtbnRyUkdCIFhZWiAH2QADABsAFQAkAB9hY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAA9tYAAQAAAADTLQAAAAAp+D3er/JVrnhC+uTKgzkNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBkZXNjAAABRAAAAHliWFlaAAABwAAAABRiVFJDAAAB1AAACAxkbWRkAAAJ4AAAAIhnWFlaAAAKaAAAABRnVFJDAAAB1AAACAxsdW1pAAAKfAAAABRtZWFzAAAKkAAAACRia3B0AAAKtAAAABRyWFlaAAAKyAAAABRyVFJDAAAB1AAACAx0ZWNoAAAK3AAAAAx2dWVkAAAK6AAAAId3dHB0AAALcAAAABRjcHJ0AAALhAAAADdjaGFkAAALvAAAACxkZXNjAAAAAAAAAB9zUkdCIElFQzYxOTY2LTItMSBibGFjayBzY2FsZWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAACSgAAAPhAAAts9jdXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4AsgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//2Rlc2MAAAAAAAAALklFQyA2MTk2Ni0yLTEgRGVmYXVsdCBSR0IgQ29sb3VyIFNwYWNlIC0gc1JHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAAYpkAALeFAAAY2lhZWiAAAAAAAAAAAABQAAAAAAAAbWVhcwAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWFlaIAAAAAAAAAMWAAADMwAAAqRYWVogAAAAAAAAb6IAADj1AAADkHNpZyAAAAAAQ1JUIGRlc2MAAAAAAAAALVJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUMgNjE5NjYtMi0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLXRleHQAAAAAQ29weXJpZ2h0IEludGVybmF0aW9uYWwgQ29sb3IgQ29uc29ydGl1bSwgMjAwOQAAc2YzMgAAAAAAAQxEAAAF3///8yYAAAeUAAD9j///+6H///2iAAAD2wAAwHX/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABaAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDvvH/wU1XVJpp9Fj0S+TflVedo2/8AQCP/AB6vI9Z+DfxD0vfcx+ALn5f47G4hmb8lk3/+O16p8WPh1Lqs76l4ekiS9/59ppPLV/8AclHzRt/47/u14lrfiD4meEJIUutf8ZaXE00kUG/U5pIXkjZkdUYuyNhl+7/wL7tevRnP7Ml8zyMTCHN70X8jG1nSfEOjx79Y0PxBpSf3riwuIf8Ax4ptra0LTk03SZtY1X/j4ZF8iCaRvkhf+OXP8R/hX/gVdP4P+L3xPuNN1K9vfFslxptvD9mT7RaQ+Y1xKrBNrxxqfk/1n/fNcdryPeabZaakcr3FxdM1zd3MnmM8j8szZ/5af3mb5q3p8/2zlfJ8UdfU43xb4p1Ce1dIpI0indt33tzrtx1rn5rvULsJaW8/+q+bb/y0dv72P4quy2TzSTTNH8zOzN+7+4vzf0qPWdMuIZIXf/Wr8jbPvfIzDt/u0TgTTqQLWhpKkHnX3yW8u5F/ebWZuobHB4rv/B+rXCWiWz+VePLu8+L5WXyz/eRj83zVwdrpkqWrvdxyzW6f88rjasufSptNvfsDpbpJvZk+6/zQsx/hGfSrE/5jvNa0yL7J/aWleakSor3NtNuVrf5sbkZvvR/+g1hyXD/I/wDf+9/vVa8L69cabrP2a8+S3uPk2vceZby54+Zj92k8X6S+iT+d9zTbj5YJHk/1TfxRO394fw/3l+b+9UC/vRKUlw/l76ktLvfB/uP/AD5rMRll+eKSOb/ck3fyqOOWGGT5/KT+9+FaGfObD3Cbv9Z/5EorL+3WX8dxbZ/66LRQaH3tAm+/tf8Aruv/AKFXmviHTrS8fUIbm3imt7idknV4/MWVQzffQ/K2P4f/AB3bXqFqn/Eytk/g85f/AEKvPNW/4+7r/rvLuX/gTV5UD25nivjpNB8MWumeG7PzIYIHkup1+aRlluGQ8fxbliWJV3fN/DurJ0K4TWIE022/0Z0ulbb5m5k/eZZtw+83zfM1YXxjlf8A4WhqyeZK6QTKu1P721Dt/BWr1r4DeHrG51pL+aOKbyoPlb+4x/8AHV+9Xd8EeY8uHv1eUJ/AGnaPpP8Ax7/PAm6Xf82/e2yX/wBkqlqXg23sNaheazi/dXXzf3XjPDN/8VXuereG/t6eTD8kTI0Uq/7JX+jVS8Q6Db38E9tcx/61P3v930+8Kw9sdv1Y821b4e2L6b9mSzimif5tqe/5f99V5TrvgCbRLt0tvtMNu33oH2yL+RBr6T0K0vv7Jhs7+T/SLVPK83/nrs4V2/2j/FVLUtG86TZN5T/7VEKxE8NGZ8v6Tol3NrX2Z7OKaJvlZX+WN13fxjkN/vLXuvwdE8XidNP0u8udKa4gaKCVI45Gl2Lv8p0bI+7W34p8F6cnhPUNVhs4/Ngh3XO/5flC/M+3+L+7/e2v/srXkvwwu/EMXxa0m2tJPtk76pG3lvJ+8dVZfNf8IpHZ/wDvpauc+eEjCEPYzj5n0lqfgTRtY/5C/gzwlqkz/enuNMjWRvxXmsx/hN4Og2fZvDFjpUq/9A6/Zd3/AABkZa9I2O8nyfJF/e/ip8cSJ9z7/wDerzuaR6nJE84uPAE3nsth4v8AHOlwrgfZLS6tJI4jgdDJAzHP3uWP3uMDABXfMn+k3H++P/QVop88h8sT468M/tWeKLRbdtf8KaTrUkIj33EU72k0jD+NvvJuP+ytW9G+LX277bNbap9tia9klXT9Ujb7RFDJIx2JKv8Ac3fe3Mv+z91a+aQf8/Wtvw1cJbatazSXEcMSzKszS7tqRvw7NtBbbht3yq1dkIRPPnOTO78fTf2r471O5SOWF72682KL/WbN6r8u6vqP4DeHn0HwJBc38fky3XzbX+9FGP8A2Y1534r8DW9nr3hPUbYf6VeOlrth+75cFigjfkBufLdv/Qq+gf7OR9FTTYZNiRIsSt9KdafuKJOGo+85SM/xD4y0zSrTe9vfOip/yxt9zf8AfNc3aeNNO1KTZbfbod//AD827R/1rjfih4JvhcfufG/je3lZ90s8V/tX/cWJdqxrVHw14ImudTe8sJNXhi/dbYprhpFT+9I0rEs2f7tRCEeU3nOXMeqR6jElZ/8AwkOjWd+iXOqWMMv8KzXCrv8Azp/izSbtPDU1npsn/EwitfN3eXu/u5214ZfeHvFf9pWzw+KNJmfzm+1rcWHnR+Xu4ZFZN27b95f++aIQjMJzlA+j/EVzYaj8NfEF1p1zFcSrplyyqnzb9sbMv/oNfL/gP4g2GhXqfES18OfbVsoPssVh9r8nZcS/KX8zY3SLfjj+OvoD4S2mv217DDq/9mXNhdfPFc28fkttO5TFLFltrf7rba+cPHegpo/g3UE02DyVg1qy06WC3j3fvEhumdu//PJGqqPJ70SK05e7L+tD09P2rbl/+aaRf+FF/wDc9WR+1DeNvz8Pbddvrrcjf+0K+ZIILz+C01H5flbZaSf/ABFa1pb6ikbv/Z+pfc/js5F/pW/1Wkcv1zEf0j9APBtw3iDw1Ya3MI4JL+1humjhBKp5kSOFyRk4DAZ4zjOBnAKj+DZJ+GHhtmO0tpFkcf8AbrFRXkyep7kFeKZ+XoTdDN/31Uke1k2t91vl3LU09u9o+yX+L5aZLaXFtJCk0exZUWWNv70b9Gr1DyPjPuH4TunxC+GHh3X57yVr6yjRZ2MnmTLd26pFNv8A99Y0k/7bvur06C4/d7/ub6+Kf2btQ1628WT2FneXv9jJayX+oWqSN5bbNio5X+9uZPmr7G83946VySgdlKfP7walcWn33+fZ/f8AmqPw9qKald3SQx/JaorN+LMF/wDQaxtWR3k2fvXrJu9PtJrTzv7YlsH+ZPPhvPs+/wDvIvPzU+QXOegfZ/tOtTf63elr8q/98iuLv7fSb+ebztPtklt52iZvL/iDYb5f96uTjh8aXN28MN5KkqOv2a5SSFvNUfxKvP8A6DW5YQypG/nSedL9+WR/vPIeWZqvk5PtBz8/Q7fwn5Vs9t5PleVvX7n3du6vHvFOl3Fh8LYNWmcfaNW8VPdfJJ/D5N0q5avTvD3mzSJCnzu+77lY/wAfdOt7DwNpFhZx7LeDV49qvIzN/qbr5iTWcfi9Rz+H0PF7R38t/wDW/fb/AJaUX7/uH/d0+C3f5/8Af/8AiaL+L9xXccJ9XfCuRG+G/ht1dFDaTZnDdf8Aj3joqn8Kd/8AwrXw0q/w6PZA/X7NHRXjT+Jnqw+FHw1b+BtW1qO9mubP7Bv8v7M95+73sG+ZmUfP93/Zrf0T4TeHbFHudWurnV2RGdlU/Z4f/HSXb/vuu0gu3ufntpIn2/eien/aIXtLpPL+fyG3RfxV7Mzy4R5DzlLWyur/APsHRbCPTbCVGlu1i3bmhjVnbexyzZ27Vr6l0TUWvdI0nUBH811plpc7f+ulujV87fD3ZZ6l/pP753tZfPlf/lq3nKjf+O7K9d+G189z8PrPTXk/4mXhr/iUz/w7o4/+Pd/+BwbP++HrOtuXhjrb93vJ/syeaiP95krjNa+F/h6wvn1vRJPsdw3zyweW0lvK3+3Fkdf7ysrV1vh7VrSaTybn9y/8Na1/b6ZNH88kSP8A3ax55QOnkjM8ck8C32q7LZNc+wf7VpHJu+9/fZ2213Ph7Sf7BsEsH1S+v3VN8s99J50zsfvfPxWvHplokn+s+9Rqb2KSIn2iOH5Gllkm+VbeMLl3f/ZC/NROfORCHIcr408f33gzVtMh0e3sbnULpJZZFu42aNLUNs+XaQdzv/6B/tVn+M/iEnjDw9DbXOjyaVdWt6rM32jzoXxHKPvYDL/rK8n8Vay3iPxJpPiXy5Vt9Ukvfs0L/eSyXyvIXv8ANhPMP+0710W/ZpKb/v3G52raEIe7IxnWlzOJp2iff/ub/vU+dP3FYUd28MCTQyeTuT/vhhxWhpt99vg2XPlQ3H/jvP8AFxWhmfTvwgTzvhvoTf3dPtl/KCMUVD8E5kb4c6XGJYmaGJIXCSg7GRFUqfcYoryanxM9Wn8KPlK0l+x3c0M3mw733r/eRv8A4mtrzfOkSF4/9IV/mZPuuv8AeX/Zrn7lme0O9i22fjJzj7/+A/IVZ8OfNdw7ufk7/wC61eseVApSIln4s2fcSXzV/wC+1U/+hLXW6Lqc2lalDrdt9908i+i+6sqiuW8S/L4hh28fOvT/AHWrc0n/AFzr/Dvbjt92iYQOw1byr+B7/SpPv/eV/l6f3v8AaFY0fiHWbb5PM37P7/zf+PVn6MzKyKrEL5B4B44mdR+SgL9ABWncf8fb1A5zZNH4n1m5kRP3Sf7X+z+NcH8TPFV94jP/AAhXh64+XUX8rUr7/nuo5KJ/0zG3c3977v3auePpJE06ZUdlBTkA4BrnPBKquqaoyqAyae20gcr9PSnyomrVnDYfqX2e58QpbWf/AB5aXBFawf7vzb62p5dkaQ/wI7J/uLWFpKr/AGtN8o+bzc8df9KatOf/AFn/AANq1IgEc0Pl7/4Ef90tSWEv+nvN/AibV/H722qsf+r/AOB0R/8As8n/ALJQM6mzxPAssWzB/v8AX2/TFFY9uS0QLHJ96Kgs/9k= + + + + Antony Lesuisse From 67bb1396605c4e145cfd8b0c397a4232e5626de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 16 Feb 2012 17:03:02 +0100 Subject: [PATCH 0038/1161] [REF] mail.thread: fixed an error in is_subscriber, cleaned code; mail.js: threadview widget: cleaned code bzr revid: tde@openerp.com-20120216160302-g5knaca3vie1ekot --- addons/mail/mail_thread.py | 53 ++++++++++-------------- addons/mail/static/src/js/mail.js | 62 +++++++++++++++++------------ addons/mail/static/src/xml/mail.xml | 2 +- 3 files changed, 59 insertions(+), 58 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 68bf4429d18..f63ebde836c 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -241,23 +241,19 @@ class mail_thread(osv.osv): # Message loading def message_load_ids(self, cr, uid, ids, context=None): - """ OpenSocial feature added this method - get ids of thread messages + """ OpenSocial feature: return thread messages ids (for web compatibility) + loading messages: search in mail.messages where res_id = ids, (res_)model = current model """ msg_obj = self.pool.get('mail.message') - msg_ids = [msg_obj.search(cr, uid, ['&', ('res_id', '=', id), ('model', '=', self._name)], context=context) for id in ids] - return msg_ids[0] + msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', 'in', ids), ('model', '=', self._name)], context=context) + return msg_ids def message_load(self, cr, uid, ids, context=None): - """ OpenSocial feature added this method - loading message: search in mail.messages where res_id = ids, (res_)model = current model + """ OpenSocial feature: return thread messages + loading messages: search in mail.messages where res_id = ids, (res_)model = current model """ - msg_ids = [] - msg_obj = self.pool.get('mail.message') - for id in ids: - msg_ids += msg_obj.search(cr, uid, ['&', ('res_id', '=', id), ('model', '=', self._name)], context=context) - msgs = msg_obj.read(cr, uid, msg_ids, context=context) - return msgs + msg_ids = self.message_load_ids(cr, uid, ids, context=context) + return self.pool.get('mail.message').read(cr, uid, msg_ids, context=context) #------------------------------------------------------ # Email specific @@ -528,9 +524,10 @@ class mail_thread(osv.osv): Find by: res_id (thread id), model (self._name), need_action_user_id != false """ msg_obj = self.pool.get('mail.message') - for id in ids: - msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', '=', id), ('model', '=', self._name)], context=context) - msg_obj.write(cr, uid, msg_ids, {'need_action_user_id': False}, context=context) + msg_ids = msg_obj.search(cr, uid, + ['&', '&', ('res_id', 'in', ids), ('model', '=', self._name), ('need_action_user_id', '!=', False)], context=context) + msg_obj.write(cr, uid, msg_ids, {'need_action_user_id': False}, context=context) + return True #------------------------------------------------------ # Subscription mechanism @@ -538,22 +535,17 @@ class mail_thread(osv.osv): def message_get_subscribers(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') - for id in ids: - sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', '=', id)], context=context) - subs = subscription_obj.browse(cr, uid, sub_ids, context=context) - return subs - - def message_get_subscribers_web(self, cr, uid, ids, context=None): - subscription_obj = self.pool.get('mail.subscription') - for id in ids: - sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', '=', id)], context=context) - subs = subscription_obj.read(cr, uid, sub_ids, context=context) + sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) + subs = subscription_obj.read(cr, uid, sub_ids, context=context) return subs def message_is_subscriber(self, cr, uid, ids, context=None): - for subscription in self.message_get_subscribers(cr, uid, ids, context=context): - if subscription.user_id == uid: return True - return False + subscription_obj = self.pool.get('mail.subscription') + sub_ids = subscription_obj.search(cr, uid, + ['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', '=', uid)], context=context) + if len(sub_ids) > 1: + print 'cacaprout error !' + return True if sub_ids else False def message_subscribe(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') @@ -565,9 +557,8 @@ class mail_thread(osv.osv): def message_unsubscribe(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') subscriber_id = uid # TODO - sub_ids = [] - for id in ids: - sub_ids += subscription_obj.search(cr, uid, ['&', '&', ('res_model', '=', self._name), ('res_id', '=', id), ('user_id', '=', subscriber_id)], context=context) + sub_ids = subscription_obj.search(cr, uid, + ['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', '=', subscriber_id)], context=context) subscription_obj.unlink(cr, uid, sub_ids, context=context) return True diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index fa7037bcacb..aa1ed33fb6d 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -14,47 +14,55 @@ openerp.mail = function(session) { template: 'ThreadView', init: function() { -// this.timeout; this.follow_state = 0; this._super.apply(this, arguments); /* DataSets */ this.ds = new session.web.DataSet(this, this.view.model); - this.ds_sub = new session.web.DataSet(this, 'mail.subscription'); -// this.ds_msg = new session.web.DataSet(this, 'mail.message'); }, start: function() { var self = this; this._super.apply(this, arguments); - /* bind follow and unfollow buttons */ - self.$element.find('button.oe_mail_button_follow').bind('click', function () { self.do_follow(); }); - self.$element.find('button.oe_mail_button_follow').hide(); - self.$element.find('button.oe_mail_button_unfollow').bind('click', function () { self.do_unfollow(); }); - self.$element.find('button.oe_mail_button_unfollow').hide(); + /* bind buttons */ self.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); self.$element.find('button.oe_mail_button_followers').bind('click', function () { self.do_toggle_followers(); }); - /* find wich (un)follow buttons to show */ - var call_res = this.ds.call('message_is_subscriber', [[this.session.uid]]).then(function (records) { - if (records == true) { self.follow_state = 1; self.$element.find('button.oe_mail_button_unfollow').show(); } - else { self.follow_state = 0; self.$element.find('button.oe_mail_button_follow').show(); } - }); + self.$element.find('button.oe_mail_button_follow').bind('click', function () { self.do_follow(); }); + self.$element.find('button.oe_mail_button_unfollow').bind('click', function () { self.do_unfollow(); }); + /* hide follow/unfollow buttons */ + self.$element.find('button.oe_mail_button_follow').hide(); + self.$element.find('button.oe_mail_button_unfollow').hide(); }, stop: function () { -// clearTimeout(this.timeout); - this._super(); + console.log('stop'); + this._super.apply(this, arguments); }, set_value: function() { + var self = this; this._super.apply(this, arguments); + /* hide follow/unfollow buttons */ + self.$element.find('button.oe_mail_button_follow').hide(); + self.$element.find('button.oe_mail_button_unfollow').hide(); if (! this.view.datarecord.id) { return; } - return this.fetch_data(); + /* find wich (un)follow buttons to show */ + var call_res = this.ds.call('message_is_subscriber', [[this.view.datarecord.id]]).then(function (records) { + if (records == true) { self.follow_state = 1; self.$element.find('button.oe_mail_button_unfollow').show(); } + else { self.follow_state = 0; self.$element.find('button.oe_mail_button_follow').show(); } + }); + /* fetch comments and subscribers */ + this.fetch_subscribers(); + return this.fetch_comments(); }, - fetch_data: function () { + fetch_comments: function () { var load_res = this.ds.call('message_load', [[this.view.datarecord.id]]).then( this.proxy('display_comments')); - var follow_res = this.ds.call('message_get_subscribers_web', [[this.view.datarecord.id]]).then( + return load_res; + }, + + fetch_subscribers: function () { + var follow_res = this.ds.call('message_get_subscribers', [[this.view.datarecord.id]]).then( this.proxy('display_followers')); return follow_res; }, @@ -69,35 +77,37 @@ openerp.mail = function(session) { }); $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_msg')); }); -// this.timeout = setTimeout(this.proxy('fetch_messages'), 5000); }, display_followers: function (records) { this.$element.find('div.oe_mail_followers').empty(); var self = this; _(records).each(function (record) { - console.log(record); //
$('
').text(record.user_id[1]).appendTo(self.$element.find('div.oe_mail_followers')); }); }, do_follow: function () { - this.$element.find('button.oe_mail_button_unfollow').show(); - this.$element.find('button.oe_mail_button_follow').hide(); - return this.ds_sub.create({'res_model': this.view.model, 'user_id': this.session.uid, 'res_id': this.view.datarecord.id}).then(); + this.do_toggle_follow(); + return this.ds.call('message_subscribe', [[this.view.datarecord.id]]).then(); }, do_unfollow: function () { - this.$element.find('button.oe_mail_button_follow').show(); - this.$element.find('button.oe_mail_button_unfollow').hide(); + this.do_toggle_follow(); return this.ds.call('message_unsubscribe', [[this.view.datarecord.id]]).then(); }, do_comment: function () { var body_text = this.$element.find('textarea').val(); return this.ds.call('message_append_note', [[this.view.datarecord.id], 'Reply comment', body_text, type='comment']).then( - this.proxy('fetch_messages')); + this.proxy('fetch_comments')); + }, + + do_toggle_follow: function () { + this.follow_state = 1 - this.follow_state; + this.$element.find('button.oe_mail_button_unfollow').toggle(); + this.$element.find('button.oe_mail_button_follow').toggle(); }, do_toggle_followers: function () { diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index ff8386f32b9..50e73f10326 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -56,4 +56,4 @@
- \ No newline at end of file + From 64164155d23453a7087dd0740da1783e6332300b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 16 Feb 2012 17:48:37 +0100 Subject: [PATCH 0039/1161] [FIX] mail_message: fixed notification creation, propagating a subscription model modification (from int to many2one); fixed unprotected accesses to 'need_action_user_id' key in vals dictionnary bzr revid: tde@openerp.com-20120216164837-jscxxu52sybvy7db --- addons/mail/mail_message.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 58e5833fa49..9ada617a177 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -209,10 +209,10 @@ class mail_message(osv.osv): ('res_id', '=', vals['res_id'])], context=context) subs = subscription_obj.browse(cr, uid, sub_ids, context=context) for sub in subs: - notification_obj.create(cr, uid, {'user_id': sub.user_id, 'message_id': msg_id}, context=context) - if vals['need_action_user_id'] == sub.user_id: need_action_pushed = True + notification_obj.create(cr, uid, {'user_id': sub.user_id.id, 'message_id': msg_id}, context=context) + if vals.get('need_action_user_id', False) == sub.user_id: need_action_pushed = True # push to need_action_user_id if user does not follow the object - if vals['need_action_user_id'] != False and not need_action_pushed: + if vals.get('need_action_user_id', False) and not need_action_pushed: notification_obj.create(cr, uid, {'user_id': vals['need_action_user_id'], 'message_id': msg_id}, context=context) return msg_id From 12514823e69781fdf6509c7e07dda2f9d6d67311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 16 Feb 2012 18:04:46 +0100 Subject: [PATCH 0040/1161] [FIX] Cleaned create method for mail_message; added protection against unknown keys in vals parameter bzr revid: tde@openerp.com-20120216170446-h4u8t3znp7p4lerb --- addons/mail/mail_message.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 9ada617a177..03eb57bfd0f 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -204,15 +204,19 @@ class mail_message(osv.osv): # push the message to suscribed users subscription_obj = self.pool.get('mail.subscription') notification_obj = self.pool.get('mail.notification') + # not pure-email: check for subscriptions + if not 'need_action_user_id' in vals: vals['need_action_user_id'] = False + if not 'model' in vals: vals['model'] = False + if not 'res_id' in vals: vals['res_id'] = 0 sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', vals['model']), ('res_id', '=', vals['res_id'])], context=context) subs = subscription_obj.browse(cr, uid, sub_ids, context=context) for sub in subs: notification_obj.create(cr, uid, {'user_id': sub.user_id.id, 'message_id': msg_id}, context=context) - if vals.get('need_action_user_id', False) == sub.user_id: need_action_pushed = True + if vals['need_action_user_id'] == sub.user_id: need_action_pushed = True # push to need_action_user_id if user does not follow the object - if vals.get('need_action_user_id', False) and not need_action_pushed: + if vals['need_action_user_id'] and not need_action_pushed: notification_obj.create(cr, uid, {'user_id': vals['need_action_user_id'], 'message_id': msg_id}, context=context) return msg_id From b23dd504c4d572fad8478f040a36b3571066f2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 20 Feb 2012 10:22:39 +0100 Subject: [PATCH 0041/1161] [FIX] Fixed template var name to match rev 2225 of web client bzr revid: tde@openerp.com-20120220092239-l1e35sv2l7qfzegx --- addons/mail/static/src/js/mail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index aa1ed33fb6d..ae98891eda9 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -11,7 +11,7 @@ openerp.mail = function(session) { /* ThreadView widget: thread of comments */ mail.ThreadView = session.web.form.Field.extend({ // QWeb template to use when rendering the object - template: 'ThreadView', + form_template: 'ThreadView', init: function() { this.follow_state = 0; From b8612374d7f4b202a1f5c092bc7bd695864848a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 20 Feb 2012 12:17:05 +0100 Subject: [PATCH 0042/1161] [IMP] crm_case: removed generic notification when changing state. Messages are now delegated to upper modules, that will have to write consistent and useful notifications. bzr revid: tde@openerp.com-20120220111705-4q7x3ukgvnz3vhe1 --- addons/crm/crm.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 4ebb0b4796d..7775e442df7 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -393,7 +393,6 @@ class crm_case(crm_base): def case_open(self, cr, uid, ids, *args): """Opens Case""" cases = self.browse(cr, uid, ids) - self.message_append(cr, uid, cases, _('Open')) for case in cases: data = {'state': 'open', 'active': True } if not case.user_id: @@ -406,7 +405,6 @@ class crm_case(crm_base): """Closes Case""" cases = self.browse(cr, uid, ids) cases[0].state # to fill the browse record cache - self.message_append(cr, uid, cases, _('Close')) self.write(cr, uid, ids, {'state': 'done', 'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'), }) @@ -430,7 +428,6 @@ class crm_case(crm_base): raise osv.except_osv(_('Error !'), _('You can not escalate, you are already at the top level regarding your sales-team category.')) self.write(cr, uid, [case.id], data) cases = self.browse(cr, uid, ids) - self.message_append(cr, uid, cases, _('Escalate')) self._action(cr, uid, cases, 'escalate') return True @@ -438,7 +435,6 @@ class crm_case(crm_base): """Cancels Case""" cases = self.browse(cr, uid, ids) cases[0].state # to fill the browse record cache - self.message_append(cr, uid, cases, _('Cancel')) self.write(cr, uid, ids, {'state': 'cancel', 'active': True}) self._action(cr, uid, cases, 'cancel') @@ -451,7 +447,6 @@ class crm_case(crm_base): """Marks case as pending""" cases = self.browse(cr, uid, ids) cases[0].state # to fill the browse record cache - self.message_append(cr, uid, cases, _('Pending')) self.write(cr, uid, ids, {'state': 'pending', 'active': True}) self._action(cr, uid, cases, 'pending') return True @@ -463,7 +458,6 @@ class crm_case(crm_base): state = 'open' cases = self.browse(cr, uid, ids) cases[0].state # to fill the browse record cache - self.message_append(cr, uid, cases, _('Draft')) self.write(cr, uid, ids, {'state': state, 'active': True}) self._action(cr, uid, cases, state) return True From 674680484179c93d424461011ce4e1503747b369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 20 Feb 2012 17:11:57 +0100 Subject: [PATCH 0043/1161] [REF] mail_thread: deleted unused mail_thread views, now unecessary since content is not managed by a message_ids o2m field anymore bzr revid: tde@openerp.com-20120220161157-b9m23nq1czt4uoy3 --- addons/mail/mail_thread_view.xml | 60 -------------------------------- 1 file changed, 60 deletions(-) diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index d2e557d06d8..a71ae040328 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -1,62 +1,12 @@ - - mail.thread.form - mail.thread - form - -
- - - - - - - - - -
- - - mail.thread.tree - mail.thread - tree - - - - - - - - - - Email Threads - mail.thread - tree,form - form - - - - - tree - - - - - - form - - - Feeds - - @@ -83,16 +33,6 @@ - -
From 1469deff854c9bf0369ece9c7f639d2fe0257b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 20 Feb 2012 18:21:06 +0100 Subject: [PATCH 0044/1161] [IMP] mail_thread API: message_get_subscribers now returns res.users read results instead of mail.subscription results. message_subscribe has now an optional parameter user_ids to subscribe ids in user_ids instead of uid. bzr revid: tde@openerp.com-20120220172106-fpjafkkvea0m1k93 --- addons/mail/mail_thread.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index f63ebde836c..e0a42f3cfe7 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -533,11 +533,16 @@ class mail_thread(osv.osv): # Subscription mechanism #------------------------------------------------------ - def message_get_subscribers(self, cr, uid, ids, context=None): + def message_get_subscribers_ids(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) subs = subscription_obj.read(cr, uid, sub_ids, context=context) - return subs + return [sub['user_id'] for sub in subs] + + def message_get_subscribers(self, cr, uid, ids, context=None): + user_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context) + users = self.pool.get('res.users').read(cr, uid, user_ids, context=context) + return users def message_is_subscriber(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') @@ -547,12 +552,13 @@ class mail_thread(osv.osv): print 'cacaprout error !' return True if sub_ids else False - def message_subscribe(self, cr, uid, ids, context=None): + def message_subscribe(self, cr, uid, ids, user_ids = None, context=None): subscription_obj = self.pool.get('mail.subscription') - subscriber_id = uid # TODO + sub_user_ids = [uid] if user_ids is None else user_ids for id in ids: - subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': subscriber_id}, context=context) - return True + create_ids = [subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': user_id}, context=context) + for user_id in sub_user_ids] + return create_ids def message_unsubscribe(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') From 3a53f777dfc5e3ce640f78d36acf94524e002d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 20 Feb 2012 18:22:30 +0100 Subject: [PATCH 0045/1161] [FIX] Propagated API modification: message_get_subscribers result are now read records from res.users bzr revid: tde@openerp.com-20120220172230-mj7vx5akh0xrmzs6 --- addons/mail/static/src/js/mail.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index ae98891eda9..b9404885b6a 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -84,7 +84,8 @@ openerp.mail = function(session) { var self = this; _(records).each(function (record) { //
- $('
').text(record.user_id[1]).appendTo(self.$element.find('div.oe_mail_followers')); + //$('
').text(record.user_id[1]).appendTo(self.$element.find('div.oe_mail_followers')); + $('
').text(record.name).appendTo(self.$element.find('div.oe_mail_followers')); }); }, From a2ef45aaebe2d75a7fb00c23276170bffbac3d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 20 Feb 2012 18:23:23 +0100 Subject: [PATCH 0046/1161] [IMP] hr_holidays: improved notifications, added notifications when creating or refusing a leave requet/allocation. bzr revid: tde@openerp.com-20120220172323-4kqkhxntcgx6g178 --- addons/hr_holidays/hr_holidays.py | 80 ++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index a2acea4792d..a8573b9bf7c 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -151,7 +151,12 @@ class hr_holidays(osv.osv): ('date_check2', "CHECK ( (type='add') OR (date_from <= date_to))", "The start date must be before the end date !"), ('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0 !"), ] - + + def create(self, cr, uid, vals, context=None): + obj_id = super(hr_holidays, self).create(cr, uid, vals, context=context) + self.create_notificate(cr, uid, [obj_id], context=context) + return obj_id + def _create_resource_leave(self, cr, uid, leaves, context=None): '''This method will create entry in resource calendar leave object at the time of holidays validated ''' obj_res_leave = self.pool.get('resource.calendar.leaves') @@ -253,13 +258,6 @@ class hr_holidays(osv.osv): manager = ids2 and ids2[0] or False self.holidays_validate_notificate(cr, uid, ids, context=context) return self.write(cr, uid, ids, {'state':'validate1', 'manager_id': manager}) - - def holidays_validate_notificate(self, cr, uid, ids, context=None): - for obj in self.browse(cr, uid, ids): - self.message_mark_done(cr, uid, [obj.id], context=context) - self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) - if obj.holiday_status_id.double_validation: - self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' is waiting for second validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) def holidays_validate2(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) @@ -313,20 +311,12 @@ class hr_holidays(osv.osv): self.holidays_valid2_notificate(self, cr, uid, [holiday_ids], context=context) self.write(cr, uid, holiday_ids, {'manager_id2': manager}) return True - - def holidays_valid2_notificate(self, cr, uid, ids, context=None): - for obj in self.browse(cr, uid, ids): - self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been double validated.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) def holidays_confirm(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) self.holidays_confirm_notificate(cr, uid, ids, context=context) return self.write(cr, uid, ids, {'state':'confirm'}) - def holidays_confirm_notificate(self, cr, uid, ids, context=None): - for obj in self.browse(cr, uid, ids): - self.message_append_note(cr, uid, [obj.id], _('System notification'), _("The %s request '%s' has been confirmed and is waiting for validation.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', need_action_user_id = obj.employee_id.parent_id.user_id.id if obj.employee_id.parent_id else False) - def holidays_refuse(self, cr, uid, ids, approval, context=None): obj_emp = self.pool.get('hr.employee') ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)]) @@ -335,6 +325,7 @@ class hr_holidays(osv.osv): self.write(cr, uid, ids, {'state': 'refuse', 'manager_id': manager}) else: self.write(cr, uid, ids, {'state': 'refuse', 'manager_id2': manager}) + self.holidays_refuse_notificate(cr, uid, ids, approval, context=context) self.holidays_cancel(cr, uid, ids, context=context) return True @@ -362,6 +353,63 @@ class hr_holidays(osv.osv): if leaves_rest < record.number_of_days_temp: raise osv.except_osv(_('Warning!'),_('You cannot validate leaves for employee %s: too few remaining days (%s).') % (record.employee_id.name, leaves_rest)) return True + + # ----------------------------- + # OpenChatter and notifications + # ----------------------------- + + def create_notificate(self, cr, uid, ids, context=None): + obj = self.browse(cr, uid, ids, context=context)[0] + self.message_append_note(cr, uid, ids, _('System notification'), + _("""The %s request '%s' has been created and is in draft mode. In this mode, it can be modified freely. + Click on Confirm to confirm your request and ask for its validation by the managers.""") + % ('leave' if obj.type == 'remove' else 'allocation', obj.name), type='notification', context=context) + return True + + def message_get_subscribers(self, cr, uid, ids, context=None): + """OpenChatter: override message_get_subscribers to add : + - employee related user + - employee manager user, if it exists""" + users = super(hr_holidays, self).message_get_subscribers(cr, uid, ids, context=context) + user_ids = [] + for holidays in self.browse(cr, uid, ids, context=context): + user_ids.append(holidays.user_id.id) + if holidays.employee_id.parent_id: + user_ids.append(holidays.employee_id.parent_id.user_id.id) + users += self.pool.get('res.users').read(cr, uid, user_ids, context=context) + return users + + def holidays_confirm_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids): + self.message_append_note(cr, uid, [obj.id], _('System notification'), + _("The %s request '%s' has been confirmed. It is now waiting for validation by the manager.") + % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', + need_action_user_id = obj.employee_id.parent_id.user_id.id if obj.employee_id.parent_id else False) + + def holidays_validate_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids): + self.message_mark_done(cr, uid, [obj.id], context=context) + if obj.holiday_status_id.double_validation: + self.message_append_note(cr, uid, [obj.id], _('System notification'), + _("The %s request '%s' has been validated. A second validation of your request is necessary and is now pending.") + % ('leave' if obj.type == 'remove' else 'allocation', obj.name), type='notification', context=context) + else: + self.message_append_note(cr, uid, [obj.id], _('System notification'), + _("The %s request '%s' has been validated. The validation process is now over.") + % ('leave' if obj.type == 'remove' else 'allocation', obj.name), type='notification', context=context) + + def holidays_valid2_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids): + self.message_append_note(cr, uid, [obj.id], _('System notification'), + _("The %s request '%s' has been double validated. The validation process is now over.") + % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) + + def holidays_refuse_notificate(self, cr, uid, ids, approval, context=None): + for obj in self.browse(cr, uid, ids): + self.message_append_note(cr, uid, [obj.id], _('System notification'), + _("The %s request '%s' has been refused. The validation process is now over.") + % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', context=context) + hr_holidays() class resource_calendar_leaves(osv.osv): From 592a41fa3e493ca6de87f91201b574063a3ab43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 21 Feb 2012 15:21:26 +0100 Subject: [PATCH 0047/1161] [FIX] mail.thread: fixed message_get_subscribers returning a tuple list, not an id list (RGA) bzr revid: tde@openerp.com-20120221142126-dzr4um7tfq1knxcv --- addons/mail/mail_thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index e0a42f3cfe7..b3592e0954e 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -537,7 +537,7 @@ class mail_thread(osv.osv): subscription_obj = self.pool.get('mail.subscription') sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) subs = subscription_obj.read(cr, uid, sub_ids, context=context) - return [sub['user_id'] for sub in subs] + return [sub['user_id'][0] for sub in subs] def message_get_subscribers(self, cr, uid, ids, context=None): user_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context) From 413df331044c61f8015cb9f580caaf424346dbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 21 Feb 2012 16:39:03 +0100 Subject: [PATCH 0048/1161] [IMP] Removed space in a note. bzr revid: tde@openerp.com-20120221153903-px8wbaia3y9h4rvg --- addons/hr_holidays/hr_holidays.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index a8573b9bf7c..82d3d7d51cb 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -361,7 +361,7 @@ class hr_holidays(osv.osv): def create_notificate(self, cr, uid, ids, context=None): obj = self.browse(cr, uid, ids, context=context)[0] self.message_append_note(cr, uid, ids, _('System notification'), - _("""The %s request '%s' has been created and is in draft mode. In this mode, it can be modified freely. + _("""The %s request '%s' has been created and is in draft mode. In this mode, it can be modified freely. \ Click on Confirm to confirm your request and ask for its validation by the managers.""") % ('leave' if obj.type == 'remove' else 'allocation', obj.name), type='notification', context=context) return True From 7429f3bfb6797b1bdd97e05afdd5992a3bd320ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 21 Feb 2012 16:39:42 +0100 Subject: [PATCH 0049/1161] [IMP] Slighty improved wall widget. bzr revid: tde@openerp.com-20120221153942-mue1h18f2fjluf27 --- addons/mail/static/src/css/mail.css | 5 +++++ addons/mail/static/src/js/mail.js | 27 ++++++++++++--------------- addons/mail/static/src/xml/mail.xml | 10 ++++++---- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 0d153ce0c06..be5e8425630 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -5,6 +5,11 @@ padding: 5px 5px 5px 5px; } +.oe_mail_wall_main { + overflow: auto; + padding: 5px 5px 5px 5px; +} + /* 2 columns view */ .oe_mail_main_left { float: left; diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index b9404885b6a..cd2e1f2ac5d 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -34,7 +34,6 @@ openerp.mail = function(session) { }, stop: function () { - console.log('stop'); this._super.apply(this, arguments); }, @@ -134,39 +133,37 @@ openerp.mail = function(session) { start: function() { var self = this; this._super.apply(this, arguments); - console.log(this); - self.$element.find('button.oe_mail_action_comment').bind('click', function () { self.do_comment(); }); - this.ds_msg.call('get_pushed_messages', [[], self.filter_search]).then( - this.proxy('display_records')); + self.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); + return this.fetch_comments(); }, stop: function () { this._super(); }, - fetch_messages: function () { - console.log('debug--fetch_messages'); - return this.ds_msg.call('get_pushed_messages', []).then( - this.proxy('display_records')); + fetch_comments: function () { + var load_res = this.ds_msg.call('get_pushed_messages', [[this.session.uid]]).then( + this.proxy('display_comments')); + return load_res; }, - display_records: function (records) { - this.$element.find('div.oe_mail_comments').empty(); + display_comments: function (records) { + this.$element.find('div.oe_mail_msg').empty(); var self = this; _(records).each(function (record) { + console.log(record); var template = 'ThreadMsgView'; var render_res = session.web.qweb.render(template, { 'record': record, }); - $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_comments')); + $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_msg')); }); -// this.timeout = setTimeout(this.proxy('fetch_messages'), 5000); }, do_comment: function () { var body_text = this.$element.find('textarea').val(); - return this.ds.call('message_append_note', [[this.view.datarecord.id], 'Reply comment', body_text, type='comment']).then( - this.proxy('fetch_messages')); + return this.ds_msg.call('create', [{'subject': 'Status tweet', 'model': 'res.users', 'body_text': body_text, 'type': 'comment'}]).then( + this.proxy('fetch_comments')); }, }); }; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 50e73f10326..ff69ef4c29f 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -47,12 +47,14 @@
-
+
-
- +
+
-
+
+
+
From babd47b963aa421c5b92624a485eb509ea7e970e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 10:09:23 +0100 Subject: [PATCH 0050/1161] [IMP] Notification push moved from mail.message to mail.thread to use message_get_subscribers method. Also added a temporary debug log on message.create method, to help tracking messages not using mail.thread. bzr revid: tde@openerp.com-20120222090923-1h6wx3bkwr5ngt4d --- addons/mail/mail_message.py | 31 +++++++++---------------------- addons/mail/mail_thread.py | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 03eb57bfd0f..87e73dbb471 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -197,31 +197,18 @@ class mail_message(osv.osv): #------------------------------------------------------ def create(self, cr, uid, vals, context=None): - # OpenSocial: notifications do not come from any user but from system - if vals.get('type') == 'notification': vals['user_id'] = False - need_action_pushed = False + # temporary log directly created messages (to debug OpenSocial) + if not 'mail.thread' in context: + _logger.warning('Creating message without using mail.thread API') + _logger.warning('Message details: %s', str(vals)) msg_id = super(mail_message, self).create(cr, uid, vals, context) - # push the message to suscribed users - subscription_obj = self.pool.get('mail.subscription') - notification_obj = self.pool.get('mail.notification') - # not pure-email: check for subscriptions - if not 'need_action_user_id' in vals: vals['need_action_user_id'] = False - if not 'model' in vals: vals['model'] = False - if not 'res_id' in vals: vals['res_id'] = 0 - sub_ids = subscription_obj.search(cr, uid, ['&', - ('res_model', '=', vals['model']), - ('res_id', '=', vals['res_id'])], context=context) - subs = subscription_obj.browse(cr, uid, sub_ids, context=context) - for sub in subs: - notification_obj.create(cr, uid, {'user_id': sub.user_id.id, 'message_id': msg_id}, context=context) - if vals['need_action_user_id'] == sub.user_id: need_action_pushed = True - # push to need_action_user_id if user does not follow the object - if vals['need_action_user_id'] and not need_action_pushed: - notification_obj.create(cr, uid, {'user_id': vals['need_action_user_id'], 'message_id': msg_id}, context=context) return msg_id def get_pushed_messages(self, cr, uid, ids, filter_search=False, context=None): - """Wall: get messages to display""" + """OpenSocial: wall: get messages to display (=pushed notifications) + :param filter_search: TODO + :return: dict { res_model: { res_id: [pushed message list] }} + """ notification_obj = self.pool.get('mail.notification') notification_ids = notification_obj.search(cr, uid, [('user_id', '=', uid)], context=context) notifications = notification_obj.browse(cr, uid, notification_ids, context=context) @@ -230,7 +217,7 @@ class mail_message(osv.osv): msgs = self.read(cr, uid, msg_ids, context=context) print msgs - # TODO / REMARK: classify based on res_model / res_id to have a 1_level hierarchy ? + # sort return msgs diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index b3592e0954e..89273389dd2 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -72,6 +72,33 @@ class mail_thread(osv.osv): #------------------------------------------------------ # Generic message api #------------------------------------------------------ + + def message_create(self, cr, uid, ids, vals, context=None): + """OpenSocial: wrapper of mail.message create method + - creates the mail.message + - push the message to subscribed users""" + subscription_obj = self.pool.get('mail.subscription') + notification_obj = self.pool.get('mail.notification') + + # notifications do not come from any user, but from system + if vals.get('type') == 'notification': vals['user_id'] = False + if not 'need_action_user_id' in vals: vals['need_action_user_id'] = False + if not 'model' in vals: vals['model'] = False + if not 'res_id' in vals: vals['res_id'] = 0 + need_action_pushed = False + + msg_id = self.pool.get('mail.message').create(cr, uid, vals, context=context) + + # push the message to suscribed users + users = self.message_get_subscribers(cr, uid, ids, context=context) + for user in users: + notification_obj.create(cr, uid, {'user_id': user['id'], 'message_id': msg_id}, context=context) + if vals['need_action_user_id'] == user['id']: need_action_pushed = True + # push to need_action_user_id if user does not follow the object + if vals['need_action_user_id'] and not need_action_pushed: + notification_obj.create(cr, uid, {'user_id': vals['need_action_user_id'], 'message_id': msg_id}, context=context) + return msg_id + def message_capable_models(self, cr, uid, context=None): ret_dict = {} for model_name in self.pool.obj_list(): @@ -197,7 +224,9 @@ class mail_thread(osv.osv): 'reply_to': reply_to, 'original': original, } - mail_message.create(cr, uid, data, context=context) + #mail_message.create(cr, uid, data, context=context) + context['mail.thread'] = True + self.message_create(cr, uid, [thread.id], data, context=context) return True def message_append_dict(self, cr, uid, ids, msg_dict, context=None): @@ -533,14 +562,14 @@ class mail_thread(osv.osv): # Subscription mechanism #------------------------------------------------------ - def message_get_subscribers_ids(self, cr, uid, ids, context=None): + def _message_get_subscribers_ids(self, cr, uid, ids, context=None): subscription_obj = self.pool.get('mail.subscription') sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) subs = subscription_obj.read(cr, uid, sub_ids, context=context) return [sub['user_id'][0] for sub in subs] def message_get_subscribers(self, cr, uid, ids, context=None): - user_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context) + user_ids = self._message_get_subscribers_ids(cr, uid, ids, context=context) users = self.pool.get('res.users').read(cr, uid, user_ids, context=context) return users From acb592d84b9710bd563df76c8c822031344bf22e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 10:58:12 +0100 Subject: [PATCH 0051/1161] [IMP] Automatically subscribe the message writer to the related object. bzr revid: tde@openerp.com-20120222095812-mor2qolqjqzm188q --- addons/mail/mail_thread.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 89273389dd2..634ac3525a0 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -76,6 +76,7 @@ class mail_thread(osv.osv): def message_create(self, cr, uid, ids, vals, context=None): """OpenSocial: wrapper of mail.message create method - creates the mail.message + - automatically subscribe the message writer if not already done - push the message to subscribed users""" subscription_obj = self.pool.get('mail.subscription') notification_obj = self.pool.get('mail.notification') @@ -89,6 +90,11 @@ class mail_thread(osv.osv): msg_id = self.pool.get('mail.message').create(cr, uid, vals, context=context) + # automatically subscribe the writer of the message if not subscribed + if vals['user_id']: + if not self.message_is_subscriber(cr, uid, ids, context=context): + self.message_subscribe(cr, uid, ids, context=context) + # push the message to suscribed users users = self.message_get_subscribers(cr, uid, ids, context=context) for user in users: @@ -574,11 +580,12 @@ class mail_thread(osv.osv): return users def message_is_subscriber(self, cr, uid, ids, context=None): + # TODO: use message_get_subscribers ? as all subscriptions are in mail.subscription table, not necessary subscription_obj = self.pool.get('mail.subscription') sub_ids = subscription_obj.search(cr, uid, ['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', '=', uid)], context=context) if len(sub_ids) > 1: - print 'cacaprout error !' + pass # TODO return True if sub_ids else False def message_subscribe(self, cr, uid, ids, user_ids = None, context=None): From bfc8e5e86671a67cf03d8d570058800ee2e29259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 10:59:50 +0100 Subject: [PATCH 0052/1161] [IMP] hr_holidays: propagated changes in subscription mechanism. Also cleaned messages. bzr revid: tde@openerp.com-20120222095950-wnx9qfta5dh4had5 --- addons/hr_holidays/hr_holidays.py | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 82d3d7d51cb..78db0dc7063 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -359,30 +359,20 @@ class hr_holidays(osv.osv): # ----------------------------- def create_notificate(self, cr, uid, ids, context=None): - obj = self.browse(cr, uid, ids, context=context)[0] - self.message_append_note(cr, uid, ids, _('System notification'), - _("""The %s request '%s' has been created and is in draft mode. In this mode, it can be modified freely. \ - Click on Confirm to confirm your request and ask for its validation by the managers.""") - % ('leave' if obj.type == 'remove' else 'allocation', obj.name), type='notification', context=context) + for obj in self.browse(cr, uid, ids, context=context): + # add the employee and its manager if specified to the subscribed users + self.message_subscribe(cr, uid, ids, [obj.employee_id.user_id.id], context=context) + if obj.employee_id.parent_id: + self.message_subscribe(cr, uid, ids, [obj.employee_id.parent_id.user_id.id], context=context) + self.message_append_note(cr, uid, ids, _('System notification'), + _("The %s request '%s' has been created and is waiting confirmation") + % ('leave' if obj.type == 'remove' else 'allocation', obj.name), type='notification', context=context) return True - def message_get_subscribers(self, cr, uid, ids, context=None): - """OpenChatter: override message_get_subscribers to add : - - employee related user - - employee manager user, if it exists""" - users = super(hr_holidays, self).message_get_subscribers(cr, uid, ids, context=context) - user_ids = [] - for holidays in self.browse(cr, uid, ids, context=context): - user_ids.append(holidays.user_id.id) - if holidays.employee_id.parent_id: - user_ids.append(holidays.employee_id.parent_id.user_id.id) - users += self.pool.get('res.users').read(cr, uid, user_ids, context=context) - return users - def holidays_confirm_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_append_note(cr, uid, [obj.id], _('System notification'), - _("The %s request '%s' has been confirmed. It is now waiting for validation by the manager.") + _("The %s request '%s' has been confirmed and is waiting for validation by the manager.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name,), type='notification', need_action_user_id = obj.employee_id.parent_id.user_id.id if obj.employee_id.parent_id else False) @@ -391,7 +381,7 @@ class hr_holidays(osv.osv): self.message_mark_done(cr, uid, [obj.id], context=context) if obj.holiday_status_id.double_validation: self.message_append_note(cr, uid, [obj.id], _('System notification'), - _("The %s request '%s' has been validated. A second validation of your request is necessary and is now pending.") + _("The %s request '%s' has been validated. A second validation is necessary and is now pending.") % ('leave' if obj.type == 'remove' else 'allocation', obj.name), type='notification', context=context) else: self.message_append_note(cr, uid, [obj.id], _('System notification'), From b0a1a7e24ae70e1a0d71b9f36ff3a9e4f7f139c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 11:12:16 +0100 Subject: [PATCH 0053/1161] [FIX] added user_id when posting a tweet from the wall bzr revid: tde@openerp.com-20120222101216-9xpo3c0gj1ickigl --- addons/mail/mail_message.py | 6 ++---- addons/mail/static/src/js/mail.js | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 87e73dbb471..f6d7d2c863c 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -214,11 +214,9 @@ class mail_message(osv.osv): notifications = notification_obj.browse(cr, uid, notification_ids, context=context) msg_ids = [notification.message_id.id for notification in notifications] - msgs = self.read(cr, uid, msg_ids, context=context) - print msgs + msgs = self.read(cr, uid, msg_ids, context=context) + # sort: TODO - # sort - return msgs #------------------------------------------------------ diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index cd2e1f2ac5d..bd3021e9f1f 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -162,8 +162,9 @@ openerp.mail = function(session) { do_comment: function () { var body_text = this.$element.find('textarea').val(); - return this.ds_msg.call('create', [{'subject': 'Status tweet', 'model': 'res.users', 'body_text': body_text, 'type': 'comment'}]).then( - this.proxy('fetch_comments')); + return this.ds_msg.call('create', [ + {'subject': 'Status tweet', 'model': 'res.users', 'body_text': body_text, 'type': 'comment', 'res_id': this.session.uid, 'user_id': this.session.uid} + ]).then(this.proxy('fetch_comments')); }, }); }; From 9ced116caa379f2b876912a0a638f61b51d5becd Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Wed, 22 Feb 2012 16:36:16 +0530 Subject: [PATCH 0054/1161] [IMP] Threadview in crm. bzr revid: bth@tinyerp.com-20120222110616-i4sz2b1630ehzqel --- addons/crm/crm_lead_view.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 3fc6aff1536..01020ac213c 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -195,6 +195,7 @@ + @@ -589,6 +590,7 @@ + From bb1b6fe1766ac240e2d6e0154bd0d6dcd4e714e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 12:59:24 +0100 Subject: [PATCH 0055/1161] [ADD] res_users: added res_users.py file, making res.users in heriting from mail.thread. This is necessary to use mail.thread API on users (for tweets). bzr revid: tde@openerp.com-20120222115924-i55twzupuuzuc3gl --- addons/mail/__init__.py | 1 + addons/mail/res_users.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 addons/mail/res_users.py diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py index 64339fcb9c0..2474c321946 100644 --- a/addons/mail/__init__.py +++ b/addons/mail/__init__.py @@ -23,6 +23,7 @@ import mail_message import mail_thread import mail_group import mail_subscription +import res_users import res_partner import wizard diff --git a/addons/mail/res_users.py b/addons/mail/res_users.py new file mode 100644 index 00000000000..1c650ab1a34 --- /dev/null +++ b/addons/mail/res_users.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009-Today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see +# +############################################################################## + +from osv import osv + +class res_users(osv.osv): + _name = 'res.users' + _inherit = ['res.users', 'mail.thread'] + + def create(self, cr, uid, data, context=None): + user_id = super(res_users, self).create(cr, uid, data, context=context) + # make user follow itself + self.message_subscribe(cr, uid, [user_id], [user_id], context=context) + return user_id + From d9a3b4b2900a477810c850e80b5cfb6fcbb5407f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 14:35:01 +0100 Subject: [PATCH 0056/1161] [REF] Cleaned mail.message get_pushed_messages method bzr revid: tde@openerp.com-20120222133501-it9li0lh8fwvuk4e --- addons/mail/mail_message.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index f6d7d2c863c..9391a931774 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -207,16 +207,13 @@ class mail_message(osv.osv): def get_pushed_messages(self, cr, uid, ids, filter_search=False, context=None): """OpenSocial: wall: get messages to display (=pushed notifications) :param filter_search: TODO - :return: dict { res_model: { res_id: [pushed message list] }} + :return: list of mail.messages, unsorted """ notification_obj = self.pool.get('mail.notification') notification_ids = notification_obj.search(cr, uid, [('user_id', '=', uid)], context=context) notifications = notification_obj.browse(cr, uid, notification_ids, context=context) - msg_ids = [notification.message_id.id for notification in notifications] - msgs = self.read(cr, uid, msg_ids, context=context) - # sort: TODO - + msgs = self.read(cr, uid, msg_ids, context=context) return msgs #------------------------------------------------------ From 167f39807cd0478ca042aa550eb80c80e4954450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 15:03:18 +0100 Subject: [PATCH 0057/1161] [IMP] mail.thread: get_subscribed_users returns only necessary fields bzr revid: tde@openerp.com-20120222140318-8trixmwfvgus00x4 --- addons/mail/mail_thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 634ac3525a0..ee3270ca872 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -576,7 +576,7 @@ class mail_thread(osv.osv): def message_get_subscribers(self, cr, uid, ids, context=None): user_ids = self._message_get_subscribers_ids(cr, uid, ids, context=context) - users = self.pool.get('res.users').read(cr, uid, user_ids, context=context) + users = self.pool.get('res.users').read(cr, uid, user_ids, fields=['id', 'name', 'avatar_mini'], context=context) return users def message_is_subscriber(self, cr, uid, ids, context=None): From 1bc3f0cec4353e558ef47cf29bcc7b974d4194b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 15:04:03 +0100 Subject: [PATCH 0058/1161] [IMP] Wall: pushed message are now displayed in conversation, with a 1-level hierarchy based on source record. Wall and Thread: added support for user image. bzr revid: tde@openerp.com-20120222140403-fbjisr0u96jml5zv --- addons/mail/static/src/css/mail.css | 19 +++++---- addons/mail/static/src/js/mail.js | 61 +++++++++++++++++++++++------ addons/mail/static/src/xml/mail.xml | 45 +++++++++++++++------ 3 files changed, 92 insertions(+), 33 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index be5e8425630..9f4d8440205 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -50,24 +50,23 @@ .oe_mail_msg { } -/*.oe_mail_msg:after { - content: ""; - display: block; - clear: both; -}*/ - .oe_mail_comment { white-space: normal; margin-bottom: 5px; } +.oe_mail_comment:after { + content: ""; + display: block; + clear: both; +} + .oe_mail_msg_image { float: left; width: 14%; } .oe_mail_msg_image img { - width: 80%; margin-left: 10%; } @@ -105,3 +104,9 @@ .oe_mail_followers_vignette img { width: 80%; } + +/* Wall CSS */ +.oe_mail_thread_content div.oe_mail_comment { + margin-left: 5%; +} + diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index bd3021e9f1f..daf15e41d35 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -70,6 +70,7 @@ openerp.mail = function(session) { this.$element.find('div.oe_mail_msg').empty(); var self = this; _(records).each(function (record) { + record.mini_url = self.thread_get_mini('res.users', 'avatar_mini', record.user_id[0]); var template = 'ThreadMsgView'; var render_res = session.web.qweb.render(template, { 'record': record, @@ -77,14 +78,14 @@ openerp.mail = function(session) { $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_msg')); }); }, - + display_followers: function (records) { this.$element.find('div.oe_mail_followers').empty(); var self = this; _(records).each(function (record) { -//
- //$('
').text(record.user_id[1]).appendTo(self.$element.find('div.oe_mail_followers')); - $('
').text(record.name).appendTo(self.$element.find('div.oe_mail_followers')); + $('
').html( + '' + record.name + '' + ).appendTo(self.$element.find('div.oe_mail_followers')); }); }, @@ -113,6 +114,12 @@ openerp.mail = function(session) { do_toggle_followers: function () { this.$element.find('div.oe_mail_followers').toggle(); }, + + thread_get_mini: function(model, field, id) { + id = id || ''; + var url = this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; + return url; + }, }); /* Add WallView widget to registry */ @@ -128,6 +135,7 @@ openerp.mail = function(session) { this.filter_search = params['filter_search']; /* DataSets */ this.ds_msg = new session.web.DataSet(this, 'mail.message'); + this.ds_users = new session.web.DataSet(this, 'res.users'); }, start: function() { @@ -149,22 +157,49 @@ openerp.mail = function(session) { display_comments: function (records) { this.$element.find('div.oe_mail_msg').empty(); + sorted_records = this.sort_comments(records); var self = this; - _(records).each(function (record) { - console.log(record); - var template = 'ThreadMsgView'; - var render_res = session.web.qweb.render(template, { - 'record': record, + _(sorted_records).each(function (rec_models, model) { // each model + _(rec_models).each(function (record_id, id) { // each record + var template = 'WallThreadView'; + var render_res = session.web.qweb.render(template, { + 'record_model': model, + 'record_id': id, }); - $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_msg')); + $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_msg')); + _(record_id).each(function (record) { // each record + record.mini_url = self.thread_get_mini('res.users', 'avatar_mini', record.user_id[0]); + var template = 'ThreadMsgView'; + var render_res = session.web.qweb.render(template, { + 'record': record, + }); + $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_thread_content:last')); + }); + }); }); }, + sort_comments: function (records) { + sorted_comments = {}; + _(records).each(function (record) { + if (! (record.model in sorted_comments)) { sorted_comments[record.model] = {}; } + if (! (record.res_id in sorted_comments[record.model])) { + sorted_comments[record.model][record.res_id] = []; } + sorted_comments[record.model][record.res_id].push(record); + }); + return sorted_comments; + }, + do_comment: function () { var body_text = this.$element.find('textarea').val(); - return this.ds_msg.call('create', [ - {'subject': 'Status tweet', 'model': 'res.users', 'body_text': body_text, 'type': 'comment', 'res_id': this.session.uid, 'user_id': this.session.uid} - ]).then(this.proxy('fetch_comments')); + return this.ds_users.call('message_append_note', [[this.session.uid], 'Tweet', body_text, type='comment']).then( + this.proxy('fetch_comments')); + }, + + thread_get_mini: function(model, field, id) { + id = id || ''; + var url = this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; + return url; }, }); }; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index ff69ef4c29f..755357b7da3 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -25,9 +25,39 @@
- + +
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + +
+ Discussion about document (id: ) +
+
+
+
+ -
Image
+
+ +

@@ -46,16 +76,5 @@

- -
-
-
- -
-
-
-
-
-
From 6671d25523af5fdb9b9da08bacce7033772a1af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 15:48:35 +0100 Subject: [PATCH 0059/1161] [IMP] ThreadView: moved follow/unfollow action on the right; see followers now has its value toggling when choosing to display or hide followers; comment textare now displays as a comment, i.e. it has user avatar on the left and is aligned with comments bzr revid: tde@openerp.com-20120222144835-w8jfscffigaggr6p --- addons/mail/static/src/css/mail.css | 2 +- addons/mail/static/src/js/mail.js | 26 ++++++++++++++++++++++---- addons/mail/static/src/xml/mail.xml | 22 ++++++++++++++-------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 9f4d8440205..ed824071f0f 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -31,7 +31,7 @@ } .oe_mail_button_follow, .oe_mail_button_unfollow, .oe_mail_button_followers { - width: 100px; + width: 120px; } .oe_mail_button_comment { diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index daf15e41d35..fe29fd8d139 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -14,10 +14,12 @@ openerp.mail = function(session) { form_template: 'ThreadView', init: function() { - this.follow_state = 0; + this.is_sub = 0; + this.see_sub = 1; this._super.apply(this, arguments); /* DataSets */ this.ds = new session.web.DataSet(this, this.view.model); + this.ds_users = new session.web.DataSet(this, 'res.users'); }, start: function() { @@ -46,14 +48,21 @@ openerp.mail = function(session) { if (! this.view.datarecord.id) { return; } /* find wich (un)follow buttons to show */ var call_res = this.ds.call('message_is_subscriber', [[this.view.datarecord.id]]).then(function (records) { - if (records == true) { self.follow_state = 1; self.$element.find('button.oe_mail_button_unfollow').show(); } - else { self.follow_state = 0; self.$element.find('button.oe_mail_button_follow').show(); } + if (records == true) { self.is_sub = 1; self.$element.find('button.oe_mail_button_unfollow').show(); } + else { self.is_sub = 0; self.$element.find('button.oe_mail_button_follow').show(); } }); + console.log(this); /* fetch comments and subscribers */ + this.fetch_current_user(); this.fetch_subscribers(); return this.fetch_comments(); }, + fetch_current_user: function () { + return this.ds_users.read_ids([this.session.uid], ['id', 'name', 'avatar_mini']).then( + this.proxy('display_current_user')); + }, + fetch_comments: function () { var load_res = this.ds.call('message_load', [[this.view.datarecord.id]]).then( this.proxy('display_comments')); @@ -66,6 +75,12 @@ openerp.mail = function(session) { return follow_res; }, + display_current_user: function (records) { + $('
').html( + '' + records[0].name + '' + ).appendTo(this.$element.find('div.oe_mail_msg_image')); + }, + display_comments: function (records) { this.$element.find('div.oe_mail_msg').empty(); var self = this; @@ -106,12 +121,15 @@ openerp.mail = function(session) { }, do_toggle_follow: function () { - this.follow_state = 1 - this.follow_state; + this.is_sub = 1 - this.is_sub; this.$element.find('button.oe_mail_button_unfollow').toggle(); this.$element.find('button.oe_mail_button_follow').toggle(); }, do_toggle_followers: function () { + this.see_sub = 1 - this.see_sub; + if (this.see_sub == 1) { this.$element.find('button.oe_mail_button_followers').html('Hide followers'); } + else { this.$element.find('button.oe_mail_button_followers').html('Display followers'); } this.$element.find('div.oe_mail_followers').toggle(); }, diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 755357b7da3..79e421cc559 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -4,13 +4,15 @@
OpenSocial
-
- - -
-
-
- +
+
+
+
+
+
+ +
+
@@ -18,8 +20,12 @@
+
+ + +
- +
From bf50057d22d0771ac59f4d57f4c8a63ba4851ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 15:58:00 +0100 Subject: [PATCH 0060/1161] [IMP] ThreadView: image left of post comment area is not refreshed in each set_value, only initialized bzr revid: tde@openerp.com-20120222145800-rfqkznqxcf3a22ok --- addons/mail/static/src/js/mail.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index fe29fd8d139..2ef72d0b816 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -16,6 +16,7 @@ openerp.mail = function(session) { init: function() { this.is_sub = 0; this.see_sub = 1; + this.user_init = 0; this._super.apply(this, arguments); /* DataSets */ this.ds = new session.web.DataSet(this, this.view.model); @@ -53,7 +54,10 @@ openerp.mail = function(session) { }); console.log(this); /* fetch comments and subscribers */ - this.fetch_current_user(); + if (this.user_init == 0) { + this.fetch_current_user(); + this.user_init = 1; + } this.fetch_subscribers(); return this.fetch_comments(); }, From 44e6b0f079edccf0ad7f21d84463a83a6df57589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 22 Feb 2012 16:26:43 +0100 Subject: [PATCH 0061/1161] [IMP] Improved display of avatars bzr revid: tde@openerp.com-20120222152643-cdiyr0klegnt9sxd --- addons/mail/static/src/css/mail.css | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index ed824071f0f..3f9fe3149d3 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -63,11 +63,25 @@ .oe_mail_msg_image { float: left; - width: 14%; + width: 100px; + height: 100px; + text-align: center; + overflow: hidden; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + -o-border-radius: 3px; + -ms-border-radius: 3px; + border-radius: 3px; + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + -o-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + -box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); } .oe_mail_msg_image img { - margin-left: 10%; + width: 100px; + height: auto; + clip: rect(10px, 100px, 110px, 0px); } .oe_mail_msg_content { From 19897724a07cb5aebcd2ebe2d84ad605e3681309 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 23 Feb 2012 15:14:21 +0530 Subject: [PATCH 0062/1161] [ADD] add new cofiguration wizard view for sale bzr revid: tpa@tinyerp.com-20120223094421-1mdenu3k0752p79j --- openerp/addons/base/__openerp__.py | 1 + openerp/addons/base/res/__init__.py | 1 + openerp/addons/base/res/res_config_sale.py | 164 ++++++++++++++++++ .../addons/base/res/res_config_sale_view.xml | 79 +++++++++ 4 files changed, 245 insertions(+) create mode 100644 openerp/addons/base/res/res_config_sale.py create mode 100644 openerp/addons/base/res/res_config_sale_view.xml diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 4e9687e4ea4..a6e4f4da897 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -78,6 +78,7 @@ 'res/res_widget_view.xml', 'res/res_widget_data.xml', 'publisher_warranty/publisher_warranty_data.xml', + 'res/res_config_sale_view.xml', ], 'demo_xml': [ 'base_demo.xml', diff --git a/openerp/addons/base/res/__init__.py b/openerp/addons/base/res/__init__.py index 2b4da739f54..7cd63bc485d 100644 --- a/openerp/addons/base/res/__init__.py +++ b/openerp/addons/base/res/__init__.py @@ -35,6 +35,7 @@ import res_lang import res_log import res_widget import ir_property +import res_config_sale import wizard import report diff --git a/openerp/addons/base/res/res_config_sale.py b/openerp/addons/base/res/res_config_sale.py new file mode 100644 index 00000000000..0700635bcc2 --- /dev/null +++ b/openerp/addons/base/res/res_config_sale.py @@ -0,0 +1,164 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta +import time +import pooler +from osv import fields, osv +from tools.translate import _ +from tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, float_compare +import decimal_precision as dp +import netsvc + +class sale_config_picking_policy(osv.osv_memory): + _name = 'sale.config.picking_policy' + _inherit = 'res.config' + + _columns = { + 'name': fields.char('Name', size=64), + 'sale_orders': fields.boolean('Based on Sales Orders',), + 'deli_orders': fields.boolean('Based on Delivery Orders'), + 'task_work': fields.boolean('Based on Tasks\' Work'), + 'timesheet': fields.boolean('Based on Timesheet'), + 'order_policy': fields.selection([ + ('manual', 'Invoice Based on Sales Orders'), + ('picking', 'Invoice Based on Deliveries'), + ], 'Main Method Based On', required=True, help="You can generate invoices based on sales orders or based on shippings."), + 'charge_delivery': fields.boolean('Do you charge the delivery?'), + #'time_unit': fields.many2one('product.uom','Main Working Time Unit'), + 'picking_policy' : fields.boolean("Deliver all products at once?"), + 'group_sale_pricelist_per_customer':fields.boolean("Activate pricelist to manage prices per customer "), + 'group_sale_uom_per_product':fields.boolean("Allow different unit of measure per product"), + 'group_sale_delivery_address':fields.boolean(" Allow delivery address different from invoice address"), + 'group_sale_disc_per_sale_order_line':fields.boolean("Allow to apply discounts per sale order lines "), + 'group_sale_notes_subtotal':fields.boolean("Allow notes and subtotals"), + 'group_sale_alerts_per_customer_products':fields.boolean("Allow to define alerts by products or customers"), + 'tax_value' : fields.float('Value'), + 'tax_policy': fields.selection([ + ('no_tax', 'No Tax'), + ('global_on_order', 'Global On Order'), + ('on_order_line', 'On Order Lines'), + ], 'Taxes'), + 'sale_margin' : fields.boolean("Display Margin For Users"), + 'sale_journal' : fields.boolean("Invoice_journal?"), + + } + _defaults = { + 'order_policy': 'manual', + 'tax_policy': 'no_tax', + #'time_unit': lambda self, cr, uid, c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c) and self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c)[0] or False, + } + + def onchange_order(self, cr, uid, ids, sale, deli, context=None): + res = {} + if sale: + res.update({'order_policy': 'manual'}) + elif deli: + res.update({'order_policy': 'picking'}) + return {'value':res} + + def execute(self, cr, uid, ids, context=None): + ir_values_obj = self.pool.get('ir.values') + data_obj = self.pool.get('ir.model.data') + menu_obj = self.pool.get('ir.ui.menu') + module_obj = self.pool.get('ir.module.module') + module_upgrade_obj = self.pool.get('base.module.upgrade') + module_name = [] + + group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id + + wizard = self.browse(cr, uid, ids)[0] + + if wizard.sale_orders: + menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').id + menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]}) + + if wizard.deli_orders: + menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').id + menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]}) + + if wizard.task_work: + module_name.append('project_timesheet') + module_name.append('project_mrp') + module_name.append('account_analytic_analysis') + + if wizard.timesheet: + module_name.append('account_analytic_analysis') + + if wizard.charge_delivery: + module_name.append('delivery') + + if len(module_name): + module_ids = [] + need_install = False + module_ids = [] + for module in module_name: + data_id = module_obj.name_search(cr, uid , module, [], '=') + module_ids.append(data_id[0][0]) + + for module in module_obj.browse(cr, uid, module_ids): + if module.state == 'uninstalled': + module_obj.state_update(cr, uid, [module.id], 'to install', ['uninstalled'], context) + need_install = True + cr.commit() + if need_install: + pooler.restart_pool(cr.dbname, update_module=True)[1] + +# if wizard.time_unit: +# prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id +# product_obj = self.pool.get('product.product') +# product_obj.write(cr, uid, prod_id, {'uom_id':wizard.time_unit.id, 'uom_po_id': wizard.time_unit.id}) + + ir_values_obj.set(cr, uid, 'default', False, 'order_policy', ['sale.order'], wizard.order_policy) + if wizard.task_work and wizard.time_unit: + company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id + self.pool.get('res.company').write(cr, uid, [company_id], { + 'project_time_mode_id': wizard.time_unit.id + }, context=context) + + def apply_cb(self, cr, uid, ids, context=None): + ir_values_obj = self.pool.get('ir.values') + wizard = self.browse(cr, uid, ids, context=context)[0] + ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], wizard.picking_policy) + return {'type' : 'ir.actions.act_window_close'} + +sale_config_picking_policy() + + + +#class define_delivery_steps(osv.osv_memory): +# _name = 'delivery.define.delivery.steps.wizard' +# +# _columns = { +# 'picking_policy' : fields.selection([('direct', 'Deliver each product when available'), ('one', 'Deliver all products at once')], 'Picking Policy'), +# } +# _defaults = { +# 'picking_policy': lambda s,c,u,ctx: s.pool.get('sale.order').default_get(c,u,['picking_policy'],context=ctx)['picking_policy'] +# } +# +# def apply_cb(self, cr, uid, ids, context=None): +# ir_values_obj = self.pool.get('ir.values') +# wizard = self.browse(cr, uid, ids, context=context)[0] +# ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], wizard.picking_policy) +# return {'type' : 'ir.actions.act_window_close'} +# +#define_delivery_steps() \ No newline at end of file diff --git a/openerp/addons/base/res/res_config_sale_view.xml b/openerp/addons/base/res/res_config_sale_view.xml new file mode 100644 index 00000000000..492032c044d --- /dev/null +++ b/openerp/addons/base/res/res_config_sale_view.xml @@ -0,0 +1,79 @@ + + + + + Setup Your Invoicing Method + sale.config.picking_policy + form + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -
-
@@ -79,6 +71,11 @@
+
+
+ +
+
@@ -110,7 +107,7 @@ wrote on
- +

@@ -120,8 +117,16 @@ To:

- +

+ + +
+ +
+
From f48f10bcfa41c03439db4ee91d26be4d39772903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 27 Feb 2012 17:14:09 +0100 Subject: [PATCH 0115/1161] [REF] Cleaned a bit truncated message code bzr revid: tde@openerp.com-20120227161409-ej67dg04cy2deyjg --- addons/mail/static/src/css/mail.css | 3 ++- addons/mail/static/src/js/mail.js | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index be02336da41..653f71fc040 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -151,7 +151,8 @@ border-bottom: 1px solid #D2D9E7; } -.oe_mail_msg_body { +.oe_mail_msg_body a.reduce, .oe_mail_msg_body_short a.expand { + color: #4E43E7; } .oe_mail_msg_author { diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 1879a117c1f..3d7bca72190 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -95,16 +95,17 @@ openerp.mail = function(session) { record.tr_body_text = self.truncate_string(record.body_text, self.params.char_show_more); record.body_text = self.do_replace_internal_links(record.body_text); if (record.tr_body_text) record.tr_body_text = self.do_replace_internal_links(record.tr_body_text); + // render $(session.web.qweb.render('ThreadMsg', {'record': record})).appendTo(self.$element.find('div.oe_mail_thread_display')); // truncated: hide full-text, show summary, add buttons if (record.tr_body_text) { - var node = self.$element.find('span.oe_mail_msg_body:last').append('Show less'); + var node = self.$element.find('span.oe_mail_msg_body:last').append(' [ ... Show less]'); + self.$element.find('p.oe_mail_msg_p:last').append($('' + record.tr_body_text + ' [ ... Show more]')); + var new_node = self.$element.find('span.oe_mail_msg_body_short:last'); node.hide(); node.find('a:last').click(function() { node.hide(); new_node.show(); return false; }); - self.$element.find('p.oe_mail_msg_p:last').append($('' + record.tr_body_text + 'Show more')); - var new_node = self.$element.find('span.oe_mail_msg_body_short:last'); new_node.find('a:last').click(function() { new_node.hide(); node.show(); return false; }); From 1c100a848cac1939a3fb696c25a13e530e5f9a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 27 Feb 2012 17:21:58 +0100 Subject: [PATCH 0116/1161] [FIX] Added a class to internal links to delegate an action when clicking bzr revid: tde@openerp.com-20120227162158-q1hyvwxr04scwod7 --- addons/mail/static/src/js/mail.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 3d7bca72190..604f93af2cb 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -10,7 +10,6 @@ openerp.mail = function(session) { /* ThreadDisplay widget: display a thread of comments */ mail.ThreadDisplay = session.web.Widget.extend({ - // QWeb template to use when rendering the object template: 'ThreadDisplay', /** @@ -27,7 +26,6 @@ openerp.mail = function(session) { */ init: function(parent, params) { this._super(parent); - console.log(parent); this.params = params; this.params.limit = this.params.limit || 10; this.params.offset = this.params.offset || 0; @@ -139,7 +137,7 @@ openerp.mail = function(session) { while (regex_res != null) { var login = regex_res[2]; var res_id = 1; - string = string.replace(regex_res[0], '@' + login + ''); + string = string.replace(regex_res[0], '@' + login + ''); regex_res = regex_login.exec(string); } return string; From 83ef71f651885b60ab11da5963b03598ed4a6608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 27 Feb 2012 18:13:23 +0100 Subject: [PATCH 0117/1161] [REF] Some code cleaning. Hashtag replacement still not working. bzr revid: tde@openerp.com-20120227171323-xvn752llibh66v9w --- addons/mail/static/src/js/mail.js | 100 +++++++++++++++--------------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 604f93af2cb..5b83020fdc4 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -31,9 +31,8 @@ openerp.mail = function(session) { this.params.offset = this.params.offset || 0; this.params.records = this.params.records || null; this.params.char_show_more = this.params.char_show_more || 100; - // tmp - this.map_hash = {'res.users': []}; - /* DataSets */ + this.map_hash = {'res.users': {'login': [] }}; + /* define DataSets */ this.ds = new session.web.DataSet(this, this.params.res_model); this.ds_users = new session.web.DataSet(this, 'res.users'); }, @@ -45,12 +44,10 @@ openerp.mail = function(session) { this.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); /* delegate links */ self.$element.find('div.oe_mail_thread_display').delegate('a.intlink', 'click', function (event) { - var res_model = event.srcElement.dataset.resModel; - var res_id = event.srcElement.dataset.resId; self.do_action({ type: 'ir.actions.act_window', - res_model: res_model, - res_id: parseInt(res_id), + res_model: event.srcElement.dataset.resModel, + res_id: parseInt(event.srcElement.dataset.resId), views: [[false, 'form']] }); }); @@ -81,32 +78,30 @@ openerp.mail = function(session) { display_comments: function (records) { var self = this; /* WIP: map matched regexp -> records to browse with name */ - _(records).each(function (record) { - //self.check_internal_links(record.body_text); - }); - //console.log(this.map_hash); + //_(records).each(function (record) { + //self.do_check_internal_links(record.body_text); + //}); _(records).each(function (record) { if (record.type == 'email') { record.mini_url = ('/mail/static/src/img/email_icon.png'); } else { record.mini_url = self.thread_get_avatar_mini('res.users', 'avatar_mini', record.user_id[0]); } + // body text manipulation record.body_text = self.do_clean_text(record.body_text); - record.tr_body_text = self.truncate_string(record.body_text, self.params.char_show_more); + record.tr_body_text = self.do_truncate_string(record.body_text, self.params.char_show_more); record.body_text = self.do_replace_internal_links(record.body_text); if (record.tr_body_text) record.tr_body_text = self.do_replace_internal_links(record.tr_body_text); + // render $(session.web.qweb.render('ThreadMsg', {'record': record})).appendTo(self.$element.find('div.oe_mail_thread_display')); + // truncated: hide full-text, show summary, add buttons if (record.tr_body_text) { var node = self.$element.find('span.oe_mail_msg_body:last').append(' [ ... Show less]'); self.$element.find('p.oe_mail_msg_p:last').append($('' + record.tr_body_text + ' [ ... Show more]')); var new_node = self.$element.find('span.oe_mail_msg_body_short:last'); node.hide(); - node.find('a:last').click(function() { - node.hide(); new_node.show(); return false; - }); - new_node.find('a:last').click(function() { - new_node.hide(); node.show(); return false; - }); + node.find('a:last').click(function() { node.hide(); new_node.show(); return false; }); + new_node.find('a:last').click(function() { new_node.hide(); node.show(); return false; }); } }); // update offset for "More" buttons @@ -115,7 +110,7 @@ openerp.mail = function(session) { display_current_user: function () { $('
').html( - '' + '' ).appendTo(this.$element.find('div.oe_mail_msg_image')); }, @@ -137,50 +132,57 @@ openerp.mail = function(session) { while (regex_res != null) { var login = regex_res[2]; var res_id = 1; - string = string.replace(regex_res[0], '@' + login + ''); + //var user_loaded = this.ds_users.call('search', [[['login', 'in', [login]]]]).then(function (records) { + //console.log(records); + //if (records) string = string.replace(regex_res[0], '@' + login + ''); + //}); + //$.when(user_loaded).then(function() { + //}); regex_res = regex_login.exec(string); } return string; }, - ///* check for internal links, and map them to limitate number of queries -- WIP, probably not useful */ - //check_internal_links: function(string) { - ///* shortcut to user: @login */ - ////var regex_login = new RegExp(/(^|\s)@(\w*[a-zA-Z_.]+\w*\s)/g); - //var regex_login = new RegExp(/(^|\s)@(\w*)/g); - //var regex_res = regex_login.exec(string); - //while (regex_res != null) { - //var login = regex_res[2]; - //this.map_hash['res.users'].push(login); - //regex_res = regex_login.exec(string); - //} - ///* internal links: #res.model,name */ - //var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g); - //regex_res = regex_intlink.exec(string); - //while (regex_res != null) { - //var res_model = regex_res[2] + '.' + regex_res[3]; - //var res_name = regex_res[4]; - //if (! (res_model in this.map_hash)) { this.map_hash[res_model] = []; } - //this.map_hash[res_model].push(res_name); - //regex_res = regex_intlink.exec(string); - //} - //}, - thread_get_avatar_mini: function(model, field, id) { return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || ''); }, - - truncate_string: function(string, max_length) { - var string_len = string.length; // TODO: check for whitespaces ? - if (string_len <= max_length) return false; - var new_string = string.slice(0, max_length); - return new_string; + + do_truncate_string: function(string, max_length) { + if (string.length <= max_length) return false; + else return string.slice(0, max_length); }, do_clean_text: function (string) { var html = $('
').text(string.replace(/\s+/g, ' ')).html().replace(new RegExp('<(/)?b\\s*>', 'gi'), '<$1b>'); return html; }, + + /** + * + * var regex_login = new RegExp(/(^|\s)@(\w*[a-zA-Z_.]+\w*\s)/g); + * var regex_login = new RegExp(/(^|\s)@(\w*)/g); + * var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g); + */ + do_check_internal_links: function(string) { + /* shortcut to user: @login */ + var regex_login = new RegExp(/(^|\s)@(\w*)/g); + var regex_res = regex_login.exec(string); + while (regex_res != null) { + var login = regex_res[2]; + this.map_hash['res.users']['login'].push(login); + regex_res = regex_login.exec(string); + } + /* internal links: #res.model,name */ + var regex_intlink = new RegExp(/(^|\s)#(\w*[a-zA-Z_]+\w*)\.(\w+[a-zA-Z_]+\w*),(\w+)/g); + regex_res = regex_intlink.exec(string); + while (regex_res != null) { + var res_model = regex_res[2] + '.' + regex_res[3]; + var res_name = regex_res[4]; + if (! (res_model in this.map_hash)) { this.map_hash[res_model]['name'] = []; } + this.map_hash[res_model]['name'].push(res_name); + regex_res = regex_intlink.exec(string); + } + }, }); From 977d3e997a766cd109dfaa10d9bacb8d626ef5b3 Mon Sep 17 00:00:00 2001 From: "Jiten (OpenERP)" Date: Tue, 28 Feb 2012 10:51:14 +0530 Subject: [PATCH 0118/1161] [IMP] Improved notifications for hr recruitment. bzr revid: jra@tinyerp.com-20120228052114-oadwo3hewlphflho --- addons/hr_recruitment/hr_recruitment.py | 86 ++++++++++++++++++------- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 4398cb72b1d..67ee298322f 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -171,7 +171,6 @@ class hr_applicant(crm.crm_case, osv.osv): 'partner_mobile': fields.char('Mobile', size=32), 'type_id': fields.many2one('hr.recruitment.degree', 'Degree'), 'department_id': fields.many2one('hr.department', 'Department'), - 'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True), 'survey': fields.related('job_id', 'survey_id', type='many2one', relation='survey', string='Survey'), 'response': fields.integer("Response"), 'reference': fields.char('Refered By', size=128), @@ -181,6 +180,7 @@ class hr_applicant(crm.crm_case, osv.osv): 'day_close': fields.function(_compute_day, string='Days to Close', \ multi='day_close', type="float", store=True), 'color': fields.integer('Color Index'), + 'emp_id': fields.many2one('hr.employee', 'employee'), 'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True), } @@ -392,16 +392,50 @@ class hr_applicant(crm.crm_case, osv.osv): return res def _case_open_notification(self, case, context=None): - message = _("The job request '%s' has been set 'in progress'.") % case.name - case.message_append_note('' ,message, need_action_user_id=case.id) + message = _("Changed Status to In Progress.") + case.message_append_note('' ,message, type='notification', need_action_user_id=case.user_id.id) + return True def _case_close_notification(self, case, context=None): - message = _("Applicant '%s' is being hired.") % case.name - case.message_append_note('' ,message, need_action_user_id=case.id) + print "\n ::: case close notification :: hr rec:::" + case[0].message_mark_done(context) + if case[0].emp_id: + message = _("Applicant is being Hired with employee.") + case[0].message_append_note('' ,message, type='notification') + else: + message = _("Applicant is being Hired without employee.") + case[0].message_append_note('' ,message, type='notification') + return True - def _case_reset_notification(self, case, context=None): - message = _("The job request %s has been Reset as 'New'.") % case.name - case.message_append_note('' ,message, need_action_user_id=case.id) + def _case_cancel_notification(self, case, context=None): + case[0].message_mark_done(context=context) + message = _("Applicant Subject '%s' has been Cancelled.") % (case[0].name) + case[0].message_append_note('' ,message, type="notification") + return True + + def _case_pending_notification(self, case, context=None): + message = _("Changed Status to Pending.") + case[0].message_append_note('' ,message, type='notification', need_action_user_id=case[0].user_id.id) + return True + + def _case_reset_notification(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids, context=context): + self.message_append_note(cr, uid, ids, _('System notification'), + _("Changed Status to New."), type='notification', need_action_user_id=obj.user_id.id, context=context) + return True + + def create_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids, context=context): + self.message_subscribe(cr, uid, ids, [obj.user_id.id], context=context) + self.message_append_note(cr, uid, ids, _('System notification'), + _("Applicant Created."), type='notification', need_action_user_id=obj.user_id.id, context=context) + return True + + + def create(self, cr, uid, vals, context=None): + obj_id = super(hr_applicant, self).create(cr, uid, vals, context=context) + self.create_notificate(cr, uid, [obj_id], context=context) + return obj_id def case_open(self, cr, uid, ids, context=None): """ @@ -413,11 +447,11 @@ class hr_applicant(crm.crm_case, osv.osv): self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'),}) return res - def case_close(self, cr, uid, ids, *args): - res = super(hr_applicant, self).case_close(cr, uid, ids, *args) + def case_close(self, cr, uid, ids, context=None): + res = super(hr_applicant, self).case_close(cr, uid, ids, context) return res - def case_close_with_emp(self, cr, uid, ids, *args): + def case_close_with_emp(self, cr, uid, ids, context=None): hr_employee = self.pool.get('hr.employee') model_data = self.pool.get('ir.model.data') act_window = self.pool.get('ir.actions.act_window') @@ -433,10 +467,10 @@ class hr_applicant(crm.crm_case, osv.osv): 'address_home_id': address_id, 'department_id': applicant.department_id.id }) - self.case_close(cr, uid, [applicant.id], *args) + self.write(cr, uid, [applicant.id], {'emp_id': emp_id}) + self.case_close(cr, uid, [applicant.id], context) else: raise osv.except_osv(_('Warning!'),_('You must define Applied Job for this applicant.')) - self._case_reset_notification(applicant, context=context) action_model, action_id = model_data.get_object_reference(cr, uid, 'hr', 'open_view_employee_list') dict_act_window = act_window.read(cr, uid, action_id, []) @@ -445,17 +479,25 @@ class hr_applicant(crm.crm_case, osv.osv): dict_act_window['view_mode'] = 'form,tree' return dict_act_window - def case_reset(self, cr, uid, ids, *args): - """Resets case as draft - @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_cancel(self, cr, uid, ids, context=None): + """Overrides cancel for crm_case for setting probability """ + res = super(hr_applicant, self).case_cancel(cr, uid, ids, context) + self.write(cr, uid, ids, {'probability' : 0.0}) + return res - res = super(hr_applicant, self).case_reset(cr, uid, ids, *args) + def case_pending(self, cr, uid, ids, context=None): + """Marks case as pending""" + res = super(hr_applicant, self).case_pending(cr, uid, ids, context) + self.write(cr, uid, ids, {'probability' : 0.0}) + return res + + def case_reset(self, cr, uid, ids, context=None): + """Resets case as draft + """ + res = super(hr_applicant, self).case_reset(cr, uid, ids, context) self.write(cr, uid, ids, {'date_open': False, 'date_closed': False}) + self._case_reset_notification(cr, uid, ids, context) return res def set_priority(self, cr, uid, ids, priority, *args): @@ -476,7 +518,7 @@ class hr_applicant(crm.crm_case, osv.osv): def write(self, cr, uid, ids, vals, context=None): if 'stage_id' in vals and vals['stage_id']: stage = self.pool.get('hr.recruitment.stage').browse(cr, uid, vals['stage_id'], context=context) - text = _("Changed Stage to: %s") % stage.name + text = _("Changed Stage to %s") % stage.name self.message_append(cr, uid, ids, text, body_text=text, context=context) return super(hr_applicant,self).write(cr, uid, ids, vals, context=context) From 2022a090a95b2028d83db65aa81a6b0721cffdae Mon Sep 17 00:00:00 2001 From: "Jiten (OpenERP)" Date: Tue, 28 Feb 2012 11:05:30 +0530 Subject: [PATCH 0119/1161] [REM] Remove print statement from close notification method. bzr revid: jra@tinyerp.com-20120228053530-u71bnf8evc11f54b --- addons/hr_recruitment/hr_recruitment.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 67ee298322f..37987a62b50 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -397,7 +397,6 @@ class hr_applicant(crm.crm_case, osv.osv): return True def _case_close_notification(self, case, context=None): - print "\n ::: case close notification :: hr rec:::" case[0].message_mark_done(context) if case[0].emp_id: message = _("Applicant is being Hired with employee.") From d709dbc86f5e6e0a0da5b75c9b4d8ae789494e69 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 11:10:41 +0530 Subject: [PATCH 0120/1161] [IMP] add module names in module list to get default values bzr revid: tpa@tinyerp.com-20120228054041-sber8n3hs26eprt8 --- openerp/addons/base/res/res_config_sale.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_config_sale.py b/openerp/addons/base/res/res_config_sale.py index 7e23cdd5bda..7e28232a2a3 100644 --- a/openerp/addons/base/res/res_config_sale.py +++ b/openerp/addons/base/res/res_config_sale.py @@ -25,7 +25,8 @@ import pooler MODULE_LIST = [ 'analytic_user_function', 'analytic_journal_billing_rate', 'import_sugarcrm', 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact', - 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook' + 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook', + 'project_timesheet','project_mrp','account_analytic_analysis','delivery', ] class sale_configuration(osv.osv_memory): From 76950baec78b64d5a33a46ad55eabf19c6d799f3 Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Tue, 28 Feb 2012 11:20:38 +0530 Subject: [PATCH 0121/1161] [IMP] When creating a lead notification put,subscribin when create a lead,when close,cancel,lost,won lead at that time need action is removed. bzr revid: bth@tinyerp.com-20120228055038-7rekfl8whlhgf12h --- addons/crm/crm_lead.py | 61 ++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index b08fcdb78eb..9868689dcc5 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -224,6 +224,12 @@ class crm_lead(crm_case, osv.osv): 'color': 0, } + def create(self, cr, uid, vals, context=None): + obj_id = super(crm_lead, self).create(cr, uid, vals, context) + self._case_create_notification(cr, uid, [obj_id], context=context) + return obj_id + + def onchange_partner_address_id(self, cr, uid, ids, add, email=False): """This function returns value of partner email based on Partner Address """ @@ -265,54 +271,64 @@ class crm_lead(crm_case, osv.osv): def stage_find_won(self, cr, uid, section_id): return self.stage_find_percent(cr, uid, 100.0, section_id) + def _case_create_notification(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids, context=context): + self.message_subscribe(cr, uid, ids, [obj.user_id.id], context=context) + self.message_append_note(cr, uid, ids, _('System notification'), + _("Lead %s is Created.") % (obj.name), type='notification', need_action_user_id=obj.user_id.id, context=context) + return True + def _case_open_notification(self, lead, context=None): if lead.state != 'draft' and lead.state != 'pending': return False if lead.type == 'lead': - message = _("The lead %s has been opened and its state is now in progress.") % (lead.name) + message = _("The lead %s has been opened.") % (lead.name) elif lead.type == 'opportunity': - message = _("The opportunity %s has been opened.") % lead.name + message = _("The opportunity %s has been opened.") % lead.name else: - message = _("The case %s has been opened.") % lead.name - lead.message_append_note('' ,message) + message = _("The case %s has been opened.") % lead.name + lead.message_append_note('' ,message, need_action_user_id=lead.user_id.id) def _case_close_notification(self, lead, context=None): + lead[0].message_mark_done(context) if lead[0].type == 'lead': - message = _("The lead %s has been closed.") % lead[0].name + message = _("The lead %s has been closed.") % lead[0].name else: - message = _("The case %s has been closed.") % lead[0].name - + message = _("The case %s has been closed.") % lead[0].name lead[0].message_append_note('' ,message) def _case_mark_lost_notification(self, lead, context=None): - message = _("The opportunity %s has been marked as lost.") % lead.name + lead.message_mark_done(context) + message = _("The opportunity %s has been marked as lost.") % lead.name lead.message_append_note('' ,message) def _case_mark_won_notification(self, lead, context=None): - message = _("The opportunity %s has been been won.") % lead.name + lead.message_mark_done(context) + message = _("The opportunity %s has been been won.") % lead.name lead.message_append_note('' ,message) def _case_cancel_notification(self, lead, context=None): - message = _("The lead %s has been cancelled.") % (lead[0].name) + lead[0].message_mark_done(context) + message = _("The lead %s has been cancelled.") % (lead[0].name) lead[0].message_append_note('' ,message) def _case_pending_notification(self, case, context=None): if case[0].type == 'lead': - message = _("The lead %s is pending.") % (case[0].name,) + message = _("The lead %s is pending.") % (case[0].name,) elif case[0].type == 'opportunity': - message = _("The opportunity %s is pending.") % (case[0].name,) - case[0].message_append_note('' ,message) + message = _("The opportunity %s is pending.") % (case[0].name,) + case[0].message_append_note('' ,message, need_action_user_id=case[0].user_id.id) def _case_escalate_notification(self, case, context=None): - message = _("The lead %s is escalated.") % (case.name,) + message = _("The lead %s is escalated.") % (case.name,) case.message_append_note('' ,message) def _case_phonecall_notification(self, case, action, context=None): - message = _("%s a call for the opportunity %s.") % (action,case.name) + message = _("%s a call for the opportunity %s.") % (action,case.name) case.message_append_note('', message, need_action_user_id=case.user_id.id) def _case_opportunity_meeting_notification(self, case, context=None): - message = _("The opportunity %s is scheduled for meeting.") % (case.name) + message = _("The opportunity %s is scheduled for meeting.") % (case.name) case.message_append_note('', message, need_action_user_id=case.user_id.id) def case_open(self, cr, uid, ids, context=None): @@ -354,7 +370,6 @@ class crm_lead(crm_case, osv.osv): stage_id = self.stage_find_lost(cr, uid, lead.section_id.id or False) if stage_id: self.stage_set(cr, uid, [lead.id], stage_id) - self._case_mark_lost_notification(lead, context=context) return res def case_mark_won(self, cr, uid, ids, context=None): @@ -472,7 +487,7 @@ class crm_lead(crm_case, osv.osv): subject = subject[0] + ", ".join(subject[1:]) details = "\n\n".join(details) - return opportunity.message_append_note(subject, body_text=details, need_action_user_id=opportunity.user_id.id) + return opportunity.message_append_note(subject, body=details, need_action_user_id=opportunity.user_id.id) def _merge_opportunity_history(self, cr, uid, opportunity_id, opportunities, context=None): message = self.pool.get('mail.message') @@ -582,8 +597,8 @@ class crm_lead(crm_case, osv.osv): } def _convert_opportunity_notification(self, cr, uid, lead, context=None): - success_message = _("Lead %s has been converted to an opportunity.") % lead.name - lead.message_append_note(success_message ,success_message) + success_message = _("Lead %s has been converted to an opportunity.") % lead.name + lead.message_append_note(success_message ,success_message, need_action_user_id=lead.user_id.id) return True def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None): @@ -878,14 +893,14 @@ class crm_lead(crm_case, osv.osv): # change probability of lead(s) if required by stage if not vals.get('probability') and stage.on_change: vals['probability'] = stage.probability - text = _("Changed Stage to: %s") % stage.name + text = _("Changed Stage to: %s") % stage.name for case in self.browse(cr, uid, ids, context=context): if case.type == 'lead' or context.get('stage_type') == 'lead': - message = _("The stage of lead %s has been changed to %s.") % (case.name, stage.name) + message = _("The stage of lead %s has been changed to %s.") % (case.name, stage.name) case.message_append_note(text, message) elif case.type == 'opportunity': - message = _("The stage of opportunity %s has been changed to %s.") % (case.name, stage.name) + message = _("The stage of opportunity %s has been changed to %s.") % (case.name, stage.name) case.message_append_note(text, message) return super(crm_lead,self).write(cr, uid, ids, vals, context) From cafffbfb467dea692e090b81bd7fb372b782e51f Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Tue, 28 Feb 2012 11:25:37 +0530 Subject: [PATCH 0122/1161] [FIX] Remove and tags from notification messages it is not working so removed. bzr revid: bth@tinyerp.com-20120228055537-asmg2uiuuwssgpex --- addons/sale_crm/wizard/crm_make_sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py index de9a6d4cd1f..fe338b0585f 100644 --- a/addons/sale_crm/wizard/crm_make_sale.py +++ b/addons/sale_crm/wizard/crm_make_sale.py @@ -106,7 +106,7 @@ 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) + message = _("Opportunity %s is converted to Quotation.") % (case.name) case.message_append_note( _("Converted to Sales Quotation(%s).") % (sale_order.name),message,need_action_user_id=sale_order.user_id.id) if make.close: From 6921b39416703c97c5725f857927c28c69eefed4 Mon Sep 17 00:00:00 2001 From: "Jiten (OpenERP)" Date: Tue, 28 Feb 2012 11:33:57 +0530 Subject: [PATCH 0123/1161] [IMP] Improved message when applicant hired with/without employee. bzr revid: jra@tinyerp.com-20120228060357-3qvhqvo1hzhc3k6s --- addons/hr_recruitment/hr_recruitment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 37987a62b50..cc63dd99b62 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -399,10 +399,10 @@ class hr_applicant(crm.crm_case, osv.osv): def _case_close_notification(self, case, context=None): case[0].message_mark_done(context) if case[0].emp_id: - message = _("Applicant is being Hired with employee.") + message = _("Applicant is being Hired as an employee.") case[0].message_append_note('' ,message, type='notification') else: - message = _("Applicant is being Hired without employee.") + message = _("Applicant is being Hired.") case[0].message_append_note('' ,message, type='notification') return True From e5dd5eb176a53b69cef16460a64f75fa23413e8e Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 11:40:54 +0530 Subject: [PATCH 0124/1161] [REV] revert 4091 bzr revid: tpa@tinyerp.com-20120228061054-0jgbutrf0jv2ezrc --- openerp/addons/base/res/res_config_sale.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openerp/addons/base/res/res_config_sale.py b/openerp/addons/base/res/res_config_sale.py index 7e28232a2a3..fa5d922776c 100644 --- a/openerp/addons/base/res/res_config_sale.py +++ b/openerp/addons/base/res/res_config_sale.py @@ -26,7 +26,6 @@ MODULE_LIST = [ 'analytic_user_function', 'analytic_journal_billing_rate', 'import_sugarcrm', 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact', 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook', - 'project_timesheet','project_mrp','account_analytic_analysis','delivery', ] class sale_configuration(osv.osv_memory): From c763083fc4a61425352a1088ff762d8e14bfd7c7 Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Tue, 28 Feb 2012 13:15:27 +0530 Subject: [PATCH 0125/1161] [FIX] remove lead and opportuniy name from notification messages,apply bold tag on stages,put quotation name when converted in quotation from opportunity,put need action only in create and open stage. bzr revid: bth@tinyerp.com-20120228074527-j53q7ulkyhb1uxib --- addons/crm/crm_lead.py | 33 ++++++++++++++----------- addons/sale_crm/wizard/crm_make_sale.py | 2 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 9868689dcc5..f166897a2cb 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -275,52 +275,57 @@ class crm_lead(crm_case, osv.osv): for obj in self.browse(cr, uid, ids, context=context): self.message_subscribe(cr, uid, ids, [obj.user_id.id], context=context) self.message_append_note(cr, uid, ids, _('System notification'), - _("Lead %s is Created.") % (obj.name), type='notification', need_action_user_id=obj.user_id.id, context=context) + _("Lead is created."), type='notification', need_action_user_id=obj.user_id.id, context=context) return True def _case_open_notification(self, lead, context=None): if lead.state != 'draft' and lead.state != 'pending': return False if lead.type == 'lead': - message = _("The lead %s has been opened.") % (lead.name) + message = _("The lead has been opened.") elif lead.type == 'opportunity': - message = _("The opportunity %s has been opened.") % lead.name + message = _("The opportunity has been opened.") else: - message = _("The case %s has been opened.") % lead.name + message = _("The case has been opened.") lead.message_append_note('' ,message, need_action_user_id=lead.user_id.id) def _case_close_notification(self, lead, context=None): lead[0].message_mark_done(context) if lead[0].type == 'lead': - message = _("The lead %s has been closed.") % lead[0].name + message = _("The lead has been closed.") + elif lead[0].type == 'opportunity': + message = _("The opportunity has been closed.") else: - message = _("The case %s has been closed.") % lead[0].name + message = _("The case has been closed.") lead[0].message_append_note('' ,message) def _case_mark_lost_notification(self, lead, context=None): lead.message_mark_done(context) - message = _("The opportunity %s has been marked as lost.") % lead.name + message = _("The opportunity has been marked as lost.") lead.message_append_note('' ,message) def _case_mark_won_notification(self, lead, context=None): lead.message_mark_done(context) - message = _("The opportunity %s has been been won.") % lead.name + message = _("The opportunity has been won.") lead.message_append_note('' ,message) def _case_cancel_notification(self, lead, context=None): lead[0].message_mark_done(context) - message = _("The lead %s has been cancelled.") % (lead[0].name) + if lead[0].type == 'lead': + message = _("The lead has been cancelled.") + elif lead[0].type == 'opportunity': + message = _("The opportunity has been cancelled.") lead[0].message_append_note('' ,message) def _case_pending_notification(self, case, context=None): if case[0].type == 'lead': - message = _("The lead %s is pending.") % (case[0].name,) + message = _("The lead is pending.") elif case[0].type == 'opportunity': - message = _("The opportunity %s is pending.") % (case[0].name,) - case[0].message_append_note('' ,message, need_action_user_id=case[0].user_id.id) + message = _("The opportunity is pending.") + case[0].message_append_note('' ,message) def _case_escalate_notification(self, case, context=None): - message = _("The lead %s is escalated.") % (case.name,) + message = _("The lead is escalated.") case.message_append_note('' ,message) def _case_phonecall_notification(self, case, action, context=None): @@ -597,7 +602,7 @@ class crm_lead(crm_case, osv.osv): } def _convert_opportunity_notification(self, cr, uid, lead, context=None): - success_message = _("Lead %s has been converted to an opportunity.") % lead.name + success_message = _("Lead is converted to an opportunity.") lead.message_append_note(success_message ,success_message, need_action_user_id=lead.user_id.id) return True diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py index fe338b0585f..1d898c5cc8d 100644 --- a/addons/sale_crm/wizard/crm_make_sale.py +++ b/addons/sale_crm/wizard/crm_make_sale.py @@ -106,7 +106,7 @@ 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) + message = _("Opportunity %s is converted to Quotation %s.") % (case.name, sale_order.name) case.message_append_note( _("Converted to Sales Quotation(%s).") % (sale_order.name),message,need_action_user_id=sale_order.user_id.id) if make.close: From 66f55d4e83f3f5464928bb5f347b37b94e7875db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 28 Feb 2012 09:26:06 +0100 Subject: [PATCH 0126/1161] [IMP] Wall thread view: lessened size of comment box in threads. bzr revid: tde@openerp.com-20120228082606-bfekwwkemxb0b3xn --- addons/mail/static/src/css/mail.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 653f71fc040..43c9c54afd0 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -20,6 +20,11 @@ margin-left: 5%; } +.oe_mail_wall_thread_content div.oe_mail_thread_act .oe_mail_action_textarea { + width: 100%; + height: 20px; + padding: 2px; +} /* Thread */ @@ -110,7 +115,7 @@ } .oe_mail_action_textarea { - width: 60%; + width: 80%; height: 50px; padding: 5px; } From 519ab10a1a9200a402552db04b65dff2ec693533 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 14:09:07 +0530 Subject: [PATCH 0127/1161] [add] added account_analytic_analysis field bzr revid: tpa@tinyerp.com-20120228083907-xn941ljd6en9t17y --- openerp/addons/base/res/res_config_sale.py | 4 +++- openerp/addons/base/res/res_config_sale_view.xml | 6 ++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/res/res_config_sale.py b/openerp/addons/base/res/res_config_sale.py index fa5d922776c..52be896d058 100644 --- a/openerp/addons/base/res/res_config_sale.py +++ b/openerp/addons/base/res/res_config_sale.py @@ -25,7 +25,7 @@ import pooler MODULE_LIST = [ 'analytic_user_function', 'analytic_journal_billing_rate', 'import_sugarcrm', 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact', - 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook', + 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook','account_analytic_analysis' ] class sale_configuration(osv.osv_memory): @@ -64,6 +64,8 @@ class sale_configuration(osv.osv_memory): help="Install plugin_thunderbird module: This module is required for the Thuderbird Plug-in to work properly."), 'plugin_outlook': fields.boolean('Push your email from Outlook to an OpenERP document', help="Install plugin_outlook module: This module provides the Outlook Plug-in."), + 'account_analytic_analysis': fields.boolean('Contracts', + help="Install account_analytic_analysis module: This module is for modifying account analytic view to show important data to project manager of services companies."), } def get_applied_groups(self, cr, uid, context=None): diff --git a/openerp/addons/base/res/res_config_sale_view.xml b/openerp/addons/base/res/res_config_sale_view.xml index 9b43b362cc9..e69a2476ac9 100644 --- a/openerp/addons/base/res/res_config_sale_view.xml +++ b/openerp/addons/base/res/res_config_sale_view.xml @@ -10,13 +10,11 @@ - - - + - + From a32d9d7b892effd23fa8f99114624aecc0fbb892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 28 Feb 2012 09:51:11 +0100 Subject: [PATCH 0128/1161] [DOC] Added comments in mail.js bzr revid: tde@openerp.com-20120228085111-13kx0t7l7bxmywmq --- addons/mail/static/src/js/mail.js | 54 +++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 5b83020fdc4..a2d8a1faed1 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -294,13 +294,21 @@ openerp.mail = function(session) { /* WallView widget: a wall of messages */ mail.WallView = session.web.Widget.extend({ - // QWeb template to use when rendering the object template: 'Wall', + /** + * + * @param {Object} parent parent + * @param {Object} [params] + * @param {Number} [params.limit=20] number of messages to show and fetch + * @var {Array} sorted_comments records sorted by res_model and res_id + * records.res_model = {res_ids} + * records.res_model.res_id = [records] + */ init: function (parent, params) { this._super(parent); - this.filter_search = params['filter_search']; - this.search = {} + this.params.limit = params.limit || 20; + this.sorted_comments = {}; /* DataSets */ this.ds_msg = new session.web.DataSet(this, 'mail.message'); this.ds_thread = new session.web.DataSet(this, 'mail.thread'); @@ -324,7 +332,13 @@ openerp.mail = function(session) { stop: function () { this._super.apply(this, arguments); }, - + + /** + * + * @param {Number} view_id id of the search view to load + * @param {??} defaults ?? + * @param {Boolean} hidden ?? + */ load_search_view: function (view_id, defaults, hidden) { this.searchview = new session.web.SearchView(this, this.ds_msg, view_id || false, defaults || {}, hidden || false); return this.searchview.appendTo(this.$element.find('div.oe_mail_wall_search')); @@ -350,12 +364,16 @@ openerp.mail = function(session) { this.proxy('display_comments')); return load_res; }, - + + /** + * + * @param {Array} records records to show in threads + */ display_comments: function (records) { this.$element.find('div.oe_mail_wall_threads').empty(); - sorted_records = this.sort_comments(records); + this.sort_comments(records, this.sorted_comments); var self = this; - _(sorted_records).each(function (rec_models, model) { // each model + _(this.sorted_comments).each(function (rec_models, model) { // each model _(rec_models).each(function (record_id, id) { // each record var template = 'WallThreadContainer'; var render_res = session.web.qweb.render(template, { @@ -371,8 +389,15 @@ openerp.mail = function(session) { }); }, - sort_comments: function (records) { - sorted_comments = {}; + /** + * Add records to sorted_comments array + * @param {Array} records records from mail.message + * @param {Array} sorted_comments already sorted comments that will be updated + * @returns {Array} sorted_comments + * sorted_comments.res_model = {res_ids} + * sorted_comments.res_model.res_id = [records] + */ + sort_comments: function (records, sorted_comments) { _(records).each(function (record) { if (! (record.model in sorted_comments)) { sorted_comments[record.model] = {}; } if (! (record.res_id in sorted_comments[record.model])) { @@ -382,12 +407,21 @@ openerp.mail = function(session) { return sorted_comments; }, + /** + * Create a domain to fetch new comments according to + * comment already present in sorted_comments + * @returns {Array} fetch_domain (OpenERP domain style) + */ + get_fetch_domain: function (sorted_comments) { + + }, + do_comment: function () { var body_text = this.$element.find('textarea').val(); return this.ds_users.call('message_append_note', [[this.session.uid], 'Tweet', body_text, type='comment']).then( this.proxy('fetch_comments')); }, - + thread_get_mini: function(model, field, id) { id = id || ''; var url = this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; From e291bf11da4540d5eb17824b59a2e85da0d6f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 28 Feb 2012 09:56:07 +0100 Subject: [PATCH 0129/1161] [DOC] Added comments in mailL.js (Wall widget) bzr revid: tde@openerp.com-20120228085607-oty29x74cwxy6zdi --- addons/mail/static/src/js/mail.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index a2d8a1faed1..156f6ff4590 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -297,7 +297,6 @@ openerp.mail = function(session) { template: 'Wall', /** - * * @param {Object} parent parent * @param {Object} [params] * @param {Number} [params.limit=20] number of messages to show and fetch @@ -334,7 +333,7 @@ openerp.mail = function(session) { }, /** - * + * Loads the mail.message search view * @param {Number} view_id id of the search view to load * @param {??} defaults ?? * @param {Boolean} hidden ?? @@ -343,7 +342,15 @@ openerp.mail = function(session) { this.searchview = new session.web.SearchView(this, this.ds_msg, view_id || false, defaults || {}, hidden || false); return this.searchview.appendTo(this.$element.find('div.oe_mail_wall_search')); }, - + + /** + * Aggregate the domains, contexts and groupbys in parameter + * with those from search form, and then calls fetch_comments + * to actually fetch comments + * @param {Array} domains + * @param {Array} contexts + * @param {Array} groupbys + */ do_searchview_search: function(domains, contexts, groupbys) { var self = this; this.rpc('/web/session/eval_domain_and_context', { @@ -357,7 +364,14 @@ openerp.mail = function(session) { self.fetch_comments(self.search['domain'], self.search['context']); }); }, - + + /** + * Fetches Wall comments (mail.thread.get_pushed_messages) + * @param {Array} domains + * @param {Array} contexts + * @param {Array} groupbys + * @param {Number} limit number of messages to fetch + */ fetch_comments: function (domain, context, offset, limit) { var load_res = this.ds_thread.call('get_pushed_messages', [[this.session.uid], limit = (limit || 100), offset = (offset || 0), domain = (domain || null), context = (context || null) ]).then( @@ -366,7 +380,6 @@ openerp.mail = function(session) { }, /** - * * @param {Array} records records to show in threads */ display_comments: function (records) { From 6b7d8c00d1c66d7d44fe23805c7acce38d1d6745 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 14:44:25 +0530 Subject: [PATCH 0130/1161] [IMP] remove group_sale_notes_subnotes ind add field sale_layout bzr revid: tpa@tinyerp.com-20120228091425-99j1kcz5so20r0yg --- addons/sale/sale.py | 27 +++++++++++++------------- addons/sale/sale_view.xml | 2 +- addons/sale/security/sale_security.xml | 7 +------ 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index c36c5e44e8c..8317aaf8ebe 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1355,7 +1355,7 @@ class sale_configuration(osv.osv_memory): 'group_sale_uom_per_product':fields.boolean("UOM per product",help="Group to Allow different unit of measure per product"), 'group_sale_delivery_address':fields.boolean("Multiple Address",help="Group To Allow delivery address different from invoice address"), 'group_sale_disc_per_sale_order_line':fields.boolean("Discounts per sale order lines ",help="Group to apply discounts per sale order lines"), - 'group_sale_notes_subtotal':fields.boolean("Notes and subtotals",help="Group to allow notes and subtotals"), + 'sale_layout':fields.boolean("Notes and subtotals",help="Install sale_layout module: This module provides features to improve the layout of the Sales Order.."), 'warning': fields.boolean("Alerts by products or customers", help="Install warning module: Module to trigger warnings in OpenERP objects."), 'tax_value' : fields.float('Value'), @@ -1416,7 +1416,7 @@ class sale_configuration(osv.osv_memory): # elif deli: # res.update({'order_policy': 'picking'}) # return {'value':res} - + def apply_groups(self, cr, uid, ids, group_name, apply=True, context=None): data_obj = self.pool.get('ir.model.data') users_obj = self.pool.get('res.users') @@ -1438,7 +1438,7 @@ class sale_configuration(osv.osv_memory): module_obj = self.pool.get('ir.module.module') users_obj = self.pool.get('res.users') groups_obj = self.pool.get('res.groups') - + module_name = [] group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id @@ -1457,27 +1457,22 @@ class sale_configuration(osv.osv_memory): self.apply_groups(cr, uid, ids, 'group_sale_pricelist_per_customer', context=context) else: self.apply_groups(cr, uid, ids, 'group_sale_pricelist_per_customer', False, context=context) - + if wizard.group_sale_uom_per_product: self.apply_groups(cr, uid, ids, 'group_sale_uom_per_product', context=context) else: self.apply_groups(cr, uid, ids, 'group_sale_uom_per_product', False, context=context) - + if wizard.group_sale_delivery_address: self.apply_groups(cr, uid, ids, 'group_sale_delivery_address', context=context) else: self.apply_groups(cr, uid, ids, 'group_sale_delivery_address', False, context=context) - + if wizard.group_sale_disc_per_sale_order_line: self.apply_groups(cr, uid, ids, 'group_sale_disc_per_sale_order_line', context=context) else: self.apply_groups(cr, uid, ids, 'group_sale_disc_per_sale_order_line', False, context=context) - - if wizard.group_sale_notes_subtotal: - self.apply_groups(cr, uid, ids, 'group_sale_notes_subtotal', context=context) - else: - self.apply_groups(cr, uid, ids, 'group_sale_notes_subtotal', False, context=context) - + if wizard.task_work: vals['project_timesheet'] = True vals['project_mrp'] = True @@ -1497,6 +1492,12 @@ class sale_configuration(osv.osv_memory): else: vals['delivery'] = False + if wizard.sale_layout: + vals['sale_layout'] = True + else: + vals['sale_layout'] = False + + if wizard.picking_policy: ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], 'one') @@ -1511,7 +1512,7 @@ class sale_configuration(osv.osv_memory): self.pool.get('res.company').write(cr, uid, [company_id], { 'project_time_mode_id': wizard.time_unit.id }, context=context) - + super(sale_configuration, self).execute(cr, uid, ids, vals, context=context) sale_configuration() diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 91bb2bbbd88..4b1e1418350 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -560,7 +560,7 @@ - + diff --git a/addons/sale/security/sale_security.xml b/addons/sale/security/sale_security.xml index 226dace3cf7..9435c449387 100644 --- a/addons/sale/security/sale_security.xml +++ b/addons/sale/security/sale_security.xml @@ -40,11 +40,6 @@ - - Notes and Subtotals - - - Sales Taxes Global/on line @@ -56,7 +51,7 @@ ref('base.group_sale_delivery_address'), ref('base.group_sale_disc_per_sale_order_line'), ref('base.group_sale_taxes_global_or_online'), - ref('base.group_sale_notes_subtotal')])]"/> + ])]"/> From b7abe29c7c4ab12db63e5c5e005ba765cd5eef8e Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 14:49:11 +0530 Subject: [PATCH 0131/1161] [IMP] rename the fields by short names bzr revid: tpa@tinyerp.com-20120228091911-n803jsy7i7gruznn --- openerp/addons/base/res/res_config_sale.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/res/res_config_sale.py b/openerp/addons/base/res/res_config_sale.py index 52be896d058..3d13eb39a72 100644 --- a/openerp/addons/base/res/res_config_sale.py +++ b/openerp/addons/base/res/res_config_sale.py @@ -24,7 +24,7 @@ import pooler MODULE_LIST = [ 'analytic_user_function', 'analytic_journal_billing_rate', 'import_sugarcrm', - 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact', + 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact','sale_layout' 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook','account_analytic_analysis' ] @@ -33,9 +33,9 @@ class sale_configuration(osv.osv_memory): _inherit = 'res.config' _columns = { - 'analytic_user_function' : fields.boolean("Use specific User function on Contract/analytic accounts", + 'analytic_user_function' : fields.boolean("User function by contracts", help="Install analytic_user_function module:This module allows you to define what is the default function of a specific user on a given account"), - 'analytic_journal_billing_rate' : fields.boolean("Manage Different billing rates on contract/analytic accounts", + 'analytic_journal_billing_rate' : fields.boolean("Billing rates by contracts", help="Install analytic_journal_billing_rate module: This module allows you to define what is the default invoicing rate for a specific journal on a given account."), 'import_sugarcrm' : fields.boolean("Import data from sugarCRM?", help="Install import_sugarcrm module: This Module Import SugarCRM Leads, Opportunities, Users, Accounts, Contacts, Employees, Meetings, Phonecalls, Emails, and Project, Project Tasks Data into OpenERP Module."), @@ -49,7 +49,7 @@ class sale_configuration(osv.osv_memory): help="Install crm_partner_assign module: This is the module used by OpenERP SA to redirect customers to its partners, based on geolocalization."), 'google_map' : fields.boolean("Google maps on customer", help="Install google_map module: The module adds Google Map field in partner address."), - 'fetchmail_crm': fields.boolean("Create Leads from an Email Account"), + 'fetchmail_crm': fields.boolean("Lead/Opportunity mail gateway"), 'server' : fields.char('Server Name', size=256), 'port' : fields.integer('Port'), 'type':fields.selection([ @@ -60,9 +60,9 @@ class sale_configuration(osv.osv_memory): 'is_ssl': fields.boolean('SSL/TLS', help="Connections are encrypted with SSL/TLS through a dedicated port (default: IMAPS=993, POP=995)"), 'user' : fields.char('Username', size=256), 'password' : fields.char('Password', size=1024), - 'plugin_thunderbird': fields.boolean('Push your email from Thunderbird to an OpenERP document', + 'plugin_thunderbird': fields.boolean('Thunderbird plugin', help="Install plugin_thunderbird module: This module is required for the Thuderbird Plug-in to work properly."), - 'plugin_outlook': fields.boolean('Push your email from Outlook to an OpenERP document', + 'plugin_outlook': fields.boolean('Outlook plugin', help="Install plugin_outlook module: This module provides the Outlook Plug-in."), 'account_analytic_analysis': fields.boolean('Contracts', help="Install account_analytic_analysis module: This module is for modifying account analytic view to show important data to project manager of services companies."), From 695065436b7e60559fb8a85ffceeeb29ca39b2ce Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 14:53:57 +0530 Subject: [PATCH 0132/1161] [IMP] added warninkg modele in module list bzr revid: tpa@tinyerp.com-20120228092357-f8z16xito6uvs2c4 --- openerp/addons/base/res/res_config_sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_config_sale.py b/openerp/addons/base/res/res_config_sale.py index 3d13eb39a72..b2f5f5f5548 100644 --- a/openerp/addons/base/res/res_config_sale.py +++ b/openerp/addons/base/res/res_config_sale.py @@ -24,7 +24,7 @@ import pooler MODULE_LIST = [ 'analytic_user_function', 'analytic_journal_billing_rate', 'import_sugarcrm', - 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact','sale_layout' + 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact','sale_layout','warning', 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook','account_analytic_analysis' ] From 01481dc5a17f0f6a36715b150fcaa323831bcc1e Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 14:54:39 +0530 Subject: [PATCH 0133/1161] [IMP] improved code bzr revid: tpa@tinyerp.com-20120228092439-k2nreueftwv68o0g --- addons/sale/sale.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 8317aaf8ebe..1ad07f70eb6 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1492,6 +1492,11 @@ class sale_configuration(osv.osv_memory): else: vals['delivery'] = False + if wizard.warning: + vals['warning'] = True + else: + vals['warning'] = False + if wizard.sale_layout: vals['sale_layout'] = True else: From 8c45474ee38bf52d04b9a9338c71587c868338a0 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 15:19:50 +0530 Subject: [PATCH 0134/1161] [IMP] rename the fields and set view. bzr revid: tpa@tinyerp.com-20120228094950-dtcf2dbknpit0sh6 --- addons/sale/sale.py | 4 ++-- addons/sale/sale_view.xml | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 1ad07f70eb6..a5f37ebb140 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1349,13 +1349,13 @@ class sale_configuration(osv.osv_memory): ('picking', 'Invoice Based on Deliveries'), ], 'Main Method Based On', required=True, help="You can generate invoices based on sales orders or based on shippings."), 'charge_delivery': fields.boolean('Do you charge the delivery?'), - 'time_unit': fields.many2one('product.uom','Main Working Time Unit'), + 'time_unit': fields.many2one('product.uom','Working Time Unit'), 'picking_policy' : fields.boolean("Deliver all products at once?"), 'group_sale_pricelist_per_customer':fields.boolean("Pricelist per customer ",help="Group to Activate pricelist to manage prices per customer"), 'group_sale_uom_per_product':fields.boolean("UOM per product",help="Group to Allow different unit of measure per product"), 'group_sale_delivery_address':fields.boolean("Multiple Address",help="Group To Allow delivery address different from invoice address"), 'group_sale_disc_per_sale_order_line':fields.boolean("Discounts per sale order lines ",help="Group to apply discounts per sale order lines"), - 'sale_layout':fields.boolean("Notes and subtotals",help="Install sale_layout module: This module provides features to improve the layout of the Sales Order.."), + 'sale_layout':fields.boolean("Notes & subtotals per line",help="Install sale_layout module: This module provides features to improve the layout of the Sales Order.."), 'warning': fields.boolean("Alerts by products or customers", help="Install warning module: Module to trigger warnings in OpenERP objects."), 'tax_value' : fields.float('Value'), diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 4b1e1418350..62f27cb1d63 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -531,7 +531,7 @@ - + @@ -541,8 +541,7 @@ - - + From 0c0fbc3ed0083a2923f0b0f06b3600e348141236 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 15:42:09 +0530 Subject: [PATCH 0135/1161] [IMP] change default value of tax and set domain in time_unit field bzr revid: tpa@tinyerp.com-20120228101209-vczx7bscfgxw5a8o --- addons/sale/sale.py | 4 ++-- addons/sale/sale_view.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index a5f37ebb140..177bf8306ec 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1364,7 +1364,7 @@ class sale_configuration(osv.osv_memory): ('no_tax', 'No Tax'), ('global_on_order', 'Global On Order'), ('on_order_line', 'On Order Lines'), - ], 'Taxes'), + ], 'Taxes', required=True), 'sale_margin': fields.boolean("Display Margin For Users", help="Install sale_margin module: This module adds the 'Margin' on sales order."), 'sale_journal': fields.boolean("Invoice journal?", @@ -1404,7 +1404,7 @@ class sale_configuration(osv.osv_memory): _defaults = { 'order_policy': 'manual', - 'tax_policy': 'no_tax', + 'tax_policy': 'global_on_order', 'time_unit': lambda self, cr, uid, c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c) and self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c)[0] or False, } diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 62f27cb1d63..6d2db9c6869 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -531,7 +531,7 @@ - + From 52436dfdcf04960eb543b1e00d762896a317c3ad Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 16:19:39 +0530 Subject: [PATCH 0136/1161] [IMP] applly picelist group on field bzr revid: tpa@tinyerp.com-20120228104939-xgs943wd1h0o0zn9 --- addons/product/partner_view.xml | 2 +- addons/product/pricelist_view.xml | 4 ++-- addons/sale/sale_view.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/product/partner_view.xml b/addons/product/partner_view.xml index 51d012b8577..f40c5ab8032 100644 --- a/addons/product/partner_view.xml +++ b/addons/product/partner_view.xml @@ -9,7 +9,7 @@ - + diff --git a/addons/product/pricelist_view.xml b/addons/product/pricelist_view.xml index 3ddfe1e6900..ebd99986991 100644 --- a/addons/product/pricelist_view.xml +++ b/addons/product/pricelist_view.xml @@ -4,7 +4,7 @@ - + product.pricelist.version.form @@ -195,7 +195,7 @@ - + Price Types ir.actions.act_window diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 6d2db9c6869..05c02bb208b 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -8,7 +8,7 @@ parent="base.menu_base_partner" sequence="1" /> - + @@ -531,7 +531,7 @@ - + From c95ed7032d697b434183d6218c42f3348495bbc8 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 16:28:58 +0530 Subject: [PATCH 0137/1161] [IMP] improved code bzr revid: tpa@tinyerp.com-20120228105858-3tys9g3laqibxndq --- openerp/addons/base/res/res_config_sale.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openerp/addons/base/res/res_config_sale.py b/openerp/addons/base/res/res_config_sale.py index b2f5f5f5548..38a5a78ff05 100644 --- a/openerp/addons/base/res/res_config_sale.py +++ b/openerp/addons/base/res/res_config_sale.py @@ -96,6 +96,7 @@ class sale_configuration(osv.osv_memory): return installed_modules def default_get(self, cr, uid, fields_list, context=None): + ir_values_obj = self.pool.get('ir.values') result = super(sale_configuration, self).default_get( cr, uid, fields_list, context=context) installed_modules = self.get_installed_modules(cr, uid, MODULE_LIST, context=context) From 504e476fc05800249b3cd2cccf31b89b9a32410e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 28 Feb 2012 12:07:40 +0100 Subject: [PATCH 0138/1161] [IMP] Wall widget: removed unused xml; added more button; added more action (displays more discussions); added comments bzr revid: tde@openerp.com-20120228110740-gcbm02ej6bee4rsl --- addons/mail/static/src/js/mail.js | 79 ++++++++++++++++++++++------- addons/mail/static/src/xml/mail.xml | 13 ++--- 2 files changed, 66 insertions(+), 26 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 156f6ff4590..4a3b92cc895 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -53,7 +53,7 @@ openerp.mail = function(session) { }); /* display user, fetch comments */ this.display_current_user(); - if (this.records) return this.display_comments(this.records); + if (this.params.records) return this.display_comments(this.params.records); else return this.init_comments(); }, @@ -306,7 +306,10 @@ openerp.mail = function(session) { */ init: function (parent, params) { this._super(parent); + this.params = params || {}; this.params.limit = params.limit || 20; + this.params.search = {}; + this.params.domain = []; this.sorted_comments = {}; /* DataSets */ this.ds_msg = new session.web.DataSet(this, 'mail.message'); @@ -324,7 +327,7 @@ openerp.mail = function(session) { self.searchview.on_search.add(self.do_searchview_search); }); /* fetch comments */ - var comments_ready = this.fetch_comments(); + var comments_ready = this.init_comments(); return (search_view_ready && comments_ready); }, @@ -358,10 +361,27 @@ openerp.mail = function(session) { contexts: contexts || [], group_by_seq: groupbys || [] }, function (results) { - self.search['context'] = results.context; - self.search['domain'] = results.domain; - self.search['groupby'] = results.group_by; - self.fetch_comments(self.search['domain'], self.search['context']); + self.params.search['context'] = results.context; + self.params.search['domain'] = results.domain; + self.params.search['groupby'] = results.group_by; + self.init_comments(self.params.search['domain'], self.params.search['context']); + }); + }, + + /** + * Initializes Wall and calls fetch_comments + * @param {Array} domains + * @param {Array} contexts + * @param {Array} groupbys + * @param {Number} limit number of messages to fetch + */ + init_comments: function(domain, context, offset, limit) { + var self = this; + this.params.domain = []; + this.sorted_comments = {}; + this.$element.find('div.oe_mail_wall_threads').empty(); + return this.fetch_comments(domain, context, offset, limit).then(function () { + self.$element.find('button.oe_mail_wall_button_more').bind('click', function () { self.do_more(); }); }); }, @@ -383,10 +403,9 @@ openerp.mail = function(session) { * @param {Array} records records to show in threads */ display_comments: function (records) { - this.$element.find('div.oe_mail_wall_threads').empty(); - this.sort_comments(records, this.sorted_comments); + var sorted_comments = this.sort_comments(records, this.sorted_comments); var self = this; - _(this.sorted_comments).each(function (rec_models, model) { // each model + _(sorted_comments).each(function (rec_models, model) { // each model _(rec_models).each(function (record_id, id) { // each record var template = 'WallThreadContainer'; var render_res = session.web.qweb.render(template, { @@ -394,23 +413,24 @@ openerp.mail = function(session) { 'record_id': id, }); $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_wall_threads')); - self.thread_display = new mail.ThreadDisplay(self, + var thread_display = new mail.ThreadDisplay(self, {'res_model': model, 'res_id': parseInt(id), 'uid': self.session.uid, 'records': record_id} ); - self.thread_display.appendTo(self.$element.find('div.oe_mail_wall_thread_content:last')); + thread_display.appendTo(self.$element.find('div.oe_mail_wall_thread_content:last')); }); }); + $.extend(true, this.sorted_comments, sorted_comments); }, /** * Add records to sorted_comments array * @param {Array} records records from mail.message - * @param {Array} sorted_comments already sorted comments that will be updated - * @returns {Array} sorted_comments - * sorted_comments.res_model = {res_ids} - * sorted_comments.res_model.res_id = [records] + * @returns {Object} sorted_comments: dict + * sorted_comments.res_model = {res_ids} + * sorted_comments.res_model.res_id = [records] */ - sort_comments: function (records, sorted_comments) { + sort_comments: function (records) { + sorted_comments = {} _(records).each(function (record) { if (! (record.model in sorted_comments)) { sorted_comments[record.model] = {}; } if (! (record.res_id in sorted_comments[record.model])) { @@ -423,18 +443,41 @@ openerp.mail = function(session) { /** * Create a domain to fetch new comments according to * comment already present in sorted_comments + * @param {Object} sorted_comments (see sort_comments) * @returns {Array} fetch_domain (OpenERP domain style) */ get_fetch_domain: function (sorted_comments) { - + var domain = []; + _(sorted_comments).each(function (rec_models, model) { //each model + var ids = []; + _(rec_models).each(function (record_id, id) { // each record + ids.push(id); + }); + domain.push('|', ['model', '!=', model], ['res_id', 'not in', ids]); + }); + return domain; }, + /** + * Action: Posts a comment + */ do_comment: function () { var body_text = this.$element.find('textarea').val(); return this.ds_users.call('message_append_note', [[this.session.uid], 'Tweet', body_text, type='comment']).then( this.proxy('fetch_comments')); }, - + + /** + * Action: Shows more discussions + */ + do_more: function () { + var domain = this.get_fetch_domain(this.sorted_comments); + return this.fetch_comments(domain); + }, + + /** + * Tools: get avatar mini (TODO: should be moved in some tools ?) + */ thread_get_mini: function(model, field, id) { id = id || ''; var url = this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 386197a0fce..b2cc1e8e0c7 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -13,6 +13,11 @@
+
+ +
@@ -25,14 +30,6 @@
- -
- Discussion about document (id: ) -
-
-
-
-
Discussion about document (id: ) From 17d077bb7d9826f581bb7611e2c9a9ce378785df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 28 Feb 2012 12:23:07 +0100 Subject: [PATCH 0139/1161] [FIX] Fixed bug when posting a comment from the wall (wrong values given through this.proxy, have to check) bzr revid: tde@openerp.com-20120228112307-8mwlrcqx66h07ood --- addons/mail/static/src/js/mail.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 4a3b92cc895..d49b7a0768c 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -464,7 +464,8 @@ openerp.mail = function(session) { do_comment: function () { var body_text = this.$element.find('textarea').val(); return this.ds_users.call('message_append_note', [[this.session.uid], 'Tweet', body_text, type='comment']).then( - this.proxy('fetch_comments')); + //this.proxy('fetch_comments')); + this.init_comments()); }, /** From 888531ae31ac23af47d6c665edfc69d0bad79c65 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 28 Feb 2012 17:29:46 +0530 Subject: [PATCH 0140/1161] [IMP] improved code for get default time_unit bzr revid: tpa@tinyerp.com-20120228115946-zltsaspb9hh04b8f --- addons/sale/sale.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 177bf8306ec..0a7b2c2a47e 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1373,6 +1373,7 @@ class sale_configuration(osv.osv_memory): def default_get(self, cr, uid, fields_list, context=None): ir_values_obj = self.pool.get('ir.values') + data_obj = self.pool.get('ir.model.data') obj_tax_temp = self.pool.get('account.tax.template') res = super(sale_configuration, self).default_get( cr, uid, fields_list, context=context) @@ -1386,8 +1387,14 @@ class sale_configuration(osv.osv_memory): for k in defaults.keys(): if k in ['project_timesheet','project_mrp']: defaults.update({'task_work': True}) + prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id + uom_id = self.pool.get('product.product').browse(cr, uid, prod_id).uom_id.id + defaults.update({'time_unit': uom_id}) if k in ['account_analytic_analysis']: defaults.update({'timesheet': True}) + prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id + uom_id = self.pool.get('product.product').browse(cr, uid, prod_id).uom_id.id + defaults.update({'time_unit': uom_id}) if k == 'delivery': defaults.update({'sale_orders': True, 'deli_orders': True, 'charge_delivery': True}) if k == 'picking_policy' and defaults[k]=='one': From 3790daaa69cb90806110669b9a378680aafb7063 Mon Sep 17 00:00:00 2001 From: "Jiten (OpenERP)" Date: Tue, 28 Feb 2012 19:05:16 +0530 Subject: [PATCH 0141/1161] [IMP] Some changes in hr recruitment - Remove page of 'Communication and History', - Remove group of 'Dates' from notebook page, - Moved button of 'Send new email' on top of right side on main page, - Improved messages and notification. bzr revid: jra@tinyerp.com-20120228133516-iw1zjxhb1xjdzgaf --- addons/hr_recruitment/hr_recruitment.py | 13 ++++---- addons/hr_recruitment/hr_recruitment_view.xml | 33 ++----------------- 2 files changed, 10 insertions(+), 36 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index cc63dd99b62..1637313a28c 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -392,6 +392,7 @@ class hr_applicant(crm.crm_case, osv.osv): return res def _case_open_notification(self, case, context=None): + case.message_mark_done(context) message = _("Changed Status to In Progress.") case.message_append_note('' ,message, type='notification', need_action_user_id=case.user_id.id) return True @@ -399,22 +400,22 @@ class hr_applicant(crm.crm_case, osv.osv): def _case_close_notification(self, case, context=None): case[0].message_mark_done(context) if case[0].emp_id: - message = _("Applicant is being Hired as an employee.") + message = _("Applicant is Hired and employee created.") case[0].message_append_note('' ,message, type='notification') else: - message = _("Applicant is being Hired.") + message = _("Applicant is Hired.") case[0].message_append_note('' ,message, type='notification') return True def _case_cancel_notification(self, case, context=None): case[0].message_mark_done(context=context) - message = _("Applicant Subject '%s' has been Cancelled.") % (case[0].name) + message = _("Applicant is Cancelled.") case[0].message_append_note('' ,message, type="notification") return True def _case_pending_notification(self, case, context=None): message = _("Changed Status to Pending.") - case[0].message_append_note('' ,message, type='notification', need_action_user_id=case[0].user_id.id) + case[0].message_append_note('' ,message, type='notification') return True def _case_reset_notification(self, cr, uid, ids, context=None): @@ -427,7 +428,7 @@ class hr_applicant(crm.crm_case, osv.osv): for obj in self.browse(cr, uid, ids, context=context): self.message_subscribe(cr, uid, ids, [obj.user_id.id], context=context) self.message_append_note(cr, uid, ids, _('System notification'), - _("Applicant Created."), type='notification', need_action_user_id=obj.user_id.id, context=context) + _("Applicant is Created."), type='notification', need_action_user_id=obj.user_id.id, context=context) return True @@ -517,7 +518,7 @@ class hr_applicant(crm.crm_case, osv.osv): def write(self, cr, uid, ids, vals, context=None): if 'stage_id' in vals and vals['stage_id']: stage = self.pool.get('hr.recruitment.stage').browse(cr, uid, vals['stage_id'], context=context) - text = _("Changed Stage to %s") % stage.name + text = _("Changed Stage to %s.") % stage.name self.message_append(cr, uid, ids, text, body_text=text, context=context) return super(hr_applicant,self).write(cr, uid, ids, vals, context=context) diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml index 65954b20323..2faac78af8c 100644 --- a/addons/hr_recruitment/hr_recruitment_view.xml +++ b/addons/hr_recruitment/hr_recruitment_view.xml @@ -79,6 +79,9 @@
@@ -69,9 +68,10 @@
-
- -
+ +
+
+ You have loaded all messages in this thread.
@@ -117,13 +117,5 @@

- - -
- -
-
From 790df40a912f7cb31f7c40bb23658003c9bfd39f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 29 Feb 2012 10:11:09 +0100 Subject: [PATCH 0157/1161] [FIX] On Wall: fixed more button on Wall. bzr revid: tde@openerp.com-20120229091109-f0fbr2gdcmjagna6 --- addons/mail/static/src/js/mail.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index fb6f4557734..79283f3ffab 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -43,6 +43,7 @@ openerp.mail = function(session) { this._super.apply(this, arguments); /* events */ this.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); + this.$element.find('button.oe_mail_button_more').bind('click', function () { self.do_more(); }); this.$element.find('div.oe_mail_thread_display').delegate('a.intlink', 'click', function (event) { // lazy implementation: fetch data and try to redirect self.do_action({ @@ -52,6 +53,7 @@ openerp.mail = function(session) { views: [[false, 'form']] }); }); + this.$element.find('div.oe_mail_thread_nomore').hide(); /* display user, fetch comments */ this.display_current_user(); if (this.params.records) return this.display_comments(this.params.records); @@ -66,8 +68,7 @@ openerp.mail = function(session) { var self = this; this.params.offset = 0; this.$element.find('div.oe_mail_thread_display').empty(); - return this.fetch_comments().then(function() { - self.$element.find('button.oe_mail_button_more').bind('click', function () { self.do_more(); }); }); + return this.fetch_comments().then(); }, fetch_comments: function (limit, offset) { From adc65d5cfadcb18f0322ad9c6315960697d60491 Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Wed, 29 Feb 2012 15:20:21 +0530 Subject: [PATCH 0158/1161] [IMP]: Improved code: added functionality to the respected modules. Added get and set methods. bzr revid: uco@tinyerp.com-20120229095021-ogpd1s4nyxa7wdns --- addons/account/__init__.py | 1 + addons/account/res_config.py | 47 ++++ addons/account_chart/res_config.py | 8 + addons/crm/__init__.py | 1 + addons/crm/__openerp__.py | 2 + addons/crm/res_config.py | 96 ++++++++ addons/crm/res_config_view.xml | 36 +++ addons/plugin_outlook/plugin_outlook.xml | 6 +- .../plugin_thunderbird/plugin_thunderbird.xml | 6 +- addons/product/__init__.py | 1 + addons/product/res_config.py | 32 +++ addons/product/security/product_security.xml | 15 ++ addons/sale/__init__.py | 1 + addons/sale/__openerp__.py | 1 + addons/sale/res_config.py | 218 ++++++++++++++++++ addons/sale/res_config_view.xml | 121 ++++++++++ addons/sale/sale.py | 200 +--------------- addons/sale/sale_view.xml | 66 ------ addons/sale/security/sale_security.xml | 25 +- addons/sale/test/manual_order_policy.yml | 4 +- 20 files changed, 599 insertions(+), 288 deletions(-) create mode 100644 addons/account/res_config.py create mode 100644 addons/account_chart/res_config.py create mode 100644 addons/crm/res_config.py create mode 100644 addons/crm/res_config_view.xml create mode 100644 addons/product/res_config.py create mode 100644 addons/sale/res_config.py create mode 100644 addons/sale/res_config_view.xml diff --git a/addons/account/__init__.py b/addons/account/__init__.py index 98f7a7d5134..726eab3680c 100644 --- a/addons/account/__init__.py +++ b/addons/account/__init__.py @@ -37,4 +37,5 @@ import ir_sequence import company import res_currency import edi +import res_config # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/res_config.py b/addons/account/res_config.py new file mode 100644 index 00000000000..6c5f32d4812 --- /dev/null +++ b/addons/account/res_config.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields, osv + +class account_configuration(osv.osv_memory): + _inherit = 'res.config' + + _columns = { + 'tax_policy': fields.selection([ + ('no_tax', 'No Tax'), + ('global_on_order', 'Global On Order'), + ('on_order_line', 'On Order Lines'), + ], 'Taxes', required=True), + 'tax_value': fields.float('Value'), + } + + _defaults = { + 'tax_policy': 'global_on_order', + 'tax_value': 15.0, + } + + def get_tax_value(self, cr, uid, ids, context=None): + result = {} + chart_account_obj = self.pool.get('wizard.multi.charts.accounts') + chart_account_obj.execute(cr, uid, ids, context=context) + return result + +account_configuration() \ No newline at end of file diff --git a/addons/account_chart/res_config.py b/addons/account_chart/res_config.py new file mode 100644 index 00000000000..5bd2b98ca66 --- /dev/null +++ b/addons/account_chart/res_config.py @@ -0,0 +1,8 @@ +class account_configuration(osv.osv_memory): + _inherit = 'res.config' + + _columns = { + 'tax_value' : fields.many2one('account.tax', 'Value'), + } + +account_configuration() \ No newline at end of file diff --git a/addons/crm/__init__.py b/addons/crm/__init__.py index 214c5c3d450..95cf8b53f27 100644 --- a/addons/crm/__init__.py +++ b/addons/crm/__init__.py @@ -28,6 +28,7 @@ import crm_phonecall import report import wizard import res_partner +import res_config # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 4968176e826..5f71c404976 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -111,6 +111,8 @@ Creates a dashboard for CRM that includes: 'res_partner_view.xml', 'board_crm_statistical_view.xml', 'board_crm_view.xml', + + 'res_config_view.xml', ], 'demo_xml': [ diff --git a/addons/crm/res_config.py b/addons/crm/res_config.py new file mode 100644 index 00000000000..6780ac17aa7 --- /dev/null +++ b/addons/crm/res_config.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields, osv + +class crm_configuration(osv.osv_memory): + _inherit = 'res.config' + + _columns = { + 'crm_caldav' : fields.boolean("Use caldav to synchronize Meetings", + help="Install crm_caldav module: Caldav features in Meeting"), + 'fetchmail_crm': fields.boolean("Lead/Opportunity mail gateway"), + 'server' : fields.char('Server Name', size=256), + 'port' : fields.integer('Port'), + 'type': fields.selection([ + ('pop', 'POP Server'), + ('imap', 'IMAP Server'), + ('local', 'Local Server'), + ], 'Server Type'), + 'is_ssl': fields.boolean('SSL/TLS', help="Connections are encrypted with SSL/TLS through a dedicated port (default: IMAPS=993, POP=995)"), + 'user' : fields.char('Username', size=256), + 'password' : fields.char('Password', size=1024), + } + + _defaults = { + 'type': 'pop', + } + + def get_default_email_configurations(self, cr, uid, ids, context=None): + ir_values_obj = self.pool.get('ir.values') + result = {} + installed_modules = self.get_default_installed_modules(cr, uid, ids, context=context) + if 'fetchmail_crm' in installed_modules.keys(): + for val in ir_values_obj.get(cr, uid, 'default', False, ['fetchmail.server']): + result.update({val[1]: val[2]}) + return result + + def onchange_server_type(self, cr, uid, ids, server_type=False, ssl=False): + port = 0 + values = {} + if server_type == 'pop': + port = ssl and 995 or 110 + elif server_type == 'imap': + port = ssl and 993 or 143 + else: + values['server'] = '' + values['port'] = port + return {'value': values} + + def set_email_configurations(self, cr, uid, ids, vals, context=None): + model_obj = self.pool.get('ir.model') + fetchmail_obj = self.pool.get('fetchmail.server') + ir_values_obj = self.pool.get('ir.values') + if vals.get('fetchmail_crm'): + object_id = model_obj.search(cr, uid, [('model','=','crm.lead')])[0] + fetchmail_vals = { + 'name': 'Incoming Leads', + 'object_id': object_id, + 'server': vals.get('server'), + 'port': vals.get('port'), + 'is_ssl': vals.get('is_ssl'), + 'type': vals.get('type'), + 'user': vals.get('user'), + 'password': vals.get('password') + } + if not self.get_installed_modules(cr, uid, ['fetchmail_crm'], context): + fetchmail_obj.create(cr, uid, fetchmail_vals, context=context) + else: + fetchmail_ids = fetchmail_obj.search(cr, uid, [('name','=','Incoming Leads')], context=context) + fetchmail_obj.write(cr, uid, fetchmail_ids, fetchmail_vals, context=context) + ir_values_obj.set(cr, uid, 'default', False, 'server', ['fetchmail.server'], fetchmail_vals.get('server')) + ir_values_obj.set(cr, uid, 'default', False, 'port', ['fetchmail.server'], fetchmail_vals.get('port')) + ir_values_obj.set(cr, uid, 'default', False, 'is_ssl', ['fetchmail.server'], fetchmail_vals.get('is_ssl')) + ir_values_obj.set(cr, uid, 'default', False, 'type', ['fetchmail.server'], fetchmail_vals.get('type')) + ir_values_obj.set(cr, uid, 'default', False, 'user', ['fetchmail.server'], fetchmail_vals.get('user')) + ir_values_obj.set(cr, uid, 'default', False, 'password', ['fetchmail.server'], fetchmail_vals.get('password')) + +crm_configuration() \ No newline at end of file diff --git a/addons/crm/res_config_view.xml b/addons/crm/res_config_view.xml new file mode 100644 index 00000000000..807685bda83 --- /dev/null +++ b/addons/crm/res_config_view.xml @@ -0,0 +1,36 @@ + + + + + Sales Application + res.config + form + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons/plugin_outlook/plugin_outlook.xml b/addons/plugin_outlook/plugin_outlook.xml index 68e265e0730..b03932c7e94 100644 --- a/addons/plugin_outlook/plugin_outlook.xml +++ b/addons/plugin_outlook/plugin_outlook.xml @@ -48,9 +48,9 @@ new - + Install Outlook Plug-In diff --git a/addons/plugin_thunderbird/plugin_thunderbird.xml b/addons/plugin_thunderbird/plugin_thunderbird.xml index 76405330c89..dff9a186c54 100644 --- a/addons/plugin_thunderbird/plugin_thunderbird.xml +++ b/addons/plugin_thunderbird/plugin_thunderbird.xml @@ -55,9 +55,9 @@ new - + diff --git a/addons/product/__init__.py b/addons/product/__init__.py index 4247b49d41b..a7e0be09dc5 100644 --- a/addons/product/__init__.py +++ b/addons/product/__init__.py @@ -23,5 +23,6 @@ import pricelist import report import partner import wizard +import res_config # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product/res_config.py b/addons/product/res_config.py new file mode 100644 index 00000000000..5211f302bb9 --- /dev/null +++ b/addons/product/res_config.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields, osv + +class product_groups_configuration(osv.osv_memory): + _inherit = 'res.config' + + _columns = { + 'group_sale_pricelist_per_customer':fields.boolean("Pricelist per customer ",help="Group to Activate pricelist to manage prices per customer"), + 'group_sale_uom_per_product':fields.boolean("UOM per product",help="Group to Allow different unit of measure per product"), +} + +product_groups_configuration() \ No newline at end of file diff --git a/addons/product/security/product_security.xml b/addons/product/security/product_security.xml index 5c993b9cd61..4fba712c00a 100644 --- a/addons/product/security/product_security.xml +++ b/addons/product/security/product_security.xml @@ -18,6 +18,21 @@ Product Variant + + + Sales Pricelists + + + + + Product UOM + + + + + + product pricelist company rule diff --git a/addons/sale/__init__.py b/addons/sale/__init__.py index b26486e1425..2688b61ddd9 100644 --- a/addons/sale/__init__.py +++ b/addons/sale/__init__.py @@ -29,5 +29,6 @@ import wizard import report import company import edi +import res_config # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index ff2cfb03f5f..e1b3c57de00 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -85,6 +85,7 @@ Dashboard for Sales Manager that includes: 'process/sale_process.xml', 'board_sale_view.xml', 'edi/sale_order_action_data.xml', + 'res_config_view.xml', ], 'demo_xml': ['sale_demo.xml'], 'test': [ diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py new file mode 100644 index 00000000000..540fe9da97a --- /dev/null +++ b/addons/sale/res_config.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields, osv +import pooler +from tools.translate import _ + +MODULE_LIST = [ + 'analytic_user_function', 'analytic_journal_billing_rate', 'import_sugarcrm', + 'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact','sale_layout','warning', + 'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook','account_analytic_analysis', + 'project_timesheet', 'account_analytic_analysis', 'project_mrp', 'delivery', + 'sale_margin', 'sale_journal' +] + +class sale_configuration(osv.osv_memory): + _inherit = 'res.config' + + _columns = { + 'sale_orders': fields.boolean('Based on Sales Orders',), + 'deli_orders': fields.boolean('Based on Delivery Orders'), + 'task_work': fields.boolean('Based on Tasks\' Work'), + 'timesheet': fields.boolean('Based on Timesheet'), + 'order_policy': fields.selection([ + ('manual', 'Invoice Based on Sales Orders'), + ('picking', 'Invoice Based on Deliveries'), + ], 'Main Method Based On', required=True, help="You can generate invoices based on sales orders or based on shippings."), + 'charge_delivery': fields.boolean('Do you charge the delivery?'), + 'time_unit': fields.many2one('product.uom','Working Time Unit'), + 'picking_policy' : fields.boolean("Deliver all products at once?"), + 'group_sale_delivery_address':fields.boolean("Multiple Address",help="Group To Allow delivery address different from invoice address"), + 'group_sale_disc_per_sale_order_line':fields.boolean("Discounts per sale order lines ",help="Group to apply discounts per sale order lines"), + 'sale_layout':fields.boolean("Notes & subtotals per line",help="Install sale_layout module: This module provides features to improve the layout of the Sales Order.."), + 'warning': fields.boolean("Alerts by products or customers", + help="Install warning module: Module to trigger warnings in OpenERP objects."), + 'sale_margin': fields.boolean("Display Margin For Users", + help="Install sale_margin module: This module adds the 'Margin' on sales order."), + 'sale_journal': fields.boolean("Invoice journal?", + help="Install sale_journal module: The sales journal modules allows you to categorise your sales and deliveries (picking lists) between different journals."), + 'analytic_user_function' : fields.boolean("User function by contracts", + help="Install analytic_user_function module:This module allows you to define what is the default function of a specific user on a given account"), + 'analytic_journal_billing_rate' : fields.boolean("Billing rates by contracts", + help="Install analytic_journal_billing_rate module: This module allows you to define what is the default invoicing rate for a specific journal on a given account."), + 'import_sugarcrm' : fields.boolean("Import data from sugarCRM?", + help="Install import_sugarcrm module: This Module Import SugarCRM Leads, Opportunities, Users, Accounts, Contacts, Employees, Meetings, Phonecalls, Emails, and Project, Project Tasks Data into OpenERP Module."), + 'import_google' : fields.boolean("Import Contacts & Meetings from Google", + help="Install import_google module: The module adds google contact in partner address and add google calendar events details in Meeting"), + 'wiki_sale_faq' : fields.boolean("Install a sales FAQ?", + help="Install wiki_sale_faq module: This module provides a Wiki Sales FAQ Template."), + 'base_contact' : fields.boolean("Manage a several address per customer", + help="Install crm_partner_assign module: This is the module used by OpenERP SA to redirect customers to its partners, based on geolocalization."), + 'google_map' : fields.boolean("Google maps on customer", + help="Install google_map module: The module adds Google Map field in partner address."), + 'plugin_thunderbird': fields.boolean('Thunderbird plugin', + help="Install plugin_thunderbird module: This module is required for the Thuderbird Plug-in to work properly."), + 'plugin_outlook': fields.boolean('Outlook plugin', + help="Install plugin_outlook module: This module provides the Outlook Plug-in."), + 'account_analytic_analysis': fields.boolean('Contracts', + help="Install account_analytic_analysis module: This module is for modifying account analytic view to show important data to project manager of services companies."), + } + + def get_default_applied_groups(self, cr, uid, ids, context=None): + applied_groups = {} + user_obj = self.pool.get('res.users') + dataobj = self.pool.get('ir.model.data') + + groups = [] + user_group_ids = user_obj.browse(cr, uid, uid, context=context).groups_id + + for group_id in user_group_ids: + groups.append(group_id.id) + + for id in groups: + key_id = dataobj.search(cr, uid,[('res_id','=',id),('model','=','res.groups')],context=context) + key = dataobj.browse(cr, uid, key_id[0], context=context).name + applied_groups[key] = True + + return applied_groups + + def get_default_installed_modules(self, cr, uid, ids, context=None): + module_obj = self.pool.get('ir.module.module') + module_ids = module_obj.search(cr, uid, + [('name','in',MODULE_LIST), + ('state','in',['to install', 'installed', 'to upgrade'])], + context=context) + installed_modules = dict([(mod.name,True) for mod in module_obj.browse(cr, uid, module_ids, context=context)]) + return installed_modules + + def get_default_sale_configs(self, cr, uid, ids, context=None): + ir_values_obj = self.pool.get('ir.values') + result = {} + defaults = ir_values_obj.get(cr, uid, 'default', False, ['sale.order']) + return result + + def get_default_groups(self, cr, uid, ids, context=None): + ir_values_obj = self.pool.get('ir.values') + result = {} + defaults = ir_values_obj.get(cr, uid, 'default', False, ['res.users']) + return result + + def default_get(self, cr, uid, fields_list, context=None): + result = super(sale_configuration, self).default_get( + cr, uid, fields_list, context=context) + for method in dir(self): + if method.startswith('get_default_'): + result.update(getattr(self, method)(cr, uid, [], context)) + return result + + _defaults = { + 'order_policy': 'manual', + 'time_unit': lambda self, cr, uid, c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c) and self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c)[0] or False, + } + + def create(self, cr, uid, vals, context=None): + ids = super(sale_configuration, self).create(cr, uid, vals, context=context) + self.execute(cr, uid, [ids], vals, context=context) + return ids + + def write(self, cr, uid, ids, vals, context=None): + self.execute(cr, uid, ids, vals, context=context) + return super(sale_configuration, self).write(cr, uid, ids, vals, context=context) + + def execute(self, cr, uid, ids, vals, context=None): + #TODO: TO BE IMPLEMENTED + for method in dir(self): + if method.startswith('set_'): + getattr(self, method)(cr, uid, ids, vals, context) + return True + + def set_modules(self, cr, uid, ids, vals, context=None): + module_obj = self.pool.get('ir.module.module') + for k, v in vals.items(): + if k in MODULE_LIST: + installed = self.get_default_installed_modules(cr, uid, [k], context) + if v == True and not installed: + module_id = module_obj.search(cr, uid, [('name','=',k)])[0] + module_obj.state_update(cr, uid, [module_id], 'to install', ['uninstalled'], context) + cr.commit() + pooler.restart_pool(cr.dbname, update_module=True)[1] + elif v == False and installed.get(k): + module_id = module_obj.search(cr, uid, [('name','=',k)])[0] + module_obj.state_update(cr, uid, [module_id], 'to remove', ['installed'], context) + cr.commit() + pooler.restart_pool(cr.dbname, update_module=True)[1] + + def set_sale_defaults(self, cr, uid, ids, vals, context=None): + ir_values_obj = self.pool.get('ir.values') + data_obj = self.pool.get('ir.model.data') + menu_obj = self.pool.get('ir.ui.menu') + res = {} + wizard = self.browse(cr, uid, ids)[0] + + if wizard.sale_orders: + menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').id + menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]}) + ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['ir.ui.menu'], [(4,group_id)]) + + if wizard.deli_orders: + menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').id + menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]}) + ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['ir.ui.menu'], [(4,group_id)]) + + if wizard.picking_policy: + ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], 'one') + + if wizard.time_unit: + prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id + product_obj = self.pool.get('product.product') + product_obj.write(cr, uid, prod_id, {'uom_id': wizard.time_unit.id, 'uom_po_id': wizard.time_unit.id}) + + ir_values_obj.set(cr, uid, 'default', False, 'order_policy', ['sale.order'], wizard.order_policy) + if wizard.task_work and wizard.time_unit: + company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id + self.pool.get('res.company').write(cr, uid, [company_id], { + 'project_time_mode_id': wizard.time_unit.id + }, context=context) + + return res + + def set_groups(self, cr, uid, ids, vals, context=None): + data_obj = self.pool.get('ir.model.data') + users_obj = self.pool.get('res.users') + groups_obj = self.pool.get('res.groups') + ir_values_obj = self.pool.get('ir.values') + dummy,user_group_id = data_obj.get_object_reference(cr, uid, 'base', 'group_user') + for group in vals.keys(): + if group.startswith('group_'): + dummy,group_id = data_obj.get_object_reference(cr, uid, 'base', group) + if vals[group]: + groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(4,group_id)]}) + users_obj.write(cr, uid, [uid], {'groups_id': [(4,group_id)]}) + ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['res.users'], [(4,group_id)]) + else: + groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(3,group_id)]}) + users_obj.write(cr, uid, [uid], {'groups_id': [(3,group_id)]}) + ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['res.users'], [(3,group_id)]) + +sale_configuration() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/sale/res_config_view.xml b/addons/sale/res_config_view.xml new file mode 100644 index 00000000000..82d1a18684d --- /dev/null +++ b/addons/sale/res_config_view.xml @@ -0,0 +1,121 @@ + + + + + Sales Application + res.config + form + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + Configure Sales Application + ir.actions.act_window + res.config + + form + form + + + + +
+
+ \ No newline at end of file diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 0a7b2c2a47e..552246f2513 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -28,7 +28,7 @@ from tools.translate import _ from tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, float_compare import decimal_precision as dp import netsvc -from openerp.addons.base.res import res_config_sale as sale_config +#from openerp.addons.base.res import res_config_sale as sale_config class sale_shop(osv.osv): _name = "sale.shop" @@ -1331,202 +1331,4 @@ class sale_order_line(osv.osv): sale_order_line() -sale_config.MODULE_LIST += [ - 'project_timesheet', 'account_analytic_analysis', 'project_mrp', 'delivery', - 'sale_margin', 'sale_journal' -] - -class sale_configuration(osv.osv_memory): - _inherit = 'sale.configuration' - - _columns = { - 'sale_orders': fields.boolean('Based on Sales Orders',), - 'deli_orders': fields.boolean('Based on Delivery Orders'), - 'task_work': fields.boolean('Based on Tasks\' Work'), - 'timesheet': fields.boolean('Based on Timesheet'), - 'order_policy': fields.selection([ - ('manual', 'Invoice Based on Sales Orders'), - ('picking', 'Invoice Based on Deliveries'), - ], 'Main Method Based On', required=True, help="You can generate invoices based on sales orders or based on shippings."), - 'charge_delivery': fields.boolean('Do you charge the delivery?'), - 'time_unit': fields.many2one('product.uom','Working Time Unit'), - 'picking_policy' : fields.boolean("Deliver all products at once?"), - 'group_sale_pricelist_per_customer':fields.boolean("Pricelist per customer ",help="Group to Activate pricelist to manage prices per customer"), - 'group_sale_uom_per_product':fields.boolean("UOM per product",help="Group to Allow different unit of measure per product"), - 'group_sale_delivery_address':fields.boolean("Multiple Address",help="Group To Allow delivery address different from invoice address"), - 'group_sale_disc_per_sale_order_line':fields.boolean("Discounts per sale order lines ",help="Group to apply discounts per sale order lines"), - 'sale_layout':fields.boolean("Notes & subtotals per line",help="Install sale_layout module: This module provides features to improve the layout of the Sales Order.."), - 'warning': fields.boolean("Alerts by products or customers", - help="Install warning module: Module to trigger warnings in OpenERP objects."), - 'tax_value' : fields.float('Value'), - 'tax_value_id': fields.many2one('account.tax.template'), - 'tax_policy': fields.selection([ - ('no_tax', 'No Tax'), - ('global_on_order', 'Global On Order'), - ('on_order_line', 'On Order Lines'), - ], 'Taxes', required=True), - 'sale_margin': fields.boolean("Display Margin For Users", - help="Install sale_margin module: This module adds the 'Margin' on sales order."), - 'sale_journal': fields.boolean("Invoice journal?", - help="Install sale_journal module: The sales journal modules allows you to categorise your sales and deliveries (picking lists) between different journals."), - } - - def default_get(self, cr, uid, fields_list, context=None): - ir_values_obj = self.pool.get('ir.values') - data_obj = self.pool.get('ir.model.data') - obj_tax_temp = self.pool.get('account.tax.template') - res = super(sale_configuration, self).default_get( - cr, uid, fields_list, context=context) - defaults = {} - module_list = sale_config.MODULE_LIST - defaults.update(self.get_installed_modules(cr, uid, module_list, context=context)) - defaults.update(self.get_applied_groups(cr, uid, context=context)) - - for val in ir_values_obj.get(cr, uid, 'default', False, ['sale.order']): - defaults.update({val[1]: val[2]}) - for k in defaults.keys(): - if k in ['project_timesheet','project_mrp']: - defaults.update({'task_work': True}) - prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id - uom_id = self.pool.get('product.product').browse(cr, uid, prod_id).uom_id.id - defaults.update({'time_unit': uom_id}) - if k in ['account_analytic_analysis']: - defaults.update({'timesheet': True}) - prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id - uom_id = self.pool.get('product.product').browse(cr, uid, prod_id).uom_id.id - defaults.update({'time_unit': uom_id}) - if k == 'delivery': - defaults.update({'sale_orders': True, 'deli_orders': True, 'charge_delivery': True}) - if k == 'picking_policy' and defaults[k]=='one': - defaults.update({'picking_policy': True}) - if k == 'order_policy': - defaults.update({'order_policy': defaults.get('order_policy')}) - if k == 'tax_policy' and defaults[k] == ['global_on_order','on_order_line']: - ref_tax_ids = obj_tax_temp.search(cr, uid, [('type_tax_use','in', ('sale','all'))], context=context, order="sequence, id desc", limit=1) - res.update({'tax_value_id': ref_tax_ids and ref_tax_ids[0] or False}) - else: - res.update({k: False}) - res.update(defaults) - return res - - _defaults = { - 'order_policy': 'manual', - 'tax_policy': 'global_on_order', - 'time_unit': lambda self, cr, uid, c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c) and self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c)[0] or False, - } - - #TODO: Need to check -# def onchange_order(self, cr, uid, ids, sale, deli, context=None): -# res = {} -# if sale: -# res.update({'order_policy': 'manual'}) -# elif deli: -# res.update({'order_policy': 'picking'}) -# return {'value':res} - - def apply_groups(self, cr, uid, ids, group_name, apply=True, context=None): - data_obj = self.pool.get('ir.model.data') - users_obj = self.pool.get('res.users') - groups_obj = self.pool.get('res.groups') - dummy,group_id = data_obj.get_object_reference(cr, uid, 'base', group_name) - dummy,user_group_id = data_obj.get_object_reference(cr, uid, 'base', 'group_user') - if apply: - groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(4,group_id)]}) - users_obj.write(cr, uid, [uid], {'groups_id': [(4,group_id)]}) - else: - groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(3,group_id)]}) - users_obj.write(cr, uid, [uid], {'groups_id': [(3,group_id)]}) - - def execute(self, cr, uid, ids, vals, context=None): - #TODO: TO BE IMPLEMENTED - ir_values_obj = self.pool.get('ir.values') - data_obj = self.pool.get('ir.model.data') - menu_obj = self.pool.get('ir.ui.menu') - module_obj = self.pool.get('ir.module.module') - users_obj = self.pool.get('res.users') - groups_obj = self.pool.get('res.groups') - - module_name = [] - - group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id - - wizard = self.browse(cr, uid, ids)[0] - - if wizard.sale_orders: - menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').id - menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]}) - - if wizard.deli_orders: - menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').id - menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]}) - - if wizard.group_sale_pricelist_per_customer: - self.apply_groups(cr, uid, ids, 'group_sale_pricelist_per_customer', context=context) - else: - self.apply_groups(cr, uid, ids, 'group_sale_pricelist_per_customer', False, context=context) - - if wizard.group_sale_uom_per_product: - self.apply_groups(cr, uid, ids, 'group_sale_uom_per_product', context=context) - else: - self.apply_groups(cr, uid, ids, 'group_sale_uom_per_product', False, context=context) - - if wizard.group_sale_delivery_address: - self.apply_groups(cr, uid, ids, 'group_sale_delivery_address', context=context) - else: - self.apply_groups(cr, uid, ids, 'group_sale_delivery_address', False, context=context) - - if wizard.group_sale_disc_per_sale_order_line: - self.apply_groups(cr, uid, ids, 'group_sale_disc_per_sale_order_line', context=context) - else: - self.apply_groups(cr, uid, ids, 'group_sale_disc_per_sale_order_line', False, context=context) - - if wizard.task_work: - vals['project_timesheet'] = True - vals['project_mrp'] = True - vals['account_analytic_analysis'] = True - else: - vals['project_timesheet'] = False - vals['project_mrp'] = False - vals['account_analytic_analysis'] = False - - if wizard.timesheet: - vals['account_analytic_analysis'] = True - else: - vals['account_analytic_analysis'] = False - - if wizard.charge_delivery: - vals['delivery'] = True - else: - vals['delivery'] = False - - if wizard.warning: - vals['warning'] = True - else: - vals['warning'] = False - - if wizard.sale_layout: - vals['sale_layout'] = True - else: - vals['sale_layout'] = False - - - if wizard.picking_policy: - ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], 'one') - - if wizard.time_unit: - prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id - product_obj = self.pool.get('product.product') - product_obj.write(cr, uid, prod_id, {'uom_id': wizard.time_unit.id, 'uom_po_id': wizard.time_unit.id}) - - ir_values_obj.set(cr, uid, 'default', False, 'order_policy', ['sale.order'], wizard.order_policy) - if wizard.task_work and wizard.time_unit: - company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id - self.pool.get('res.company').write(cr, uid, [company_id], { - 'project_time_mode_id': wizard.time_unit.id - }, context=context) - - super(sale_configuration, self).execute(cr, uid, ids, vals, context=context) - -sale_configuration() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 05c02bb208b..3c6c2330660 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -503,71 +503,5 @@ - - - - Configure Sales Application - sale.configuration - form - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/addons/sale/security/sale_security.xml b/addons/sale/security/sale_security.xml index 9435c449387..315433447ac 100644 --- a/addons/sale/security/sale_security.xml +++ b/addons/sale/security/sale_security.xml @@ -20,16 +20,6 @@
- - Sales Pricelists - - - - - Product UOM - - - Addresses in Sale Orders @@ -40,17 +30,22 @@ - - Sales Taxes Global/on line + + Sales Taxes Global on Order + + + + + Sales Taxes on Order Lines - diff --git a/addons/sale/test/manual_order_policy.yml b/addons/sale/test/manual_order_policy.yml index dcbc4ebc56b..de93b76795b 100644 --- a/addons/sale/test/manual_order_policy.yml +++ b/addons/sale/test/manual_order_policy.yml @@ -82,8 +82,8 @@ - I set order policy "Deliver & invoice on demand" as default policy. - - !record {model: sale.configuration, id: sale_configuration_0}: + !record {model: res.config, id: sale_configuration_0}: order_policy: 'manual' - - !python {model: sale.configuration}: | + !python {model: res.config}: | self.execute(cr, uid, [ref("sale_configuration_0")], {}) From d03350b164df767e769f7c47ff8949e827b81e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 29 Feb 2012 10:57:52 +0100 Subject: [PATCH 0159/1161] [IMP] Thread Widget: @login finally implemented. Link is lazy: when clicking, it tries to find a record and redirects if found. bzr revid: tde@openerp.com-20120229095752-t57mepak000bu55r --- addons/mail/static/src/js/mail.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 79283f3ffab..01dde5615a3 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -31,7 +31,7 @@ openerp.mail = function(session) { this.params.offset = this.params.offset || 0; this.params.records = this.params.records || null; this.params.char_show_more = this.params.char_show_more || 100; - this.map_hash = {'res.users': {'login': [] }}; + this.map_hash = {}; this.params.show_more = true; /* define DataSets */ this.ds = new session.web.DataSet(this, this.params.res_model); @@ -46,11 +46,20 @@ openerp.mail = function(session) { this.$element.find('button.oe_mail_button_more').bind('click', function () { self.do_more(); }); this.$element.find('div.oe_mail_thread_display').delegate('a.intlink', 'click', function (event) { // lazy implementation: fetch data and try to redirect - self.do_action({ - type: 'ir.actions.act_window', - res_model: event.srcElement.dataset.resModel, - res_id: parseInt(event.srcElement.dataset.resId), - views: [[false, 'form']] + if (! event.srcElement.dataset.resModel) return false; + else var res_model = event.srcElement.dataset.resModel; + if (! event.srcElement.dataset.resLogin) return false; + else var res_login = event.srcElement.dataset.resLogin; + var ds = new session.web.DataSet(self, res_model); + var defer = ds.call('search', [[['login', '=', res_login]]]).then(function (records) { + if (records[0]) { + self.do_action({ + type: 'ir.actions.act_window', + res_model: res_model, + res_id: parseInt(records[0]), + views: [[false, 'form']] + }); + } }); }); this.$element.find('div.oe_mail_thread_nomore').hide(); @@ -175,6 +184,7 @@ openerp.mail = function(session) { var regex_res = regex_login.exec(string); while (regex_res != null) { var login = regex_res[2]; + if (! ('res.users' in this.map_hash)) { this.map_hash['res.users']['name'] = []; } this.map_hash['res.users']['login'].push(login); regex_res = regex_login.exec(string); } From 6873eb1616c7ffefc699b040604e034c7adbbd2f Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 29 Feb 2012 15:39:58 +0530 Subject: [PATCH 0160/1161] [IMP] remove conflict bzr revid: tpa@tinyerp.com-20120229100958-621k7gheoi70p0th --- addons/sale/sale.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 9dc4781e26c..552246f2513 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -28,11 +28,7 @@ from tools.translate import _ from tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, float_compare import decimal_precision as dp import netsvc -<<<<<<< TREE -from openerp.addons.base.res import res_config_sale as sale_config -======= #from openerp.addons.base.res import res_config_sale as sale_config ->>>>>>> MERGE-SOURCE class sale_shop(osv.osv): _name = "sale.shop" From 44ca05c1293aec5e91d8d97569ddaaf46d887920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 29 Feb 2012 11:16:17 +0100 Subject: [PATCH 0161/1161] [CL] Wall: Cleaned a bit mail.xml: removed unused 'dusplay followers' on wall bzr revid: tde@openerp.com-20120229101617-ubru2sqmjznomrwf --- addons/mail/static/src/xml/mail.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index ef795c9f3e3..66a8e5b0835 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -19,13 +19,6 @@
-
-
- -
-
-
-
From 38e6f8c6ee82af01a2fcb3ec01e4c460351cb77c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 29 Feb 2012 11:17:16 +0100 Subject: [PATCH 0162/1161] [IMP] Wall: added font color similar to general OpenERP font color bzr revid: tde@openerp.com-20120229101716-pdjtjbiv9p4x32lp --- addons/mail/static/src/css/mail.css | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 195e25807c4..6b9b1e5c1c6 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -3,6 +3,7 @@ .oe_mail_wall { overflow: auto; padding: 5px 5px 5px 5px; + color: #4C4C4C; } /* 2 columns view */ From 747134642b1d45998635ed0ac1ed66f6949e9a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 29 Feb 2012 11:17:58 +0100 Subject: [PATCH 0163/1161] [IMP] Wall: messages search_view_id is now passed as an argument to the wall, allowing to display the correct search view bzr revid: tde@openerp.com-20120229101758-vse9o4p5lo133bje --- addons/mail/mail_message_view.xml | 4 ++-- addons/mail/static/src/js/mail.js | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index 09174e54f06..759a60cdb89 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -229,13 +229,13 @@ (w)All Feeds mail.all_feeds - + My Feeds mail.all_feeds - + diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 01dde5615a3..7d1de6384e6 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -316,6 +316,7 @@ openerp.mail = function(session) { * @param {Object} parent parent * @param {Object} [params] * @param {Number} [params.limit=20] number of messages to show and fetch + * @param {Number} [params.search_view_id=false] search view id for messages * @var {Array} sorted_comments records sorted by res_model and res_id * records.res_model = {res_ids} * records.res_model.res_id = [records] @@ -324,6 +325,7 @@ openerp.mail = function(session) { this._super(parent); this.params = params || {}; this.params.limit = params.limit || 20; + this.params.search_view_id = params.search_view_id || false; this.params.search = {}; this.params.domain = []; this.sorted_comments = {}; @@ -336,9 +338,10 @@ openerp.mail = function(session) { start: function() { var self = this; this._super.apply(this, arguments); + /* events and buttons */ this.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); /* load mail.message search view */ - var search_view_loaded = this.load_search_view(); + var search_view_loaded = this.load_search_view(this.params.search_view_id, {}, false); var search_view_ready = $.when(search_view_loaded).then(function () { self.searchview.on_search.add(self.do_searchview_search); }); From 4fd9980327c7e80c34ea25bced12313bfa1948d9 Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Wed, 29 Feb 2012 15:52:49 +0530 Subject: [PATCH 0164/1161] [IMP] Call notifications methods from crm base. bzr revid: bth@tinyerp.com-20120229102249-xci8gnbic0npnovs --- addons/crm/crm.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 4c603777820..fdcd7a1a52a 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -289,6 +289,7 @@ class crm_base(object): if not case.user_id: data['user_id'] = uid self.write(cr, uid, [case.id], data) + self._case_open_notification(case, context=context) self._action(cr, uid, cases, 'open') return True @@ -301,6 +302,7 @@ class crm_base(object): cases[0].state # to fill the browse record cache self.write(cr, uid, ids, {'state': 'done', 'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'), }) # We use the cache of cases to keep the old case state + self._case_close_notification(cases, context=context) self._action(cr, uid, cases, 'done') return True @@ -312,6 +314,7 @@ class crm_base(object): cases[0].state # to fill the browse record cache self.write(cr, uid, ids, {'state': 'cancel', 'active': True}) # We use the cache of cases to keep the old case state + self._case_cancel_notification(cases, context=context) self._action(cr, uid, cases, 'cancel') return True @@ -322,6 +325,7 @@ class crm_base(object): cases = self.browse(cr, uid, ids) cases[0].state # to fill the browse record cache self.write(cr, uid, ids, {'state': 'pending', 'active': True}) + self._case_pending_notification(cases, context=context) self._action(cr, uid, cases, 'pending') return True From 8f5c6d0b30d1541febadee9362dedfd4c449b440 Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Wed, 29 Feb 2012 15:58:27 +0530 Subject: [PATCH 0165/1161] [IMP]: Improved field names and method names. bzr revid: uco@tinyerp.com-20120229102827-z4zku1yj3b6ho9eg --- addons/sale/res_config.py | 20 +++++++++++++------- addons/sale/res_config_view.xml | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 540fe9da97a..b7f5fb0564a 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -43,7 +43,7 @@ class sale_configuration(osv.osv_memory): ('manual', 'Invoice Based on Sales Orders'), ('picking', 'Invoice Based on Deliveries'), ], 'Main Method Based On', required=True, help="You can generate invoices based on sales orders or based on shippings."), - 'charge_delivery': fields.boolean('Do you charge the delivery?'), + 'delivery': fields.boolean('Do you charge the delivery?'), 'time_unit': fields.many2one('product.uom','Working Time Unit'), 'picking_policy' : fields.boolean("Deliver all products at once?"), 'group_sale_delivery_address':fields.boolean("Multiple Address",help="Group To Allow delivery address different from invoice address"), @@ -107,13 +107,15 @@ class sale_configuration(osv.osv_memory): def get_default_sale_configs(self, cr, uid, ids, context=None): ir_values_obj = self.pool.get('ir.values') result = {} - defaults = ir_values_obj.get(cr, uid, 'default', False, ['sale.order']) + for res in ir_values_obj.get(cr, uid, 'default', False, ['sale.order']): + result[res[1]] = res[2] return result def get_default_groups(self, cr, uid, ids, context=None): ir_values_obj = self.pool.get('ir.values') result = {} - defaults = ir_values_obj.get(cr, uid, 'default', False, ['res.users']) + for res in ir_values_obj.get(cr, uid, 'default', False, ['res.users']): + result[res[1]] = res[2] return result def default_get(self, cr, uid, fields_list, context=None): @@ -141,13 +143,17 @@ class sale_configuration(osv.osv_memory): def execute(self, cr, uid, ids, vals, context=None): #TODO: TO BE IMPLEMENTED for method in dir(self): - if method.startswith('set_'): + if method.startswith('_set'): getattr(self, method)(cr, uid, ids, vals, context) return True - def set_modules(self, cr, uid, ids, vals, context=None): + def _set_modules(self, cr, uid, ids, vals, context=None): module_obj = self.pool.get('ir.module.module') for k, v in vals.items(): + if k == 'task_work': + MODULE_LIST += ['project_timesheet','project_mrp'] + if k == 'timesheet': + MODULE_LIST += ['account_analytic_analysis'] if k in MODULE_LIST: installed = self.get_default_installed_modules(cr, uid, [k], context) if v == True and not installed: @@ -161,7 +167,7 @@ class sale_configuration(osv.osv_memory): cr.commit() pooler.restart_pool(cr.dbname, update_module=True)[1] - def set_sale_defaults(self, cr, uid, ids, vals, context=None): + def _set_sale_defaults(self, cr, uid, ids, vals, context=None): ir_values_obj = self.pool.get('ir.values') data_obj = self.pool.get('ir.model.data') menu_obj = self.pool.get('ir.ui.menu') @@ -195,7 +201,7 @@ class sale_configuration(osv.osv_memory): return res - def set_groups(self, cr, uid, ids, vals, context=None): + def _set_groups(self, cr, uid, ids, vals, context=None): data_obj = self.pool.get('ir.model.data') users_obj = self.pool.get('res.users') groups_obj = self.pool.get('res.groups') diff --git a/addons/sale/res_config_view.xml b/addons/sale/res_config_view.xml index 82d1a18684d..3bf7879e81c 100644 --- a/addons/sale/res_config_view.xml +++ b/addons/sale/res_config_view.xml @@ -24,7 +24,7 @@ - + From 6990492b3389246522f0acb246caa2bc843322c8 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 29 Feb 2012 16:41:23 +0530 Subject: [PATCH 0166/1161] [IMP] use methods of module to install and uninstall bzr revid: tpa@tinyerp.com-20120229111123-keka5l6txo0tx7zc --- addons/sale/res_config.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 540fe9da97a..d407e4b445f 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -150,16 +150,13 @@ class sale_configuration(osv.osv_memory): for k, v in vals.items(): if k in MODULE_LIST: installed = self.get_default_installed_modules(cr, uid, [k], context) - if v == True and not installed: + if v == True and not installed.get(k): module_id = module_obj.search(cr, uid, [('name','=',k)])[0] - module_obj.state_update(cr, uid, [module_id], 'to install', ['uninstalled'], context) - cr.commit() - pooler.restart_pool(cr.dbname, update_module=True)[1] + module_obj.button_immediate_install(cr, uid, [module_id], context) elif v == False and installed.get(k): module_id = module_obj.search(cr, uid, [('name','=',k)])[0] - module_obj.state_update(cr, uid, [module_id], 'to remove', ['installed'], context) - cr.commit() - pooler.restart_pool(cr.dbname, update_module=True)[1] + module_obj.button_uninstall(self, cr, uid, [module_id], context=None) + module_obj.button_upgrade(self, cr, uid, [module_id], context=None) def set_sale_defaults(self, cr, uid, ids, vals, context=None): ir_values_obj = self.pool.get('ir.values') From 89020fbf6ca71f4202937a60bc1eef5b49054993 Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Wed, 29 Feb 2012 17:03:15 +0530 Subject: [PATCH 0167/1161] [ADD] account: Added methods to get default values and change type of tax value field. bzr revid: uco@tinyerp.com-20120229113315-aa0orm39gli20rl9 --- addons/account/res_config.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/addons/account/res_config.py b/addons/account/res_config.py index 6c5f32d4812..b274f9616db 100644 --- a/addons/account/res_config.py +++ b/addons/account/res_config.py @@ -35,10 +35,26 @@ class account_configuration(osv.osv_memory): _defaults = { 'tax_policy': 'global_on_order', - 'tax_value': 15.0, } + def default_get(self, cr, uid, fields_list, context=None): + ir_values_obj = self.pool.get('ir.values') + res = super(account_configuration, self).default_get(cr, uid, fields_list, context=context) + res.update({'tax_value': 15.0}) + for tax in ir_values_obj.get(cr, uid, 'default', False, ['product.product']): + if tax[1] == 'taxes_id': + res.update({'tax_value': tax[2] and tax[2][0]}) + return res - def get_tax_value(self, cr, uid, ids, context=None): + def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): + ir_values_obj = self.pool.get('ir.values') + res = super(account_configuration, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu) + for tax in ir_values_obj.get(cr, uid, 'default', False, ['product.product']): + if tax[1] == 'taxes_id': + if res['fields'].get('tax_value'): + res['fields']['tax_value'] = {'domain': [], 'views': {}, 'context': {}, 'selectable': True, 'type': 'many2one', 'relation': 'account.tax', 'string': 'Value'} + return res + + def set_tax_value(self, cr, uid, ids, context=None): result = {} chart_account_obj = self.pool.get('wizard.multi.charts.accounts') chart_account_obj.execute(cr, uid, ids, context=context) From c45888c2d010a5aefe2a5f67eb4271d6dcc55c15 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 29 Feb 2012 17:28:33 +0530 Subject: [PATCH 0168/1161] [IMP] Improved code bzr revid: tpa@tinyerp.com-20120229115833-645usbdbo340fazd --- .../account_analytic_analysis_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml index 5633958efc0..8347f6333b6 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml +++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml @@ -113,8 +113,8 @@ Sales Application - sale.configuration - + res.config + form From 0688cc33a2b0164892b27f1999c4efe8ba7dabfe Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Wed, 29 Feb 2012 17:33:55 +0530 Subject: [PATCH 0169/1161] [FIX] Remove subject from stage change notification. bzr revid: bth@tinyerp.com-20120229120355-4rnh98lsssrd96l7 --- addons/crm/crm_lead.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 18f746880ca..50aa8dfff06 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -905,15 +905,13 @@ class crm_lead(crm_case, osv.osv): # change probability of lead(s) if required by stage if not vals.get('probability') and stage.on_change: vals['probability'] = stage.probability - text = _("Changed Stage to: %s") % stage.name - for case in self.browse(cr, uid, ids, context=context): if case.type == 'lead' or context.get('stage_type') == 'lead': message = _("The stage of lead has been changed to %s.") % (stage.name) - case.message_append_note(text, message) + case.message_append_note('', message) elif case.type == 'opportunity': message = _("The stage of opportunity has been changed to %s.") % (stage.name) - case.message_append_note(text, message) + case.message_append_note('', message) return super(crm_lead,self).write(cr, uid, ids, vals, context) From 273472b095eb4263fc0f2ab9d48d5e8a6f2a4d0f Mon Sep 17 00:00:00 2001 From: "Jiten (OpenERP)" Date: Wed, 29 Feb 2012 17:40:04 +0530 Subject: [PATCH 0170/1161] [IMP] Improved write method for change stage id. bzr revid: jra@tinyerp.com-20120229121004-5p1otoss3d9i8vzv --- addons/hr_recruitment/hr_recruitment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 1637313a28c..4988fef8278 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -518,8 +518,8 @@ class hr_applicant(crm.crm_case, osv.osv): def write(self, cr, uid, ids, vals, context=None): if 'stage_id' in vals and vals['stage_id']: stage = self.pool.get('hr.recruitment.stage').browse(cr, uid, vals['stage_id'], context=context) - text = _("Changed Stage to %s.") % stage.name - self.message_append(cr, uid, ids, text, body_text=text, context=context) + self.message_append_note(cr, uid, ids, _('System notification'), + _("Changed Stage to %s.") % stage.name, type='notification') return super(hr_applicant,self).write(cr, uid, ids, vals, context=context) hr_applicant() From a759f6e7387391e19dfab504aedb0ab4f6f3082e Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Wed, 29 Feb 2012 17:51:36 +0530 Subject: [PATCH 0171/1161] [FIX]: Fixed problem of global variable. Removed unnecessary file. bzr revid: uco@tinyerp.com-20120229122136-f8iqsyvpe07ls1k9 --- addons/account_chart/res_config.py | 8 -------- addons/sale/res_config.py | 12 ++++++------ 2 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 addons/account_chart/res_config.py diff --git a/addons/account_chart/res_config.py b/addons/account_chart/res_config.py deleted file mode 100644 index 5bd2b98ca66..00000000000 --- a/addons/account_chart/res_config.py +++ /dev/null @@ -1,8 +0,0 @@ -class account_configuration(osv.osv_memory): - _inherit = 'res.config' - - _columns = { - 'tax_value' : fields.many2one('account.tax', 'Value'), - } - -account_configuration() \ No newline at end of file diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 6ab0203e55a..29f2c432c5e 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -143,17 +143,17 @@ class sale_configuration(osv.osv_memory): def execute(self, cr, uid, ids, vals, context=None): #TODO: TO BE IMPLEMENTED for method in dir(self): - if method.startswith('_set'): + if method.startswith('set_'): + vals['modules'] = MODULE_LIST getattr(self, method)(cr, uid, ids, vals, context) return True - def _set_modules(self, cr, uid, ids, vals, context=None): + def set_modules(self, cr, uid, ids, vals, context=None): module_obj = self.pool.get('ir.module.module') + MODULE_LIST = vals.get('modules') for k, v in vals.items(): if k == 'task_work': MODULE_LIST += ['project_timesheet','project_mrp'] - if k == 'timesheet': - MODULE_LIST += ['account_analytic_analysis'] if k in MODULE_LIST: installed = self.get_default_installed_modules(cr, uid, [k], context) if v == True and not installed.get(k): @@ -164,7 +164,7 @@ class sale_configuration(osv.osv_memory): module_obj.button_uninstall(self, cr, uid, [module_id], context=None) module_obj.button_upgrade(self, cr, uid, [module_id], context=None) - def _set_sale_defaults(self, cr, uid, ids, vals, context=None): + def set_sale_defaults(self, cr, uid, ids, vals, context=None): ir_values_obj = self.pool.get('ir.values') data_obj = self.pool.get('ir.model.data') menu_obj = self.pool.get('ir.ui.menu') @@ -198,7 +198,7 @@ class sale_configuration(osv.osv_memory): return res - def _set_groups(self, cr, uid, ids, vals, context=None): + def set_groups(self, cr, uid, ids, vals, context=None): data_obj = self.pool.get('ir.model.data') users_obj = self.pool.get('res.users') groups_obj = self.pool.get('res.groups') From 324eb16d3cc983e3169157a07e43b1410516977a Mon Sep 17 00:00:00 2001 From: "Jiten (OpenERP)" Date: Wed, 29 Feb 2012 17:53:05 +0530 Subject: [PATCH 0172/1161] [FIX] Remove the need action for state 'In Progress' as per paid instruction. bzr revid: jra@tinyerp.com-20120229122305-ixjn05tqddsng4sb --- addons/hr_recruitment/hr_recruitment.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 4988fef8278..2a6bc0db64c 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -392,9 +392,8 @@ class hr_applicant(crm.crm_case, osv.osv): return res def _case_open_notification(self, case, context=None): - case.message_mark_done(context) message = _("Changed Status to In Progress.") - case.message_append_note('' ,message, type='notification', need_action_user_id=case.user_id.id) + case.message_append_note('' ,message, type='notification') return True def _case_close_notification(self, case, context=None): From b8b535fcaad523687d89fc4c322557054c262ea5 Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Wed, 29 Feb 2012 18:02:08 +0530 Subject: [PATCH 0173/1161] [IMP] account: Improved code to add default taxes. bzr revid: uco@tinyerp.com-20120229123208-x6qpw7cem4fszj7e --- addons/account/res_config.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/addons/account/res_config.py b/addons/account/res_config.py index b274f9616db..f35d261d888 100644 --- a/addons/account/res_config.py +++ b/addons/account/res_config.py @@ -36,28 +36,42 @@ class account_configuration(osv.osv_memory): _defaults = { 'tax_policy': 'global_on_order', } + + def _check_default_tax(self, cr, uid, context=None): + ir_values_obj = self.pool.get('ir.values') + for tax in ir_values_obj.get(cr, uid, 'default', False, ['product.product']): + if tax[1] == 'taxes_id': + return tax[2] + return False + def default_get(self, cr, uid, fields_list, context=None): ir_values_obj = self.pool.get('ir.values') res = super(account_configuration, self).default_get(cr, uid, fields_list, context=context) res.update({'tax_value': 15.0}) - for tax in ir_values_obj.get(cr, uid, 'default', False, ['product.product']): - if tax[1] == 'taxes_id': - res.update({'tax_value': tax[2] and tax[2][0]}) + tax_id = self._check_default_tax(cr, uid, context) + if tax_id: + res.update({'tax_value': tax_id and tax_id[0]}) return res def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): ir_values_obj = self.pool.get('ir.values') res = super(account_configuration, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu) - for tax in ir_values_obj.get(cr, uid, 'default', False, ['product.product']): - if tax[1] == 'taxes_id': - if res['fields'].get('tax_value'): - res['fields']['tax_value'] = {'domain': [], 'views': {}, 'context': {}, 'selectable': True, 'type': 'many2one', 'relation': 'account.tax', 'string': 'Value'} + if self._check_default_tax(cr, uid, context) and res['fields'].get('tax_value'): + res['fields']['tax_value'] = {'domain': [], 'views': {}, 'context': {}, 'selectable': True, 'type': 'many2one', 'relation': 'account.tax', 'string': 'Value'} return res - def set_tax_value(self, cr, uid, ids, context=None): - result = {} + def set_tax_value(self, cr, uid, ids, vals, context=None): chart_account_obj = self.pool.get('wizard.multi.charts.accounts') - chart_account_obj.execute(cr, uid, ids, context=context) + acc_installer_obj = self.pool.get('account.installer') + chart_template_ids = self.pool.get('account.chart.template').search(cr, uid, [('visible', '=', True)], context=context) + result = {} + if not self._check_default_tax(cr, uid, context): + installer_id = acc_installer_obj.create(cr, uid, {}, context=context) + acc_installer_obj.execute(cr, uid, [installer_id], context=context) + if chart_template_ids: + code_digits = chart_account_obj.onchange_chart_template_id(cr, uid, [], chart_template_ids[0], context=context)['value']['code_digits'] + object_id = chart_account_obj.create(cr, uid, {'code_digits': code_digits}, context=context) + chart_account_obj.execute(cr, uid, [object_id], context=context) return result account_configuration() \ No newline at end of file From 195252f7c698f1fd33924b920f4639d9b8adc7b5 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 29 Feb 2012 18:26:13 +0530 Subject: [PATCH 0174/1161] [IMP] improved condition for fetchmail_crm bzr revid: tpa@tinyerp.com-20120229125613-ucbir9o3segh51eb --- addons/crm/res_config.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/crm/res_config.py b/addons/crm/res_config.py index 6780ac17aa7..ab6183d7e52 100644 --- a/addons/crm/res_config.py +++ b/addons/crm/res_config.py @@ -81,8 +81,9 @@ class crm_configuration(osv.osv_memory): 'user': vals.get('user'), 'password': vals.get('password') } - if not self.get_installed_modules(cr, uid, ['fetchmail_crm'], context): - fetchmail_obj.create(cr, uid, fetchmail_vals, context=context) + server_ids = fetchmail_obj.search(cr, uid, []) + if not self.get_default_installed_modules(cr, uid, ['fetchmail_crm'], context) or not server_ids: + tt = fetchmail_obj.create(cr, uid, fetchmail_vals, context=context) else: fetchmail_ids = fetchmail_obj.search(cr, uid, [('name','=','Incoming Leads')], context=context) fetchmail_obj.write(cr, uid, fetchmail_ids, fetchmail_vals, context=context) From 5d98b230ab2bb42b60358820c9bb28486b3ab64d Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Wed, 29 Feb 2012 18:32:34 +0530 Subject: [PATCH 0175/1161] [IMP]: Improved code for tax templates. Revoked view for plugins_xx. bzr revid: uco@tinyerp.com-20120229130234-99e485onvwj3q0lx --- addons/account/res_config.py | 8 ++++++-- addons/plugin_outlook/plugin_outlook.xml | 6 +++--- addons/plugin_thunderbird/plugin_thunderbird.xml | 6 +++--- addons/sale/res_config.py | 12 +++++++----- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/addons/account/res_config.py b/addons/account/res_config.py index f35d261d888..353f711ea17 100644 --- a/addons/account/res_config.py +++ b/addons/account/res_config.py @@ -63,9 +63,13 @@ class account_configuration(osv.osv_memory): def set_tax_value(self, cr, uid, ids, vals, context=None): chart_account_obj = self.pool.get('wizard.multi.charts.accounts') acc_installer_obj = self.pool.get('account.installer') - chart_template_ids = self.pool.get('account.chart.template').search(cr, uid, [('visible', '=', True)], context=context) + chart_template_obj = self.pool.get('account.chart.template') + tax_template_obj = self.pool.get('account.tax.template') + chart_template_ids = chart_template_obj.search(cr, uid, [('visible', '=', True)], context=context) + if chart_template_ids: + taxes = tax_template_obj.search(cr, uid, [('chart_template_id', '=', chart_template_ids[0])], context=context) result = {} - if not self._check_default_tax(cr, uid, context): + if not self._check_default_tax(cr, uid, context) and not taxes: installer_id = acc_installer_obj.create(cr, uid, {}, context=context) acc_installer_obj.execute(cr, uid, [installer_id], context=context) if chart_template_ids: diff --git a/addons/plugin_outlook/plugin_outlook.xml b/addons/plugin_outlook/plugin_outlook.xml index b03932c7e94..8dd0ec481a8 100644 --- a/addons/plugin_outlook/plugin_outlook.xml +++ b/addons/plugin_outlook/plugin_outlook.xml @@ -48,17 +48,17 @@ new - + Install Outlook Plug-In diff --git a/addons/plugin_thunderbird/plugin_thunderbird.xml b/addons/plugin_thunderbird/plugin_thunderbird.xml index dff9a186c54..c36e2f807c5 100644 --- a/addons/plugin_thunderbird/plugin_thunderbird.xml +++ b/addons/plugin_thunderbird/plugin_thunderbird.xml @@ -55,17 +55,17 @@ new - + diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 29f2c432c5e..f23e0c9b088 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -154,15 +154,17 @@ class sale_configuration(osv.osv_memory): for k, v in vals.items(): if k == 'task_work': MODULE_LIST += ['project_timesheet','project_mrp'] + if k == 'timesheet': + MODULE_LIST += ['account_analytic_analysis'] if k in MODULE_LIST: installed = self.get_default_installed_modules(cr, uid, [k], context) if v == True and not installed.get(k): - module_id = module_obj.search(cr, uid, [('name','=',k)])[0] - module_obj.button_immediate_install(cr, uid, [module_id], context) + module_id = module_obj.search(cr, uid, [('name','=',k)]) + module_obj.button_immediate_install(cr, uid, module_id, context) elif v == False and installed.get(k): - module_id = module_obj.search(cr, uid, [('name','=',k)])[0] - module_obj.button_uninstall(self, cr, uid, [module_id], context=None) - module_obj.button_upgrade(self, cr, uid, [module_id], context=None) + module_id = module_obj.search(cr, uid, [('name','=',k)]) + module_obj.button_uninstall(self, cr, uid, module_id, context=None) + module_obj.button_upgrade(self, cr, uid, module_id, context=None) def set_sale_defaults(self, cr, uid, ids, vals, context=None): ir_values_obj = self.pool.get('ir.values') From ce197bb6ddd09cfaf89abe00465537b05246c582 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 29 Feb 2012 18:34:15 +0530 Subject: [PATCH 0176/1161] [IMP] improved code for default group bzr revid: tpa@tinyerp.com-20120229130415-7mg2ki5u22teiemz --- addons/sale/res_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 29f2c432c5e..bb483527f5c 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -170,6 +170,7 @@ class sale_configuration(osv.osv_memory): menu_obj = self.pool.get('ir.ui.menu') res = {} wizard = self.browse(cr, uid, ids)[0] + group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id if wizard.sale_orders: menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').id From 27fe954a1b1d7e7776510bd2f7f61fc7dfe322cd Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Wed, 29 Feb 2012 19:05:09 +0530 Subject: [PATCH 0177/1161] [IMP] sale: Improved code for getting default settings of sale. bzr revid: uco@tinyerp.com-20120229133509-yomie0d9o1k73veq --- addons/account/res_config.py | 2 +- addons/sale/res_config.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/addons/account/res_config.py b/addons/account/res_config.py index 353f711ea17..0af0a9dcbae 100644 --- a/addons/account/res_config.py +++ b/addons/account/res_config.py @@ -50,7 +50,7 @@ class account_configuration(osv.osv_memory): res.update({'tax_value': 15.0}) tax_id = self._check_default_tax(cr, uid, context) if tax_id: - res.update({'tax_value': tax_id and tax_id[0]}) + res.update({'tax_value': tax_id and tax_id[0]}) return res def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 367aa5ef3e9..ce6312ecfce 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -106,7 +106,18 @@ class sale_configuration(osv.osv_memory): def get_default_sale_configs(self, cr, uid, ids, context=None): ir_values_obj = self.pool.get('ir.values') + data_obj = self.pool.get('ir.model.data') + menu_obj = self.pool.get('ir.ui.menu') result = {} + invoicing_groups_id = [gid.id for gid in data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').groups_id] + picking_groups_id = [gid.id for gid in data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').groups_id] + group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id + for menu in ir_values_obj.get(cr, uid, 'default', False, ['ir.ui.menu']): + if menu[1] == 'groups_id' and group_id in menu[2][0]: + if group_id in invoicing_groups_id: + result['sale_orders'] = True + if group_id in picking_groups_id: + result['deli_orders'] = True for res in ir_values_obj.get(cr, uid, 'default', False, ['sale.order']): result[res[1]] = res[2] return result From 4847f720442c3fa6faefa60398d245c5814eb2c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 29 Feb 2012 15:23:31 +0100 Subject: [PATCH 0178/1161] [REF] Wall small cleaning of code bzr revid: tde@openerp.com-20120229142331-zr42yxqy8i0xv7js --- addons/mail/static/src/js/mail.js | 10 +++++----- addons/mail/static/src/xml/mail.xml | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 7d1de6384e6..b8a82ff0192 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -339,7 +339,9 @@ openerp.mail = function(session) { var self = this; this._super.apply(this, arguments); /* events and buttons */ - this.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); + this.$element.find('button.oe_mail_button_comment').bind('click', function () { self.do_comment(); }); + this.$element.find('button.oe_mail_wall_button_more').bind('click', function () { self.do_more(); }); + this.$element.find('div.oe_mail_wall_nomore').hide(); /* load mail.message search view */ var search_view_loaded = this.load_search_view(this.params.search_view_id, {}, false); var search_view_ready = $.when(search_view_loaded).then(function () { @@ -357,7 +359,7 @@ openerp.mail = function(session) { /** * Loads the mail.message search view * @param {Number} view_id id of the search view to load - * @param {??} defaults ?? + * @param {Object} defaults ?? * @param {Boolean} hidden ?? */ load_search_view: function (view_id, defaults, hidden) { @@ -399,9 +401,7 @@ openerp.mail = function(session) { this.params.domain = []; this.sorted_comments = {}; this.$element.find('div.oe_mail_wall_threads').empty(); - return this.fetch_comments(domain, context, offset, limit).then(function () { - self.$element.find('button.oe_mail_wall_button_more').bind('click', function () { self.do_more(); }); - }); + return this.fetch_comments(domain, context, offset, limit); }, /** diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 66a8e5b0835..1e4e301bc2e 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -17,6 +17,9 @@
+
+ You have loaded all discussions. +
From 2d1f03fa5270bb64c78a6ead6be84970e8a9532d Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Thu, 1 Mar 2012 10:26:21 +0530 Subject: [PATCH 0179/1161] [IMP]: Improved default get code. Improved views. Fixed account chart error. bzr revid: uco@tinyerp.com-20120301045621-ntwm1o22ruy7940u --- addons/account/res_config.py | 1 + .../account_analytic_analysis_view.xml | 6 ++---- addons/crm/res_config_view.xml | 2 +- addons/plugin_outlook/plugin_outlook.xml | 2 +- addons/plugin_thunderbird/plugin_thunderbird.xml | 2 +- addons/sale/res_config.py | 12 ++++++++---- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/addons/account/res_config.py b/addons/account/res_config.py index 0af0a9dcbae..3966e7ad7b9 100644 --- a/addons/account/res_config.py +++ b/addons/account/res_config.py @@ -66,6 +66,7 @@ class account_configuration(osv.osv_memory): chart_template_obj = self.pool.get('account.chart.template') tax_template_obj = self.pool.get('account.tax.template') chart_template_ids = chart_template_obj.search(cr, uid, [('visible', '=', True)], context=context) + taxes = [] if chart_template_ids: taxes = tax_template_obj.search(cr, uid, [('chart_template_id', '=', chart_template_ids[0])], context=context) result = {} diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml index 8347f6333b6..5cdc744ccb6 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml +++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml @@ -119,10 +119,8 @@ - - - - + + diff --git a/addons/crm/res_config_view.xml b/addons/crm/res_config_view.xml index 807685bda83..e6948d5f664 100644 --- a/addons/crm/res_config_view.xml +++ b/addons/crm/res_config_view.xml @@ -20,7 +20,7 @@ - + diff --git a/addons/plugin_outlook/plugin_outlook.xml b/addons/plugin_outlook/plugin_outlook.xml index 8dd0ec481a8..27fd8d6d11f 100644 --- a/addons/plugin_outlook/plugin_outlook.xml +++ b/addons/plugin_outlook/plugin_outlook.xml @@ -55,7 +55,7 @@ - -
-
- You have loaded all discussions. + +

You have loaded all discussions.

@@ -33,11 +30,11 @@
-
+
OpenSocial
-
+
-
+
@@ -52,22 +49,18 @@
-
+
-
-
+
User_image

-
-
+
- -
-
- You have loaded all messages in this thread. + +

You have loaded all messages in this thread.

@@ -76,31 +69,25 @@
- - - - - - + +
+
- +

- - OpenERP System Notification - - - - - - + + + via OpenERP System Notification + - Need action by wrote on
+

From 15581b5286cb2861395f4475c1aeb826c709052d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 2 Mar 2012 18:35:11 +0100 Subject: [PATCH 0201/1161] [REF] Small refactoring of Wall. Refactoring still needed. bzr revid: tde@openerp.com-20120302173511-eyky2ibpzdvp0hgq --- addons/mail/static/src/js/mail.js | 47 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 2e270bd82a0..6f9060c75c7 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -555,7 +555,7 @@ openerp.mail = function(session) { $('
').html(render_res).appendTo(self.$element.find('div.oe_mail_wall_threads')); var thread = new mail.Thread(self, { 'res_model': model_name, 'res_id': parseInt(id), 'uid': self.session.uid, 'records': records, - 'parent_id': false, 'thread_level': 1} + 'parent_id': false, 'thread_level': 2} ); thread.appendTo(self.$element.find('div.oe_mail_wall_thread_content:last')); }); @@ -565,40 +565,41 @@ openerp.mail = function(session) { /** * Add records to sorted_comments array - * @param {Array} records records from mail.message - * @returns {Object} sorted_comments: dict - * sorted_comments.res_model = {res_ids} - * sorted_comments.res_model.res_id = [records] - * sorted = [{'hr_holidays': [{3: 'A'}, {2: 'B'}]}, {'crm': [{3: 'A'}, {2: 'B'}]}] + * @param {Array} records records from mail.message sorted by date desc + * @returns {Object} sc sorted_comments: dict + * sc.model_list = [record.model names] + * sc.models.model = { + * 'id_list': list or root_ids + * 'id_to_anc': {'record_id': [ancestor_ids]}, still sorted by date desc + * 'ids': {'root_id': [records]}, still sorted by date desc + * }, for each model */ sort_comments: function (records) { sc = {'model_list': [], 'models': {}} var cur_iter = 0; var max_iter = 10; var modif = true; /* step1: get roots */ while ( modif && (cur_iter++) < max_iter) { + console.log(cur_iter); modif = false; _(records).each(function (record) { if ($.inArray(record.model, sc['model_list']) == -1) { sc['model_list'].push(record.model); - sc['models'][record.model] = {'id_list': [], 'id_to_root': {}, 'ids': {}}; + sc['models'][record.model] = {'id_list': [], 'id_to_anc': {}, 'ids': {}}; + } + var rmod = sc['models'][record.model]; + if (record.parent_id == false && (_.indexOf(rmod['id_list'], record.id) == -1)) { + rmod['id_list'].push(record.id); + rmod['ids'][record.id] = []; modif = true; - } - var sort_id = (record.parent_id) ? record.parent_id[0]: record.id; - if (record.parent_id == false) { - if (_.indexOf(sc['models'][record.model]['id_list'], sort_id) == -1) { - sc['models'][record.model]['id_list'].push(sort_id); - sc['models'][record.model]['ids'][sort_id] = []; - modif = true; - } - } + } else { - var test = sc['models'][record.model]['id_to_root'][sort_id]; - if (_.indexOf(sc['models'][record.model]['id_list'], sort_id) != -1) { - sc['models'][record.model]['id_to_root'][record.id] = sort_id; + var test = rmod['id_to_anc'][record.parent_id[0]]; + if (_.indexOf(rmod['id_list'], record.parent_id[0]) != -1) { + rmod['id_to_anc'][record.id] = record.parent_id[0]; modif = true; } else if ( test ) { - sc['models'][record.model]['id_to_root'][record.id] = test; + rmod['id_to_anc'][record.id] = test; modif = true; } } @@ -606,7 +607,7 @@ openerp.mail = function(session) { } /* step2: add records */ _(records).each(function (record) { - var root_id = sc['models'][record.model]['id_to_root'][record.id]; + var root_id = sc['models'][record.model]['id_to_anc'][record.id]; if (! root_id) root_id = record.id; sc['models'][record.model]['ids'][root_id].push(record); }); @@ -655,9 +656,7 @@ openerp.mail = function(session) { * Tools: get avatar mini (TODO: should be moved in some tools ?) */ thread_get_mini: function(model, field, id) { - id = id || ''; - var url = this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; - return url; + return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || ''); }, }); }; From 9c536a772c06118a724a6d26487c20e8e807106c Mon Sep 17 00:00:00 2001 From: "Ujjvala Collins (OpenERP)" Date: Sat, 3 Mar 2012 12:49:07 +0530 Subject: [PATCH 0202/1161] [IMP,FIX]: Fixed problem of plugin installation. Improved fetchmail code. bzr revid: uco@tinyerp.com-20120303071907-kk0942ijn0ztouak --- addons/crm/res_config.py | 51 +++++++------------ addons/crm/res_config_view.xml | 48 +++++++---------- addons/mail/__init__.py | 1 + addons/mail/__openerp__.py | 1 + addons/plugin_outlook/plugin_outlook.xml | 10 ++-- .../plugin_thunderbird/plugin_thunderbird.xml | 12 ++--- addons/sale/res_config.py | 5 +- 7 files changed, 54 insertions(+), 74 deletions(-) diff --git a/addons/crm/res_config.py b/addons/crm/res_config.py index d29e98047a5..ea376bb4edd 100644 --- a/addons/crm/res_config.py +++ b/addons/crm/res_config.py @@ -28,9 +28,7 @@ class crm_configuration(osv.osv_memory): 'module_crm_caldav' : fields.boolean("Caldav Synchronization", help="""Allows Caldav features in Meeting, Share meeting with other calendar clients like sunbird. It installs crm_caldav module."""), - 'module_fetchmail_crm': fields.boolean("Lead/Opportunity mail gateway", help=""" - Allows you to configure your incoming mail server. And creates leads for your mails. - It installs fetchmail_crm module."""), + 'fetchmail_crm': fields.boolean("Lead/Opportunity mail gateway", help="Allows you to configure your incoming mail server. And creates leads for your mails."), 'server' : fields.char('Server Name', size=256), 'port' : fields.integer('Port'), 'type': fields.selection([ @@ -68,36 +66,19 @@ class crm_configuration(osv.osv_memory): Allows you to locate customer on Google Map. It installs google_map module. """), - 'module_plugin_thunderbird': fields.boolean('Thunderbird plugin', - help=""" - The plugin allows you archive email and its attachments to the selected - OpenERP objects. You can select a partner, a task, a project, an analytical - account, or any other object and attach the selected mail as a .eml file in - the attachment of a selected record. You can create documents for CRM Lead, - HR Applicant and Project Issue from selected mails. - It installs plugin_thunderbird module. - """), - 'module_plugin_outlook': fields.boolean('Outlook plugin', - help=""" - Outlook plug-in allows you to select an object that you would like to add - to your email and its attachments from MS Outlook. You can select a partner, a task, - a project, an analytical account, or any other object and archive selected - mail into mail.message with attachments. - It installs plugin_outlook module. - """), } _defaults = { 'type': 'pop', } - + def create(self, cr, uid, vals, context=None): ids = super(crm_configuration, self).create(cr, uid, vals, context=context) - self.execute(cr, uid, [ids], vals, context=context) + self.execute(cr, uid, [ids], vals, context) return ids def write(self, cr, uid, ids, vals, context=None): - self.execute(cr, uid, ids, vals, context=context) + self.execute(cr, uid, ids, vals, context) return super(crm_configuration, self).write(cr, uid, ids, vals, context=context) def execute(self, cr, uid, ids, vals, context=None): @@ -108,11 +89,13 @@ class crm_configuration(osv.osv_memory): def get_default_email_configurations(self, cr, uid, ids, context=None): ir_values_obj = self.pool.get('ir.values') + fetchmail_obj = self.pool.get('fetchmail.server') result = {} - installed_modules = self.get_default_installed_modules(cr, uid, ids, context=context) - if 'module_fetchmail_crm' in installed_modules.keys(): - for val in ir_values_obj.get(cr, uid, 'default', False, ['fetchmail.server']): - result.update({val[1]: val[2]}) + server_ids = fetchmail_obj.search(cr, uid, [('name','=','Incoming Leads'),('state','=','done')]) + if server_ids: + result.update({'fetchmail_crm': True}) + for val in ir_values_obj.get(cr, uid, 'default', False, ['fetchmail.server']): + result.update({val[1]: val[2]}) return result def onchange_server_type(self, cr, uid, ids, server_type=False, ssl=False): @@ -132,7 +115,7 @@ class crm_configuration(osv.osv_memory): fetchmail_obj = self.pool.get('fetchmail.server') ir_values_obj = self.pool.get('ir.values') object_id = model_obj.search(cr, uid, [('model','=','crm.lead')]) - if vals.get('module_fetchmail_crm') and object_id: + if vals.get('fetchmail_crm') and object_id: fetchmail_vals = { 'name': 'Incoming Leads', 'object_id': object_id[0], @@ -143,9 +126,8 @@ class crm_configuration(osv.osv_memory): 'user': vals.get('user'), 'password': vals.get('password') } - server_ids = fetchmail_obj.search(cr, uid, []) - installed_modules = self.get_default_installed_modules(cr, uid, ids, context=context) - if installed_modules.get('module_fetchmail_crm') or not server_ids: + server_ids = fetchmail_obj.search(cr, uid, [('name','=','Incoming Leads'),('state','!=','done')]) + if not server_ids: server_ids = [fetchmail_obj.create(cr, uid, fetchmail_vals, context=context)] else: server_ids = fetchmail_obj.search(cr, uid, [('name','=','Incoming Leads')], context=context) @@ -157,5 +139,10 @@ class crm_configuration(osv.osv_memory): ir_values_obj.set(cr, uid, 'default', False, 'type', ['fetchmail.server'], fetchmail_vals.get('type')) ir_values_obj.set(cr, uid, 'default', False, 'user', ['fetchmail.server'], fetchmail_vals.get('user')) ir_values_obj.set(cr, uid, 'default', False, 'password', ['fetchmail.server'], fetchmail_vals.get('password')) + else: + server_ids = fetchmail_obj.search(cr, uid, [('name','=','Incoming Leads'),('state','=','done')]) + fetchmail_obj.set_draft(cr, uid, server_ids, context=None) -crm_configuration() \ No newline at end of file +crm_configuration() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/crm/res_config_view.xml b/addons/crm/res_config_view.xml index 62761794ce8..aeb1e9a5892 100644 --- a/addons/crm/res_config_view.xml +++ b/addons/crm/res_config_view.xml @@ -7,34 +7,24 @@ form - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + @@ -59,7 +49,7 @@ - + diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py index 4787883ef9c..72164b89865 100644 --- a/addons/mail/__init__.py +++ b/addons/mail/__init__.py @@ -23,6 +23,7 @@ import mail_message import mail_thread import res_partner import wizard +import res_config # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py index 8085d301364..1cad3fafa5d 100644 --- a/addons/mail/__openerp__.py +++ b/addons/mail/__openerp__.py @@ -62,6 +62,7 @@ The main features are: "res_partner_view.xml", 'security/ir.model.access.csv', 'mail_data.xml', + 'res_config_view.xml', ], 'installable': True, 'auto_install': False, diff --git a/addons/plugin_outlook/plugin_outlook.xml b/addons/plugin_outlook/plugin_outlook.xml index d86445c014d..ef1797b19b2 100644 --- a/addons/plugin_outlook/plugin_outlook.xml +++ b/addons/plugin_outlook/plugin_outlook.xml @@ -48,18 +48,18 @@ new - - + Sales Application res.config form - + - +
+
From da087c47b0c7cea83a78fefb16c9cffb9dace1f1 Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Tue, 6 Mar 2012 14:48:55 +0530 Subject: [PATCH 0231/1161] [IMP] notification for crm meeting and crm phonecall. bzr revid: bth@tinyerp.com-20120306091855-b7kx0wxxcu81uw0d --- addons/crm/crm.py | 5 ++++ addons/crm/crm_lead.py | 7 ++++++ addons/crm/crm_meeting.py | 34 +++++++++++++++++++++------ addons/crm/crm_meeting_view.xml | 1 + addons/crm/crm_phonecall.py | 39 ++++++++++++++++++++++++++----- addons/crm/crm_phonecall_view.xml | 1 + 6 files changed, 74 insertions(+), 13 deletions(-) diff --git a/addons/crm/crm.py b/addons/crm/crm.py index fdcd7a1a52a..4f2d2a120d8 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -273,6 +273,9 @@ class crm_base(object): def _case_pending_notification(self, case, context=None): return True + def _case_reset_notification(self, case, context=None): + return True + def _case_escalate_notification(self, case, context=None): return True @@ -336,6 +339,7 @@ class crm_base(object): cases = self.browse(cr, uid, ids) cases[0].state # to fill the browse record cache self.write(cr, uid, ids, {'state': 'draft', 'active': True}) + self._case_reset_notification(cases, context=context) self._action(cr, uid, cases, 'draft') return True @@ -485,6 +489,7 @@ class crm_case(crm_base): cases = self.browse(cr, uid, ids) cases[0].state # to fill the browse record cache self.write(cr, uid, ids, {'state': state, 'active': True}) + self._case_reset_notification(cases, context=context); self._action(cr, uid, cases, state) return True diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 50aa8dfff06..ed9cce87a8e 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -334,6 +334,13 @@ class crm_lead(crm_case, osv.osv): message = _("The lead is escalated.") case.message_append_note('' ,message) + def _case_reset_notification(self, case, context=None): + if case[0].type == 'lead': + message = _("The lead is renewed.") + elif case[0].type == 'opportunity': + message = _("The opportunity is renewed.") + case[0].message_append_note('' ,message, need_action_user_id=case[0].user_id.id) + def _case_phonecall_notification(self, cr, uid, ids, case, phonecall, action, context=None): for obj in phonecall.browse(cr, uid, ids, context=context): if action == "schedule" : diff --git a/addons/crm/crm_meeting.py b/addons/crm/crm_meeting.py index 5ba93d526af..10635d66a6c 100644 --- a/addons/crm/crm_meeting.py +++ b/addons/crm/crm_meeting.py @@ -42,7 +42,7 @@ class crm_meeting(crm_base, osv.osv): _name = 'crm.meeting' _description = "Meeting" _order = "id desc" - _inherit = "calendar.event" + _inherit = ["calendar.event","mail.thread"] _columns = { # From crm.case 'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}), @@ -87,15 +87,37 @@ class crm_meeting(crm_base, osv.osv): def _case_opportunity_meeting_notification(self, cr, uid, ids, context=None): lead_obj = self.pool.get('crm.lead') - + phonecall_obj = self.pool.get('crm.phonecall') for obj in self.browse(cr, uid, ids, context=context): if(obj.opportunity_id.id): newid = obj.opportunity_id.id - message = _("scheduled for meeting %s.") % (obj.date) + message = _("scheduled meeting on %s for opportunity.") % (obj.date) for lead in lead_obj.browse(cr, uid, [newid], context=context): lead.message_append_note('', message) + obj.message_append_note('', message, need_action_user_id=lead.user_id.id) + elif(obj.phonecall_id.id): + newid = obj.phonecall_id.id + message = _("scheduled meeting on %s for phonecall.") % (obj.date) + for phonecall in phonecall_obj.browse(cr, uid, [newid], context=context): + phonecall.message_append_note('', message) + obj.message_append_note('', message, need_action_user_id=phonecall.user_id.id) - def case_open(self, cr, uid, ids, *args): + def _case_close_notification(self, meeting, context=None): + meeting[0].message_mark_done(context) + message = _("The meeting is done.") + meeting[0].message_append_note('' ,message) + + def _case_reset_notification(self, meeting, context=None): + message = _("The meeting is unconfirmed.") + meeting[0].message_append_note('' ,message) + + def _case_open_notification(self, meeting, context=None): + if meeting.state != 'draft': + return False + message = _("The meeting has been confirmed.") + meeting.message_append_note('' ,message, need_action_user_id=meeting.user_id.id) + + def case_open(self, cr, uid, ids, context=None): """Confirms meeting @param self: The object pointer @param cr: the current row, from the database cursor, @@ -103,11 +125,9 @@ class crm_meeting(crm_base, osv.osv): @param ids: List of Meeting Ids @param *args: Tuple Value for additional Params """ - res = super(crm_meeting, self).case_open(cr, uid, ids, args) + res = super(crm_meeting, self).case_open(cr, uid, ids, context) for (id, name) in self.name_get(cr, uid, ids): - message = _("The meeting '%s' has been confirmed.") % name id=base_calendar.base_calendar_id2real_id(id) - self.log(cr, uid, id, message) return res crm_meeting() diff --git a/addons/crm/crm_meeting_view.xml b/addons/crm/crm_meeting_view.xml index 527f5814be4..cd0b6240d41 100644 --- a/addons/crm/crm_meeting_view.xml +++ b/addons/crm/crm_meeting_view.xml @@ -216,6 +216,7 @@ + diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py index 4063157aed9..d7d52120652 100644 --- a/addons/crm/crm_phonecall.py +++ b/addons/crm/crm_phonecall.py @@ -80,6 +80,7 @@ class crm_phonecall(crm_base, osv.osv): def create(self, cr, uid, vals, context=None): obj_id = super(crm_phonecall, self).create(cr, uid, vals, context=context) + self.open_notification(cr, uid, [obj_id], context) return obj_id def _get_default_state(self, cr, uid, context=None): @@ -94,6 +95,29 @@ class crm_phonecall(crm_base, osv.osv): 'user_id': lambda self,cr,uid,ctx: uid, 'active': 1, } + def _case_cancel_notification(self, phonecall, context=None): + phonecall[0].message_mark_done(context) + message = _("The Phonecall is cancelled.") + phonecall[0].message_append_note( _('System notification'), + message, type='notification', context=context) + + def _case_pending_notification(self, phonecall, context=None): + message = _("The Phonecall is pending.") + phonecall[0].message_append_note('' ,message) + + def done_notification(self, cr, uid, ids, context=None): + for phonecall in self.browse(cr, uid, ids): + phonecall.message_mark_done(context) + message = _("The Phonecall is done.") + self.message_append_note(cr, uid, [phonecall.id], _('System notification'), + message, type='notification', context=context) + + def open_notification(self, cr, uid, ids, context=None): + for phonecall in self.browse(cr, uid, ids): + self.message_subscribe(cr, uid, ids, [phonecall.user_id.id], context=context) + message = _("The Phonecall is open.") + self.message_append_note(cr, uid, [phonecall.id], _('System notification'),message, + type='notification', need_action_user_id=phonecall.user_id.id, context=context) # From crm.case def onchange_partner_address_id(self, cr, uid, ids, add, email=False): @@ -105,7 +129,7 @@ class crm_phonecall(crm_base, osv.osv): res['value']['partner_mobile'] = address.mobile return res - def case_close(self, cr, uid, ids, *args): + def case_close(self, cr, uid, ids, context=None): """Overrides close for crm_case for setting close date """ res = True @@ -115,23 +139,26 @@ class crm_phonecall(crm_base, osv.osv): if phone.duration <=0: duration = datetime.now() - datetime.strptime(phone.date, '%Y-%m-%d %H:%M:%S') data.update({'duration': duration.seconds/float(60)}) - res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], args) + res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], context) self.write(cr, uid, [phone_id], data) + self.done_notification(cr, uid, [phone_id], context); return res - def case_reset(self, cr, uid, ids, *args): + def case_reset(self, cr, uid, ids, context=None): """Resets case as Todo """ - res = super(crm_phonecall, self).case_reset(cr, uid, ids, args) + res = super(crm_phonecall, self).case_reset(cr, uid, ids, context) self.write(cr, uid, ids, {'duration': 0.0, 'state':'open'}) + self.open_notification(cr, uid, ids, context) return res - def case_open(self, cr, uid, ids, *args): + def case_open(self, cr, uid, ids, context=None): """Overrides cancel for crm_case for setting Open Date """ - res = super(crm_phonecall, self).case_open(cr, uid, ids, *args) + res = super(crm_phonecall, self).case_open(cr, uid, ids, context) self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')}) + self.open_notification(cr, uid, ids, context) return res def schedule_another_phonecall(self, cr, uid, ids, schedule_time, call_summary, \ diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml index 34ef2612623..6bebccdaf6f 100644 --- a/addons/crm/crm_phonecall_view.xml +++ b/addons/crm/crm_phonecall_view.xml @@ -123,6 +123,7 @@ states="cancel" type="object" icon="gtk-convert" /> + From b0d0b176abae6da2efa6c77e769cf6e05c532815 Mon Sep 17 00:00:00 2001 From: "Bhumi Thakkar (Open ERP)" Date: Tue, 6 Mar 2012 15:53:43 +0530 Subject: [PATCH 0232/1161] [IMP] on create meeting notification. bzr revid: bth@tinyerp.com-20120306102343-h32fhvuzfpuynjtl --- addons/crm/crm_meeting.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/crm/crm_meeting.py b/addons/crm/crm_meeting.py index 10635d66a6c..0261612c32d 100644 --- a/addons/crm/crm_meeting.py +++ b/addons/crm/crm_meeting.py @@ -101,6 +101,9 @@ class crm_meeting(crm_base, osv.osv): for phonecall in phonecall_obj.browse(cr, uid, [newid], context=context): phonecall.message_append_note('', message) obj.message_append_note('', message, need_action_user_id=phonecall.user_id.id) + else: + message = _("scheduled meeting on %s.") % (obj.date) + obj.message_append_note('', message, need_action_user_id=obj.user_id.id) def _case_close_notification(self, meeting, context=None): meeting[0].message_mark_done(context) From 7a316408c1f16c5b61d9245b61753e8741d88f3e Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Tue, 6 Mar 2012 16:08:04 +0530 Subject: [PATCH 0233/1161] [IMP] apply new groups on fields bzr revid: tpa@tinyerp.com-20120306103804-ffum2zffoi3xnxl3 --- addons/stock/partner_view.xml | 2 +- addons/stock/product_view.xml | 18 +-- addons/stock/res_config_view.xml | 16 +-- addons/stock/stock_view.xml | 204 +++++++++++++++---------------- 4 files changed, 120 insertions(+), 120 deletions(-) diff --git a/addons/stock/partner_view.xml b/addons/stock/partner_view.xml index 04cd0207dd3..ff55108a26d 100644 --- a/addons/stock/partner_view.xml +++ b/addons/stock/partner_view.xml @@ -12,7 +12,7 @@ - + diff --git a/addons/stock/product_view.xml b/addons/stock/product_view.xml index bded802dfe6..8cbea604b05 100644 --- a/addons/stock/product_view.xml +++ b/addons/stock/product_view.xml @@ -42,10 +42,10 @@ - - - - + + + + @@ -116,11 +116,11 @@ - + - - - + + + @@ -169,7 +169,7 @@ - + diff --git a/addons/stock/res_config_view.xml b/addons/stock/res_config_view.xml index 1e129ed2e83..46ab77e2e3d 100644 --- a/addons/stock/res_config_view.xml +++ b/addons/stock/res_config_view.xml @@ -1,7 +1,7 @@ - + Warehouse Application warehouse.configuration form @@ -10,7 +10,7 @@
- + @@ -20,7 +20,7 @@ - + @@ -30,13 +30,13 @@ - + - + @@ -46,7 +46,7 @@ - + @@ -63,12 +63,12 @@ Configure Warehouse Application ir.actions.act_window warehouse.configuration - + form form - + diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 4264a488436..de1019906db 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -22,11 +22,11 @@ action="product.product_category_action_form" id="menu_product_category_config_stock" parent="stock.menu_product_in_config_stock" sequence="0"/> + parent="stock.menu_product_in_config_stock" sequence="2" groups="base.group_stock_uom"/> @@ -42,10 +42,10 @@ - - + +