This commit is contained in:
gsinghpal
2026-03-16 08:14:56 -04:00
parent fdca9518ab
commit e56974d46f
196 changed files with 19739 additions and 3471 deletions

View File

@@ -14,6 +14,45 @@ _logger = logging.getLogger(__name__)
class AuthorizerPortal(CustomerPortal):
"""Portal controller for Authorizers (OTs/Therapists)"""
def _get_user_tz(self):
"""Return a pytz timezone from the best available source.
Priority: user tz > browser cookie > company calendar > UTC."""
candidates = [
request.env.user.tz,
]
try:
candidates.append(request.httprequest.cookies.get('tz'))
except Exception:
pass
try:
cal = request.env.company.resource_calendar_id
if cal:
candidates.append(cal.tz)
except Exception:
pass
for tz_name in candidates:
if tz_name:
try:
return pytz.timezone(tz_name)
except pytz.exceptions.UnknownTimeZoneError:
continue
return pytz.UTC
@http.route('/my/timezone/detect', type='jsonrpc', auth='user', website=True)
def timezone_auto_detect(self, timezone=None, **kw):
"""Auto-save browser-detected timezone to the user profile if not already set."""
if not timezone:
return {'status': 'ignored'}
user = request.env.user
if user.tz:
return {'status': 'already_set', 'tz': user.tz}
try:
pytz.timezone(timezone)
except pytz.exceptions.UnknownTimeZoneError:
return {'status': 'invalid'}
user.sudo().write({'tz': timezone})
return {'status': 'saved', 'tz': timezone}
@http.route(['/my', '/my/home'], type='http', auth='user', website=True)
def home(self, **kw):
"""Override home to add ADP posting info for Fusion users"""
@@ -111,15 +150,8 @@ class AuthorizerPortal(CustomerPortal):
except (ValueError, TypeError):
base_date = date(2026, 1, 23)
# Get user's timezone for accurate date display
user_tz = request.env.user.tz or 'UTC'
try:
tz = pytz.timezone(user_tz)
except pytz.exceptions.UnknownTimeZoneError:
tz = pytz.UTC
# Get today's date in user's timezone
from datetime import datetime
tz = self._get_user_tz()
now_utc = datetime.now(pytz.UTC)
now_local = now_utc.astimezone(tz)
today = now_local.date()
@@ -1116,14 +1148,27 @@ class AuthorizerPortal(CustomerPortal):
('check_out', '=', False),
], limit=1)
if att:
check_in_time = att.check_in.isoformat() if att.check_in else ''
check_in_time = (att.check_in.isoformat() + 'Z') if att.check_in else ''
location_name = att.x_fclk_location_id.name if att.x_fclk_location_id else ''
from datetime import datetime
tz = self._get_user_tz()
now_local = pytz.utc.localize(fields.Datetime.now()).astimezone(tz)
today_local = now_local.date()
today_start = tz.localize(datetime.combine(today_local, datetime.min.time())).astimezone(pytz.utc).replace(tzinfo=None)
today_atts = request.env['hr.attendance'].sudo().search([
('employee_id', '=', employee.id),
('check_in', '>=', today_start),
('check_out', '!=', False),
])
today_hours = sum(a.x_fclk_net_hours or 0 for a in today_atts)
return {
'clock_enabled': True,
'clock_checked_in': is_checked_in,
'clock_check_in_time': check_in_time,
'clock_location_name': location_name,
'clock_today_hours': round(today_hours, 1),
}
except Exception as e:
_logger.warning("Clock status check failed: %s", e)
@@ -1310,10 +1355,18 @@ class AuthorizerPortal(CustomerPortal):
('id', '!=', task.id),
], order='time_start', limit=1)
# Get order lines if linked to a sale order
# Get order lines from linked sale order or purchase order
order_lines = []
linked_order = False
linked_order_type = ''
if task.sale_order_id:
linked_order = task.sale_order_id
linked_order_type = 'sale'
order_lines = task.sale_order_id.order_line.filtered(lambda l: not l.display_type)
elif task.purchase_order_id:
linked_order = task.purchase_order_id
linked_order_type = 'purchase'
order_lines = task.purchase_order_id.order_line
# Get VAPID public key for push notifications
vapid_public = request.env['ir.config_parameter'].sudo().get_param(
@@ -1323,6 +1376,8 @@ class AuthorizerPortal(CustomerPortal):
values = {
'task': task,
'order_lines': order_lines,
'linked_order': linked_order,
'linked_order_type': linked_order_type,
'vapid_public_key': vapid_public,
'page_name': 'technician_task_detail',
'earlier_incomplete': earlier_incomplete,
@@ -1384,7 +1439,9 @@ class AuthorizerPortal(CustomerPortal):
safe_notes = str(escape(notes or ''))
formatted_notes = re.sub(r'\n', '<br/>', safe_notes)
timestamp = fields.Datetime.now().strftime("%b %d, %Y %I:%M %p")
tz = self._get_user_tz()
local_now = pytz.utc.localize(fields.Datetime.now()).astimezone(tz)
timestamp = local_now.strftime("%b %d, %Y %I:%M %p")
safe_user = str(escape(user.name))
safe_task = str(escape(task.name))
@@ -2077,7 +2134,7 @@ class AuthorizerPortal(CustomerPortal):
'x_fc_pod_client_name': client_name.strip(),
'x_fc_pod_signature_date': sig_date,
'x_fc_pod_signed_by_user_id': user.id,
'x_fc_pod_signed_datetime': datetime.now(),
'x_fc_pod_signed_datetime': fields.Datetime.now(),
})
# Generate the signed POD PDF