diff --git a/addons/account/board_account_view.xml b/addons/account/board_account_view.xml index 0621946938e..6738c7a7d37 100644 --- a/addons/account/board_account_view.xml +++ b/addons/account/board_account_view.xml @@ -48,10 +48,8 @@ menu - - - - + + + diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index cc22143782f..167fb0f44d2 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -661,9 +661,7 @@ true, it will allow you to hide the event alarm information without removing it. cr.execute('Update %s set base_calendar_alarm_id=%s, alarm_id=%s \ where id=%s' % (model_obj._table, \ cal_alarm.id, new_res_alarm, data.id)) - if not context.get('alarm_id', False): - self.do_alarm_unlink(cr, uid, [data.id], model) - return True + self.do_alarm_unlink(cr, uid, [data.id], model) if basic_alarm: vals = { @@ -1334,7 +1332,7 @@ true, it will allow you to hide the event alarm information without removing it. yearstring = bymonth + bystring if datas.get('end_date'): - datas['end_date'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + '235959Z' + datas['end_date'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + 'T235959Z' enddate = (datas.get('count') and (';COUNT=' + str(datas.get('count'))) or '') +\ ((datas.get('end_date') and (';UNTIL=' + datas.get('end_date'))) or '') @@ -1464,7 +1462,7 @@ true, it will allow you to hide the event alarm information without removing it. fields.append('date') for base_calendar_id, real_id in select: res = super(calendar_event, self).read(cr, uid, real_id, fields=fields, context=context, load=load) - ls = base_calendar_id2real_id(base_calendar_id, with_date=res.get('duration', 0)) + ls = base_calendar_id2real_id(base_calendar_id, with_date=res and res.get('duration', 0) or 0) if not isinstance(ls, (str, int, long)) and len(ls) >= 2: res['date'] = ls[1] res['date_deadline'] = ls[2] @@ -1502,27 +1500,23 @@ true, it will allow you to hide the event alarm information without removing it. @return: True """ res = False - for id in ids: - ls = base_calendar_id2real_id(id) - if not isinstance(ls, (str, int, long)) and len(ls) >= 2: - date_new = ls[1] - for record in self.read(cr, uid, [base_calendar_id2real_id(id)], \ - ['date', 'rrule', 'exdate']): - if record['rrule']: - exdate = (record['exdate'] and (record['exdate'] + ',') or '') + ''.join((re.compile('\d')).findall(date_new)) + 'Z' - if record['date'] == date_new: - res = self.write(cr, uid, [base_calendar_id2real_id(id)], {'exdate': exdate}) - else: - ids = map(lambda x: base_calendar_id2real_id(x), ids) - res = super(calendar_event, self).unlink(cr, uid, \ - base_calendar_id2real_id(ids)) - alarm_obj = self.pool.get('res.alarm') - alarm_obj.do_alarm_unlink(cr, uid, ids, self._name) - else: - ids = map(lambda x: base_calendar_id2real_id(x), ids) - res = super(calendar_event, self).unlink(cr, uid, ids) - alarm_obj = self.pool.get('res.alarm') - alarm_obj.do_alarm_unlink(cr, uid, ids, self._name) + for event_id in ids: + if isinstance(event_id, (int, long)): + res = super(calendar_event, self).unlink(cr, uid, event_id) + self.pool.get('res.alarm').do_alarm_unlink(cr, uid, [event_id], self._name) + continue + event_id, date_new = event_id.split('-') + event_id = [int(event_id)] + for record in self.read(cr, uid, event_id, ['date', 'rrule', 'exdate']): + if record['rrule']: + # Remove one of the recurrent event + date_new = time.strftime("%Y-%m-%d %H:%M:%S", \ + time.strptime(date_new, "%Y%m%d%H%M%S")) + exdate = (record['exdate'] and (record['exdate'] + ',') or '') + ''.join((re.compile('\d')).findall(date_new)) + 'Z' + res = self.write(cr, uid, event_id, {'exdate': exdate}) + else: + res = super(calendar_event, self).unlink(cr, uid, event_id) + self.pool.get('res.alarm').do_alarm_unlink(cr, uid, event_id, self._name) return res def create(self, cr, uid, vals, context=None): diff --git a/addons/board/board_view.xml b/addons/board/board_view.xml index a1dd41ae5ae..c7e1a37b8fa 100644 --- a/addons/board/board_view.xml +++ b/addons/board/board_view.xml @@ -3,6 +3,8 @@ + diff --git a/addons/crm/board_crm_statistical_view.xml b/addons/crm/board_crm_statistical_view.xml index 0851a32ad66..1baf673990d 100644 --- a/addons/crm/board_crm_statistical_view.xml +++ b/addons/crm/board_crm_statistical_view.xml @@ -96,11 +96,12 @@ + diff --git a/addons/crm/board_crm_view.xml b/addons/crm/board_crm_view.xml index 30caaeb5ac9..c90ecb28e03 100644 --- a/addons/crm/board_crm_view.xml +++ b/addons/crm/board_crm_view.xml @@ -89,13 +89,9 @@ menu - + - diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 8d63bc2933e..5958564669e 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -212,13 +212,10 @@ class crm_case(object): address = self.pool.get('res.partner.address').browse(cr, uid, add) return {'value': {'email_from': address.email, 'phone': address.phone}} - def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=[], context={}): + def _history(self, cr, uid, cases, keyword, history=False, emails=None, message=None, context=None): mailgate_pool = self.pool.get('mailgate.thread') return mailgate_pool._history(cr, uid, cases, keyword, history=history,\ - subject=subject, email=email, \ - details=details, email_from=email_from,\ - message_id=message_id, attach=attach, \ - context=context) + emails=emails, message=message, context=context) def case_open(self, cr, uid, ids, *args): """Opens Case @@ -360,14 +357,13 @@ class crm_case(object): src = case.email_from dest = case.section_id.reply_to body = "" - body = case.email_last or case.description + body = case.description if not destination: src, dest = dest, src if body and case.user_id.signature: body += '\n\n%s' % (case.user_id.signature) body = self.format_body(body) - dest = [dest] attach_to_send = None @@ -377,16 +373,19 @@ class crm_case(object): attach_to_send = map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send) # Send an email + subject = "Reminder: [%s] %s" % (str(case.id), case.name, ) flag = tools.email_send( src, - dest, - "Reminder: [%s] %s" % (str(case.id), case.name, ), + [dest], + subject, body, reply_to=case.section_id.reply_to, openobject_id=str(case.id), attach=attach_to_send ) - self._history(cr, uid, [case], _('Send'), history=True, email=dest, details=body, email_from=src) + emails = {'email_from': src, 'email_to': dest} + message = {'subject': subject, 'description': body, 'attach': attach_to_send} + self._history(cr, uid, [case], _('Send'), history=True, emails=emails, message=message) return True def _check(self, cr, uid, ids=False, context={}): diff --git a/addons/crm/wizard/crm_forward_to_partner.py b/addons/crm/wizard/crm_forward_to_partner.py index cf0463af66b..c67b9b4ec0f 100644 --- a/addons/crm/wizard/crm_forward_to_partner.py +++ b/addons/crm/wizard/crm_forward_to_partner.py @@ -204,19 +204,22 @@ class crm_lead_forward_to_partner(osv.osv_memory): if this.history == 'latest': msgs = msgs[:1] attachments.extend(itertools.chain(*[m.attachment_ids for m in msgs])) - + attach = [(a.datas_fname or a.name, base64.decodestring(a.datas)) for a in attachments if a.datas] + result = tools.email_send( email_from, emails, this.subject, body, openobject_id=str(case.id), - attach=[(a.datas_fname or a.name, base64.decodestring(a.datas)) for a in attachments if a.datas], + attach=attach, reply_to=case.section_id.reply_to, ) if result: - case_pool._history(cr, uid, [case], _('Forward'), history=True, email=this.email_to, subject=this.subject, details=body, email_from=email_from) + emails = {'email_from': email_from, 'email_to': this.email_to} + message = {'subject': this.subject, 'description': body , 'attach': attach} + case_pool._history(cr, uid, [case], _('Forward'), history=True, emails=emails, message=message) else: raise osv.except_osv(_('Error!'), _('Unable to send mail. Please check SMTP is configured properly.')) diff --git a/addons/crm/wizard/crm_send_email.py b/addons/crm/wizard/crm_send_email.py index e158c2177b8..bfcd201aad5 100644 --- a/addons/crm/wizard/crm_send_email.py +++ b/addons/crm/wizard/crm_send_email.py @@ -90,6 +90,7 @@ class crm_send_new_email(osv.osv_memory): ] message_id = None + ref_id = None case = case_pool.browse(cr, uid, res_id) if context.get('mail', 'new') == 'new': @@ -101,6 +102,7 @@ class crm_send_new_email(osv.osv_memory): model = hist.model model_pool = self.pool.get(model) res_id = hist.res_id + ref_id = hist.ref_id case = model_pool.browse(cr, uid, res_id) emails = [obj.email_to] email_cc = (obj.email_cc or '').split(',') @@ -128,13 +130,11 @@ class crm_send_new_email(osv.osv_memory): if not flag: raise osv.except_osv(_('Error!'), _('Unable to send mail. Please check SMTP is configured properly.')) if flag: - case_pool._history(cr, uid, [case], _('Send'), history=True, \ - email=obj.email_to, details=body, \ - subject=obj.subject, email_from=email_from, \ - message_id=message_id, attach=attach) + email_dict = {'email_from': email_from, 'email_to': obj.email_to, 'email_cc': email_cc} + message = {'subject': obj.subject, 'description': body, 'message_id': message_id, 'ref_id': ref_id , 'attach': attach} + case_pool._history(cr, uid, [case], _('Send'), history=True, emails=email_dict, message=message) if obj.state == 'unchanged': pass - elif obj.state == 'done': case_pool.case_close(cr, uid, [case.id]) elif obj.state == 'draft': case_pool.case_reset(cr, uid, [case.id]) diff --git a/addons/email_template/__init__.py b/addons/email_template/__init__.py index c959f7204da..6d99e9a4492 100644 --- a/addons/email_template/__init__.py +++ b/addons/email_template/__init__.py @@ -1,3 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009 Sharoon Thomas +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + import email_template_account import email_template import email_template_mailbox diff --git a/addons/email_template/__openerp__.py b/addons/email_template/__openerp__.py index ef50f631e3e..917df3dde70 100644 --- a/addons/email_template/__openerp__.py +++ b/addons/email_template/__openerp__.py @@ -1,7 +1,29 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009 Sharoon Thomas +# 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 . +# +############################################################################## + { "name" : "Email Template for Open ERP", "version" : "0.7 RC", - "author" : "Open ERP", + "author" : "Sharoon Thomas, Openlabs", "website" : "http://openerp.com", "category" : "Added functionality", "depends" : ['base'], diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index 0ca89a5bbb8..730502bc549 100644 --- a/addons/email_template/email_template.py +++ b/addons/email_template/email_template.py @@ -1,3 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009 Sharoon Thomas +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + import base64 import random import time @@ -41,7 +63,6 @@ import tools import report import pooler - def get_value(cursor, user, recid, message=None, template=None, context=None): """ Evaluates an expression and returns its value diff --git a/addons/email_template/email_template_account.py b/addons/email_template/email_template_account.py index 9ea1cd5b8fa..e5bbe0f5e56 100644 --- a/addons/email_template/email_template_account.py +++ b/addons/email_template/email_template_account.py @@ -1,3 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009 Sharoon Thomas +# 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 osv, fields from html2text import html2text import re diff --git a/addons/email_template/email_template_engines.py b/addons/email_template/email_template_engines.py index 2fc58310e9b..cd6aedade39 100644 --- a/addons/email_template/email_template_engines.py +++ b/addons/email_template/email_template_engines.py @@ -1,3 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009 Sharoon Thomas +# 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 . +# +############################################################################## + # To change this template, choose Tools | Templates # and open the template in the editor. from osv import fields,osv diff --git a/addons/email_template/email_template_mailbox.py b/addons/email_template/email_template_mailbox.py index b20fa9f76bf..d594a01c087 100644 --- a/addons/email_template/email_template_mailbox.py +++ b/addons/email_template/email_template_mailbox.py @@ -1,3 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009 Sharoon Thomas +# 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 osv, fields import time import email_template_engines diff --git a/addons/hr/board_hr_view.xml b/addons/hr/board_hr_view.xml index fdbd4f87d2e..873032a4067 100644 --- a/addons/hr/board_hr_view.xml +++ b/addons/hr/board_hr_view.xml @@ -32,12 +32,13 @@ menu - + + diff --git a/addons/mail_gateway/mail_gateway.py b/addons/mail_gateway/mail_gateway.py index 95b95489c6b..a75b2383e85 100644 --- a/addons/mail_gateway/mail_gateway.py +++ b/addons/mail_gateway/mail_gateway.py @@ -68,8 +68,7 @@ class mailgate_thread(osv.osv): def msg_send(self, cr, uid, id, *args, **argv): raise Exception, _('Method is not implemented') - def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, \ - email_from=False, message_id=False, references=None, attach=None, context=None): + def _history(self, cr, uid, cases, keyword, history=False, emails=None, message=None, context=None): """ @param self: The object pointer @param cr: the current row, from the database cursor, @@ -77,17 +76,18 @@ class mailgate_thread(osv.osv): @param cases: a browse record list @param keyword: Case action keyword e.g.: If case is closed "Close" keyword is used @param history: Value True/False, If True it makes entry in case History otherwise in Case Log - @param email: Email address if any - @param details: Details of case history if any - @param atach: Attachment sent in email + @param emails: Email details, e.g. emails = {'email_from': 'FROM', 'email_to': 'TO', 'email_cc': 'CC', 'email_bcc': 'BCC'} + @param message: Details of email to send, e.g. message = {'subject': 'SUBJECT', 'description': 'DESCRIPTION', 'message_id':'MESSAGE_ID', 'ref_id': 'REFERENCES' , 'attach': 'ATTACH'} @param context: A standard dictionary for contextual values""" if context is None: context = {} - if attach is None: - attach = [] - + if message is None: + message = {} + if emails is None: + emails = {} + if message.get('attach') is None: + message.update({'attach': []}) # The mailgate sends the ids of the cases and not the object list - if all(isinstance(case_id, (int, long)) for case_id in cases): cases = self.browse(cr, uid, cases, context=context) @@ -101,34 +101,40 @@ class mailgate_thread(osv.osv): 'model' : case._name, 'res_id': case.id, 'date': time.strftime('%Y-%m-%d %H:%M:%S'), - 'message_id': message_id, + 'message_id': message.get('message_id', False), } attachments = [] if history: - for att in attach: + for att in message.get('attach'): attachments.append(att_obj.create(cr, uid, {'name': att[0], 'datas': base64.encodestring(att[1])})) data = { - 'name': subject or 'History', + 'name': message.get('subject', 'History'), 'history': True, 'user_id': uid, 'model' : case._name, 'res_id': case.id, 'date': time.strftime('%Y-%m-%d %H:%M:%S'), - 'description': details or (hasattr(case, 'description') and case.description or False), - 'email_to': email or \ + 'description': message.get('description') or (hasattr(case, 'description') and case.description or False), + 'email_to': emails.get('email_to') or \ (hasattr(case, 'user_id') and case.user_id and case.user_id.address_id and \ case.user_id.address_id.email) or tools.config.get('email_from', False), - 'email_from': email_from or \ + 'email_from': emails.get('email_from') or \ (hasattr(case, 'user_id') and case.user_id and case.user_id.address_id and \ case.user_id.address_id.email) or tools.config.get('email_from', False), + 'email_cc': emails.get('email_cc', None), + 'email_bcc': emails.get('email_bcc', None), 'partner_id': hasattr(case, 'partner_id') and (case.partner_id and case.partner_id.id or False) or False, - 'references': references, - 'message_id': message_id, + 'ref_id': message.get('ref_id'), + 'message_id': message.get('message_id'), 'attachment_ids': [(6, 0, attachments)] } - obj.create(cr, uid, data, context) + obj.create(cr, uid, data, context=context) return True + + history = _history + __history = _history + mailgate_thread() class mailgate_message(osv.osv): @@ -415,15 +421,9 @@ class mailgate_tool(osv.osv_memory): # Store messages context.update({'model' : model}) if hasattr(model_pool, '_history'): - model_pool._history(cr, uid, res_ids, _('Receive'), history=True, - subject = msg.get('subject'), - email = msg.get('to'), - details = msg.get('body'), - email_from = msg.get('from'), - message_id = msg.get('message-id'), - references = msg.get('references', False), - attach = attachments.items(), - context = context) + emails = {'email_from': msg.get('from'), 'email_to': msg.get('to'), 'email_cc': msg.get('cc')} + message = {'subject': msg.get('subject'), 'description': msg.get('body'), 'message_id': msg.get('message-id'), 'ref_id': msg.get('references', False) , 'attach': attachments.items()} + model_pool._history(cr, uid, res_ids, _('Receive'), history=True, emails=emails, message=message, context = context) else: self.history(cr, uid, model, res_ids, msg, attachment_ids, context=context) self.email_forward(cr, uid, model, res_ids, msg_txt) diff --git a/addons/mrp/board_manufacturing_view.xml b/addons/mrp/board_manufacturing_view.xml index 25d124206fe..4f62030999c 100644 --- a/addons/mrp/board_manufacturing_view.xml +++ b/addons/mrp/board_manufacturing_view.xml @@ -35,17 +35,13 @@ - - + + parent="menus_dash_mrp" + sequence="1" groups="mrp.group_mrp_manager"/> diff --git a/addons/purchase/board_purchase_view.xml b/addons/purchase/board_purchase_view.xml index bdfb5663f66..b1822519cf0 100644 --- a/addons/purchase/board_purchase_view.xml +++ b/addons/purchase/board_purchase_view.xml @@ -2,11 +2,11 @@ - + name="Dashboard" + icon="terp-graph" + parent="base.next_id_73" sequence="0"/> Draft Purchases diff --git a/addons/sale/board_sale_view.xml b/addons/sale/board_sale_view.xml index 2f290ce5dd8..0e25af519b4 100644 --- a/addons/sale/board_sale_view.xml +++ b/addons/sale/board_sale_view.xml @@ -50,9 +50,8 @@ form - - - + + diff --git a/addons/stock/board_warehouse_view.xml b/addons/stock/board_warehouse_view.xml index 0c13e83cd84..5cf24cc8228 100644 --- a/addons/stock/board_warehouse_view.xml +++ b/addons/stock/board_warehouse_view.xml @@ -43,8 +43,7 @@ - - - + + \ No newline at end of file diff --git a/addons/thunderbird/partner/partner.py b/addons/thunderbird/partner/partner.py index f91a4e29737..4b0f150b3f5 100644 --- a/addons/thunderbird/partner/partner.py +++ b/addons/thunderbird/partner/partner.py @@ -94,7 +94,7 @@ class tinythunderbird_partner(osv.osv): dictcreate.update({'partner_id':partner[0]['partner_id'][0]}) create_id = case_pool.create(cr, user, dictcreate) cases=case_pool.browse(cr,user,[create_id]) - case_pool._history(cr, user, cases, _('Archive'), history=True, email=False) + case_pool._history(cr, user, cases, _('Archive'), history=True) return create_id def thunderbird_createcontact(self,cr,user,vals):