Voile.Schema.StockOpname (Voile v0.1.23)

Copy Markdown View Source

The StockOpname context for inventory checking functionality.

Handles stock opname (inventory check) sessions where librarians scan and verify physical items against database records.

Summary

Functions

Add an item to the session with snapshot (transaction-based). This is called when initializing the session, not during scanning.

Add multiple leftover items to an existing stock opname session. Only adds items that match the session's scope criteria.

Admin completes a librarian's assignment by assignment ID (Super Admin only).

Manually complete a librarian's work by admin.

Check if all assigned librarians have completed their work.

Approve a stock opname session.

Assign a single librarian to an existing session. Only allowed for sessions in 'draft', 'initializing', or 'in_progress' status.

Assign librarians to a session. Creates LibrarianAssignment records for each user.

Cancel a librarian's work completion and reopen their session.

Cancel a stock opname session.

Mark an item as checked with changes recorded in JSONB.

Check an item with collection updates during a stock opname session.

Complete a librarian's work session.

Complete a stock opname session (in_progress → pending_review). Flags unscanned items as missing within the session scope. Only Super Admin can complete sessions.

Count the number of items currently added to a session.

Creates a new stock opname session (Super Admin only).

Delete a stock opname session. Only allowed for 'approved' or 'cancelled' sessions.

Search for items by barcode, legacy_item_code, or item_code. Returns a list to handle duplicates.

Get librarian's progress in a session. Returns virtual assignment for super admins who aren't explicitly assigned.

Get a single stock opname session with all associations preloaded.

Get detailed report of all librarians' work in a session.

Get session review summary with detailed statistics.

Get session statistics.

Get a session without preloading items (for performance). Use this when you don't need the items list.

List librarians available for assignment to a session. Returns users with eligible staff roles who are not suspended, not already assigned to the session, and (if not super_admin) from the same node.

List items with changes for a session. Optimized query with database-level filtering.

List missing items for a session. Optimized query with database-level filtering. Missing items are tracked by changes->>'availability' = 'missing'.

List recent checked items for a specific user with limit. Optimized query that limits at database level to avoid loading all items.

List session items filtered by check status.

Get all librarians assigned to a session with their user details.

List stock opname sessions with pagination and filters.

List sessions pending review (Super Admin).

Recalculate and update session counters based on actual item states. Useful for fixing counter drift or after manual database updates.

Reject a stock opname session.

Remove a librarian from an existing session. Only allowed for sessions in 'draft', 'initializing', or 'in_progress' status. Cannot remove librarians who have completed their work.

Request revision on a session (send back to librarians).

Reset a session stuck in the "applying" state back to "pending_review".

Start a librarian's work session.

