How to use Open function on server script on Core doctype?

I added some field to User doctype like foto_vaksin with type attach image,
and my goal is, when user save/upload foto_vaksin then that image will be renamed to user full_name.extension and file uploaded to file manager Home/Users/Foto Vaksin/<full_name>.extension

This is my code on server script doctype with type after save

def create_folders_if_not_exist(base_path, folder_path):
    # Pisahkan path menjadi komponen folder
    folders = folder_path.split('/')

    # Variable untuk melacak full path dari folder
    current_folder = base_path

    # Loop melalui setiap folder di path
    for folder in folders:
        current_folder = f"{current_folder}/{folder}"

        # Jika folder belum ada, buat folder baru
        if not frappe.db.exists('File', current_folder):
            folder_doc = frappe.get_doc({
                "doctype": "File",
                "file_name": folder,
                "folder": base_path if current_folder == f"{base_path}/{folder}" else current_folder.rsplit('/', 1)[0],
                "is_folder": 1,
                "is_private": 1
            })
            folder_doc.save()
            frappe.logger().info(f"Folder '{folder}' created in '{current_folder}'")


if doc.foto_vaksin:
    with open(foto_vaksin, 'rb') as f:
        file_data = f.read()

    user_name = doc.full_name.replace(' ', '_')  # Replace spaces with underscores
    file_doc = frappe.get_doc("File", {"file_url": doc.foto_vaksin})
    file_path = file_doc.file_url

    # Get the extension of the file
    ext = file_path.split('.')[-1]

    # Set the new file name and destination folder
    new_file_name = f"{user_name}.{ext}"

    folder_structure = "Users/Foto Vaksin"
    create_folders_if_not_exist("Home", folder_structure)

    final_folder = f'Home/{folder_structure}'

    file_doc = frappe.get_doc({
        "doctype": "File",
        "file_name": new_file_name,
        "folder": final_folder,
        "content": file_data,
        "is_private": 1,
        "ignore_duplicate_entry_error": True
    })
    file_doc.save()

    doc.foto_vaksin = file_doc.file_url

but thats generate error

### App Versions

{
“frappe”: “16.0.0-dev”,
“hr_management”: “0.0.1”
}

### Route

Form/User/lcm@gmail.com

### Traceback

Traceback (most recent call last):
File “apps/frappe/frappe/app.py”, line 115, in application
response = frappe.api.handle(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/api/init.py”, line 49, in handle
data = endpoint(**arguments)
^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/api/v1.py”, line 36, in handle_rpc_call
return frappe.handler.handle()
^^^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/handler.py”, line 49, in handle
data = execute_cmd(cmd)
^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/handler.py”, line 85, in execute_cmd
return frappe.call(method, **frappe.form_dict)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/init.py”, line 1822, in call
return fn(*args, **newargs)
^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/utils/typing_validations.py”, line 32, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/desk/form/save.py”, line 39, in savedocs
doc.save()
File “apps/frappe/frappe/model/document.py”, line 340, in save
return self._save(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/model/document.py”, line 393, in _save
self.run_post_save_methods()
File “apps/frappe/frappe/model/document.py”, line 1164, in run_post_save_methods
self.run_method(“on_update”)
File “apps/frappe/frappe/model/document.py”, line 983, in run_method
run_server_script_for_doc_event(self, method)
File “apps/frappe/frappe/core/doctype/server_script/server_script_utils.py”, line 49, in run_server_script_for_doc_event
frappe.get_cached_doc(“Server Script”, script_name).execute_doc(doc)
File “apps/frappe/frappe/core/doctype/server_script/server_script.py”, line 186, in execute_doc
safe_exec(
File “apps/frappe/frappe/utils/safe_exec.py”, line 113, in safe_exec
exec(
File “: save_foto_to_consistent_directory”, line 26, in
NameError: name ‘open’ is not defined

### Request Data

{
“type”: “POST”,
“args”: {
“doc”: “{"name":"lcm@gmail.com","owner":"Administrator","creation":"2024-09-25 22:59:01.682542","modified":"2024-09-26 08:48:20.074242","modified_by":"Administrator","docstatus":0,"idx":0,"enabled":1,"email":"lcm@gmail.com","first_name":"dsw","full_name":"dsw","username":"dsw","language":"en","time_zone":"Asia/Kolkata","send_welcome_email":1,"unsubscribed":0,"mute_sounds":0,"desk_theme":"Light","code_editor_type":"vscode","new_password":"","logout_all_sessions":1,"reset_password_key":"","last_reset_password_key_generated_on":"","document_follow_notify":0,"document_follow_frequency":"Daily","follow_created_documents":0,"follow_commented_documents":0,"follow_liked_documents":0,"follow_assigned_documents":0,"follow_shared_documents":0,"thread_notify":1,"send_me_a_copy":0,"allowed_in_mentions":1,"simultaneous_sessions":2,"login_after":0,"user_type":"Website User","login_before":0,"bypass_restrict_ip_check_if_2fa_enabled":0,"onboarding_status":"{}","no_ktp":0,"foto_ktp":"/private/files/Picture1.png","agama":"Islam","no_rek_bca":0,"pendidikan_terakhir":"SD","status_kontrak":"Project Base","foto_vaksin":"/private/files/Picture1.png","sudah_menikah":0,"jumlah_anak":0,"doctype":"User","social_logins":[{"name":"k05qbd2kdj","owner":"Administrator","creation":"2024-09-25 22:59:01.803480","modified":"2024-09-26 08:48:20.074242","modified_by":"Administrator","docstatus":0,"idx":1,"provider":"frappe","userid":"b50f1a8f90b09e75d7fcb550057e71742ec4776","parent":"lcm@gmail.com","parentfield":"social_logins","parenttype":"User","doctype":"User Social Login"}],"role_profiles":,"user_emails":,"defaults":,"roles":,"block_modules":,"__onload":{"all_modules":["Automation","Contacts","Core","Custom","Desk","Email","Geo","Hr Management","Integrations","Printing","Social","Website","Workflow"]},"__last_sync_on":"2024-09-26T01:48:43.590Z","__unsaved":1}”,
“action”: “Save”
},
“freeze”: true,
“headers”: {},
“error_handlers”: {},
“url”: “/api/method/frappe.desk.form.save.savedocs”,
“request_id”: null
}

### Response Data

{
“exception”: “NameError: name ‘open’ is not defined”,
“exc_type”: “NameError”,
“_exc_source”: “Server Script”
}

Lots of limitation in server script doctype because certain operations are restricted in safe_exec.
If you develop the larger level code then go with a custom app and develop them.

I try to custom user core doctype with some employee field like joined at to company etc, So that my employee can login with user account. Is that wrong? Should i make employee doctype separate with user doctype?