|
- Net Total:
+ Net Total:
|
[[ formatLang(o.amount_untaxed) ]]
@@ -418,7 +418,7 @@
|
- Taxes:
+ Taxes:
|
[[ formatLang(o.amount_tax) ]]
diff --git a/addons/account_voucher/voucher.py b/addons/account_voucher/voucher.py
index 13df5a496fc..47ff58a3226 100644
--- a/addons/account_voucher/voucher.py
+++ b/addons/account_voucher/voucher.py
@@ -428,15 +428,17 @@ class account_voucher_line(osv.osv):
'type': lambda *a: 'cr'
}
- def onchange_partner(self, cr, uid, ids, partner_id, ttype ,type1):
- vals = {}
+ def onchange_partner(self, cr, uid, ids, partner_id, ttype ,type1, currency):
+ currency_pool = self.pool.get('res.currency')
+ company = self.pool.get('res.users').browse(cr, uid, uid).company_id
+
+ vals = {
+ 'account_id': False,
+ 'type': False ,
+ 'amount': False
+ }
if not partner_id:
- vals.update({
- 'account_id': False,
- 'type': False ,
- 'amount': False
- })
return {
'value' : vals
}
@@ -466,6 +468,9 @@ class account_voucher_line(osv.osv):
balance = partner.debit
ttype = 'cr'
+ if company.currency_id != currency:
+ balance = currency_pool.compute(cr, uid, company.currency_id.id, currency, balance)
+
vals.update({
'account_id': account_id,
'type': ttype,
diff --git a/addons/account_voucher/voucher_view.xml b/addons/account_voucher/voucher_view.xml
index 658b8f8429b..1a781c4cc34 100644
--- a/addons/account_voucher/voucher_view.xml
+++ b/addons/account_voucher/voucher_view.xml
@@ -37,7 +37,7 @@
-
+
diff --git a/addons/account_voucher_payment/account_voucher_payment_view.xml b/addons/account_voucher_payment/account_voucher_payment_view.xml
index cc11d3a064c..3f118120c8a 100755
--- a/addons/account_voucher_payment/account_voucher_payment_view.xml
+++ b/addons/account_voucher_payment/account_voucher_payment_view.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index f66cd0ca463..a8cdba58975 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -383,7 +383,7 @@ property or property parameter."),
'rsvp': True,
'cutype': 'individual',
}
-
+
def copy(self, cr, uid, id, default=None, context=None):
raise osv.except_osv(_('Warning!'), _('Can not Duplicate'))
@@ -419,10 +419,14 @@ property or property parameter."),
event.add('location').value = event_obj.location
if event_obj.rrule:
event.add('rrule').value = event_obj.rrule
- if event_obj.user_id:
+ if event_obj.user_id or event_obj.organizer_id:
event_org = event.add('organizer')
- event_org.params['CN'] = [event_obj.user_id.name]
- event_org.value = 'MAILTO:' + (event_obj.user_id.user_email or event_obj.user_id.name)
+ organizer = event_obj.organizer_id
+ if not organizer:
+ organizer = event_obj.user_id
+ event_org.params['CN'] = [organizer.name]
+ event_org.value = 'MAILTO:' + (organizer.user_email or organizer.name)
+
if event_obj.alarm_id:
# computes alarm data
valarm = event.add('valarm')
@@ -455,14 +459,14 @@ property or property parameter."),
attendee_add.value = 'MAILTO:' + (attendee.email or '')
res = cal.serialize()
return res
-
+
def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None):
"""
- Send mail for event invitation to event attendees.
+ Send mail for event invitation to event attendees.
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of attendee’s IDs.
- @param email_from: Email address for user sending the mail
+ @param email_from: Email address for user sending the mail
@param context: A standard dictionary for contextual values
@return: True
"""
@@ -474,7 +478,7 @@ property or property parameter."),
sign = att.sent_by_uid and att.sent_by_uid.signature or ''
sign = ' '.join(sign and sign.split('\n') or [])
res_obj = att.ref
- sub = '[%s Invitation][%d] %s' % (company, att.id, res_obj.name)
+ sub = res_obj.name
att_infos = []
other_invitaion_ids = self.search(cr, uid, [('ref', '=', res_obj._name + ',' + str(res_obj.id))])
for att2 in self.browse(cr, uid, other_invitaion_ids):
@@ -495,12 +499,12 @@ property or property parameter."),
if mail_to and email_from:
attach = self.get_ics_file(cr, uid, res_obj, context=context)
tools.email_send(
- email_from,
- mail_to,
- sub,
- body,
- attach=attach and [('invitation.ics', attach)] or None,
- subtype='html',
+ email_from,
+ mail_to,
+ sub,
+ body,
+ attach=attach and [('invitation.ics', attach)] or None,
+ subtype='html',
reply_to=email_from
)
return True
@@ -528,31 +532,28 @@ property or property parameter."),
@param uid: the current user’s ID for security checks,
@param ids: List of calendar attendee’s IDs
@param *args: Get Tupple value
- @param context: A standard dictionary for contextual values
+ @param context: A standard dictionary for contextual values
"""
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
def do_accept(self, cr, uid, ids, context=None, *args):
"""
- Update state of invitation as Accepted and
+ Update state of invitation as Accepted and
if the invited user is other then event user it will make a copy of this event for invited user
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of calendar attendee’s IDs.
- @param context: A standard dictionary for contextual values
+ @param context: A standard dictionary for contextual values
@return: True
"""
if not context:
context = {}
for vals in self.browse(cr, uid, ids, context=context):
- #user = vals.user_id
- #if user:
- # mod_obj = self.pool.get(vals.ref._name)
- # if vals.ref:
- # if vals.ref.user_id.id != user.id:
- # defaults = {'user_id': user.id}
- # new_event = mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
+ if vals.ref and vals.ref.user_id:
+ mod_obj = self.pool.get(vals.ref._name)
+ defaults = {'user_id': vals.user_id.id, 'organizer_id': vals.ref.user_id.id}
+ new_event = mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
self.write(cr, uid, vals.id, {'state': 'accepted'}, context)
return True
@@ -565,7 +566,8 @@ property or property parameter."),
@param ids: List of calendar attendee’s IDs
@param *args: Get Tupple value
@param context: A standard dictionary for contextual values """
-
+ if not context:
+ context = {}
return self.write(cr, uid, ids, {'state': 'declined'}, context)
def create(self, cr, uid, vals, context=None):
@@ -585,7 +587,6 @@ property or property parameter."),
vals['cn'] = vals.get("cn")
res = super(calendar_attendee, self).create(cr, uid, vals, context)
return res
-
calendar_attendee()
class res_alarm(osv.osv):
@@ -654,9 +655,9 @@ true, it will allow you to hide the event alarm information without removing it.
alarm_ids = res_alarm_obj.search(cr, uid, domain, context=context)
if not alarm_ids:
val = {
- 'trigger_duration': duration,
- 'trigger_interval': interval,
- 'trigger_occurs': occurs,
+ 'trigger_duration': duration,
+ 'trigger_interval': interval,
+ 'trigger_occurs': occurs,
'trigger_related': related,
'name': str(duration) + ' ' + str(interval) + ' ' + str(occurs)
}
@@ -724,35 +725,35 @@ class calendar_alarm(osv.osv):
__attribute__ = {}
_columns = {
- 'alarm_id': fields.many2one('res.alarm', 'Basic Alarm', ondelete='cascade'),
+ 'alarm_id': fields.many2one('res.alarm', 'Basic Alarm', ondelete='cascade'),
'name': fields.char('Summary', size=124, help="""Contains the text to be \
used as the message subject for email \
- or contains the text to be used for display"""),
+ or contains the text to be used for display"""),
'action': fields.selection([('audio', 'Audio'), ('display', 'Display'), \
('procedure', 'Procedure'), ('email', 'Email') ], 'Action', \
- required=True, help="Defines the action to be invoked when an alarm is triggered"),
+ required=True, help="Defines the action to be invoked when an alarm is triggered"),
'description': fields.text('Description', help='Provides a more complete \
description of the calendar component, than that \
- provided by the "SUMMARY" property'),
+ provided by the "SUMMARY" property'),
'attendee_ids': fields.many2many('calendar.attendee', 'alarm_attendee_rel', \
- 'alarm_id', 'attendee_id', 'Attendees', readonly=True),
+ 'alarm_id', 'attendee_id', 'Attendees', readonly=True),
'attach': fields.binary('Attachment', help="""* Points to a sound resource,\
which is rendered when the alarm is triggered for audio,
* File which is intended to be sent as message attachments for email,
* Points to a procedure resource, which is invoked when\
- the alarm is triggered for procedure."""),
- 'res_id': fields.integer('Resource ID'),
- 'model_id': fields.many2one('ir.model', 'Model'),
- 'user_id': fields.many2one('res.users', 'Owner'),
- 'event_date': fields.datetime('Event Date'),
- 'event_end_date': fields.datetime('Event End Date'),
- 'trigger_date': fields.datetime('Trigger Date', readonly="True"),
+ the alarm is triggered for procedure."""),
+ 'res_id': fields.integer('Resource ID'),
+ 'model_id': fields.many2one('ir.model', 'Model'),
+ 'user_id': fields.many2one('res.users', 'Owner'),
+ 'event_date': fields.datetime('Event Date'),
+ 'event_end_date': fields.datetime('Event End Date'),
+ 'trigger_date': fields.datetime('Trigger Date', readonly="True"),
'state':fields.selection([
- ('draft', 'Draft'),
- ('run', 'Run'),
- ('stop', 'Stop'),
- ('done', 'Done'),
- ], 'State', select=True, readonly=True),
+ ('draft', 'Draft'),
+ ('run', 'Run'),
+ ('stop', 'Stop'),
+ ('done', 'Done'),
+ ], 'State', select=True, readonly=True),
}
_defaults = {
@@ -801,7 +802,7 @@ class calendar_alarm(osv.osv):
current_datetime = datetime.now()
request_obj = self.pool.get('res.request')
alarm_ids = self.search(cr, uid, [('state', '!=', 'done')], context=context)
-
+
mail_to = []
for alarm in self.browse(cr, uid, alarm_ids, context=context):
@@ -916,10 +917,10 @@ class calendar_event(osv.osv):
return {}
event = self.browse(cr, uid, ids, context=context)[0]
value = {
- 'duration': 24
+ 'duration': 24
}
return {'value': value}
-
+
def onchange_dates(self, cr, uid, ids, start_date, duration=False, end_date=False, allday=False, context=None):
"""Returns duration and/or end date based on values passed
@param self: The object pointer
@@ -1082,11 +1083,11 @@ class calendar_event(osv.osv):
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
'description': fields.text('Description', states={'done': [('readonly', True)]}),
'class': fields.selection([('public', 'Public'), ('private', 'Private'), \
- ('confidential', 'Confidential')], 'Mark as', states={'done': [('readonly', True)]}),
- 'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}),
+ ('confidential', 'Confidential')], 'Mark as', states={'done': [('readonly', True)]}),
+ 'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}),
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \
'Show as', states={'done': [('readonly', True)]}),
- 'base_calendar_url': fields.char('Caldav URL', size=264),
+ 'base_calendar_url': fields.char('Caldav URL', size=264),
'state': fields.selection([('tentative', 'Tentative'),
('confirmed', 'Confirmed'),
('cancelled', 'Cancelled')], 'State', readonly=True),
@@ -1110,6 +1111,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
'vtimezone': fields.related('user_id', 'context_tz', type='char', size=24, \
string='Timezone', store=True),
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
+ 'organizer_id': fields.many2one('res.users', 'Organizer', states={'done': [('readonly', True)]}),
'freq': fields.selection([('None', 'No Repeat'), \
('secondly', 'Secondly'), \
('minutely', 'Minutely'), \
@@ -1136,25 +1138,27 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
('SU', 'Sunday')], 'Weekday'),
'byday': fields.selection([('1', 'First'), ('2', 'Second'), \
('3', 'Third'), ('4', 'Fourth'), \
- ('5', 'Fifth'), ('-1', 'Last')], 'By day'),
- 'month_list': fields.selection(months.items(), 'Month'),
- 'end_date': fields.date('Repeat Until'),
+ ('5', 'Fifth'), ('-1', 'Last')], 'By day'),
+ 'month_list': fields.selection(months.items(), 'Month'),
+ 'end_date': fields.date('Repeat Until'),
'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', \
- 'event_id', 'attendee_id', 'Attendees'),
- 'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}),
+ 'event_id', 'attendee_id', 'Attendees'),
+ '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.")
}
_defaults = {
- 'state': 'tentative',
+ 'state': 'tentative',
'class': 'public',
'show_as': 'busy',
'freq': 'None',
'select1': 'date',
'interval': 1,
'active': 1,
- }
+ 'user_id': lambda self, cr, uid, ctx: uid,
+ 'organizer_id': lambda self, cr, uid, ctx: uid,
+ }
def open_event(self, cr, uid, ids, context=None):
"""
@@ -1183,26 +1187,26 @@ true, it will allow you to hide the event alarm information without removing it.
id4 = data_obj.browse(cr, uid, id4, context=context).res_id
for id in ids:
value = {
- 'name': _('Event'),
- 'view_type': 'form',
- 'view_mode': 'form,tree',
- 'res_model': 'calendar.event',
- 'view_id': False,
- 'views': [(id2, 'form'), (id3, 'tree'), (id4, 'calendar')],
- 'type': 'ir.actions.act_window',
- 'res_id': base_calendar_id2real_id(id),
+ 'name': _('Event'),
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'calendar.event',
+ 'view_id': False,
+ 'views': [(id2, 'form'), (id3, 'tree'), (id4, 'calendar')],
+ 'type': 'ir.actions.act_window',
+ 'res_id': base_calendar_id2real_id(id),
'nodestroy': True
}
return value
def modify_this(self, cr, uid, event_id, defaults, real_date, context=None, *args):
- """Modifies only one event record out of virtual recurrent events
+ """Modifies only one event record out of virtual recurrent events
and creates new event as a specific instance of a Recurring Event",
@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 event_id: Id of Recurring Event
+ @param event_id: Id of Recurring Event
@param real_date: Date of event recurrence that is being modified
@param context: A standard dictionary for contextual values
@param *args: Get Tupple Value
@@ -1225,7 +1229,7 @@ true, it will allow you to hide the event alarm information without removing it.
def modify_all(self, cr, uid, event_ids, defaults, context=None, *args):
"""
- Modifies the recurring event
+ Modifies the recurring event
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param event_ids: List of crm meeting’s IDs.
@@ -1252,7 +1256,7 @@ true, it will allow you to hide the event alarm information without removing it.
def get_recurrent_ids(self, cr, uid, select, base_start_date, base_until_date, limit=100):
"""Gives virtual event ids for recurring events based on value of Recurrence Rule
- This method gives ids of dates that comes between start date and end date of calendar views
+ This method gives ids of dates that comes between start date and end date of calendar views
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@@ -1418,8 +1422,7 @@ true, it will allow you to hide the event alarm information without removing it.
until_date = arg[2]
res = super(calendar_event, self).search(cr, uid, args_without_date, \
offset, limit, order, context, count)
- #Search Event ID which are invitted
-
+
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
@@ -1558,7 +1561,7 @@ true, it will allow you to hide the event alarm information without removing it.
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
+ # 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'
@@ -1584,7 +1587,7 @@ true, it will allow you to hide the event alarm information without removing it.
alarm_obj = self.pool.get('res.alarm')
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
return res
-
+
def do_tentative(self, cr, uid, ids, context=None, *args):
""" Makes event invitation as Tentative
@param self: The object pointer
@@ -1592,10 +1595,10 @@ true, it will allow you to hide the event alarm information without removing it.
@param uid: the current user’s ID for security checks,
@param ids: List of Event IDs
@param *args: Get Tupple value
- @param context: A standard dictionary for contextual values
+ @param context: A standard dictionary for contextual values
"""
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
-
+
def do_cancel(self, cr, uid, ids, context=None, *args):
""" Makes event invitation as Tentative
@param self: The object pointer
@@ -1603,7 +1606,7 @@ true, it will allow you to hide the event alarm information without removing it.
@param uid: the current user’s ID for security checks,
@param ids: List of Event IDs
@param *args: Get Tupple value
- @param context: A standard dictionary for contextual values
+ @param context: A standard dictionary for contextual values
"""
return self.write(cr, uid, ids, {'state': 'cancelled'}, context)
@@ -1614,7 +1617,7 @@ true, it will allow you to hide the event alarm information without removing it.
@param uid: the current user’s ID for security checks,
@param ids: List of Event IDs
@param *args: Get Tupple value
- @param context: A standard dictionary for contextual values
+ @param context: A standard dictionary for contextual values
"""
return self.write(cr, uid, ids, {'state': 'confirmed'}, context)
@@ -1758,9 +1761,9 @@ class ir_model(osv.osv):
_inherit = 'ir.model'
- def read(self, cr, uid, ids, fields=None, context=None,
+ def read(self, cr, uid, ids, fields=None, context=None,
load='_classic_read'):
- """
+ """
Overrides orm read method.
@param self: The object pointer
@param cr: the current row, from the database cursor,
@@ -1807,7 +1810,7 @@ class res_users(osv.osv):
_inherit = 'res.users'
def _get_user_avail(self, cr, uid, ids, context=None):
- """
+ """
Get User Availability
@param self: The object pointer
@param cr: the current row, from the database cursor,
@@ -1838,7 +1841,7 @@ class res_users(osv.osv):
return res
def _get_user_avail_fun(self, cr, uid, ids, name, args, context=None):
- """
+ """
Get User Availability Function
@param self: The object pointer
@param cr: the current row, from the database cursor,
diff --git a/addons/base_setup/base_setup_todo.xml b/addons/base_setup/base_setup_todo.xml
index 5db25283777..cfe815fb94e 100644
--- a/addons/base_setup/base_setup_todo.xml
+++ b/addons/base_setup/base_setup_todo.xml
@@ -36,11 +36,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/addons/caldav/caldav_data.xml b/addons/caldav/caldav_data.xml
index 04f5a6004a7..e2ae6624979 100644
--- a/addons/caldav/caldav_data.xml
+++ b/addons/caldav/caldav_data.xml
@@ -1,7 +1,7 @@
-
+
Calendars
True
@@ -14,6 +14,11 @@
vevent
+
+ organizer
+ vevent
+
+
uid
vevent
@@ -58,12 +63,12 @@
valarm
vevent
-
+
vtimezone
vevent
-
+
priority
vevent
@@ -181,12 +186,12 @@
seq
vtodo
-
+
vtimezone
vtodo
-
+
url
vtodo
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index 6dc1e23ea66..a45152501cc 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -228,6 +228,8 @@ class CalDAV(object):
att_data = []
for cal_data in child.getChildren():
+ if cal_data.name.lower() == 'organizer':
+ self.ical_set(cal_data.name.lower(), {'name':cal_data.params['CN']}, 'value')
if cal_data.name.lower() == 'attendee':
ctx = context.copy()
if cal_children:
@@ -266,7 +268,7 @@ class CalDAV(object):
if not datas:
return
timezones = []
- for data in datas:
+ for data in datas:
tzval = None
vevent = ical.add(name)
for field in self.__attribute__.keys():
@@ -307,6 +309,13 @@ class CalDAV(object):
ical = tz_obj.export_cal(cr, uid, None, \
data[map_field], ical, context=context)
timezones.append(data[map_field])
+ elif field == 'organizer' and data[map_field]:
+ event_org = vevent.add('organizer')
+ organizer_id = data[map_field][0]
+ user_obj = self.pool.get('res.users')
+ organizer = user_obj.browse(cr, uid, organizer_id, context=context)
+ event_org.params['CN'] = [organizer.name]
+ event_org.value = 'MAILTO:' + (organizer.user_email or organizer.name)
elif data[map_field]:
if map_type in ("char", "text"):
if field in ('exdate'):
@@ -414,7 +423,7 @@ class CalDAV(object):
return res
class Calendar(CalDAV, osv.osv):
- _name = 'basic.calendar'
+ _name = 'basic.calendar'
_calname = 'calendar'
__attribute__ = {
@@ -431,13 +440,13 @@ class Calendar(CalDAV, osv.osv):
'vtimezone': None, # Use: O-n, Type: Collection of Timezone class
}
_columns = {
- 'name': fields.char("Name", size=64),
+ 'name': fields.char("Name", size=64),
'user_id': fields.many2one('res.users', 'Owner'),
'collection_id': fields.many2one('document.directory', 'Collection', \
required=True),
'type': fields.selection([('vevent', 'Event'), ('vtodo', 'TODO')], \
string="Type", size=64),
- 'line_ids': fields.one2many('basic.calendar.lines', 'calendar_id', 'Calendar Lines'),
+ 'line_ids': fields.one2many('basic.calendar.lines', 'calendar_id', 'Calendar Lines'),
'create_date': fields.datetime('Created Date'),
'write_date': fields.datetime('Modifided Date'),
}
@@ -448,8 +457,8 @@ class Calendar(CalDAV, osv.osv):
if not domain:
domain = []
res = []
- ctx_res_id = context.get('res_id', None)
- ctx_model = context.get('model', None)
+ ctx_res_id = context.get('res_id', None)
+ ctx_model = context.get('model', None)
for cal in self.browse(cr, uid, ids):
for line in cal.line_ids:
if ctx_model and ctx_model != line.object_id.model:
@@ -458,13 +467,13 @@ class Calendar(CalDAV, osv.osv):
continue
line_domain = eval(line.domain)
line_domain += domain
- if ctx_res_id:
+ if ctx_res_id:
line_domain += [('id','=',ctx_res_id)]
mod_obj = self.pool.get(line.object_id.model)
- data_ids = mod_obj.search(cr, uid, line_domain, context=context)
+ data_ids = mod_obj.search(cr, uid, line_domain, context=context)
for data in mod_obj.browse(cr, uid, data_ids, context):
ctx = parent and parent.context or None
- node = res_node_calendar('%s' %data.id, parent, ctx, data, line.object_id.model, data.id)
+ node = res_node_calendar('%s' %data.id, parent, ctx, data, line.object_id.model, data.id)
res.append(node)
return res
@@ -478,8 +487,8 @@ class Calendar(CalDAV, osv.osv):
"""
if not context:
context = {}
- ctx_model = context.get('model', None)
- ctx_res_id = context.get('res_id', None)
+ ctx_model = context.get('model', None)
+ ctx_res_id = context.get('res_id', None)
ical = vobject.iCalendar()
for cal in self.browse(cr, uid, ids):
for line in cal.line_ids:
@@ -488,7 +497,7 @@ class Calendar(CalDAV, osv.osv):
if line.name in ('valarm', 'attendee'):
continue
domain = eval(line.domain)
- if ctx_res_id:
+ if ctx_res_id:
domain += [('id','=',ctx_res_id)]
mod_obj = self.pool.get(line.object_id.model)
data_ids = mod_obj.search(cr, uid, domain, context=context)
@@ -496,7 +505,7 @@ class Calendar(CalDAV, osv.osv):
context.update({'model': line.object_id.model,
'calendar_id': cal.id
})
- self.__attribute__ = get_attribute_mapping(cr, uid, line.name, context)
+ self.__attribute__ = get_attribute_mapping(cr, uid, line.name, context)
self.create_ics(cr, uid, datas, line.name, ical, context=context)
return ical.serialize()
@@ -511,16 +520,18 @@ class Calendar(CalDAV, osv.osv):
if not context:
context = {}
- vals = []
+ vals = []
ical_data = base64.decodestring(content)
parsedCal = vobject.readOne(ical_data)
if not data_id:
- data_id = self.search(cr, uid, [])[0]
+ data_id = self.search(cr, uid, [])[0]
cal = self.browse(cr, uid, data_id, context=context)
cal_children = {}
count = 0
for line in cal.line_ids:
cal_children[line.name] = line.object_id.model
+ objs = []
+ checked = True
for child in parsedCal.getChildren():
if child.name.lower() in cal_children:
context.update({'model': cal_children[child.name.lower()],
@@ -528,12 +539,14 @@ class Calendar(CalDAV, osv.osv):
})
self.__attribute__ = get_attribute_mapping(cr, uid, child.name.lower(), context=context)
val = self.parse_ics(cr, uid, child, cal_children=cal_children, context=context)
- val.update({'user_id': uid})
vals.append(val)
- obj = self.pool.get(cal_children[child.name.lower()])
- if hasattr(obj, 'check_import'):
- obj.check_import(cr, uid, vals, context=context)
- else:
+ objs.append(cal_children[child.name.lower()])
+ for obj_name in list(set(objs)):
+ obj = self.pool.get(obj_name)
+ if hasattr(obj, 'check_import'):
+ obj.check_import(cr, uid, vals, context=context)
+ checked = True
+ if not checked:
self.check_import(cr, uid, vals, context=context)
return {}
Calendar()
diff --git a/addons/crm/board_crm_view.xml b/addons/crm/board_crm_view.xml
index ccaf0f7e35c..aec83760a76 100644
--- a/addons/crm/board_crm_view.xml
+++ b/addons/crm/board_crm_view.xml
@@ -29,21 +29,69 @@
+
+
+ My Open Opportunities
+ crm.lead
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ My Open Opportunities
crm.lead
form
tree,form
-
[('user_id','=',uid),('state','=','open'), ('type', '=', 'opportunity')]
+
+
+
+ tree
+
+
+
+
+
+
+ form
+
+
+
crm.meeting
form
tree,form
- [('user_id','=',uid),('state','!=','cancel'),('date','ilike',time.strftime("%Y-%m"))]
+ [('user_id','=',uid),('state','not in',('cancel','done'))]
@@ -59,7 +107,7 @@
form
graph,tree,form
- ['&', ('state', '=', 'done') , '&', ('create_date','>',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%Y-%m-%d')), ('type', '=', 'opportunity')]
+ ['&', ('user_id', '=', uid),'&', ('state', '=', 'done') , '&', ('create_date','>',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%Y-%m-%d')), ('type', '=', 'opportunity')]
@@ -84,11 +132,11 @@
diff --git a/addons/crm/crm_meeting_view.xml b/addons/crm/crm_meeting_view.xml
index 6759590d89d..2c6fbd02cc9 100644
--- a/addons/crm/crm_meeting_view.xml
+++ b/addons/crm/crm_meeting_view.xml
@@ -107,6 +107,7 @@
+
@@ -154,7 +155,9 @@
-
+
+
+
@@ -342,7 +345,7 @@
-
+
diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py
index bcdcc2e9bf6..05413ddcd8f 100644
--- a/addons/crm/crm_phonecall.py
+++ b/addons/crm/crm_phonecall.py
@@ -24,6 +24,7 @@ from osv import fields, osv
from tools.translate import _
import crm
import time
+from datetime import datetime, timedelta
class crm_phonecall(osv.osv, crm_case):
""" Phonecall Cases """
@@ -65,7 +66,7 @@ class crm_phonecall(osv.osv, crm_case):
('object_id.model', '=', 'crm.phonecall')]"),
'date_open': fields.datetime('Opened', readonly=True),
# phonecall fields
- 'duration': fields.float('Duration'),
+ 'duration': fields.float('Duration', help="Duration in Minutes"),
'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.phonecall')]"),
@@ -113,10 +114,29 @@ class crm_phonecall(osv.osv, crm_case):
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
- res = super(crm_phonecall, self).case_close(cr, uid, ids, args)
- self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
+ for phone in self.browse(cr, uid, ids):
+ phone_id= phone.id
+ data = {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')}
+ if phone.duration <=0:
+ duration = datetime.now() - datetime.strptime(phone.date, '%Y-%m-%d %H:%M:%S')
+ data.update({'duration': duration.seconds/float(60)})
+ res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], args)
+ self.write(cr, uid, ids, data)
return res
+ def case_reset(self, cr, uid, ids, *args):
+ """Resets case as draft
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of case Ids
+ @param *args: Tuple Value for additional Params
+ """
+ res = super(crm_phonecall, self).case_reset(cr, uid, ids, args)
+ self.write(cr, uid, ids, {'duration': 0.0})
+ return res
+
+
def case_open(self, cr, uid, ids, *args):
"""Overrides cancel for crm_case for setting Open Date
@param self: The object pointer
diff --git a/addons/crm_caldav/crm_caldav_data.xml b/addons/crm_caldav/crm_caldav_data.xml
index 0f160bfd85d..3b74eef123c 100644
--- a/addons/crm_caldav/crm_caldav_data.xml
+++ b/addons/crm_caldav/crm_caldav_data.xml
@@ -1,6 +1,6 @@
-
+
@@ -22,13 +22,20 @@
-
+
attendee
-
+
+
+
+
+
+ field
+
+
@@ -42,7 +49,7 @@
field
-
+
@@ -55,7 +62,7 @@
field
-
+
@@ -154,7 +161,7 @@
field
-
+
@@ -313,7 +320,7 @@
field
-
+
diff --git a/addons/document/test/document_test.yml b/addons/document/test/document_test.yml
index fe3008d35da..5864a223033 100644
--- a/addons/document/test/document_test.yml
+++ b/addons/document/test/document_test.yml
@@ -45,8 +45,9 @@
-
Attach a pdf file in "My document"
-
- !python {model: ir.attachment}: |
+ !python {model: 'ir.attachment'}: |
import tools
import base64
- file = open(tools.config['addons_path'] + '/document/test/partner.pdf')
- id = self.write(cr, uid, [ref("document_1")], {'datas' : base64.encodestring(file.read())}, context)
+ pdf_file = open(tools.config['addons_path'] + '/document/test/partner.pdf')
+ self.write(cr, uid, [ref("document_1")], {'datas_fname': 'partner.pdf', 'datas' : base64.encodestring(pdf_file.read())}, context)
+
diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml
index c72cc60dcef..9caaae6e722 100644
--- a/addons/event/event_view.xml
+++ b/addons/event/event_view.xml
@@ -53,21 +53,22 @@
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/project_caldav/project_caldav.py b/addons/project_caldav/project_caldav.py
index b6a87516194..65e61c6e4cd 100644
--- a/addons/project_caldav/project_caldav.py
+++ b/addons/project_caldav/project_caldav.py
@@ -30,7 +30,13 @@ class project_task(osv.osv):
'create_date': fields.datetime('Create Date'),
'attendee_ids': fields.many2many('calendar.attendee', \
'task_attendee_rel', 'task_id', 'attendee_id', 'Attendees'),
- }
+ 'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
+ help='If the task is created the state is \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
+ \n If the task is over, the states is set to \'Done\'.'),
+ }
+ _defaults = {
+ 'state': 'draft',
+ }
def import_cal(self, cr, uid, data, data_id=None, context=None):
todo_obj = self.pool.get('basic.calendar.todo')
@@ -43,7 +49,7 @@ class project_task(osv.osv):
ids = []
for val in vals:
obj_tm = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.project_time_mode_id
- if not val.has_key('planned_hours'):
+ if not val.get('planned_hours', False):
# 'Computes duration' in days
plan = 0.0
if val.get('date') and val.get('date_deadline'):
diff --git a/addons/project_caldav/project_caldav_data.xml b/addons/project_caldav/project_caldav_data.xml
index a6b7ef870f4..e5e2ce0578d 100644
--- a/addons/project_caldav/project_caldav_data.xml
+++ b/addons/project_caldav/project_caldav_data.xml
@@ -3,7 +3,7 @@
- Todo
+ Tasks
vtodo
diff --git a/addons/project_caldav/project_caldav_view.xml b/addons/project_caldav/project_caldav_view.xml
index 3055fee85bc..01133108b6d 100644
--- a/addons/project_caldav/project_caldav_view.xml
+++ b/addons/project_caldav/project_caldav_view.xml
@@ -17,7 +17,9 @@
-
+
+
+
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index ca2b36a3245..172fe1226ef 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -785,8 +785,8 @@ class sale_order_line(osv.osv):
res = {}
context = context or {}
for line in self.browse(cr, uid, ids, context=context):
- price = line.price_unit * line.product_uom_qty * (1 - (line.discount or 0.0) / 100.0)
- taxes = tax_obj.compute_all(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty)
+ price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
+ taxes = tax_obj.compute_all(cr, uid, line.tax_id, price, line.product_uom_qty, line.order_id.partner_invoice_id.id, line.product_id, line.order_id.partner_id)
cur = line.order_id.pricelist_id.currency_id
res[line.id] = cur_obj.round(cr, uid, cur, taxes['total'])
return res
diff --git a/addons/sale/wizard/sale_make_invoice.xml b/addons/sale/wizard/sale_make_invoice.xml
index 9884aa1f021..b3f121b8c40 100644
--- a/addons/sale/wizard/sale_make_invoice.xml
+++ b/addons/sale/wizard/sale_make_invoice.xml
@@ -1,30 +1,39 @@
-
+
Create invoices
sale.make.invoice
form
-
+
-
+
-
+ Make Invoices
+ ir.actions.act_window
+ sale.make.invoice
+ form
+ form
+ new
+
+
+
+ id="action_view_sale_order_make_invoice"/>
diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py
index e54d5d2a374..683d050b454 100644
--- a/addons/sale_crm/wizard/crm_make_sale.py
+++ b/addons/sale_crm/wizard/crm_make_sale.py
@@ -22,6 +22,8 @@
from osv import fields, osv
from tools.translate import _
from mx.DateTime import now
+import time
+import decimal_precision as dp
class crm_make_sale(osv.osv_memory):
""" Make sale order for crm """
@@ -100,7 +102,6 @@ class crm_make_sale(osv.osv_memory):
vals = {
'origin': 'Opportunity:%s' % str(case.id),
'section_id': case.section_id and case.section_id.id or False,
- 'picking_policy': make.picking_policy,
'shop_id': make.shop_id.id,
'partner_id': partner_id,
'pricelist_id': pricelist,
@@ -119,14 +120,16 @@ class crm_make_sale(osv.osv_memory):
if make.analytic_account.id:
vals['project_id'] = make.analytic_account.id
new_id = sale_obj.create(cr, uid, vals)
- for product_id in make.product_ids:
+ for line in make.sale_order_line:
value = sale_line_obj.product_id_change(cr, uid, [], pricelist,
- product_id.id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
- value['product_id'] = product_id.id
+ line.product_id.id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
+ value['product_id'] =line.product_id.id
value['order_id'] = new_id
- value['tax_id'] = [(6,0,value['tax_id'])]
+ value['tax_id'] = [(6,0,line['tax_id'])]
+ value['product_uom_qty']=line.product_uom_qty
+ value['discount']=line.discount
+ value['product_uom']=line.product_uom.id
sale_line_obj.create(cr, uid, value)
-
case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
new_ids.append(new_id)
message = _('Opportunity ') + " '" + case.name + "' "+ _("is converted to Sales Quotation.")
@@ -163,10 +166,7 @@ class crm_make_sale(osv.osv_memory):
_columns = {
'shop_id': fields.many2one('sale.shop', 'Shop', required=True),
'partner_id': fields.many2one('res.partner', 'Customer', required=True, help='Use this partner if there is no partner on the Opportunity'),
- 'picking_policy': fields.selection([('direct','Partial Delivery'),
- ('one','Complete Delivery')], 'Picking Policy', required=True),
- 'product_ids': fields.many2many('product.product', 'product_sale_rel',\
- 'sale_id', 'product_id', 'Products'),
+ 'sale_order_line': fields.one2many('sale.order.make.line', 'order_line', 'Product Line', readonly=True, states={'draft': [('readonly', False)]}),
'analytic_account': fields.many2one('account.analytic.account', 'Analytic Account'),
'close': fields.boolean('Close Case', help='Check this to close the case after having created the sale order.'),
}
@@ -174,6 +174,160 @@ class crm_make_sale(osv.osv_memory):
'partner_id': _selectPartner,
'close': 1
}
+
crm_make_sale()
+
+class sale_order_make_line(osv.osv_memory):
+
+
+ def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
+ uom=False, qty_uos=0, uos=False, name='', partner_id=False,
+ lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False):
+ if not partner_id:
+ raise osv.except_osv(_('No Customer Defined !'), _('You have to select a customer in the sale form !\nPlease set one customer before choosing a product.'))
+ warning = {}
+ product_uom_obj = self.pool.get('product.uom')
+ partner_obj = self.pool.get('res.partner')
+ product_obj = self.pool.get('product.product')
+ if partner_id:
+ lang = partner_obj.browse(cr, uid, partner_id).lang
+ context = {'lang': lang, 'partner_id': partner_id}
+
+ if not product:
+ return {'value': {'th_weight': 0, 'product_packaging': False,
+ 'product_uos_qty': qty}, 'domain': {'product_uom': [],
+ 'product_uos': []}}
+
+ if not date_order:
+ date_order = time.strftime('%Y-%m-%d')
+
+ result = {}
+ product_obj = product_obj.browse(cr, uid, product, context=context)
+ if not packaging and product_obj.packaging:
+ packaging = product_obj.packaging[0].id
+ result['product_packaging'] = packaging
+
+ if packaging:
+ default_uom = product_obj.uom_id and product_obj.uom_id.id
+ pack = self.pool.get('product.packaging').browse(cr, uid, packaging, context=context)
+ q = product_uom_obj._compute_qty(cr, uid, uom, pack.qty, default_uom)
+# qty = qty - qty % q + q
+ if qty and (q and not (qty % q) == 0):
+ ean = pack.ean
+ qty_pack = pack.qty
+ type_ul = pack.ul
+ warn_msg = _("You selected a quantity of %d Units.\nBut it's not compatible with the selected packaging.\nHere is a proposition of quantities according to the packaging: ") % (qty)
+ warn_msg = warn_msg + "\n\n" + _("EAN: ") + str(ean) + _(" Quantity: ") + str(qty_pack) + _(" Type of ul: ") + str(type_ul.name)
+ warning = {
+ 'title': _('Picking Information !'),
+ 'message': warn_msg
+ }
+ result['product_uom_qty'] = qty
+
+ uom2 = False
+ if uom:
+ uom2 = product_uom_obj.browse(cr, uid, uom)
+ if product_obj.uom_id.category_id.id != uom2.category_id.id:
+ uom = False
+
+ if uos:
+ if product_obj.uos_id:
+ uos2 = product_uom_obj.browse(cr, uid, uos)
+ if product_obj.uos_id.category_id.id != uos2.category_id.id:
+ uos = False
+ else:
+ uos = False
+ if product_obj.description_sale:
+ result['notes'] = product_obj.description_sale
+ fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False
+ if update_tax: #The quantity only have changed
+ result['delay'] = (product_obj.sale_delay or 0.0)
+ partner = partner_obj.browse(cr, uid, partner_id)
+ result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
+ result.update({'type': product_obj.procure_method})
+
+ if not flag:
+ result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context)[0][1]
+ domain = {}
+ if (not uom) and (not uos):
+ result['product_uom'] = product_obj.uom_id.id
+ if product_obj.uos_id:
+ result['product_uos'] = product_obj.uos_id.id
+ result['product_uos_qty'] = qty * product_obj.uos_coeff
+ uos_category_id = product_obj.uos_id.category_id.id
+ else:
+ result['product_uos'] = False
+ result['product_uos_qty'] = qty
+ uos_category_id = False
+ domain = {'product_uom':
+ [('category_id', '=', product_obj.uom_id.category_id.id)],
+ 'product_uos':
+ [('category_id', '=', uos_category_id)]}
+
+ elif uos and not uom: # only happens if uom is False
+ result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id
+ result['product_uom_qty'] = qty_uos / product_obj.uos_coeff
+ elif uom: # whether uos is set or not
+ default_uom = product_obj.uom_id and product_obj.uom_id.id
+ q = product_uom_obj._compute_qty(cr, uid, uom, qty, default_uom)
+ if product_obj.uos_id:
+ result['product_uos'] = product_obj.uos_id.id
+ result['product_uos_qty'] = qty * product_obj.uos_coeff
+ else:
+ result['product_uos'] = False
+ result['product_uos_qty'] = qty
+
+ if not uom2:
+ uom2 = product_obj.uom_id
+ return {'value': result, 'domain': domain, 'warning': warning}
+
+ def product_uom_change(self, cursor, user, ids, pricelist, product, qty=0,
+ uom=False, qty_uos=0, uos=False, name='', partner_id=False,
+ lang=False, update_tax=True, date_order=False):
+ res = self.product_id_change(cursor, user, ids, pricelist, product,
+ qty=qty, uom=uom, qty_uos=qty_uos, uos=uos, name=name,
+ partner_id=partner_id, lang=lang, update_tax=update_tax,
+ date_order=date_order)
+ if 'product_uom' in res['value']:
+ del res['value']['product_uom']
+ if not uom:
+ res['value']['price_unit'] = 0.0
+ return res
+
+ _name = 'sale.order.make.line'
+ _description = 'Sale Order Line'
+ _columns = {
+ 'order_line': fields.many2one('crm.make.sale', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, ),
+ 'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, ),
+ 'name': fields.char('Description', size=256, required=True, select=True, readonly=True, ),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale order lines."),
+ 'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation the the shipping of the products to the customer", readonly=True, ),
+ 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
+ 'procurement_id': fields.many2one('procurement.order', 'Procurement'),
+ 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Sale Price'), readonly=True, ),
+ 'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft':[('readonly',False)]}),
+ 'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Procurement Method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
+ 'product_uom_qty': fields.float('Quantity (UoM)', digits=(16, 2), required=True, readonly=True, states={'draft':[('readonly',False)]}),
+ 'product_uom': fields.many2one('product.uom', 'Unit of Measure ', required=True, readonly=True, states={'draft':[('readonly',False)]}),
+ 'product_uos_qty': fields.float('Quantity (UoS)', readonly=True, states={'draft':[('readonly',False)]}),
+ 'product_uos': fields.many2one('product.uom', 'Product UoS'),
+ 'product_packaging': fields.many2one('product.packaging', 'Packaging'),
+ 'discount': fields.float('Discount (%)', digits=(16, 2), readonly=True, states={'draft':[('readonly',False)]}),
+ 'notes': fields.text('Notes'),
+ }
+ _order = 'sequence, id'
+ _defaults = {
+ 'discount': 0.0,
+ 'delay': 0.0,
+ 'product_uom_qty': 1,
+ 'product_uos_qty': 1,
+ 'type': 'make_to_stock',
+ 'product_packaging': False
+ }
+
+sale_order_make_line()
+
+
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/sale_crm/wizard/crm_make_sale_view.xml b/addons/sale_crm/wizard/crm_make_sale_view.xml
index a1da3ed1fec..17e743987f0 100644
--- a/addons/sale_crm/wizard/crm_make_sale_view.xml
+++ b/addons/sale_crm/wizard/crm_make_sale_view.xml
@@ -9,21 +9,66 @@
form
diff --git a/addons/scrum/scrum.py b/addons/scrum/scrum.py
index 673c47850d6..0eb23916bc1 100644
--- a/addons/scrum/scrum.py
+++ b/addons/scrum/scrum.py
@@ -248,7 +248,7 @@ class scrum_product_backlog(osv.osv):
'note' : fields.text('Note'),
'active' : fields.boolean('Active', help="If Active field is set to true, it will allow you to hide the product backlog without removing it."),
'project_id': fields.many2one('project.project', 'Project', required=True, domain=[('scrum','=',1)], help="If you have [?] in the project name, it means there are no analytic account linked to this project."),
- 'user_id': fields.many2one('res.users', 'Responsible'),
+ 'user_id': fields.many2one('res.users', 'Author'),
'sprint_id': fields.many2one('scrum.sprint', 'Sprint'),
'sequence' : fields.integer('Sequence', help="Gives the sequence order when displaying a list of product backlog."),
'tasks_id': fields.one2many('project.task', 'product_backlog_id', 'Tasks Details'),
diff --git a/addons/scrum/scrum_view.xml b/addons/scrum/scrum_view.xml
index db4d5d7af81..86f92981fed 100644
--- a/addons/scrum/scrum_view.xml
+++ b/addons/scrum/scrum_view.xml
@@ -134,7 +134,7 @@
icon="terp-check"
string="Current"
name="current"
- domain="['|','&',('sprint_id.date_start','<=',time.strftime('%%Y-%%m-%%d')), ('sprint_id.date_stop','>=',time.strftime('%%Y-%%m-%%d')), ('state','in',['draft','open'])]"
+ domain="['|','&',('sprint_id.date_start','<=',time.strftime('%%Y-%%m-%%d')), ('sprint_id.date_stop','>=',time.strftime('%%Y-%%m-%%d')), ('state','in',['draft','open','pending'])]"
help="Current Backlogs"/>
@@ -156,7 +156,8 @@
+ domain="[('user_id','=',uid)]"
+ help="My Backlogs"/>
@@ -178,7 +179,7 @@
Product Backlogs
scrum.product.backlog
form
- {"search_default_user_id":uid, 'search_default_current': 1}
+ {'search_default_current': 1}
| |