diff options
| author | rpa (Open ERP) <rpa@openerp.co.in> | 2010-03-04 15:24:42 +0530 |
|---|---|---|
| committer | rpa (Open ERP) <rpa@openerp.co.in> | 2010-03-04 15:24:42 +0530 |
| commit | c08e198cd25cf26dc9a1aff816e53384dfb2c76c (patch) | |
| tree | 42854c6dd56faba9f6e66ebf428520040ddb6250 | |
| parent | 739b4a584d2ead0f3af3176d3b97ce5f00696822 (diff) | |
[IMP]: crm(Meetings): * Changed logic of duration/End date computation form function field to onchange
* Removed timezone and priority
* Removed unrelated states
* Improved invitation+invitation accept logic
bzr revid: rpa@openerp.co.in-20100304095442-8ke1gvtr1avs6n0t
| -rw-r--r-- | addons/base_calendar/base_calendar.py | 90 | ||||
| -rw-r--r-- | addons/crm/crm_meeting.py | 28 | ||||
| -rw-r--r-- | addons/crm/crm_meeting_demo.xml | 8 | ||||
| -rw-r--r-- | addons/crm/crm_meeting_view.xml | 46 |
4 files changed, 93 insertions, 79 deletions
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 82ceb2aab70..b2ca2af3b0b 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -202,6 +202,10 @@ class invite_attendee_wizard(osv.osv_memory): to send an Email to Invited Person') } + _defaults = { + 'type': lambda *x: 'internal' + } + def do_invite(self, cr, uid, ids, context={}): datas = self.read(cr, uid, ids)[0] model = False @@ -224,12 +228,10 @@ class invite_attendee_wizard(osv.osv_memory): user_obj = self.pool.get('res.users') for user_id in datas.get('user_ids', []): user = user_obj.browse(cr, uid, user_id) - if not user.address_id.email: - raise osv.except_osv(_('Error!'), \ - ("User does not have an email Address")) vals.update({'user_id': user_id, 'email': user.address_id.email}) - mail_to.append(user.address_id.email) + if user.address_id.email: + mail_to.append(user.address_id.email) elif type == 'external' and datas.get('email'): vals.update({'email': datas['email']}) @@ -237,13 +239,11 @@ class invite_attendee_wizard(osv.osv_memory): elif type == 'partner': add_obj = self.pool.get('res.partner.address') for contact in add_obj.browse(cr, uid, datas['contact_ids']): - if not contact.email: - raise osv.except_osv(_('Error!'), \ - ("Partner does not have an email Address")) vals.update({ 'partner_address_id': contact.id, 'email': contact.email}) - mail_to.append(contact.email) + if contact.email: + mail_to.append(contact.email) if model == 'calendar.attendee': att = att_obj.browse(cr, uid, context['active_id']) @@ -256,9 +256,14 @@ class invite_attendee_wizard(osv.osv_memory): obj.write(cr, uid, res_obj.id, {model_field: [(4, att_id)]}) if datas.get('send_mail'): + if not mail_to: + name = map(lambda x: x[1], filter(lambda x: type==x[0], \ + self._columns['type'].selection)) + raise osv.except_osv(_('Error!'), ("%s must have an email \ +Address to send mail") % (name[0])) att_obj._send_mail(cr, uid, [att_id], mail_to, \ email_from=tools.config.get('email_from', False)) - + return {} @@ -268,10 +273,6 @@ class invite_attendee_wizard(osv.osv_memory): cr.execute('select id from res_partner_address \ where partner_id=%s' % (partner_id)) contacts = map(lambda x: x[0], cr.fetchall()) - if not contacts: - raise osv.except_osv(_('Error!'), \ - ("Partner does not have any Contacts")) - return {'value': {'contact_ids': contacts}} invite_attendee_wizard() @@ -398,7 +399,7 @@ request was delegated to"), 'user_id': fields.many2one('res.users', 'User'), 'partner_address_id': fields.many2one('res.partner.address', 'Contact'), 'partner_id': fields.related('partner_address_id', 'partner_id', type='many2one', relation='res.partner', string='Partner', help="Partner related to contact"), - 'email': fields.char('Email', size=124, required=True, help="Email of Invited Person"), + 'email': fields.char('Email', size=124, help="Email of Invited Person"), 'event_date': fields.function(_compute_data, method=True, string='Event Date', type="datetime", multi='event_date'), 'event_end_date': fields.function(_compute_data, method=True, string='Event End Date', type="datetime", multi='event_end_date'), 'ref': fields.reference('Event Ref', selection=_links_get, size=128), @@ -480,6 +481,17 @@ request was delegated to"), self.write(cr, uid, ids, {'state': 'tentative'}, context) def do_accept(self, cr, uid, ids, context=None, *args): + vals = self.read(cr, uid, ids, context=context)[0] + user = vals.get('user_id') + if user: + ref = vals.get('ref', None) + if ref: + model, event = ref.split(',') + model_obj = self.pool.get(model) + event_ref = model_obj.browse(cr, uid, event, context=context)[0] + if event_ref.user_id.id != user[0]: + defaults = {'user_id': user[0]} + new_event = model_obj.copy(cr, uid, event, default=defaults, context=context) self.write(cr, uid, ids, {'state': 'accepted'}, context) def do_decline(self, cr, uid, ids, context=None, *args): @@ -708,26 +720,21 @@ class calendar_event(osv.osv): 'interval': 1}) return {'value': {'rrule': rrulestr}} - def _get_duration(self, cr, uid, ids, name, arg, context): - res = {} - for event in self.browse(cr, uid, ids, context=context): - start = datetime.strptime(event.date, "%Y-%m-%d %H:%M:%S") - res[event.id] = 0 - if event.date_deadline: - end = datetime.strptime(event.date_deadline[:19], "%Y-%m-%d %H:%M:%S") - diff = end - start - duration = float(diff.days)* 24 + (float(diff.seconds) / 3600) - res[event.id] = round(duration, 2) - return res + def onchange_dates(self, cr, uid, ids, start_date, duration=False, end_date=False, context={}): + if not start_date: + return {} + start = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S") + value = {} + if end_date and not duration: + end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S") + diff = end - start + duration = float(diff.days)* 24 + (float(diff.seconds) / 3600) + value['duration'] = round(duration, 2) + elif not end_date: + end = start + timedelta(hours=duration) + value['date_deadline'] = end.strftime("%Y-%m-%d %H:%M:%S") + return {'value': value} - def _set_duration(self, cr, uid, id, name, value, arg, context): - event = self.browse(cr, uid, id, context=context) - start = datetime.strptime(event.date, "%Y-%m-%d %H:%M:%S") - end = start + timedelta(hours=value) - cr.execute("UPDATE %s set date_deadline='%s' \ - where id=%s"% (self._table, end.strftime("%Y-%m-%d %H:%M:%S"), id)) - return True - _columns = { 'id': fields.integer('ID'), 'sequence': fields.integer('Sequence'), @@ -735,8 +742,7 @@ class calendar_event(osv.osv): 'date': fields.datetime('Date'), 'date_deadline': fields.datetime('Deadline'), 'create_date': fields.datetime('Created', readonly=True), - 'duration': fields.function(_get_duration, method=True, \ - fnct_inv=_set_duration, string='Duration'), + 'duration': fields.float('Duration'), 'description': fields.text('Your action'), 'class': fields.selection([('public', 'Public'), ('private', 'Private'), \ ('confidential', 'Confidential')], 'Mark as'), @@ -757,25 +763,15 @@ rule or repeating pattern for anexception to a recurrence set"), 'base_calendar_alarm_id': fields.many2one('calendar.alarm', 'Alarm'), 'recurrent_uid': fields.integer('Recurrent ID'), 'recurrent_id': fields.datetime('Recurrent ID date'), - 'vtimezone': fields.selection(_tz_get, 'Timezone', size=64), + 'vtimezone': fields.related('user_id', 'context_tz', type='char', size=24, string='Timezone'), 'user_id': fields.many2one('res.users', 'Responsible'), } - + _defaults = { 'class': lambda *a: 'public', 'show_as': lambda *a: 'busy', } - def onchange_user_id(self, cr, uid, ids, user_id, *args, **argv): - if not user_id: - return {'value': {'vtimezone': False}} - value = {'vtimezone': False} - cr.execute('select context_tz from res_users where id=%s' % (user_id)) - timezone = cr.fetchone()[0] - if timezone: - value.update({'vtimezone': timezone.lower()}) - return {'value': value} - def modify_this(self, cr, uid, ids, defaults, context=None, *args): datas = self.read(cr, uid, ids[0], context=context) defaults.update({ diff --git a/addons/crm/crm_meeting.py b/addons/crm/crm_meeting.py index 4027c097227..ce818fa0189 100644 --- a/addons/crm/crm_meeting.py +++ b/addons/crm/crm_meeting.py @@ -41,17 +41,25 @@ class crm_meeting(osv.osv): _inherit = ["crm.case", "calendar.event"] _columns = { - 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'), 'categ_id': fields.many2one('crm.case.categ', 'Meeting Type', \ - domain="[('object_id.model', '=', 'crm.meeting')]", \ - ), - 'phonecall_id':fields.many2one ('crm.phonecall', 'Phonecall'), - 'opportunity_id':fields.many2one ('crm.opportunity', 'Opportunity'), - 'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', 'event_id', 'attendee_id', 'Attendees'), + domain="[('object_id.model', '=', 'crm.meeting')]", \ + ), + 'phonecall_id':fields.many2one ('crm.phonecall', 'Phonecall'), + 'opportunity_id':fields.many2one ('crm.opportunity', 'Opportunity'), + 'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', 'event_id', 'attendee_id', 'Attendees'), 'date_closed': fields.datetime('Closed', readonly=True), - 'date_deadline': fields.datetime('Deadline'), + 'date_deadline': fields.datetime('Deadline'), + 'state': fields.selection([('open', 'Confirmed'), + ('draft', 'Unconfirmed'), + ('cancel', 'Cancelled'), + ('done', 'Done')], 'State', \ + size=16, readonly=True) } - + + _defaults = { + 'state': lambda *a: 'draft', + } + crm_meeting() class calendar_attendee(osv.osv): @@ -74,7 +82,9 @@ class calendar_attendee(osv.osv): result[id][name] = False return result _columns = { - 'categ_id': fields.function(_compute_data, method=True, string='Event Type', type="many2one", relation="crm.case.categ", multi='categ_id'), + 'categ_id': fields.function(_compute_data, method=True, \ + string='Event Type', type="many2one", \ + relation="crm.case.categ", multi='categ_id'), } calendar_attendee() diff --git a/addons/crm/crm_meeting_demo.xml b/addons/crm/crm_meeting_demo.xml index 4eefc6c1042..a43f3e0d571 100644 --- a/addons/crm/crm_meeting_demo.xml +++ b/addons/crm/crm_meeting_demo.xml @@ -10,7 +10,6 @@ <field name="partner_address_id" ref="base.res_partner_address_wong"/> <field eval="1" name="active"/> <field name="partner_id" ref="base.res_partner_maxtor"/> - <field eval=""3"" name="priority"/> <field name="user_id" ref="base.user_root"/> <field eval=""Meeting to discuss project plan and hash out the details of implementation "" name="description"/> <field eval=""open"" name="state"/> @@ -27,7 +26,6 @@ <field eval="1" name="active"/> <field eval="7.0" name="duration"/> <field name="partner_id" ref="base.res_partner_10"/> - <field eval=""3"" name="priority"/> <field name="user_id" ref="base.user_root"/> <field eval=""draft"" name="state"/> <field name="section_id" ref="crm.section_sales_department"/> @@ -43,7 +41,6 @@ <field eval="1" name="active"/> <field eval="3.0" name="duration"/> <field name="partner_id" ref="base.res_partner_3"/> - <field eval=""1"" name="priority"/> <field name="user_id" ref="base.user_root"/> <field eval=""Meeting to discuss project plan and hash out the details of implementation "" name="description"/> <field eval=""done"" name="state"/> @@ -59,7 +56,6 @@ <field eval="1" name="active"/> <field eval="6.0" name="duration"/> <field name="partner_id" ref="base.res_partner_11"/> - <field eval=""3"" name="priority"/> <field name="user_id" ref="base.user_demo"/> <field eval=""draft"" name="state"/> <field name="section_id" ref="crm.section_sales_department"/> @@ -74,9 +70,8 @@ <field eval="1" name="active"/> <field eval="05" name="duration"/> <field name="partner_id" ref="base.res_partner_9"/> - <field eval=""3"" name="priority"/> <field name="user_id" ref="base.user_demo"/> - <field eval=""pending"" name="state"/> + <field eval=""draft"" name="state"/> <field name="section_id" ref="crm.section_sales_department"/> <field eval="time.strftime('%Y-%m-22 11:05:05')" name="date"/> <field name="categ_id" ref="crm.categ_meet2"/> @@ -89,7 +84,6 @@ <field name="partner_address_id" ref="base.res_partner_address_7"/> <field eval="1" name="active"/> <field name="partner_id" ref="base.res_partner_4"/> - <field eval=""3"" name="priority"/> <field name="user_id" ref="base.user_root"/> <field eval=""done"" name="state"/> <field name="section_id" ref="crm.section_sales_department"/> diff --git a/addons/crm/crm_meeting_view.xml b/addons/crm/crm_meeting_view.xml index 40b9f7ecef8..cff4bc09aeb 100644 --- a/addons/crm/crm_meeting_view.xml +++ b/addons/crm/crm_meeting_view.xml @@ -29,9 +29,9 @@ <field name="name" select="1" string="Summary" colspan="4" /> <field name="categ_id" widget="selection" string="Meeting Type" domain="[('object_id.model', '=', 'crm.meeting')]"/> - <field name="date" string="Start Date" required="1" /> - <field name="duration" widget="float_time" /> - <field name="date_deadline" string="End Date" required="1" /> + <field name="date" string="Start Date" required="1" on_change="onchange_dates(date,duration,False)"/> + <field name="duration" widget="float_time" on_change="onchange_dates(date,duration,False)"/> + <field name="date_deadline" string="End Date" required="1" on_change="onchange_dates(date,False,date_deadline)"/> <field name="location" /> <field name="alarm_id" string="Reminder" widget="selection" /> <group colspan="2" col="4" > @@ -59,14 +59,11 @@ on_change="onchange_partner_address_id(partner_address_id, email_from)" /> <field name="email_from"/> <separator colspan="4" string="Status and Categorization"/> - <group colspan="4" col="6"> - <field name="priority"/> - <field name="user_id" on_change="onchange_user_id(user_id)"/> + <group colspan="4" col="4"> + <field name="user_id" /> <field name="section_id" widget="selection" /> - <newline/> <field name="show_as" string="Show time as"/> <field name="class" string="Privacy"/> - <field name="vtimezone"/> <field name="recurrent_id" invisible="1" /> <field name="recurrent_uid" invisible="1" /> <field name="rrule" invisible="1" /> @@ -75,13 +72,16 @@ <field name="description" nolabel="1" colspan="4" /> <separator colspan="4"/> <group col="8" colspan="4"> - <field name="state" select="2"/> - <button name="case_close" string="Done" states="open,draft,pending" type="object" icon="gtk-close"/> - <button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward"/> - <button name="case_cancel" string="Cancel" states="draft,open,pending" type="object" icon="gtk-cancel"/> - <button name="case_pending" string="Pending" states="draft,open" type="object" icon="gtk-media-pause"/> - <button name="case_escalate" string="Escalate" states="open,draft,pending" type="object" icon="gtk-go-up"/> - <button name="case_reset" string="Reset to Draft" states="done,cancel" type="object" icon="gtk-convert"/> + <field name="state" select="2" /> + <button name="case_close" string="Done" + states="open" type="object" + icon="gtk-jump-to" /> + <button name="case_open" string="Confirm" + states="draft" type="object" + icon="gtk-go-forward" /> + <button name="case_cancel" string="Cancel" + states="draft,open" type="object" + icon="gtk-cancel" /> </group> </page> <page string="Invitation Detail"> @@ -105,6 +105,21 @@ <field name="role" select="1" /> <separator colspan="4" string="" /> <field name="state" /> + <group col="6" colspan="4"> + <field name="state" select="2" /> + <button name="do_tentative" states="needs-action,declined,accepted" + string="Uncertain" type="object" + icon="terp-crm" /> + <button name="do_accept" string="Accept" states="needs-action,tentative,declined" + type="object" icon="gtk-apply" /> + <button name="do_decline" string="Decline" states="needs-action,tentative,accepted" + type="object" icon="gtk-cancel" /> + <button + name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d" + string="Delegate" type="action" + icon="gtk-sort-descending" states="needs-action,tentative,declined,accepted" + context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}" /> + </group> </page> <page string="Other"> <field name="user_id"/> @@ -134,7 +149,6 @@ <field name="section_id" /> <field name="date" string="Meeting Date"/> <field name="categ_id"/> - <field name="priority"/> <field name="user_id"/> <field name="state"/> </tree> |
