fix(fusion_clock): kiosk photo now shows on clock + profile (right image fields)
Root-caused on live entech (not guessed): - The kiosk runs as a non-HR operator (uid 141) who gets AccessError reading hr.employee images, so /web/image served a placeholder. Point the result-card avatar at hr.employee.public/avatar_128 — verified readable as the operator, returns the real photo. (Odoo's own UI uses .public for employee images.) - The Odoo profile/preferences avatar is res.users → res.partner.image_1920, which the capture never wrote. Propagate the captured photo to the linked user's partner image so the profile updates too. - Enlarge the capture oval (it was small): stage 62vh/520px, guide width 64%. Live as 19.0.3.11.4. Also backfilled the existing test photo to the user's partner image so the profile shows it without re-capturing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
{
|
||||
'name': 'Fusion Clock',
|
||||
'version': '19.0.3.11.3',
|
||||
'version': '19.0.3.11.4',
|
||||
'category': 'Human Resources/Attendances',
|
||||
'summary': 'Complete Employee T&A with Geofencing, Shifts, Penalties, Overtime, Kiosk, Dashboard & Payroll Export',
|
||||
'description': """
|
||||
|
||||
@@ -256,6 +256,11 @@ class FusionClockNfcKiosk(http.Controller):
|
||||
if not emp.exists():
|
||||
return {'error': 'employee_not_found'}
|
||||
emp.image_1920 = photo
|
||||
# Also push to the linked user's partner image, which is the image Odoo
|
||||
# shows on the user's profile/preferences avatar (res.users delegates
|
||||
# image_1920 to res.partner). Employees with no user are HR-only photos.
|
||||
if emp.user_id and emp.user_id.partner_id:
|
||||
emp.user_id.partner_id.sudo().write({'image_1920': photo})
|
||||
return {'success': True}
|
||||
|
||||
@http.route('/fusion_clock/kiosk/nfc/verify_pin', type='jsonrpc', auth='user', methods=['POST'])
|
||||
@@ -311,7 +316,11 @@ class FusionClockNfcKiosk(http.Controller):
|
||||
# freshly-saved profile photo never shows. write_date bumps on every
|
||||
# write (incl. saving image_1920), so it refreshes exactly when needed.
|
||||
avatar_unique = employee.write_date.strftime('%Y%m%d%H%M%S') if employee.write_date else ''
|
||||
avatar_url = f'/web/image/hr.employee/{employee.id}/avatar_128?unique={avatar_unique}'
|
||||
# PUBLIC model: the kiosk runs as a non-HR operator who can't read
|
||||
# hr.employee images (ACL) — /web/image would serve a placeholder.
|
||||
# hr.employee.public exposes the same avatar to any internal user
|
||||
# (verified readable as the kiosk operator, uid 141).
|
||||
avatar_url = f'/web/image/hr.employee.public/{employee.id}/avatar_128?unique={avatar_unique}'
|
||||
now = fields.Datetime.now()
|
||||
today = get_local_today(request.env, employee)
|
||||
day_plan = employee._get_fclk_day_plan(today)
|
||||
|
||||
@@ -684,8 +684,8 @@ html:has(#nfc_kiosk_root) {
|
||||
.nfc-photo-stage {
|
||||
position: relative;
|
||||
aspect-ratio: 3 / 4; // portrait — width follows the (height-driven) box
|
||||
height: 56vh;
|
||||
max-height: 440px;
|
||||
height: 62vh;
|
||||
max-height: 520px;
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
border-radius: 1rem;
|
||||
@@ -706,7 +706,7 @@ html:has(#nfc_kiosk_root) {
|
||||
position: absolute;
|
||||
top: 47%;
|
||||
left: 50%;
|
||||
width: 54%;
|
||||
width: 64%;
|
||||
aspect-ratio: 3 / 4; // VERTICAL oval — a face is taller than it is wide
|
||||
transform: translate(-50%, -50%);
|
||||
border: 3px dashed rgba(255, 255, 255, 0.92);
|
||||
|
||||
Reference in New Issue
Block a user