From c1afba4742c73bd25b818515b27d793869b25fd2 Mon Sep 17 00:00:00 2001 From: Jigar Amin Date: Tue, 26 Mar 2013 05:14:37 -0700 Subject: [PATCH] [FIX] SO/PO: Fixed date to dateime convestion for expected date based on Order Date, Converstion is based on assumption date date will be in user tz and taking 12:00 hours time to make right time converstion bzr revid: jam@tinyerp.com-20130326121437-89c42jtdw7qv3l2w --- addons/purchase/purchase.py | 37 ++++++++++++++++++++++++++------- addons/sale/sale.py | 2 +- addons/sale_stock/sale_stock.py | 34 ++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 17f2e9b4592..1041b016fb3 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -20,6 +20,8 @@ ############################################################################## import time +import pytz +from openerp import SUPERUSER_ID from datetime import datetime from dateutil.relativedelta import relativedelta @@ -29,7 +31,7 @@ from openerp import pooler from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp from openerp.osv.orm import browse_record, browse_null -from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, DEFAULT_SERVER_TIME_FORMAT +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP class purchase_order(osv.osv): @@ -226,7 +228,7 @@ class purchase_order(osv.osv): 'journal_id': fields.many2one('account.journal', 'Journal'), } _defaults = { - 'date_order': lambda *args: datetime.now().strftime(DEFAULT_SERVER_DATE_FORMAT), + 'date_order': fields.date.context_today, 'state': 'draft', 'name': lambda obj, cr, uid, context: '/', 'shipped': 0, @@ -593,15 +595,34 @@ class purchase_order(osv.osv): wf_service.trg_validate(uid, 'purchase.order', id, 'purchase_cancel', cr) return True - def _get_gmtdatetime(self, cr, uid, utcdate, context=None): - nowutctime = datetime.utcnow().strftime(DEFAULT_SERVER_TIME_FORMAT) - return "%s %s"%(utcdate, nowutctime) + def date_to_datetime(self, cr, uid, userdate, context=None): + """ + Function accepts date string assumed in client TZ and result is produced + in UTC timezone with 12:00 is assumed time to be sure, that system will + avoid tz date converstion issues. + e.g. Date 2013-03-26 in user tz will get 12:00 Hours and will then + get converted to UTC to avoid tz converstion. + userdate: date string in in user time zone. + return : the utc datetime string. + """ + user_datetime = datetime.strptime(userdate, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(hours=12.0) + if context and context.get('tz'): + tz_name = context['tz'] + else: + tz_name = self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz'] + if not tz_name: + tz_name = time.tzname[time.daylight] + utc = pytz.timezone('UTC') + context_tz = pytz.timezone(tz_name) + local_timestamp = context_tz.localize(user_datetime, is_dst=False) + user_datetime = local_timestamp.astimezone(utc) + return user_datetime.strftime(DEFAULT_SERVER_DATETIME_FORMAT) def _prepare_order_picking(self, cr, uid, order, context=None): return { 'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.in'), 'origin': order.name + ((order.origin and (':' + order.origin)) or ''), - 'date': self._get_gmtdatetime(cr, uid, order.date_order, context), + 'date': self.date_to_datetime(cr, uid, order.date_order, context), 'partner_id': order.dest_address_id.id or order.partner_id.id, 'invoice_state': '2binvoiced' if order.invoice_method == 'picking' else 'none', 'type': 'in', @@ -619,8 +640,8 @@ class purchase_order(osv.osv): 'product_uos_qty': order_line.product_qty, 'product_uom': order_line.product_uom.id, 'product_uos': order_line.product_uom.id, - 'date': self._get_gmtdatetime(cr, uid, order.date_order, context), - 'date_expected': self._get_gmtdatetime(cr, uid, order.date_order, context), + 'date': self.date_to_datetime(cr, uid, order.date_order, context), + 'date_expected': self.date_to_datetime(cr, uid, order.date_order, context), 'location_id': order.partner_id.property_stock_supplier.id, 'location_dest_id': order.location_id.id, 'picking_id': picking_id, diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 99a8e875f77..3655b3a8184 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -252,7 +252,7 @@ class sale_order(osv.osv): 'company_id': fields.related('shop_id','company_id',type='many2one',relation='res.company',string='Company',store=True,readonly=True) } _defaults = { - 'date_order': lambda *args: datetime.now().strftime(DEFAULT_SERVER_DATE_FORMAT), + 'date_order': fields.date.context_today, 'order_policy': 'manual', 'state': 'draft', 'user_id': lambda obj, cr, uid, context: uid, diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index 04289abb294..3fb41895d6e 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -20,11 +20,14 @@ # ############################################################################## from datetime import datetime, timedelta -from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, float_compare, DEFAULT_SERVER_TIME_FORMAT +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, float_compare from dateutil.relativedelta import relativedelta from openerp.osv import fields, osv from openerp import netsvc from openerp.tools.translate import _ +import pytz +import time +from openerp import SUPERUSER_ID class sale_shop(osv.osv): _inherit = "sale.shop" @@ -232,9 +235,28 @@ class sale_order(osv.osv): res.append(line.procurement_id.id) return res - def _get_gmtdatetime(self, cr, uid, utcdate, context=None): - nowutctime = datetime.utcnow().strftime(DEFAULT_SERVER_TIME_FORMAT) - return "%s %s"%(utcdate, nowutctime) + def date_to_datetime(self, cr, uid, userdate, context=None): + """ + Function accepts date string assumed in client TZ and result is produced + in UTC timezone with 12:00 is assumed time to be sure, that system will + avoid tz date converstion issues. + e.g. Date 2013-03-26 in user tz will get 12:00 Hours and will then + get converted to UTC to avoid tz converstion. + userdate: date string in in user time zone. + return : the utc datetime string. + """ + user_datetime = datetime.strptime(userdate, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(hours=12.0) + if context and context.get('tz'): + tz_name = context['tz'] + else: + tz_name = self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz'] + if not tz_name: + tz_name = time.tzname[time.daylight] + utc = pytz.timezone('UTC') + context_tz = pytz.timezone(tz_name) + local_timestamp = context_tz.localize(user_datetime, is_dst=False) + user_datetime = local_timestamp.astimezone(utc) + return user_datetime.strftime(DEFAULT_SERVER_DATETIME_FORMAT) # if mode == 'finished': # returns True if all lines are done, False otherwise @@ -318,7 +340,7 @@ class sale_order(osv.osv): return { 'name': pick_name, 'origin': order.name, - 'date': self._get_gmtdatetime(cr, uid, order.date_order, context), + 'date': self.date_to_datetime(cr, uid, order.date_order, context), 'type': 'out', 'state': 'auto', 'move_type': order.picking_policy, @@ -352,7 +374,7 @@ class sale_order(osv.osv): return True def _get_date_planned(self, cr, uid, order, line, start_date, context=None): - start_date = self._get_gmtdatetime(cr, uid, start_date, context) + start_date = self.date_to_datetime(cr, uid, start_date, context) date_planned = datetime.strptime(start_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=line.delay or 0.0) date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT) return date_planned