diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index 896b71e9f25..1a0727e626f 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -183,7 +183,7 @@ class account_cash_statement(osv.osv): ('open','Open')], 'State', required=True, states={'confirm': [('readonly', True)]}, readonly="1"), 'total_entry_encoding':fields.function(_get_sum_entry_encoding, method=True, store=True, string="Cash Transaction", help="Total cash transactions"), 'closing_date':fields.datetime("Closed On"), - 'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance', help="Closing balance based on Opening Balance and Transactions"), + 'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance', help="Closing balance based on Starting Balance and Cash Transactions"), 'balance_end_cash': fields.function(_balance_end_cash, method=True, store=True, string='Balance', help="Closing balance based on cashBox"), 'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'), 'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'), diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index f4635e74806..f3739a993c5 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -682,6 +682,7 @@ class account_move_line(osv.osv): account_id = line['account_id']['id'] partner_id = (line['partner_id'] and line['partner_id']['id']) or False writeoff = debit - credit + # Ifdate_p in context => take this date if context.has_key('date_p') and context['date_p']: date=context['date_p'] diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index de8bc843faa..78cb6cadd7e 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -2300,7 +2300,6 @@ - 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 cc24d131e39..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')) @@ -409,7 +409,6 @@ property or property parameter."), return res cal = vobject.iCalendar() event = cal.add('vevent') - event.add('uid').value = 'OpenObject-%s_%s@%s' % (event_obj._name, event_obj.id, cr.dbname) 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) @@ -420,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') @@ -456,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 """ @@ -475,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): @@ -496,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 @@ -529,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: + if vals.ref and vals.ref.user_id: 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) + 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 @@ -566,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): @@ -586,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): @@ -655,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) } @@ -725,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 = { @@ -802,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): @@ -917,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 @@ -1083,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), @@ -1111,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'), \ @@ -1137,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): """ @@ -1184,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 @@ -1226,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. @@ -1253,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, @@ -1419,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) @@ -1559,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' @@ -1585,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 @@ -1593,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 @@ -1604,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) @@ -1615,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) @@ -1759,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, @@ -1808,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, @@ -1839,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/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 aa34518a716..aec83760a76 100644 --- a/addons/crm/board_crm_view.xml +++ b/addons/crm/board_crm_view.xml @@ -107,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')] 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/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 177ef8d029d..b3f121b8c40 100644 --- a/addons/sale/wizard/sale_make_invoice.xml +++ b/addons/sale/wizard/sale_make_invoice.xml @@ -1,24 +1,24 @@ - + Create invoices sale.make.invoice form -
- - - - - -