Skip to content

katana_public_api_client.domain.material

katana_public_api_client.domain.material

Domain model for Material entities.

This module provides a Pydantic model representing a Material (raw material or component) optimized for ETL, data processing, and business logic.

Classes

KatanaMaterial

Bases: KatanaBaseModel

Domain model for a Material.

A Material represents raw materials and components used in manufacturing, including inventory tracking, supplier information, and batch management. This is a Pydantic model optimized for: - ETL and data processing - Business logic - Data validation - JSON schema generation

Unlike the generated attrs model, this model: - Has no Unset sentinel values - Provides ETL-friendly methods - Is immutable by default - Clean Optional types

Example
material = KatanaMaterial(
    id=3201,
    name="Stainless Steel Sheet 304",
    type="material",
    uom="m²",
    category_name="Raw Materials",
    is_sellable=False,
    batch_tracked=True,
)

# Business methods available
print(material.get_display_name())  # "Stainless Steel Sheet 304"

# ETL export
csv_row = material.to_csv_row()
schema = KatanaMaterial.model_json_schema()
Functions
get_display_name()

Get formatted display name.

Returns:

  • str

    Material name, or "Unnamed Material {id}" if no name

Example
material = KatanaMaterial(id=3201, name="Steel Sheet")
print(material.get_display_name())  # "Steel Sheet"
Source code in katana_public_api_client/domain/material.py
def get_display_name(self) -> str:
    """Get formatted display name.

    Returns:
        Material name, or "Unnamed Material {id}" if no name

    Example:
        ```python
        material = KatanaMaterial(id=3201, name="Steel Sheet")
        print(material.get_display_name())  # "Steel Sheet"
        ```
    """
    return self.name or f"Unnamed Material {self.id}"

Check if material matches search query.

Searches across: - Material name - Category name

Parameters:

  • query (str) –

    Search query string (case-insensitive)

Returns:

  • bool

    True if material matches query

Example
material = KatanaMaterial(
    id=3201, name="Stainless Steel Sheet", category_name="Raw Materials"
)
material.matches_search("steel")  # True
material.matches_search("raw")  # True
material.matches_search("aluminum")  # False
Source code in katana_public_api_client/domain/material.py
def matches_search(self, query: str) -> bool:
    """Check if material matches search query.

    Searches across:
    - Material name
    - Category name

    Args:
        query: Search query string (case-insensitive)

    Returns:
        True if material matches query

    Example:
        ```python
        material = KatanaMaterial(
            id=3201, name="Stainless Steel Sheet", category_name="Raw Materials"
        )
        material.matches_search("steel")  # True
        material.matches_search("raw")  # True
        material.matches_search("aluminum")  # False
        ```
    """
    query_lower = query.lower()

    # Check name
    if self.name and query_lower in self.name.lower():
        return True

    # Check category
    return bool(self.category_name and query_lower in self.category_name.lower())
to_csv_row()

Export as CSV-friendly row.

Returns:

  • dict[str, Any]

    Dictionary with flattened data suitable for CSV export

Example
material = KatanaMaterial(
    id=3201, name="Test Material", is_sellable=False
)
row = material.to_csv_row()
# {
#   "ID": 3201,
#   "Name": "Test Material",
#   "Type": "material",
#   "Category": "",
#   ...
# }
Source code in katana_public_api_client/domain/material.py
def to_csv_row(self) -> dict[str, Any]:
    """Export as CSV-friendly row.

    Returns:
        Dictionary with flattened data suitable for CSV export

    Example:
        ```python
        material = KatanaMaterial(
            id=3201, name="Test Material", is_sellable=False
        )
        row = material.to_csv_row()
        # {
        #   "ID": 3201,
        #   "Name": "Test Material",
        #   "Type": "material",
        #   "Category": "",
        #   ...
        # }
        ```
    """
    return {
        "ID": self.id,
        "Name": self.get_display_name(),
        "Type": self.type_,
        "Category": self.category_name or "",
        "UOM": self.uom or "",
        "Is Sellable": self.is_sellable or False,
        "Batch Tracked": self.batch_tracked or False,
        "Variant Count": self.variant_count,
        "Config Count": self.config_count,
        "Created At": self.created_at.isoformat() if self.created_at else "",
        "Updated At": self.updated_at.isoformat() if self.updated_at else "",
        "Archived At": self.archived_at or "",
    }