diff --git a/addons/account_followup/__openerp__.py b/addons/account_followup/__openerp__.py index bda833d5767..3505fa3704e 100644 --- a/addons/account_followup/__openerp__.py +++ b/addons/account_followup/__openerp__.py @@ -44,7 +44,7 @@ Note that if you want to check the followup level for a given partner/account en 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', 'images': ['images/follow_ups.jpeg','images/send_followups.jpeg'], - 'depends': ['account'], + 'depends': ['account', 'mail'], 'init_xml': [], 'update_xml': [ 'security/ir.model.access.csv', diff --git a/addons/account_followup/wizard/account_followup_print.py b/addons/account_followup/wizard/account_followup_print.py index a8608c2fdd0..05fa6ee6886 100644 --- a/addons/account_followup/wizard/account_followup_print.py +++ b/addons/account_followup/wizard/account_followup_print.py @@ -205,6 +205,7 @@ class account_followup_print_all(osv.osv_memory): move_obj = self.pool.get('account.move.line') user_obj = self.pool.get('res.users') line_obj = self.pool.get('account_followup.stat') + email_message_obj = self.pool.get('email.message') if context is None: context = {} @@ -277,7 +278,7 @@ class account_followup_print_all(osv.osv_memory): msg = '' if dest: try: - tools.email_send(src, dest, sub, body) + email_message_obj.schedule_with_attach(cr, uid, src, dest, sub, body, model='account.followup.print.all') msg_sent += partner.name + '\n' except Exception, e: raise osv.except_osv('Error !', e ) diff --git a/addons/base_action_rule/__openerp__.py b/addons/base_action_rule/__openerp__.py index 018f14d83a9..33060d3c5e3 100644 --- a/addons/base_action_rule/__openerp__.py +++ b/addons/base_action_rule/__openerp__.py @@ -36,7 +36,7 @@ trigger an automatic reminder email. """, 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', - 'depends': ['base'], + 'depends': ['base', 'mail'], 'init_xml': [ 'base_action_rule_data.xml' ], diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 2a4e2c0e4e1..02e929f6a28 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -24,7 +24,7 @@ from tools.translate import _ from datetime import datetime from datetime import timedelta from tools.safe_eval import safe_eval -import pooler +import pooler import re import time import tools @@ -39,7 +39,7 @@ class base_action_rule(osv.osv): _name = 'base.action.rule' _description = 'Action Rules' - + def _state_get(self, cr, uid, context=None): """ Get State @param self: The object pointer @@ -55,7 +55,7 @@ class base_action_rule(osv.osv): @param uid: the current user’s ID for security checks, @param context: A standard dictionary for contextual values """ return [('', '')] - + def priority_get(self, cr, uid, context=None): """ Get Priority @param self: The object pointer @@ -65,57 +65,57 @@ class base_action_rule(osv.osv): return [('', '')] _columns = { - 'name': fields.char('Rule Name', size=64, required=True), - 'model_id': fields.many2one('ir.model', 'Object', required=True), - 'create_date': fields.datetime('Create Date', readonly=1), + 'name': fields.char('Rule Name', size=64, required=True), + 'model_id': fields.many2one('ir.model', 'Object', required=True), + 'create_date': fields.datetime('Create Date', readonly=1), 'active': fields.boolean('Active', help="If the active field is set to False,\ - it will allow you to hide the rule without removing it."), + it will allow you to hide the rule without removing it."), 'sequence': fields.integer('Sequence', help="Gives the sequence order \ -when displaying a list of rules."), +when displaying a list of rules."), 'trg_date_type': fields.selection([ - ('none', 'None'), - ('create', 'Creation Date'), - ('action_last', 'Last Action Date'), - ('date', 'Date'), - ('deadline', 'Deadline'), - ], 'Trigger Date', size=16), + ('none', 'None'), + ('create', 'Creation Date'), + ('action_last', 'Last Action Date'), + ('date', 'Date'), + ('deadline', 'Deadline'), + ], 'Trigger Date', size=16), 'trg_date_range': fields.integer('Delay after trigger date', \ help="Delay After Trigger Date,\ specifies you can put a negative number. If you need a delay before the \ -trigger date, like sending a reminder 15 minutes before a meeting."), +trigger date, like sending a reminder 15 minutes before a meeting."), 'trg_date_range_type': fields.selection([('minutes', 'Minutes'), ('hour', 'Hours'), \ - ('day', 'Days'), ('month', 'Months')], 'Delay type'), - 'trg_user_id': fields.many2one('res.users', 'Responsible'), - 'trg_partner_id': fields.many2one('res.partner', 'Partner'), - 'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'), - 'trg_state_from': fields.selection(_state_get, 'State', size=16), - 'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16), + ('day', 'Days'), ('month', 'Months')], 'Delay type'), + 'trg_user_id': fields.many2one('res.users', 'Responsible'), + 'trg_partner_id': fields.many2one('res.partner', 'Partner'), + 'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'), + 'trg_state_from': fields.selection(_state_get, 'State', size=16), + 'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16), - 'act_method': fields.char('Call Object Method', size=64), - 'act_user_id': fields.many2one('res.users', 'Set Responsible to'), - 'act_state': fields.selection(_state_get, 'Set State to', size=16), + 'act_method': fields.char('Call Object Method', size=64), + 'act_user_id': fields.many2one('res.users', 'Set Responsible to'), + 'act_state': fields.selection(_state_get, 'Set State to', size=16), 'act_email_cc': fields.char('Add Watchers (Cc)', size=250, help="\ These people will receive a copy of the future communication between partner \ -and users by email"), +and users by email"), 'act_remind_partner': fields.boolean('Remind Partner', help="Check \ -this if you want the rule to send a reminder by email to the partner."), +this if you want the rule to send a reminder by email to the partner."), 'act_remind_user': fields.boolean('Remind Responsible', help="Check \ -this if you want the rule to send a reminder by email to the user."), - 'act_reply_to': fields.char('Reply-To', size=64), - 'act_remind_attach': fields.boolean('Remind with Attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."), +this if you want the rule to send a reminder by email to the user."), + 'act_reply_to': fields.char('Reply-To', size=64), + 'act_remind_attach': fields.boolean('Remind with Attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."), 'act_mail_to_user': fields.boolean('Mail to Responsible', help="Check\ - this if you want the rule to send an email to the responsible person."), - 'act_mail_to_watchers': fields.boolean('Mail to Watchers (CC)', + this if you want the rule to send an email to the responsible person."), + 'act_mail_to_watchers': fields.boolean('Mail to Watchers (CC)', help="Check this if you want \ -the rule to mark CC(mail to any other person defined in actions)."), +the rule to mark CC(mail to any other person defined in actions)."), 'act_mail_to_email': fields.char('Mail to these Emails', size=128, \ - help="Email-id of the persons whom mail is to be sent"), - 'act_mail_body': fields.text('Mail body', help="Content of mail"), + help="Email-id of the persons whom mail is to be sent"), + 'act_mail_body': fields.text('Mail body', help="Content of mail"), 'regex_name': fields.char('Regex on Resource Name', size=128, help="Regular expression for matching name of the resource\ \ne.g.: 'urgent.*' will search for records having name starting with the string 'urgent'\ -\nNote: This is case sensitive search."), - 'server_action_id': fields.many2one('ir.actions.server', 'Server Action', help="Describes the action name.\neg:on which object which action to be taken on basis of which condition"), - 'filter_id':fields.many2one('ir.filters', 'Filter', required=False), +\nNote: This is case sensitive search."), + 'server_action_id': fields.many2one('ir.actions.server', 'Server Action', help="Describes the action name.\neg:on which object which action to be taken on basis of which condition"), + 'filter_id':fields.many2one('ir.filters', 'Filter', required=False), 'act_email_from' : fields.char('Email From', size=64, required=False, help="Use a python expression to specify the right field on which one than we will use for the 'From' field of the header"), 'act_email_to' : fields.char('Email To', size=64, required=False, @@ -124,17 +124,17 @@ the rule to mark CC(mail to any other person defined in actions)."), } _defaults = { - 'active': lambda *a: True, - 'trg_date_type': lambda *a: 'none', - 'trg_date_range_type': lambda *a: 'day', - 'act_mail_to_user': lambda *a: 0, - 'act_remind_partner': lambda *a: 0, - 'act_remind_user': lambda *a: 0, - 'act_mail_to_watchers': lambda *a: 0, + 'active': lambda *a: True, + 'trg_date_type': lambda *a: 'none', + 'trg_date_range_type': lambda *a: 'day', + 'act_mail_to_user': lambda *a: 0, + 'act_remind_partner': lambda *a: 0, + 'act_remind_user': lambda *a: 0, + 'act_mail_to_watchers': lambda *a: 0, } - + _order = 'sequence' - + def onchange_model_id(self, cr, uid, ids, name): #This is not a good solution as it will affect the domain only on onchange res = {'domain':{'filter_id':[]}} @@ -174,7 +174,7 @@ the rule to mark CC(mail to any other person defined in actions)."), self.pre_action(cr, uid, [new_id], model, context=context) return new_id return make_call_old - + def _write(self, old_write, model, context=None): if context is None: context = {} @@ -202,9 +202,9 @@ the rule to mark CC(mail to any other person defined in actions)."), return True def create(self, cr, uid, vals, context=None): res_id = super(base_action_rule, self).create(cr, uid, vals, context=context) - self._register_hook(cr, uid, [res_id], context=context) + self._register_hook(cr, uid, [res_id], context=context) return res_id - + def write(self, cr, uid, ids, vals, context=None): res = super(base_action_rule, self).write(cr, uid, ids, vals, context=context) self._register_hook(cr, uid, ids, context=context) @@ -272,18 +272,18 @@ the rule to mark CC(mail to any other person defined in actions)."), @param self: The object pointer """ data = { - 'object_id': obj.id, - 'object_subject': hasattr(obj, 'name') and obj.name or False, - 'object_date': hasattr(obj, 'date') and obj.date or False, - 'object_description': hasattr(obj, 'description') and obj.description or False, - 'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/', + 'object_id': obj.id, + 'object_subject': hasattr(obj, 'name') and obj.name or False, + 'object_date': hasattr(obj, 'date') and obj.date or False, + 'object_description': hasattr(obj, 'description') and obj.description or False, + 'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/', 'object_user_email': hasattr(obj, 'user_id') and (obj.user_id and \ - obj.user_id.address_id and obj.user_id.address_id.email) or '/', + obj.user_id.address_id and obj.user_id.address_id.email) or '/', 'object_user_phone': hasattr(obj, 'user_id') and (obj.user_id and\ - obj.user_id.address_id and obj.user_id.address_id.phone) or '/', - 'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/', + obj.user_id.address_id and obj.user_id.address_id.phone) or '/', + 'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/', 'partner_email': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and\ - obj.partner_address_id.email) or '/', + obj.partner_address_id.email) or '/', } return self.format_body(body % data) @@ -302,6 +302,7 @@ the rule to mark CC(mail to any other person defined in actions)."), if context is None: context = {} + email_message_obj = self.pool.get('email.message') body = self.format_mail(obj, body) if not emailfrom: if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.address_id and\ @@ -312,9 +313,9 @@ the rule to mark CC(mail to any other person defined in actions)."), emailfrom = tools.ustr(emailfrom) reply_to = emailfrom if not emailfrom: - raise osv.except_osv(_('Error!'), + raise osv.except_osv(_('Error!'), _("No E-Mail ID Found for your Company address!")) - return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id)) + return email_message_obj.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, openobject_id=str(obj.id)) def do_check(self, cr, uid, action, obj, context=None): @@ -325,7 +326,7 @@ the rule to mark CC(mail to any other person defined in actions)."), @param context: A standard dictionary for contextual values """ if context is None: context = {} - ok = True + ok = True if action.filter_id: if action.model_id.model == action.filter_id.model_id: context.update(eval(action.filter_id.context)) @@ -480,15 +481,15 @@ the rule to mark CC(mail to any other person defined in actions)."), return True _constraints = [ - (_check_mail, 'Error: The mail is not well formated', ['act_mail_body']), + (_check_mail, 'Error: The mail is not well formated', ['act_mail_body']), ] base_action_rule() class ir_cron(osv.osv): - _inherit = 'ir.cron' - + _inherit = 'ir.cron' + def _poolJobs(self, db_name, check=False): try: db = pooler.get_db(db_name) diff --git a/addons/base_calendar/__openerp__.py b/addons/base_calendar/__openerp__.py index 5688c0e05b5..7efca0f4f23 100644 --- a/addons/base_calendar/__openerp__.py +++ b/addons/base_calendar/__openerp__.py @@ -1,11 +1,57 @@ +# -*- 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 . +# +############################################################################## + { - "name": "Base calendar", - "version": "2.0", - "depends": ['base'], - "js": [ - 'static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.js', - 'static/src/js/calendar.js' + "name" : "Basic Calendar Functionality", + "version" : "1.0", + "depends" : ["base", "mail"], + 'description': """ +This is a full-featured calendar system. +======================================== + +It supports: + - Calendar of events + - Alerts (create requests) + - Recurring events + - Invitations to people""", + "author" : "OpenERP SA", + 'category': 'Tools', + 'website': 'http://www.openerp.com', + "init_xml" : [ + 'base_calendar_data.xml' ], - "css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css'], - 'active': True + "demo_xml" : [], + "update_xml" : [ + 'security/calendar_security.xml', + 'security/ir.model.access.csv', + 'wizard/calendar_event_edit_all_view.xml', + 'wizard/base_calendar_invite_attendee_view.xml', + 'wizard/base_calendar_set_exrule_view.xml', + 'base_calendar_view.xml' + ], + "test" : ['test/base_calendar_test.yml'], + "installable" : True, + "active" : False, + "certificate" : "00694071962960352821", + 'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',], } + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 9693a0d5c0f..d49594f4a60 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -411,7 +411,7 @@ property or property parameter."), cal = vobject.iCalendar() event = cal.add('vevent') if not event_obj.date_deadline or not event_obj.date: - raise osv.except_osv(_('Warning !'),_("Couldn't Invite because date is not specified!")) + raise osv.except_osv(_('Warning !'),_("Couldn't Invite because date is not specified!")) event.add('created').value = ics_datetime(time.strftime('%Y-%m-%d %H:%M:%S')) event.add('dtstart').value = ics_datetime(event_obj.date) event.add('dtend').value = ics_datetime(event_obj.date_deadline) @@ -456,7 +456,7 @@ property or property parameter."), trigger.value = delta # Compute other details valarm.add('DESCRIPTION').value = alarm_data['name'] or 'OpenERP' - + for attendee in event_obj.attendee_ids: attendee_add = event.add('attendee') attendee_add.params['CUTYPE'] = [str(attendee.cutype)] @@ -480,6 +480,7 @@ property or property parameter."), context = {} company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name + email_message_obj = self.pool.get('email.message') for att in self.browse(cr, uid, ids, context=context): sign = att.sent_by_uid and att.sent_by_uid.signature or '' sign = '
'.join(sign and sign.split('\n') or []) @@ -506,11 +507,12 @@ property or property parameter."), body = html_invitation % body_vals if mail_to and email_from: attach = self.get_ics_file(cr, uid, res_obj, context=context) - tools.email_send( + email_message_obj.schedule_with_attach(cr, uid, email_from, mail_to, sub, body, + model='calendar.attendee', attach=attach and [('invitation.ics', attach)] or None, subtype='html', reply_to=email_from @@ -674,7 +676,7 @@ true, it will allow you to hide the event alarm information without removing it. new_res_alarm = alarm_ids[0] cr.execute('UPDATE %s ' % model_obj._table + \ ' SET base_calendar_alarm_id=%s, alarm_id=%s ' \ - ' WHERE id=%s', + ' WHERE id=%s', (cal_alarm.id, new_res_alarm, data.id)) self.do_alarm_unlink(cr, uid, [data.id], model) @@ -809,6 +811,7 @@ class calendar_alarm(osv.osv): return True # XXX FIXME REMOVE THIS AFTER FIXING get_recurrent_dates!! if context is None: context = {} + email_message_obj = self.pool.get('email.message') current_datetime = datetime.now() request_obj = self.pool.get('res.request') alarm_ids = self.search(cr, uid, [('state', '!=', 'done')], context=context) @@ -890,11 +893,12 @@ From: for att in alarm.attendee_ids: mail_to.append(att.user_id.address_id.email) if mail_to: - tools.email_send( + email_message_obj.schedule_with_attach(cr, uid, tools.config.get('email_from', False), mail_to, sub, - body + body, + model='calendar.alarm' ) if next_trigger_date: update_vals.update({'trigger_date': next_trigger_date}) @@ -966,7 +970,7 @@ class calendar_event(osv.osv): value['date_deadline'] = end.strftime("%Y-%m-%d %H:%M:%S") elif end_date and duration and not allday: # we have both, keep them synchronized: - # set duration based on end_date (arbitrary decision: this avoid + # set duration based on end_date (arbitrary decision: this avoid # getting dates like 06:31:48 instead of 06:32:00) end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S") diff = end - start @@ -1130,7 +1134,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=-1SU'), 'rrule_type': fields.selection([('none', ''), ('daily', 'Daily'), \ ('weekly', 'Weekly'), ('monthly', 'Monthly'), \ - ('yearly', 'Yearly'),], + ('yearly', 'Yearly'),], 'Recurrency', states={'done': [('readonly', True)]}, help="Let the event automatically repeat at that interval"), 'alarm_id': fields.many2one('res.alarm', 'Alarm', states={'done': [('readonly', True)]}, @@ -1148,7 +1152,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ ('weekly', 'Weeks'), ('monthly', 'Months'), ('yearly', 'Years'), ], 'Frequency'), - + 'end_type' : fields.selection([('forever', 'Forever'), ('count', 'Fix amout of times'), ('end_date','End date')], 'Way to end reccurency'), 'interval': fields.integer('Repeat every', help="Repeat every (Days/Week/Month/Year)"), 'count': fields.integer('Repeat', help="Repeat x times"), @@ -1159,7 +1163,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ 'fr': fields.boolean('Fri'), 'sa': fields.boolean('Sat'), 'su': fields.boolean('Sun'), - 'select1': fields.selection([('date', 'Date of month'), + 'select1': fields.selection([('date', 'Date of month'), ('day', 'Day of month')], 'Option'), 'day': fields.integer('Date of month'), 'week_list': fields.selection([('MO', 'Monday'), ('TU', 'Tuesday'), \ @@ -1176,8 +1180,8 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ 'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}), 'active': fields.boolean('Active', help="If the active field is set to \ true, it will allow you to hide the event alarm information without removing it."), - 'recurrency': fields.boolean('Recurrent', help="Recurrent Meeting"), - 'edit_all': fields.boolean('Edit All', help="Edit all Occurrences of recurrent Meeting."), + 'recurrency': fields.boolean('Recurrent', help="Recurrent Meeting"), + 'edit_all': fields.boolean('Edit All', help="Edit all Occurrences of recurrent Meeting."), } def default_organizer(self, cr, uid, context=None): user_pool = self.pool.get('res.users') @@ -1204,12 +1208,12 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ def onchange_edit_all(self, cr, uid, ids, rrule_type,edit_all, context=None): if not context: context = {} - + value = {} if edit_all and rrule_type: for id in ids: base_calendar_id2real_id(id) - return value + return value def modify_all(self, cr, uid, event_ids, defaults, context=None, *args): """ @@ -1342,7 +1346,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ freq=datas.get('rrule_type') if freq == 'none': return '' - + interval_srting = datas.get('interval') and (';INTERVAL=' + str(datas.get('interval'))) or '' if freq == 'weekly': @@ -1358,7 +1362,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ elif datas.get('select1')=='date': monthstring = ';BYMONTHDAY=' + str(datas.get('day')) - + if datas.get('end_date'): datas['end_date'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + 'T235959Z' enddate = (datas.get('count') and (';COUNT=' + str(datas.get('count'))) or '') +\ @@ -1403,7 +1407,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ res = self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit) return res - + def get_edit_all(self, cr, uid, id, vals=None): """ @@ -1414,10 +1418,10 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ if(vals and 'edit_all' in vals): #we jsut check edit_all return vals['edit_all'] else: #it's a recurrent event and edit_all is already check - return meeting['recurrency'] and meeting['edit_all'] + return meeting['recurrency'] and meeting['edit_all'] + - def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True): """ @@ -1440,12 +1444,12 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ res = False for event_id in select: real_event_id = base_calendar_id2real_id(event_id) - + if(self.get_edit_all(cr, uid, event_id, vals=vals)): event_id = real_event_id - - + + if len(str(event_id).split('-')) > 1: data = self.read(cr, uid, event_id, ['date', 'date_deadline', \ 'rrule', 'duration', 'exdate']) @@ -1459,15 +1463,15 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ 'edit_all': False, 'recurrency' : False, }) - + new_id = self.copy(cr, uid, real_event_id, default=data, context=context) - + date_new = event_id.split('-')[1] date_new = time.strftime("%Y%m%dT%H%M%S", \ time.strptime(date_new, "%Y%m%d%H%M%S")) exdate = (data['exdate'] and (data['exdate'] + ',') or '') + date_new res = self.write(cr, uid, [real_event_id], {'exdate': exdate}) - + context.update({'active_id': new_id, 'active_ids': [new_id]}) continue if not real_event_id in new_ids: @@ -1590,10 +1594,10 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\ res = False for event_datas in self.read(cr, uid, ids, ['date', 'rrule', 'exdate'], context=context): event_id = event_datas['id'] - + if self.get_edit_all(cr, uid, event_id, vals=None): event_id = base_calendar_id2real_id(event_id) - + if isinstance(event_id, (int, long)): res = super(calendar_event, self).unlink(cr, uid, event_id, context=context) self.pool.get('res.alarm').do_alarm_unlink(cr, uid, [event_id], self._name) @@ -1711,7 +1715,7 @@ class calendar_todo(osv.osv): @param args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...]. @param context: A standard dictionary for contextual values """ - + assert name == 'date' return self.write(cr, uid, id, { 'date_start': value }, context=context) @@ -1743,9 +1747,9 @@ class ir_attachment(osv.osv): for arg in args: args1.append(map(lambda x:str(x).split('-')[0], arg)) return super(ir_attachment, self).search_count(cr, user, args1, context) - - - + + + def create(self, cr, uid, vals, context=None): if context: id = context.get('default_res_id', False) diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 903bf5f0b68..caf040b31c5 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -57,7 +57,7 @@ Creates a dashboard for CRM that includes: 'base', 'base_action_rule', 'process', - 'mail_gateway', + 'mail', 'base_calendar', 'resource', 'board' @@ -84,7 +84,7 @@ Creates a dashboard for CRM that includes: 'wizard/crm_opportunity_to_phonecall_view.xml', 'wizard/crm_partner_to_opportunity_view.xml', - 'wizard/crm_send_email_view.xml', +# 'wizard/crm_send_email_view.xml', 'wizard/crm_add_note_view.xml', 'wizard/crm_merge_opportunities_view.xml', diff --git a/addons/crm/crm.py b/addons/crm/crm.py index f25e4c1a0bf..f6b3a20c138 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -308,8 +308,8 @@ class crm_case(object): return {'value': {'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=None): - mailgate_pool = self.pool.get('mailgate.thread') - return mailgate_pool.history(cr, uid, cases, keyword, history=history,\ + thread_pool = self.pool.get('email.thread') + return thread_pool.history(cr, uid, cases, keyword, history=history,\ subject=subject, email=email, \ details=details, email_from=email_from,\ message_id=message_id, attach=attach, \ @@ -452,12 +452,13 @@ class crm_case(object): @param ids: List of case's IDs to remind @param context: A standard dictionary for contextual values """ + email_message_obj = self.pool.get('email.message') for case in self.browse(cr, uid, ids, context=context): if not destination and not case.email_from: raise osv.except_osv(_('Error!'), ("Partner Email is not specified in Case")) if not case.user_id.user_email: raise osv.except_osv(_('Error!'), ("User Email is not specified in Case")) - + if destination and case.section_id.user_id: case_email = case.section_id.user_id.user_email else: @@ -485,19 +486,19 @@ class crm_case(object): attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname', 'datas']) 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,) - tools.email_send( + # Send an email + subject = "Reminder: [%s] %s" % (str(case.id), case.name, ) + email_message_obj.schedule_with_attach(cr, uid, src, [dest], subject, body, - reply_to=case.section_id.reply_to or '', + model='crm.case', + reply_to=case.section_id.reply_to, openobject_id=str(case.id), attach=attach_to_send ) self._history(cr, uid, [case], _('Send'), history=True, subject=subject, email=dest, details=body, email_from=src) - return True def _check(self, cr, uid, ids=False, context=None): @@ -537,7 +538,7 @@ class crm_case(object): def format_mail(self, obj, body): return self.pool.get('base.action.rule').format_mail(obj, body) - def message_followers(self, cr, uid, ids, context=None): + def thread_followers(self, cr, uid, ids, context=None): """ Get a list of emails of the people following this thread """ res = {} diff --git a/addons/crm/crm_action_rule.py b/addons/crm/crm_action_rule.py index 477f9132fab..acb7801c7c9 100644 --- a/addons/crm/crm_action_rule.py +++ b/addons/crm/crm_action_rule.py @@ -37,25 +37,26 @@ class base_action_rule(osv.osv): """ Base Action Rule """ _inherit = 'base.action.rule' _description = 'Action Rules' - + _columns = { - 'trg_section_id': fields.many2one('crm.case.section', 'Sales Team'), - 'trg_max_history': fields.integer('Maximum Communication History'), - 'trg_categ_id': fields.many2one('crm.case.categ', 'Category'), - 'regex_history' : fields.char('Regular Expression on Case History', size=128), - 'act_section_id': fields.many2one('crm.case.section', 'Set Team to'), - 'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'), + 'trg_section_id': fields.many2one('crm.case.section', 'Sales Team'), + 'trg_max_history': fields.integer('Maximum Communication History'), + 'trg_categ_id': fields.many2one('crm.case.categ', 'Category'), + 'regex_history' : fields.char('Regular Expression on Case History', size=128), + 'act_section_id': fields.many2one('crm.case.section', 'Set Team to'), + 'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'), 'act_mail_to_partner': fields.boolean('Mail to Partner', help="Check \ -this if you want the rule to send an email to the partner."), +this if you want the rule to send an email to the partner."), } - + def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from', False), context=None): + email_message_obj = self.pool.get('email.message') body = self.format_mail(obj, body) if not emailfrom: if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.address_id and obj.user_id.address_id.email: emailfrom = obj.user_id.address_id.email - + name = '[%d] %s' % (obj.id, tools.ustr(obj.name)) emailfrom = tools.ustr(emailfrom) if hasattr(obj, 'section_id') and obj.section_id and obj.section_id.reply_to: @@ -63,10 +64,10 @@ this if you want the rule to send an email to the partner."), else: reply_to = emailfrom if not emailfrom: - raise osv.except_osv(_('Error!'), + raise osv.except_osv(_('Error!'), _("No E-Mail ID Found for your Company address!")) - return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id)) - + return email_message_obj.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, openobject_id=str(obj.id)) + def do_check(self, cr, uid, action, obj, context=None): """ @param self: The object pointer @param cr: the current row, from the database cursor, @@ -79,7 +80,7 @@ this if you want the rule to send an email to the partner."), if hasattr(obj, 'categ_id'): ok = ok and (not action.trg_categ_id or action.trg_categ_id.id==obj.categ_id.id) - #Cheking for history + #Cheking for history regex = action.regex_history result_history = True if regex: @@ -109,7 +110,7 @@ this if you want the rule to send an email to the partner."), @param context: A standard dictionary for contextual values """ res = super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=context) write = {} - + if hasattr(action, 'act_section_id') and action.act_section_id: obj.section_id = action.act_section_id write['section_id'] = action.act_section_id.id diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index fb3a8f5e223..febab3ac2a2 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -40,7 +40,7 @@ class crm_lead(crm_case, osv.osv): _name = "crm.lead" _description = "Lead/Opportunity" _order = "date_action, priority, id desc" - _inherit = ['mailgate.thread','res.partner.address'] + _inherit = ['email.thread','res.partner.address'] def _compute_day(self, cr, uid, ids, fields, args, context=None): """ @param cr: the current row, from the database cursor, @@ -169,8 +169,7 @@ class crm_lead(crm_case, osv.osv): \nIf the case is in progress the state is set to \'Open\'.\ \nWhen the case is over, the state is set to \'Done\'.\ \nIf the case needs to be reviewed then the state is set to \'Pending\'.'), - 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]), - 'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', method=True, type='char', size=64), + 'message_ids': fields.one2many('email.message', 'res_id', 'Messages', domain=[('model','=',_name)]), } @@ -336,8 +335,9 @@ class crm_lead(crm_case, osv.osv): @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 msg: dictionary object to contain email message data """ - mailgate_pool = self.pool.get('email.server.tools') + thread_pool = self.pool.get('email.thread') subject = msg.get('subject') body = msg.get('body') @@ -354,26 +354,13 @@ class crm_lead(crm_case, osv.osv): if msg.get('priority', False): vals['priority'] = priority - res = mailgate_pool.get_partner(cr, uid, msg.get('from') or msg.get_unixfrom()) + res = thread_pool.get_partner(cr, uid, msg.get('from', False)) if res: vals.update(res) - res = self.create(cr, uid, vals, context) - attachents = msg.get('attachments', []) - for attactment in attachents or []: - data_attach = { - 'name': attactment, - 'datas':binascii.b2a_base64(str(attachents.get(attactment))), - 'datas_fname': attactment, - 'description': 'Mail attachment', - 'res_model': self._name, - 'res_id': res, - } - self.pool.get('ir.attachment').create(cr, uid, data_attach) + return self.create(cr, uid, vals, context) - return res - - def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context=None): + def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None): """ @param self: The object pointer @param cr: the current row, from the database cursor, @@ -410,18 +397,6 @@ class crm_lead(crm_case, osv.osv): res = self.write(cr, uid, [case.id], values, context=context) return res - def msg_send(self, cr, uid, id, *args, **argv): - - """ Send The Message - @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 email’s IDs - @param *args: Return Tuple Value - @param **args: Return Dictionary of Keyword Value - """ - return True - def on_change_optin(self, cr, uid, ids, optin): return {'value':{'optin':optin,'optout':False}} diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 55be89c2252..6d3c8726d78 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -105,10 +105,11 @@ - + + + + + + + + + + + + + + + + + + +