# `PhoenixKitWarehouse.StorageFolders`
[🔗](https://github.com/BeamLabEU/phoenix_kit_warehouse/blob/0.5.0/lib/phoenix_kit_warehouse/storage_folders.ex#L1)

Resolves (and creates if missing) the PhoenixKit Storage folder for a
warehouse document.

Consolidates what were 5 near-identical `*_storage_folders.ex` modules in
Andi (`goods_issue_storage_folders.ex`, `goods_receipt_storage_folders.ex`,
`inventory_storage_folders.ex`, `supplier_order_storage_folders.ex`,
`internal_order_storage_folders.ex`) into one module with 5 `ensure_for_*/2`
functions.

Layout: `<prefix>-<number>` (falling back to `<prefix>-<uuid>` when the
document has no number yet), created under the parent folder returned by
the optional host hook

    config :phoenix_kit_warehouse, :storage_parent_folder, {MyApp.Media, :for_warehouse}

called as `for_warehouse(resource, actor_uuid)` with `resource` one of
`:goods_issue | :goods_receipt | :inventory | :supplier_order |
:internal_order | :transfer`, returning `{:ok, parent_folder_uuid}` or
`nil` (= storage root, the default when the hook is absent). A hook that
raises or returns something other than a UUID is logged and treated as
`nil`. Lookup by name ignores trashed folders and checks the parent
first, then the root; a root hit — or a cached folder still sitting at the
root — is adopted (moved under the parent) so folders created before the
hook existed keep their files. A failed move leaves the folder at the root.

Four of the five original resources (goods issue, goods receipt, inventory,
supplier order) cache the resolved folder's uuid on a `storage_folder_uuid`
column and take a fast path once cached. The fifth — internal orders — has
no `storage_folder_uuid` column at all (confirmed: `internal_order_storage_folders.ex`
is a genuine smaller variant with a single function clause and no
write-back) and resolves by name on every call instead.

A sixth resource, transfers (added later, Plan 4/T15), also has a
`storage_folder_uuid` column and follows the same cached fast-path as the
four originals — see `ensure_for_transfer/2`.

# `ensure_for_goods_issue`

Returns `{:ok, %Folder{}}` for the given goods issue, creating the folder
if needed. Persists `storage_folder_uuid` on the issue record after first
creation. Pass `admin_user_uuid` as the folder owner.

# `ensure_for_goods_receipt`

Returns `{:ok, %Folder{}}` for the given goods receipt, creating the folder
if needed. Persists `storage_folder_uuid` on the receipt record after first
creation. Pass `admin_user_uuid` as the folder owner.

# `ensure_for_internal_order`

Returns `{:ok, %Folder{}}` for the given internal order, creating the
folder if needed. Resolves the folder by name on every call — internal
orders have no `storage_folder_uuid` column to cache against (dropped
along with `sub_order_uuid`; nothing in Plan 1's migration created either
column on `phoenix_kit_warehouse_internal_orders`). Pass `admin_user_uuid`
as the folder owner.

# `ensure_for_inventory`

Returns `{:ok, %Folder{}}` for the given inventory document, creating the
folder if needed. Persists `storage_folder_uuid` on the document record
after first creation. Pass `admin_user_uuid` as the folder owner.

# `ensure_for_supplier_order`

Returns `{:ok, %Folder{}}` for the given supplier order, creating the folder
if needed. Persists `storage_folder_uuid` on the order record after first
creation. Pass `admin_user_uuid` as the folder owner.

# `ensure_for_transfer`

Returns `{:ok, %Folder{}}` for the given transfer, creating the folder if
needed. Persists `storage_folder_uuid` on the transfer record after first
creation. Pass `admin_user_uuid` as the folder owner.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
