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',
|
'name': 'Fusion Clock',
|
||||||
'version': '19.0.3.11.3',
|
'version': '19.0.3.11.4',
|
||||||
'category': 'Human Resources/Attendances',
|
'category': 'Human Resources/Attendances',
|
||||||
'summary': 'Complete Employee T&A with Geofencing, Shifts, Penalties, Overtime, Kiosk, Dashboard & Payroll Export',
|
'summary': 'Complete Employee T&A with Geofencing, Shifts, Penalties, Overtime, Kiosk, Dashboard & Payroll Export',
|
||||||
'description': """
|
'description': """
|
||||||
|
|||||||
@@ -256,6 +256,11 @@ class FusionClockNfcKiosk(http.Controller):
|
|||||||
if not emp.exists():
|
if not emp.exists():
|
||||||
return {'error': 'employee_not_found'}
|
return {'error': 'employee_not_found'}
|
||||||
emp.image_1920 = photo
|
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}
|
return {'success': True}
|
||||||
|
|
||||||
@http.route('/fusion_clock/kiosk/nfc/verify_pin', type='jsonrpc', auth='user', methods=['POST'])
|
@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
|
# freshly-saved profile photo never shows. write_date bumps on every
|
||||||
# write (incl. saving image_1920), so it refreshes exactly when needed.
|
# 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_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()
|
now = fields.Datetime.now()
|
||||||
today = get_local_today(request.env, employee)
|
today = get_local_today(request.env, employee)
|
||||||
day_plan = employee._get_fclk_day_plan(today)
|
day_plan = employee._get_fclk_day_plan(today)
|
||||||
|
|||||||
@@ -684,8 +684,8 @@ html:has(#nfc_kiosk_root) {
|
|||||||
.nfc-photo-stage {
|
.nfc-photo-stage {
|
||||||
position: relative;
|
position: relative;
|
||||||
aspect-ratio: 3 / 4; // portrait — width follows the (height-driven) box
|
aspect-ratio: 3 / 4; // portrait — width follows the (height-driven) box
|
||||||
height: 56vh;
|
height: 62vh;
|
||||||
max-height: 440px;
|
max-height: 520px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
@@ -706,7 +706,7 @@ html:has(#nfc_kiosk_root) {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 47%;
|
top: 47%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
width: 54%;
|
width: 64%;
|
||||||
aspect-ratio: 3 / 4; // VERTICAL oval — a face is taller than it is wide
|
aspect-ratio: 3 / 4; // VERTICAL oval — a face is taller than it is wide
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
border: 3px dashed rgba(255, 255, 255, 0.92);
|
border: 3px dashed rgba(255, 255, 255, 0.92);
|
||||||
|
|||||||
Reference in New Issue
Block a user