itemep

package
v1.4.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ItemCostsPresenter

func ItemCostsPresenter(resp *pb.GetItemCostsResponse) *apiresource.ItemCosts

func ItemPresenter

func ItemPresenter(i *pb.ItemInfo) apiresource.Item

func ItemTrendsPresenter

func ItemTrendsPresenter(resp *pb.GetItemTrendsResponse) *apiresource.ItemTrends

Types

type AddItemAttributeEndpoint

type AddItemAttributeEndpoint struct{}

Assigns an attribute to an item and returns the updated item.

The attribute's property must be one the item's category carries, so link the property to the category before assigning any of its attributes.

Adding an attribute the item already carries succeeds and changes nothing, so the call is safe to repeat.

func (*AddItemAttributeEndpoint) Materialize

type AddItemAttributeRequest

type AddItemAttributeRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
	// ID of the attribute to assign to the item.
	AttributeID string `path:"attribute_id" validate:"required"`
}

Request to add an attribute to an item.

type BulkCreateItemInput

type BulkCreateItemInput struct {
	// SKU for the new item, unique within the account.
	//
	// If an item with this SKU already exists, that item is updated in place (description, category, and product line) instead of a new item being created; this path additionally requires permission to update items, and the result for the row is still reported with status `created`.
	SKU string `json:"sku" validate:"required"`
	// Item description.
	Description field.Optional[string] `json:"description,omitzero"`
	// ID of the category to assign to the item.
	//
	// The category determines the base unit the item's rates are expressed in, so choose one whose unit group matches how the item is counted.
	ItemCategoryID string `json:"item_category_id" validate:"required"`
	// ID of the product line to assign the item's product to.
	//
	// Only applies when `type` is `product`; ignored for materials and parts.
	ProductLineID field.Optional[string] `json:"product_line_id,omitzero"`
}

One item to create in a bulk create request.

type BulkCreateItemsEndpoint

type BulkCreateItemsEndpoint struct{}

Creates multiple items of a single type in one call, returning a per-item result indicating success or failure.

An input whose SKU already exists updates the existing item in place instead of creating a duplicate. A failure on one item does not abort the rest of the batch; check each result's status.

Newly created items start with a unit value, unit cost, and burn rate of zero, counted in their category's base unit; set the real figures afterwards.

type BulkCreateItemsRequest

type BulkCreateItemsRequest struct {
	// Items to create.
	Items []BulkCreateItemInput `json:"items" validate:"required"`
	// The item type applied to every item in the request.
	//
	// - `product`: a finished product.
	// - `material`: a raw material or component consumed in production.
	// - `part`: a part used in production.
	Type constants.ItemTypeCode `json:"type" validate:"required"`
}

Request to create multiple items of the same type.

func (*BulkCreateItemsRequest) SchemaExample

func (*BulkCreateItemsRequest) SchemaExample() any

type BulkReconcileItemInput

type BulkReconcileItemInput struct {
	// SKU of the item to reconcile.
	//
	// Items whose SKU does not match an existing item are reported in the response's `skipped_items` rather than failing the request.
	SKU string `json:"sku" validate:"required"`
	// Abbreviation of a unit available to your account (e.g. `kg`).
	//
	// The unit is checked for existence only: the quantity is always recorded in the item's own base unit, so send figures already expressed in that unit. Rows naming an abbreviation that matches no built-in or account-defined unit are reported in the response's `errors`.
	Unit string `json:"unit" validate:"required"`
	// Quantity to apply, interpreted according to the request's `reconcile_type`.
	//
	// A decimal string rather than a number: a quantity that has been through a binary float is not the quantity you sent.
	Quantity string `json:"quantity" validate:"required" format:"decimal"`
}

One item to reconcile in a bulk reconcile request.

type BulkReconcileItemsEndpoint

type BulkReconcileItemsEndpoint struct{}

Reconciles inventory for multiple items by SKU in one call, the bulk equivalent of counting stock and correcting the books.

`reconcile_type` controls whether each quantity is added to the item's current quantity (`addition`) or replaces it (`force`). The figure a `force` measures against is what is on hand net of demand nothing has covered, the same basis the single-item endpoint uses. The response reports each item as reconciled, skipped (e.g. unknown SKU), or errored (e.g. unknown unit), so a problem with one item does not fail the rest of the batch.