@doc """ Start a stock opname session (draft → in_progress). Only Super Admin can start sessions. Cannot start if status is "initializing".

Subscribe to real-time updates for a specific stock opname session.

Update a stock opname session.

Functions

add_item_to_session(session, item_id, user)

Add an item to the session with snapshot (transaction-based). This is called when initializing the session, not during scanning.

add_leftover_items_to_session(session_id, item_ids, user)

Add multiple leftover items to an existing stock opname session. Only adds items that match the session's scope criteria.

Parameters

  • session_id: The UUID of the stock opname session
  • item_ids: List of item UUIDs to potentially add
  • user: The user performing the operation

Returns

  • on success
  • on failure

admin_complete_librarian_assignment(assignment_id, admin_user)

Admin completes a librarian's assignment by assignment ID (Super Admin only).

admin_complete_librarian_work(session, user, notes \\ nil)

Manually complete a librarian's work by admin.

all_librarians_completed?(session)

Check if all assigned librarians have completed their work.

approve_session(session, admin_user, notes \\ nil)

Approve a stock opname session.

Returns {:ok, session} immediately after marking the session as "applying". The actual bulk item updates (Steps 1-3) run in a supervised background task so the caller is never blocked.

Subscribers on the topic "stock_opname:session:<id>" will receive either:

  • {:session_approved, %Session{}} on success
  • {:session_approval_failed, reason} on failure

Use subscribe_session/1 to subscribe before calling this function if you need real-time completion feedback in a LiveView.

assign_librarian(session, librarian_id, assigned_by_user)

Assign a single librarian to an existing session. Only allowed for sessions in 'draft', 'initializing', or 'in_progress' status.

assign_librarians(session, user_ids, admin_user)

Assign librarians to a session. Creates LibrarianAssignment records for each user.

cancel_librarian_completion(session, user)

Cancel a librarian's work completion and reopen their session.

cancel_session(session, admin_user)

Cancel a stock opname session.

check_item(session, opname_item_id, changes, notes, user)

Mark an item as checked with changes recorded in JSONB.

Parameters

  • session: The stock opname session
  • opname_item_id: The ID of the stock_opname_item record
  • changes: Map of changes found by librarian, e.g. %{"status" => "damaged", "condition" => "poor"}
  • scanned_barcode: Optional barcode scanned by librarian
  • notes: Optional notes about the check
  • user: The librarian checking the item

Returns

  • on success
  • on failure

check_item_with_collection(session, opname_item_id, item_changes, collection_changes, notes, user)

Check an item with collection updates during a stock opname session.

This function marks the item as checked and can update both item fields and collection metadata (title, author).

Parameters

  • session: The stock opname session
  • opname_item_id: The ID of the stock_opname_item record
  • item_changes: Map of item field changes, e.g. %{"status" => "damaged"}
  • collection_changes: Map of collection changes, e.g. %{"title" => "New Title", "author" => "Author Name"}
  • notes: Optional notes about the check
  • user: The librarian checking the item

Returns

  • on success
  • on failure

complete_librarian_work(session, user, notes \\ nil)

Complete a librarian's work session.

complete_session(session, admin_user)

Complete a stock opname session (in_progress → pending_review). Flags unscanned items as missing within the session scope. Only Super Admin can complete sessions.

count_session_items(session)

Count the number of items currently added to a session.

create_session(attrs \\ %{}, user)

Creates a new stock opname session (Super Admin only).

Examples

iex> create_session(%{title: "Jan 2026 Inventory", ...}, admin_user)
{:ok, %Session{}}

delete_session(session, user)

Delete a stock opname session. Only allowed for 'approved' or 'cancelled' sessions.

find_items_for_scanning(session, search_term)

Search for items by barcode, legacy_item_code, or item_code. Returns a list to handle duplicates.

get_librarian_progress(session, user)

Get librarian's progress in a session. Returns virtual assignment for super admins who aren't explicitly assigned.

get_session!(id)

Get a single stock opname session with all associations preloaded.

get_session_librarian_report(session)

Get detailed report of all librarians' work in a session.

get_session_review_summary(session)

Get session review summary with detailed statistics.

get_session_statistics(session)

Get session statistics.

get_session_without_items!(id)

Get a session without preloading items (for performance). Use this when you don't need the items list.

list_available_librarians(session, current_user)

List librarians available for assignment to a session. Returns users with eligible staff roles who are not suspended, not already assigned to the session, and (if not super_admin) from the same node.

list_items_with_changes(session)

List items with changes for a session. Optimized query with database-level filtering.

list_items_with_changes_paginated(session, page \\ 1, per_page \\ 20)

List items with changes with pagination.

list_missing_items(session)

List missing items for a session. Optimized query with database-level filtering. Missing items are tracked by changes->>'availability' = 'missing'.

list_missing_items_paginated(session, page \\ 1, per_page \\ 20)

List missing items with pagination.

list_recent_checked_items_by_user(session, user, limit \\ 10)

List recent checked items for a specific user with limit. Optimized query that limits at database level to avoid loading all items.

list_session_items(session, check_status \\ nil)

List session items filtered by check status.

list_session_items_paginated(session, page \\ 1, per_page \\ 50, filters \\ %{})

List session items with pagination.

list_session_librarians(session)

Get all librarians assigned to a session with their user details.

list_sessions(page \\ 1, per_page \\ 10, filters \\ %{})

List stock opname sessions with pagination and filters.

Filter options:

  • :status - Filter by session status
  • :node_id - Filter by node
  • :created_by_id - Filter by creator
  • :from_date - Filter sessions created after this date
  • :to_date - Filter sessions created before this date
  • :user - Filter sessions the user can access (based on node membership)

list_sessions_pending_review(page \\ 1, per_page \\ 10)

List sessions pending review (Super Admin).

recalculate_session_counters(session)

Recalculate and update session counters based on actual item states. Useful for fixing counter drift or after manual database updates.

reject_session(session, admin_user, reason)

Reject a stock opname session.

remove_librarian(assignment_id, removed_by_user)

Remove a librarian from an existing session. Only allowed for sessions in 'draft', 'initializing', or 'in_progress' status. Cannot remove librarians who have completed their work.

request_session_revision(session, admin_user, notes)

Request revision on a session (send back to librarians).

Resets the session to "in_progress" and resets all librarian assignments back to "in_progress" so they can re-scan items. Also clears completed_at since the session is no longer complete.

reset_applying_session(session, admin_user)

Reset a session stuck in the "applying" state back to "pending_review".

Use this when the background approval task crashed without completing the rollback (e.g. a server restart during a long-running bulk update). The session will be returned to "pending_review" so the admin can retry approval.

start_librarian_work(session, user)

Start a librarian's work session.

start_session(session, admin_user)

@doc """ Start a stock opname session (draft → in_progress). Only Super Admin can start sessions. Cannot start if status is "initializing".

subscribe_session(session_id)

Subscribe to real-time updates for a specific stock opname session.

Messages you will receive:

  • {:session_approved, %Session{}} — background approval completed
  • {:session_approval_failed, reason} — background approval failed

update_session(session, attrs, user)

Update a stock opname session.