[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
This commit is contained in:
parent
739b4a584d
commit
c08e198cd2
|
@ -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({
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue