Skip to content

Staff

qgendapy.resources.staff

StaffResource(client)

Bases: BaseResource

Synchronous staff member endpoints.

Source code in src/qgendapy/resources/_base.py
def __init__(self, client: QGendaClient) -> None:
    self._client = client

list(*, odata=None, expand=None, includes=None)

List staff members.

expand is a convenience shortcut for OData().expand(...) — pass a string (expand="Tags") or a list of nav properties to request expanded entities. Valid OData v4 nav names on StaffMemberDetailDto include Tags, Skillset (singular), and Profiles.

includes is QGenda's own related-entity selector (separate from OData $expand). For schedule-style endpoints it returns rich nested data even under non-admin scope; on /staffmember its behavior should be verified per-deployment.

Source code in src/qgendapy/resources/staff.py
def list(
    self,
    *,
    odata: OData | None = None,
    expand: str | Sequence[str] | None = None,
    includes: str | None = None,
) -> QGendaResponse[StaffMember]:
    """List staff members.

    ``expand`` is a convenience shortcut for ``OData().expand(...)`` —
    pass a string (``expand="Tags"``) or a list of nav properties to
    request expanded entities. Valid OData v4 nav names on
    ``StaffMemberDetailDto`` include ``Tags``, ``Skillset`` (singular),
    and ``Profiles``.

    ``includes`` is QGenda's own related-entity selector (separate from
    OData ``$expand``). For schedule-style endpoints it returns rich
    nested data even under non-admin scope; on ``/staffmember`` its
    behavior should be verified per-deployment.
    """
    params: dict[str, str] = {"companyKey": self._client.company_key}
    if includes:
        params["includes"] = includes
    return self._get(
        "/staffmember",
        params=params,
        model=StaffMember,
        odata=merge_expand(expand, odata),
    )

create(*, data)

Source code in src/qgendapy/resources/staff.py
def create(self, *, data: dict) -> QGendaResponse[StaffMember]:
    return self._post("/staffmember", json=data, model=StaffMember)

get(staff_key, *, odata=None, expand=None, includes=None)

Source code in src/qgendapy/resources/staff.py
def get(
    self,
    staff_key: str,
    *,
    odata: OData | None = None,
    expand: str | Sequence[str] | None = None,
    includes: str | None = None,
) -> QGendaResponse[StaffMember]:
    params: dict[str, str] = {}
    if includes:
        params["includes"] = includes
    return self._get(
        f"/staffmember/{staff_key}",
        params=params or None,
        model=StaffMember,
        odata=merge_expand(expand, odata),
    )

update(staff_key, *, data)

Source code in src/qgendapy/resources/staff.py
def update(self, staff_key: str, *, data: dict) -> QGendaResponse[StaffMember]:
    return self._put(f"/staffmember/{staff_key}", json=data, model=StaffMember)

locations(staff_key)

Source code in src/qgendapy/resources/staff.py
def locations(self, staff_key: str) -> QGendaResponse:
    return self._get(f"/staffmember/{staff_key}/location")

tags(staff_key)

Return tags for a single staff member.

QGenda's API does not expose GET /staffmember/{key}/tag (it returns 405). This method instead issues GET /staffmember?$filter=StaffKey eq '<key>'&$expand=Tags and unwraps the Tags navigation collection.

Returns an empty list under non-admin scope. The Tags navigation property exists on QGenda's DTO but only populates for admin-scoped service accounts. If you need tag/profile catalogs, provision the API user with admin scope and call client.tag.list().

Source code in src/qgendapy/resources/staff.py
def tags(self, staff_key: str) -> QGendaResponse[StaffTag]:
    """Return tags for a single staff member.

    QGenda's API does not expose ``GET /staffmember/{key}/tag`` (it
    returns 405). This method instead issues
    ``GET /staffmember?$filter=StaffKey eq '<key>'&$expand=Tags`` and
    unwraps the ``Tags`` navigation collection.

    **Returns an empty list under non-admin scope.** The ``Tags``
    navigation property exists on QGenda's DTO but only populates for
    admin-scoped service accounts. If you need tag/profile catalogs,
    provision the API user with admin scope and call
    ``client.tag.list()``.
    """
    params: dict[str, str] = {"companyKey": self._client.company_key}
    odata = OData().filter(f"StaffKey eq '{escape_literal(staff_key)}'").expand("Tags")
    raw = self._get("/staffmember", params=params, odata=odata)
    tag_dicts = _extract_nested(raw.data, "Tags")
    return QGendaResponse(
        data=tag_dicts,
        status_code=raw.status_code,
        headers=raw.headers,
        items=[StaffTag.from_dict(d) for d in tag_dicts],
    )

add_tag(staff_key, *, data)

Source code in src/qgendapy/resources/staff.py
def add_tag(self, staff_key: str, *, data: dict) -> QGendaResponse[StaffTag]:
    return self._post(f"/staffmember/{staff_key}/tag", json=data, model=StaffTag)

update_location_tag(staff_key, location_key, *, data)

Source code in src/qgendapy/resources/staff.py
def update_location_tag(
    self, staff_key: str, location_key: str, *, data: dict
) -> QGendaResponse:
    return self._put(f"/staffmember/{staff_key}/location/{location_key}/tag", json=data)

skillsets(staff_key)

Return skillsets for a single staff member.

QGenda's API does not expose GET /staffmember/{key}/skillset (it returns 405). This method instead issues GET /staffmember?$filter=StaffKey eq '<key>'&$expand=Skillset — note the singular Skillset nav property — and unwraps the navigation collection.

Returns an empty list under non-admin scope. Like Tags, the Skillset navigation populates only for admin-scoped accounts.

Source code in src/qgendapy/resources/staff.py
def skillsets(self, staff_key: str) -> QGendaResponse[StaffSkillset]:
    """Return skillsets for a single staff member.

    QGenda's API does not expose ``GET /staffmember/{key}/skillset`` (it
    returns 405). This method instead issues
    ``GET /staffmember?$filter=StaffKey eq '<key>'&$expand=Skillset`` —
    note the singular ``Skillset`` nav property — and unwraps the
    navigation collection.

    **Returns an empty list under non-admin scope.** Like ``Tags``, the
    ``Skillset`` navigation populates only for admin-scoped accounts.
    """
    params: dict[str, str] = {"companyKey": self._client.company_key}
    odata = OData().filter(f"StaffKey eq '{escape_literal(staff_key)}'").expand("Skillset")
    raw = self._get("/staffmember", params=params, odata=odata)
    skillset_dicts = _extract_nested(raw.data, "Skillset")
    return QGendaResponse(
        data=skillset_dicts,
        status_code=raw.status_code,
        headers=raw.headers,
        items=[StaffSkillset.from_dict(d) for d in skillset_dicts],
    )

update_skillset(staff_key, task_key, *, data)

Source code in src/qgendapy/resources/staff.py
def update_skillset(
    self, staff_key: str, task_key: str, *, data: dict
) -> QGendaResponse[StaffSkillset]:
    return self._put(
        f"/staffmember/{staff_key}/skillset/{task_key}",
        json=data,
        model=StaffSkillset,
    )

delete_skillset(staff_key, task_key)

Source code in src/qgendapy/resources/staff.py
def delete_skillset(self, staff_key: str, task_key: str) -> QGendaResponse:
    return self._delete(f"/staffmember/{staff_key}/skillset/{task_key}")

profiles(staff_key)

Source code in src/qgendapy/resources/staff.py
def profiles(self, staff_key: str) -> QGendaResponse[StaffProfile]:
    return self._get(f"/staffmember/{staff_key}/profile", model=StaffProfile)

update_profile(staff_key, profile_key, *, data)

Source code in src/qgendapy/resources/staff.py
def update_profile(
    self, staff_key: str, profile_key: str, *, data: dict
) -> QGendaResponse[StaffProfile]:
    return self._put(
        f"/staffmember/{staff_key}/profile/{profile_key}",
        json=data,
        model=StaffProfile,
    )

pay_modifiers(staff_key)

Source code in src/qgendapy/resources/staff.py
def pay_modifiers(self, staff_key: str) -> QGendaResponse[PayModifier]:
    return self._get(f"/staffmember/{staff_key}/payModifier", model=PayModifier)

create_pay_modifier(staff_key, *, data)

Source code in src/qgendapy/resources/staff.py
def create_pay_modifier(self, staff_key: str, *, data: dict) -> QGendaResponse[PayModifier]:
    return self._post(f"/staffmember/{staff_key}/payModifier", json=data, model=PayModifier)

update_pay_modifier(staff_key, pay_modifier_key, *, data)

Source code in src/qgendapy/resources/staff.py
def update_pay_modifier(
    self, staff_key: str, pay_modifier_key: str, *, data: dict
) -> QGendaResponse[PayModifier]:
    return self._put(
        f"/staffmember/{staff_key}/payModifier/{pay_modifier_key}",
        json=data,
        model=PayModifier,
    )

delete_pay_modifier(staff_key, pay_modifier_key)

Source code in src/qgendapy/resources/staff.py
def delete_pay_modifier(self, staff_key: str, pay_modifier_key: str) -> QGendaResponse:
    return self._delete(f"/staffmember/{staff_key}/payModifier/{pay_modifier_key}")

badge_id(staff_key)

Source code in src/qgendapy/resources/staff.py
def badge_id(self, staff_key: str) -> QGendaResponse:
    return self._get(f"/staffmember/{staff_key}/badgeId")

request_limits(staff_key)

Source code in src/qgendapy/resources/staff.py
def request_limits(self, staff_key: str) -> QGendaResponse:
    return self._get(f"/staffmember/{staff_key}/requestlimit")

set_manager(staff_key, *, data)

Source code in src/qgendapy/resources/staff.py
def set_manager(self, staff_key: str, *, data: dict) -> QGendaResponse:
    return self._post(f"/staffmember/{staff_key}/manager", json=data)

AsyncStaffResource(client)

Bases: AsyncBaseResource

Asynchronous staff member endpoints.

Source code in src/qgendapy/resources/_base.py
def __init__(self, client: AsyncQGendaClient) -> None:
    self._client = client

list(*, odata=None, expand=None, includes=None) async

Source code in src/qgendapy/resources/staff.py
async def list(
    self,
    *,
    odata: OData | None = None,
    expand: str | Sequence[str] | None = None,
    includes: str | None = None,
) -> QGendaResponse[StaffMember]:
    params: dict[str, str] = {"companyKey": self._client.company_key}
    if includes:
        params["includes"] = includes
    return await self._get(
        "/staffmember",
        params=params,
        model=StaffMember,
        odata=merge_expand(expand, odata),
    )

create(*, data) async

Source code in src/qgendapy/resources/staff.py
async def create(self, *, data: dict) -> QGendaResponse[StaffMember]:
    return await self._post("/staffmember", json=data, model=StaffMember)

get(staff_key, *, odata=None, expand=None, includes=None) async

Source code in src/qgendapy/resources/staff.py
async def get(
    self,
    staff_key: str,
    *,
    odata: OData | None = None,
    expand: str | Sequence[str] | None = None,
    includes: str | None = None,
) -> QGendaResponse[StaffMember]:
    params: dict[str, str] = {}
    if includes:
        params["includes"] = includes
    return await self._get(
        f"/staffmember/{staff_key}",
        params=params or None,
        model=StaffMember,
        odata=merge_expand(expand, odata),
    )

update(staff_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def update(self, staff_key: str, *, data: dict) -> QGendaResponse[StaffMember]:
    return await self._put(f"/staffmember/{staff_key}", json=data, model=StaffMember)

locations(staff_key) async

Source code in src/qgendapy/resources/staff.py
async def locations(self, staff_key: str) -> QGendaResponse:
    return await self._get(f"/staffmember/{staff_key}/location")

tags(staff_key) async

Async version of :meth:StaffResource.tags.

Source code in src/qgendapy/resources/staff.py
async def tags(self, staff_key: str) -> QGendaResponse[StaffTag]:
    """Async version of :meth:`StaffResource.tags`."""
    params: dict[str, str] = {"companyKey": self._client.company_key}
    odata = OData().filter(f"StaffKey eq '{escape_literal(staff_key)}'").expand("Tags")
    raw = await self._get("/staffmember", params=params, odata=odata)
    tag_dicts = _extract_nested(raw.data, "Tags")
    return QGendaResponse(
        data=tag_dicts,
        status_code=raw.status_code,
        headers=raw.headers,
        items=[StaffTag.from_dict(d) for d in tag_dicts],
    )

add_tag(staff_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def add_tag(self, staff_key: str, *, data: dict) -> QGendaResponse[StaffTag]:
    return await self._post(f"/staffmember/{staff_key}/tag", json=data, model=StaffTag)

update_location_tag(staff_key, location_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def update_location_tag(
    self, staff_key: str, location_key: str, *, data: dict
) -> QGendaResponse:
    return await self._put(f"/staffmember/{staff_key}/location/{location_key}/tag", json=data)

skillsets(staff_key) async

Async version of :meth:StaffResource.skillsets.

Source code in src/qgendapy/resources/staff.py
async def skillsets(self, staff_key: str) -> QGendaResponse[StaffSkillset]:
    """Async version of :meth:`StaffResource.skillsets`."""
    params: dict[str, str] = {"companyKey": self._client.company_key}
    odata = OData().filter(f"StaffKey eq '{escape_literal(staff_key)}'").expand("Skillset")
    raw = await self._get("/staffmember", params=params, odata=odata)
    skillset_dicts = _extract_nested(raw.data, "Skillset")
    return QGendaResponse(
        data=skillset_dicts,
        status_code=raw.status_code,
        headers=raw.headers,
        items=[StaffSkillset.from_dict(d) for d in skillset_dicts],
    )

update_skillset(staff_key, task_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def update_skillset(
    self, staff_key: str, task_key: str, *, data: dict
) -> QGendaResponse[StaffSkillset]:
    return await self._put(
        f"/staffmember/{staff_key}/skillset/{task_key}",
        json=data,
        model=StaffSkillset,
    )

delete_skillset(staff_key, task_key) async

Source code in src/qgendapy/resources/staff.py
async def delete_skillset(self, staff_key: str, task_key: str) -> QGendaResponse:
    return await self._delete(f"/staffmember/{staff_key}/skillset/{task_key}")

profiles(staff_key) async

Source code in src/qgendapy/resources/staff.py
async def profiles(self, staff_key: str) -> QGendaResponse[StaffProfile]:
    return await self._get(f"/staffmember/{staff_key}/profile", model=StaffProfile)

update_profile(staff_key, profile_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def update_profile(
    self, staff_key: str, profile_key: str, *, data: dict
) -> QGendaResponse[StaffProfile]:
    return await self._put(
        f"/staffmember/{staff_key}/profile/{profile_key}",
        json=data,
        model=StaffProfile,
    )

pay_modifiers(staff_key) async

Source code in src/qgendapy/resources/staff.py
async def pay_modifiers(self, staff_key: str) -> QGendaResponse[PayModifier]:
    return await self._get(f"/staffmember/{staff_key}/payModifier", model=PayModifier)

create_pay_modifier(staff_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def create_pay_modifier(
    self, staff_key: str, *, data: dict
) -> QGendaResponse[PayModifier]:
    return await self._post(
        f"/staffmember/{staff_key}/payModifier", json=data, model=PayModifier
    )

update_pay_modifier(staff_key, pay_modifier_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def update_pay_modifier(
    self, staff_key: str, pay_modifier_key: str, *, data: dict
) -> QGendaResponse[PayModifier]:
    return await self._put(
        f"/staffmember/{staff_key}/payModifier/{pay_modifier_key}",
        json=data,
        model=PayModifier,
    )

delete_pay_modifier(staff_key, pay_modifier_key) async

Source code in src/qgendapy/resources/staff.py
async def delete_pay_modifier(self, staff_key: str, pay_modifier_key: str) -> QGendaResponse:
    return await self._delete(f"/staffmember/{staff_key}/payModifier/{pay_modifier_key}")

badge_id(staff_key) async

Source code in src/qgendapy/resources/staff.py
async def badge_id(self, staff_key: str) -> QGendaResponse:
    return await self._get(f"/staffmember/{staff_key}/badgeId")

request_limits(staff_key) async

Source code in src/qgendapy/resources/staff.py
async def request_limits(self, staff_key: str) -> QGendaResponse:
    return await self._get(f"/staffmember/{staff_key}/requestlimit")

set_manager(staff_key, *, data) async

Source code in src/qgendapy/resources/staff.py
async def set_manager(self, staff_key: str, *, data: dict) -> QGendaResponse:
    return await self._post(f"/staffmember/{staff_key}/manager", json=data)