Each correction is written to the item's inventory audit trail as a user correction, attributed to the caller.

type BulkReconcileItemsRequest

type BulkReconcileItemsRequest struct {
	// Items to reconcile.
	Data []BulkReconcileItemInput `json:"data" validate:"required"`
	// How each item's quantity is applied to its current quantity.
	//
	// - `addition`: adds the quantity to the item's current quantity.
	// - `force`: sets the item's current quantity to exactly the given quantity.
	ReconcileType constants.ItemReconcileType `json:"reconcile_type" validate:"required"`
}

Request to reconcile inventory for many items at once.

func (*BulkReconcileItemsRequest) SchemaExample

func (*BulkReconcileItemsRequest) SchemaExample() any

type ChangeItemCategoryEndpoint

type ChangeItemCategoryEndpoint struct{}

Moves an item to a different category and returns the updated item.

The item's rate units (unit value, unit cost, burn rate) and any related order-point, consumption, and production quantity units are switched to the new category's base unit. Only the units change — the numbers attached to them are carried over as they were, so review any figure whose meaning depends on the unit after moving between categories that count differently.

Re-assigning the item's current category succeeds and changes nothing.

func (*ChangeItemCategoryEndpoint) Materialize

type ChangeItemCategoryRequest

type ChangeItemCategoryRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
	// ID of the category to move the item to.
	//
	// The category's type has to suit the item: a material can only move to a material category, and a product or part can only move to a product category. Anything else fails validation.
	//
	// The category also has to carry the properties of every attribute the item already has, since the move keeps those attributes. Unlink the offending attributes, or add their properties to the target category, before moving the item.
	CategoryID string `path:"category_id" validate:"required"`
}

Request to change an item's category.

type ExportItemsEndpoint

type ExportItemsEndpoint struct{}

Downloads every item in your account, with its category and on-hand inventory, as an Excel workbook named `items.xlsx`.

The export takes no filters and is not paginated: it always covers the whole catalog, one row per item, ordered by SKU.

func (*ExportItemsEndpoint) Materialize

type ExportItemsRequest

type ExportItemsRequest struct{}

Request to export items.

type GetItemCostsEndpoint

type GetItemCostsEndpoint struct{}

Returns what it costs to make one unit of an item, split into direct material, direct labor, and overhead.

The figures are recomputed on each call by walking back through every production step that feeds the step producing this item, so the answer reflects the current recipe and the current cost of everything consumed along the way. Items that no production flow produces — purchased materials, for instance — return a not-found error rather than a zero breakdown.

Calling this also writes the computed total back to the item's `unit_cost`, so it is how a stale unit cost gets refreshed.

func (*GetItemCostsEndpoint) Materialize

type GetItemCostsRequest

type GetItemCostsRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
}

Request to retrieve an item's cost breakdown.

type GetItemTrendsEndpoint

type GetItemTrendsEndpoint struct{}

Returns how an item's stock level has moved over the last 30 days, as a series of point-in-time measurements.

Days on which nothing was logged produce no point, and days with several entries contribute only the first, so the series is sparse rather than one point per calendar day.

func (*GetItemTrendsEndpoint) Materialize

type GetItemTrendsRequest

type GetItemTrendsRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
	// The trend metric to fetch.
	//
	// `inventory` returns the item's inventory-level measurements from the last 30 days.
	TrendType constants.ItemTrendType `query:"trend_type" validate:"required"`
}

Request to retrieve trend data for an item.

type ItemSvc

type ItemSvc interface {
	ListItems(ctx context.Context, req *ListItemsRequest) (*apiresource.List[apiresource.Item], *apierror.APIError)
	GetItem(ctx context.Context, req *RetrieveItemRequest) (*apiresource.Item, *apierror.APIError)
	GetItemInventory(ctx context.Context, req *RetrieveItemInventoryRequest) (*apiresource.ItemInventory, *apierror.APIError)
	GetItemLotDefault(ctx context.Context, req *RetrieveItemLotDefaultRequest) (*apiresource.ItemLotDefault, *apierror.APIError)
	GetItemCosts(ctx context.Context, req *GetItemCostsRequest) (*apiresource.ItemCosts, *apierror.APIError)
	GetItemTrends(ctx context.Context, req *GetItemTrendsRequest) (*apiresource.ItemTrends, *apierror.APIError)
	ExportItems(ctx context.Context, req *ExportItemsRequest) (*httptransport.FileDownload, *apierror.APIError)
	AddItemAttribute(ctx context.Context, req *AddItemAttributeRequest) (*apiresource.Item, *apierror.APIError)
	RemoveItemAttribute(ctx context.Context, req *RemoveItemAttributeRequest) (*apiresource.Item, *apierror.APIError)
	ChangeItemCategory(ctx context.Context, req *ChangeItemCategoryRequest) (*apiresource.Item, *apierror.APIError)
	UpdateItemInventory(ctx context.Context, req *UpdateItemInventoryRequest) (*apiresource.EmptyResource, *apierror.APIError)
	BulkCreateItems(ctx context.Context, req *BulkCreateItemsRequest) (*apiresource.BulkCreateItemsResponse, *apierror.APIError)
	BulkReconcileItems(ctx context.Context, req *BulkReconcileItemsRequest) (*apiresource.BulkReconcileItemsResponse, *apierror.APIError)
}

func NewItemSvc

func NewItemSvc(config *ItemSvcConfig) ItemSvc

type ItemSvcConfig

type ItemSvcConfig struct {
	// CoreClient (required) is the core-service gRPC client.
	CoreClient pb.CoreServiceClient
}

type ListItemsEndpoint

type ListItemsEndpoint struct{}

Returns a paginated list of items, newest first.

Items backed by a non-sale product — the service, shipping, tax, credit, and return products that carry charges on orders — are left out, so this reflects the catalog you sell and stock rather than every item row. `q` matches against SKU and description, with closer SKU matches ranked first.

func (*ListItemsEndpoint) Materialize

type ListItemsRequest

type ListItemsRequest struct {
	apiresource.PaginationRequest
	// Filter to items of these types (`product`, `material`, `part`).
	Types []string `query:"types"`
	// Filter to items in any of these categories.
	CategoryIDs []string `query:"category_ids"`
	// Filter to items carrying any of these attributes.
	AttributeIDs []string `query:"attribute_ids"`
	// Filter to materials this supplier account supplies to you.
	//
	// Only materials can have suppliers, so combining this with a `types` filter that excludes `material` returns nothing.
	SupplierID *string `query:"supplier_id"`
	// Filter to items created on or after this date.
	StartDate *time.Time `query:"starts_at"`
	// Filter to items created on or before this date.
	EndDate *time.Time `query:"ends_at"`
	// Restricts results based on where the item is produced in its production flow.
	//
	// - `all`: no restriction.
	// - `initial_only`: only items produced by an initial production step, i.e. a step with no upstream steps feeding into it.
	SubassemblyFilter *constants.SubassemblyFilter `query:"subassembly_filter" default:"all"`
	// Filter to items whose product belongs to any of these product lines.
	ProductLineIDs []string `query:"product_line_ids"`
	// Filter to items any of these customers are allowed to order.
	//
	// A customer qualifies when its relationship, its account group, or its price group grants access to the product line the item's product sits in. Items with no product line, including materials and parts, never match.
	CustomerIDs []string `query:"customer_ids"`
}

Request to list items.

func (*ListItemsRequest) SchemaExample

func (*ListItemsRequest) SchemaExample() any

SchemaExample aligns list filters with SampleItem for OpenAPI documentation.

type RemoveItemAttributeEndpoint

type RemoveItemAttributeEndpoint struct{}

Unassigns an attribute from an item and returns the updated item.

Returns a not-found error if the attribute is not currently assigned to the item, so unlike adding an attribute, this call is not safe to repeat blindly. The attribute itself is not deleted and stays available for other items.

func (*RemoveItemAttributeEndpoint) Materialize

type RemoveItemAttributeRequest

type RemoveItemAttributeRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
	// ID of the attribute to unassign from the item.
	AttributeID string `path:"attribute_id" validate:"required"`
}

Request to remove an attribute from an item.

type RetrieveItemEndpoint

