PhoenixKitCatalogue.Import.Pro100Plan (PhoenixKitCatalogue v0.19.0)

Copy Markdown View Source

Builds the PRO100 sync diff/report. Rows fall into three buckets:

  • :updates — matched rows become per-field change sets (base_price, materials unit) plus a data["pro100"] round-trip blob
  • :creates — rows with no catalogue match but enough data to become a new item; applied only when the operator opts in on the preview screen
  • :skipped — ambiguous matches, rows belonging to another group, and unmatched rows that cannot be created (no id, no name)

Pure — no DB. All three buckets are computed unconditionally so the preview can show counts before the operator decides what to apply.

Summary

Functions

Splits a PRO100 row name into {category_name_or_nil, item_name}.

Converts the :creates bucket into the plan shape Executor.execute/4 wants.

Functions

build(rows, index, catalogue_name)

@spec build([map()], PhoenixKitCatalogue.Import.Matcher.t(), String.t() | nil) :: %{
  updates: [map()],
  creates: [map()],
  skipped: [map()],
  stats: map()
}

split_name(name)

@spec split_name(String.t() | nil) :: {String.t() | nil, String.t()}

Splits a PRO100 row name into {category_name_or_nil, item_name}.

Both parts are trimmed. When there is no whitespace-padded separator — or when either side of it is blank ("/ Foo", "Group /") — the whole trimmed string becomes the item name and there is no category. A blank category name would fail create_category's changeset, which the executor swallows silently, leaving items uncategorized with no diagnostic.

to_executor_plan(creates)

@spec to_executor_plan([map()]) :: %{
  items: [map()],
  categories_to_create: [String.t()]
}

Converts the :creates bucket into the plan shape Executor.execute/4 wants.

Category linkage runs through the :_category_name placeholder resolved against the phase-1 lookup, which is built from categories_to_create — a name present on an item but missing from that list is dropped silently, so the two must be derived together.