@spec primary_for_item(Ecto.UUID.t()) :: PhoenixKitCatalogue.Schemas.ItemSupplierInfo.t() | nil
Returns the primary supplier-info row for an item, or nil if none is marked primary.
Suppliers — delivery companies linked to manufacturers via the
many-to-many phoenix_kit_cat_manufacturer_suppliers table.
Same lifecycle as manufacturers: hard-delete only, "active" /
"inactive" status.
resolve/1 and list_all/1 provide a unified view of suppliers across
sources (local cat_suppliers + CRM when available). CRM access is
guarded via Code.ensure_loaded? / function_exported? — the CRM module
is an optional runtime dependency and may not be present.
Public surface is re-exported from PhoenixKitCatalogue.Catalogue.
Returns the current junction row for an item/supplier pair, or nil.
Returns a changeset for tracking supplier changes.
Creates a supplier.
The CRM company uuid a supplier reference points at — directly when
the reference is already a party, or through the xref when it is a local
row linked to one. nil when there is no company behind it.
Hard-deletes a supplier from the database.
Fetches a supplier by UUID. Returns nil if not found.
Fetches a supplier by UUID. Raises Ecto.NoResultsError if not found.
Everything a CRM party currently supplies, for the catalogue panel on that party's page in CRM.
Lists all suppliers from all available sources as normalized maps.
Lists all suppliers, ordered by name.
Returns the primary supplier-info row for an item, or nil if none is marked primary.
Resolves a supplier UUID to a unified map regardless of source.
Batch form of resolve/1: %{uuid => resolved_map} for many supplier uuids
in a bounded number of queries, whatever mix of local and CRM they are.
Delegates to ItemSupplierInfos.revise_unit_cost/3.
Updates a supplier with the given attributes.
@spec active_info_for(Ecto.UUID.t(), Ecto.UUID.t()) :: PhoenixKitCatalogue.Schemas.ItemSupplierInfo.t() | nil
Returns the current junction row for an item/supplier pair, or nil.
"Current" means valid_to is nil. This is the function warehouse calls
to check whether a receipt line's unit price diverges from the catalogued
cost for the same supplier.
@spec change_supplier(PhoenixKitCatalogue.Schemas.Supplier.t(), map()) :: Ecto.Changeset.t(PhoenixKitCatalogue.Schemas.Supplier.t())
Returns a changeset for tracking supplier changes.
@spec create_supplier( map(), keyword() ) :: {:ok, PhoenixKitCatalogue.Schemas.Supplier.t()} | {:error, Ecto.Changeset.t(PhoenixKitCatalogue.Schemas.Supplier.t())}
Creates a supplier.
:name — supplier name (1-255 chars):description, :website, :contact_info, :notes:status — "active" (default) or "inactive":data — flexible JSON map@spec crm_company_uuid(map()) :: Ecto.UUID.t() | nil
The CRM company uuid a supplier reference points at — directly when
the reference is already a party, or through the xref when it is a local
row linked to one. nil when there is no company behind it.
This is the join anyone needs to address a supplier as a CRM company:
comments, activity, anything CRM stores per company. Contacts return
nil deliberately — a contact is not a company, and pointing
company-scoped records at one would file them against the wrong party.
@spec delete_supplier( PhoenixKitCatalogue.Schemas.Supplier.t(), keyword() ) :: {:ok, PhoenixKitCatalogue.Schemas.Supplier.t()} | {:error, Ecto.Changeset.t(PhoenixKitCatalogue.Schemas.Supplier.t())}
Hard-deletes a supplier from the database.
@spec get_supplier(Ecto.UUID.t()) :: PhoenixKitCatalogue.Schemas.Supplier.t() | nil
Fetches a supplier by UUID. Returns nil if not found.
@spec get_supplier!(Ecto.UUID.t()) :: PhoenixKitCatalogue.Schemas.Supplier.t()
Fetches a supplier by UUID. Raises Ecto.NoResultsError if not found.
@spec items_supplied_by(Ecto.UUID.t()) :: [PhoenixKitCatalogue.Schemas.Item.t()]
Everything a CRM party currently supplies, for the catalogue panel on that party's page in CRM.
Matches the party's own uuid AND the uuid of any local supplier row that
projects it — the same resolve-through rule resolve/1 uses, so sourcing
recorded against the old local row before the party existed still shows up.
Current rows only (valid_to is null), deleted items excluded.
Returns plain maps, not schemas: the caller is another module rendering a read-only list, and handing it structs would invite it to write them back.
Lists all suppliers from all available sources as normalized maps.
Each entry has keys :uuid, :name, :email, :phone, :website,
:source (:crm_company | :crm_contact | :local). CRM companies then
CRM contacts are listed first (when available), then local suppliers
ordered by name.
CRM access is guarded — when PhoenixKitCRM.PartyRoles is not loaded,
only local suppliers are returned.
@spec list_suppliers(keyword()) :: [PhoenixKitCatalogue.Schemas.Supplier.t()]
Lists all suppliers, ordered by name.
:status — filter by status (e.g. "active", "inactive").@spec primary_for_item(Ecto.UUID.t()) :: PhoenixKitCatalogue.Schemas.ItemSupplierInfo.t() | nil
Returns the primary supplier-info row for an item, or nil if none is marked primary.
@spec resolve(Ecto.UUID.t()) :: {:ok, map()} | :error
Resolves a supplier UUID to a unified map regardless of source.
Returns {:ok, map} with keys :uuid, :name, :email, :phone,
:website, :source (:crm | :local), or :error when the supplier
cannot be found in any source.
The CRM branch reports the generic :crm tag rather than
:crm_company / :crm_contact — PhoenixKitCRM.PartyRoles.get_supplier/1
resolves either roleable type in one call but its return shape doesn't
say which; list_all/1 (backed by per-type role listings) is the
source for the more specific tags used elsewhere in this module.
CRM lookup is guarded — when PhoenixKitCRM.PartyRoles is not loaded
(the CRM module is an optional runtime dependency), the CRM path is
skipped and only local suppliers are checked.
@spec resolve_many([Ecto.UUID.t()]) :: %{required(Ecto.UUID.t()) => map()}
Batch form of resolve/1: %{uuid => resolved_map} for many supplier uuids
in a bounded number of queries, whatever mix of local and CRM they are.
Unresolvable uuids are simply absent — callers render their stored name snapshot, or a placeholder.
@spec revise_unit_cost( PhoenixKitCatalogue.Schemas.ItemSupplierInfo.t(), Decimal.t(), keyword() ) :: {:ok, PhoenixKitCatalogue.Schemas.ItemSupplierInfo.t()} | {:error, :not_current | Ecto.Changeset.t()}
Delegates to ItemSupplierInfos.revise_unit_cost/3.
This is the stable public surface that warehouse and other consumers should
call. See ItemSupplierInfos.revise_unit_cost/3 for full documentation.
@spec update_supplier(PhoenixKitCatalogue.Schemas.Supplier.t(), map(), keyword()) :: {:ok, PhoenixKitCatalogue.Schemas.Supplier.t()} | {:error, Ecto.Changeset.t(PhoenixKitCatalogue.Schemas.Supplier.t())}
Updates a supplier with the given attributes.