def person():

    # Enable this to allow migration of users between instances
    #s3.filter = (s3db.pr_person.pe_id == s3db.pr_person_user.pe_id) & \
                #(s3db.auth_user.id == s3db.pr_person_user.user_id) & \
                #(s3db.auth_user.registration_key != "disabled")

    # Organisation Dependent Fields
    set_org_dependent_field = settings.set_org_dependent_field
    set_org_dependent_field("pr_person_details", "father_name")
    set_org_dependent_field("pr_person_details", "mother_name")
    set_org_dependent_field("pr_person_details", "affiliations")
    set_org_dependent_field("pr_person_details", "company")

    def prep(r):
        if r.representation == "json" and \
           not r.component and session.s3.filter_staff:
            person_ids = session.s3.filter_staff
            session.s3.filter_staff = None
            r.resource.add_filter = (~(db.pr_person.id.belongs(person_ids)))
        elif r.interactive:
            if r.representation == "popup":
                # Hide "pe_label" and "missing" fields in person popups
                table = r.table
                table.pe_label.readable = table.pe_label.writable = False
                table.missing.readable = table.missing.writable = False

                # S3SQLCustomForm breaks popup return, so disable
                s3db.clear_config("pr_person", "crud_form")
            if r.component:
                component_name = r.component_name
                if component_name == "config":
                    ctable = s3db.gis_config
                    s3db.gis_config_form_setup()
                    # Name will be generated from person's name.
                    field = ctable.name
                    field.readable = field.writable = False
                    # Hide Location
                    field = ctable.region_location_id
                    field.readable = field.writable = False

                elif component_name == "competency":
                    ctable = s3db.hrm_competency
                    ctable.organisation_id.writable = False
                    ctable.skill_id.comment = None

                elif component_name == "group_membership":
                    s3db.configure("pr_group_membership",
                                   list_fields = ["id",
                                                  "group_id",
                                                  "group_head",
                                                  "comments",
                                                  ],
                                   )

        return True
    s3.prep = prep

    # Address tab
    if settings.get_pr_use_address():
        address_tab = (T("Address"), "address")
    else:
        address_tab = None

    # Contacts Tabs
    contacts_tabs = []
    set_method = s3db.set_method
    setting = settings.get_pr_contacts_tabs()
    if "all" in setting:
        s3db.set_method(module, resourcename,
                        method = "contacts",
                        action = s3db.pr_Contacts)
        contacts_tabs.append((T("Contacts"), "contacts"))
    if "public" in setting:
        s3db.set_method(module, resourcename,
                        method = "public_contacts",
                        action = s3db.pr_Contacts)
        contacts_tabs.append((T("Public Contacts"), "public_contacts"))
    if "private" in setting and auth.is_logged_in():
        s3db.set_method(module, resourcename,
                        method = "private_contacts",
                        action = s3db.pr_Contacts)
        contacts_tabs.append((T("Private Contacts"), "private_contacts"))

    # All tabs
    tabs = [(T("Basic Details"), None),
            address_tab,
            ]
    if contacts_tabs:
        tabs.extend(contacts_tabs)

    tabs.extend([(T("Images"), "image"),
                 (T("Identity"), "identity"),
                 (T("Education"), "education"),
                 (T("Groups"), "group_membership"),
                 (T("Journal"), "note"),
                 (T("Skills"), "competency"),
                 (T("Training"), "training"),
                 (T("Map Settings"), "config"),
                 ])

    s3db.configure("pr_person",
                   insertable = True,
                   listadd = False,
                   )

    output = s3_rest_controller(main = "first_name",
                                extra = "last_name",
                                rheader = lambda r: \
                                            s3db.pr_rheader(r, tabs=tabs))

    return output

# -----------------------------------------------------------------------------
RESTful CRUD controller
dataset/ETHPy150Open sahana/eden/controllers/pr.py/person