type RetrieveItemEndpoint struct{}

Returns a single item by ID.

func (*RetrieveItemEndpoint) Materialize

type RetrieveItemInventoryEndpoint

type RetrieveItemInventoryEndpoint struct{}

Returns the stock position for an item: what is on hand, what is reserved against existing orders, what is free to promise, and what is short.

Stock your account either owns or holds counts toward the on-hand figure, so customer-supplied material sitting in your facility is included. All four quantities are reported in the base unit of the item's category.

type RetrieveItemInventoryRequest

type RetrieveItemInventoryRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
}

Request to retrieve an item's inventory position.

type RetrieveItemLotDefaultEndpoint

type RetrieveItemLotDefaultEndpoint struct{}

Returns the lot this item is made in — how many, counted in what.

A lot is a doff, a pallet, a batch: the quantity production is issued in. The unit is what makes it meaningful, since 60 pairs and 60 eaches are different lots, so `quantity` should never be read without `unit`.

Resolved through the same chain the production schedule uses, most specific first: a per-item override, then the item's own product line, then the product lines of the finished goods it becomes, then the account-wide default. `source` names which rule applied. Intermediate items like greige are not sold and have no product line of their own, which is why they inherit from what they become.

`quantity` is `0` when nothing in the chain supplies a lot. That means the item has no lot convention, not that its lot is zero.

type RetrieveItemLotDefaultRequest

type RetrieveItemLotDefaultRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
}

Request to resolve an item's lot.

type RetrieveItemRequest

type RetrieveItemRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
}

Request to retrieve an item by ID.

type UpdateItemInventoryEndpoint

type UpdateItemInventoryEndpoint struct{}

Adjusts or reconciles the quantity of an item you hold.

With `operation` set to `adjust` (the behavior when it is omitted), `quantity` is added to the current quantity; with `reconcile`, the current quantity is set to exactly `quantity`. Either way it is the resulting difference that gets written, so a difference of zero moves no stock.

The figure a `reconcile` measures against is what is on hand net of demand nothing has covered — the same figure `available_to_promise` is derived from, not the raw on-hand total. Reconciling to the quantity already reported therefore writes nothing.

Stock that arrives is allocated against unfilled demand for the item, so an adjustment can settle a shortfall instead of raising the quantity free to promise. That allocation happens just after the request rather than inside it, because it walks every open issue for the item. The change is recorded in the item's inventory audit trail as a user correction attributed to the caller.

type UpdateItemInventoryRequest

type UpdateItemInventoryRequest struct {
	// Item ID.
	ItemID string `path:"id" validate:"required"`
	// The quantity to apply, interpreted according to `operation`.
	//
	// With `adjust` it is added to the current quantity and may be negative; with `reconcile` the current quantity is set to exactly this value. It is recorded in the unit you send it in, and the current quantity a `reconcile` measures against is read in that same unit, so a reconcile to the figure already reported moves no stock.
	Quantity apirequest.QuantityInput `json:"quantity" validate:"required"`
	// How `quantity` is applied.
	//
	// - `adjust`: adds `quantity` to the current quantity.
	// - `reconcile`: sets the current quantity to exactly `quantity`.
	Operation field.Optional[constants.InventoryUpdateOperation] `json:"operation,omitzero"`
	// ID of the customer account that owns the resulting inventory.
	//
	// Use this for stock you hold but do not own, such as customer-supplied material. It only affects quantity being added: your account stays the holder, the customer becomes the owner, and the current quantity a `reconcile` measures against is still your account's. Requires edit access to that customer.
	CustomerID field.Optional[string] `json:"customer_id,omitzero" validate:"omitempty"`
	// ID of the location to record the inventory change against.
	//
	// Must be a location in your account.
	LocationID field.Optional[string] `json:"location_id,omitzero" validate:"omitempty"`
	// Lot number to record the inventory change against.
	//
	// The lot is created for the item if it does not already exist.
	LotNumber field.Optional[string] `json:"lot_number,omitzero" validate:"omitempty,max=255"`
}

Request to adjust or reconcile inventory for an item.

func (*UpdateItemInventoryRequest) SchemaExample

func (*UpdateItemInventoryRequest) SchemaExample() any

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL