diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py index c5b8012c89e..bb427680c05 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py @@ -22,9 +22,11 @@ import time from datetime import datetime from dateutil.relativedelta import relativedelta +from pytz import timezone +import pytz from openerp.osv import fields, osv -from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT from openerp.tools.translate import _ class hr_timesheet_sheet(osv.osv): @@ -386,22 +388,53 @@ class hr_attendance(osv.osv): attendance_ids.extend([row[0] for row in cr.fetchall()]) return attendance_ids + def _get_attendance_employee_tz(self, cr, uid, employee_id, date, context=None): + """ Simulate timesheet in employee timezone + + Return the attendance date in string format in the employee + tz converted from utc timezone as we consider date of employee + timesheet is in employee timezone + """ + employee_obj = self.pool['hr.employee'] + + tz = False + if employee_id: + employee = employee_obj.browse(cr, uid, employee_id, context=context) + tz = employee.user_id.partner_id.tz + + att_tz = timezone(tz or 'utc') + + attendance_dt = datetime.strptime(date, DEFAULT_SERVER_DATETIME_FORMAT) + att_tz_dt = pytz.utc.localize(attendance_dt) + att_tz_dt = att_tz_dt.astimezone(att_tz) + # We take only the date omiting the hours as we compare with timesheet + # date_from which is a date format thus using hours would lead to + # be out of scope of timesheet + att_tz_date_str = datetime.strftime(att_tz_dt, DEFAULT_SERVER_DATE_FORMAT) + return att_tz_date_str + def _get_current_sheet(self, cr, uid, employee_id, date=False, context=None): + + sheet_obj = self.pool['hr_timesheet_sheet.sheet'] if not date: date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) - # ending date with no time to avoid timesheet with early date_to - date_to = date[0:10]+' 00:00:00' - # limit=1 because only one sheet possible for an employee between 2 dates - sheet_ids = self.pool.get('hr_timesheet_sheet.sheet').search(cr, uid, [ - ('date_to', '>=', date_to), ('date_from', '<=', date), - ('employee_id', '=', employee_id) - ], limit=1, context=context) + + att_tz_date_str = self._get_attendance_employee_tz( + cr, uid, employee_id, + date=date, context=context) + sheet_ids = sheet_obj.search(cr, uid, + [('date_from', '<=', att_tz_date_str), + ('date_to', '>=', att_tz_date_str), + ('employee_id', '=', employee_id)], + limit=1, context=context) return sheet_ids and sheet_ids[0] or False def _sheet(self, cursor, user, ids, name, args, context=None): res = {}.fromkeys(ids, False) for attendance in self.browse(cursor, user, ids, context=context): - res[attendance.id] = self._get_current_sheet(cursor, user, attendance.employee_id.id, attendance.name, context=context) + res[attendance.id] = self._get_current_sheet( + cursor, user, attendance.employee_id.id, attendance.name, + context=context) return res _columns = { @@ -423,10 +456,13 @@ class hr_attendance(osv.osv): sheet_id = context.get('sheet_id') or self._get_current_sheet(cr, uid, vals.get('employee_id'), vals.get('name'), context=context) if sheet_id: + att_tz_date_str = self._get_attendance_employee_tz( + cr, uid, vals.get('employee_id'), + date=vals.get('name'), context=context) ts = self.pool.get('hr_timesheet_sheet.sheet').browse(cr, uid, sheet_id, context=context) if ts.state not in ('draft', 'new'): raise osv.except_osv(_('Error!'), _('You can not enter an attendance in a submitted timesheet. Ask your manager to reset it before adding attendance.')) - elif ts.date_from > vals.get('name') or ts.date_to < vals.get('name'): + elif ts.date_from > att_tz_date_str or ts.date_to < att_tz_date_str: raise osv.except_osv(_('User Error!'), _('You can not enter an attendance date outside the current timesheet dates.')) return super(hr_attendance,self).create(cr, uid, vals, context=context) @@ -578,4 +614,3 @@ class res_company(osv.osv): # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py index a913d3c067d..4a069cb5428 100644 --- a/addons/mail/controllers/main.py +++ b/addons/mail/controllers/main.py @@ -6,6 +6,7 @@ from openerp import SUPERUSER_ID from openerp import http from openerp.http import request from openerp.addons.web.controllers.main import content_disposition +import mimetypes class MailController(http.Controller): @@ -19,10 +20,11 @@ class MailController(http.Controller): if res: filecontent = base64.b64decode(res.get('base64')) filename = res.get('filename') + content_type = mimetypes.guess_type(filename) if filecontent and filename: return request.make_response( filecontent, - headers=[('Content-Type', 'application/octet-stream'), + headers=[('Content-Type', content_type[0] or 'application/octet-stream'), ('Content-Disposition', content_disposition(filename))]) return request.not_found() diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index a33eaaea15d..f984f8f3482 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -284,7 +284,7 @@ class mail_mail(osv.Model): res = ir_mail_server.send_email(cr, uid, msg, mail_server_id=mail.mail_server_id.id, context=context) - + if res: mail.write({'state': 'sent', 'message_id': res}) mail_sent = True @@ -296,6 +296,10 @@ class mail_mail(osv.Model): # see revid:odo@openerp.com-20120622152536-42b2s28lvdv3odyr in 6.1 if mail_sent: self._postprocess_sent_message(cr, uid, mail, context=context) + except MemoryError: + # prevent catching transient MemoryErrors, bubble up to notify user or abort cron job + # instead of marking the mail as failed + raise except Exception as e: _logger.exception('failed sending mail.mail %s', mail.id) mail.write({'state': 'exception'}) diff --git a/addons/multi_company/multi_company_demo.xml b/addons/multi_company/multi_company_demo.xml index 44a021c1434..d7d1af24f07 100644 --- a/addons/multi_company/multi_company_demo.xml +++ b/addons/multi_company/multi_company_demo.xml @@ -59,7 +59,7 @@ - + OpenERP US @@ -400,7 +400,7 @@ - + diff --git a/addons/stock/product.py b/addons/stock/product.py index 3eddf0a1c72..1cd93225d45 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -105,7 +105,9 @@ class product_product(osv.osv): 'compute_child': False }) - qty = product.qty_available + # qty_available depends of the location in the context + qty = self.read(cr, uid, [product.id], ['qty_available'], context=c)[0]['qty_available'] + diff = product.standard_price - new_price if not diff: raise osv.except_osv(_('Error!'), _("No difference between standard price and new price!")) if qty: diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 4707da2bbb0..dba3225e760 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -792,7 +792,7 @@ - + @@ -926,7 +926,7 @@ - +
@@ -1053,7 +1053,7 @@ - +
@@ -1340,7 +1340,7 @@ - +