domain

package
v1.4.2 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: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultCategoryShipping = "shipping"
	DefaultCategoryService  = "service"
	DefaultCategoryCredit   = "credit"
	DefaultCategoryTax      = "tax"
)

Default category IDs that cannot be mutated.

View Source
const (
	OeeBucketAvailability               = string(constants.OeeBucketAvailability)
	OeeBucketPerformance                = string(constants.OeeBucketPerformance)
	OeeBucketQuality                    = string(constants.OeeBucketQuality)
	OeeBucketNotScheduled               = string(constants.OeeBucketNotScheduled)
	MachineDowntimeReasonCodeChangeover = string(constants.MachineDowntimeReasonCodeChangeover)
)

OEE buckets. A reason's bucket decides which OEE term its downtime charges. OeeBucketNotScheduled is the odd one out: it is removed from the Availability denominator entirely rather than counted as a loss against it, because a machine nobody planned to run has no OEE rather than 0% OEE.

These are string-typed views of the shared enums in shared/constants — the single source of truth for values that cross the gRPC contract — kept here so repository code that works in plain storage strings does not re-declare the vocabulary.

View Source
const (
	MachineDowntimeSourceManual   = string(constants.MachineDowntimeSourceManual)
	MachineDowntimeSourceScanner  = string(constants.MachineDowntimeSourceScanner)
	MachineDowntimeSourceInferred = string(constants.MachineDowntimeSourceInferred)
	MachineDowntimeSourceAPI      = string(constants.MachineDowntimeSourceAPI)
)

Downtime event sources. Manual is a person in the UI; scanner is the shop-floor station; inferred is a system-derived gap; api is an integration. String-typed views of constants.MachineDowntimeSource, the single source of truth.

View Source
const (
	DefaultProductLineShipping = "shipping"
	DefaultProductLineService  = "service"
	DefaultProductLineCredit   = "credit"
	DefaultProductLineTax      = "tax"
)

Default product line IDs that cannot be mutated.

View Source
const (
	ScheduleResourceScopeMachine        = string(constants.ScheduleResourceScopeMachine)
	ScheduleResourceScopeDepartment     = string(constants.ScheduleResourceScopeDepartment)
	ScheduleResourceScopeProductionStep = string(constants.ScheduleResourceScopeProductionStep)
)

Resource-setting scopes. A setting attaches to a machine, a department or a production step; the scope says which. These alias the shared enum so the vocabulary has a single source of truth.

View Source
const (
	DeviationTypeLineAdded       = string(constants.ScheduleDeviationTypeLineAdded)
	DeviationTypeLineRemoved     = string(constants.ScheduleDeviationTypeLineRemoved)
	DeviationTypeQuantityChanged = string(constants.ScheduleDeviationTypeQuantityChanged)
	DeviationTypeMachineChanged  = string(constants.ScheduleDeviationTypeMachineChanged)
	DeviationTypeResequenced     = string(constants.ScheduleDeviationTypeResequenced)
	DeviationTypeWeekMoved       = string(constants.ScheduleDeviationTypeWeekMoved)
)

Deviation types name what changed about a line. The reason code carries why, and is required only for edits inside a frozen week. These alias the shared enum so the vocabulary has a single source of truth.

Production schedule statuses. These alias the shared enum so the vocabulary has a single source of truth.

View Source
const (
	ScheduleLineStatusPlanned    = string(constants.ProductionScheduleLineStatusPlanned)
	ScheduleLineStatusReleased   = string(constants.ProductionScheduleLineStatusReleased)
	ScheduleLineStatusInProgress = string(constants.ProductionScheduleLineStatusInProgress)
	ScheduleLineStatusComplete   = string(constants.ProductionScheduleLineStatusComplete)
	ScheduleLineStatusCancelled  = string(constants.ProductionScheduleLineStatusCancelled)
)

Schedule line statuses, aliasing the shared enum.

How a schedule came to exist, aliasing the shared enum.

View Source
const (
	ScheduleLineSourceSolver = string(constants.ScheduleLineSourceSolver)
	ScheduleLineSourceManual = string(constants.ScheduleLineSourceManual)
)

Why a line exists, aliasing the shared enum.

View Source
const (
	ScheduleMergeModePreserveManual = string(constants.ScheduleMergeModePreserveManual)
	ScheduleMergeModeReplaceAll     = string(constants.ScheduleMergeModeReplaceAll)
)

How a regenerate treats the hand edits already on a draft, aliasing the shared enum.

View Source
const (
	ScheduleDiffAdded     = string(constants.ScheduleDiffChangeAdded)
	ScheduleDiffRemoved   = string(constants.ScheduleDiffChangeRemoved)
	ScheduleDiffChanged   = string(constants.ScheduleDiffChangeChanged)
	ScheduleDiffUnchanged = string(constants.ScheduleDiffChangeUnchanged)
)

What a regenerate would do to one campaign, aliasing the shared enum.

View Source
const (
	PurchaseOrderStatusChangeIssue   = "issue"
	PurchaseOrderStatusChangeUnissue = "unissue"
	PurchaseOrderStatusChangeClose   = "close"
	PurchaseOrderStatusChangeOpen    = "open"
)

Purchase order status change constants.

View Source
const ExportRowLimit = 50_000

bounds an export so one oversized account cannot exhaust the worker's memory. Queries fetch one row beyond it, so an overflow is detected rather than silently truncated.

View Source
const (
	ServiceName = "core-service"
)

Variables

This section is empty.

Functions

func GenerateSSCC

func GenerateSSCC(counter int64) string

GenerateSSCC generates an SSCC-18 barcode string from a counter value.

func IsDefaultCategory

func IsDefaultCategory(id string) bool

IsDefaultCategory returns true if the given category ID is a system default.

func IsDefaultProductLine

func IsDefaultProductLine(id string) bool

IsDefaultProductLine returns true if the given product line ID is a system default.

func RequireNotSandboxAccount

func RequireNotSandboxAccount(accountCtx *AccountContext) *apierror.APIError

RequireNotSandboxAccount returns a validation error if the account IS a sandbox. Used to block sandbox-from-sandbox creation. SAFETY: DO NOT REMOVE — prevents sandbox accounts from spawning nested sandboxes.

func RequireSandboxAccount

func RequireSandboxAccount(accountCtx *AccountContext) *apierror.APIError

RequireSandboxAccount returns an invariant violation error if the account is not a sandbox. Used before sandbox-mutating operations (delete, purge). SAFETY: DO NOT REMOVE — protects production accounts from sandbox-only operations.

Types

type Account

type Account struct {
	ID                       string
	Name                     string           `audit:"name"`
	DefaultBillingAddressID  *string          `audit:"default_billing_address_id"`
	DefaultShippingAddressID *string          `audit:"default_shipping_address_id"`
	Branding                 *AccountBranding `audit:"branding"`
	Portal                   *AccountPortal   `audit:"portal"`
	CreatedAt                time.Time
	UpdatedAt                time.Time
}

Account represents the full account with branding and portal sub-resources.

type AccountAffiliation

type AccountAffiliation struct {
	AccountID   string
	AccountName string
	RoleID      string
	RoleName    string
	RoleType    string
	LastUsedAt  *time.Time
}

type AccountBranding

type AccountBranding struct {
	ID              string
	SupportEmail    *string `audit:"support_email"`
	PhoneNumber     *string `audit:"phone_number"`
	LogoURL         *string `audit:"logo_url"`
	FaviconURL      *string `audit:"favicon_url"`
	FacebookHandle  *string `audit:"facebook_handle"`
	InstagramHandle *string `audit:"instagram_handle"`
	LinkedInHandle  *string `audit:"linkedin_handle"`
	TwitterHandle   *string `audit:"twitter_handle"`
	WebsiteURL      *string `audit:"website_url"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

AccountBranding holds the branding metadata for an account.

type AccountContext

type AccountContext struct {
	AccountID                    string
	IsSandbox                    bool
	OwnerAccountID               *string
	AccountMode                  constants.AccountMode
	SubscriptionStatus           *string
	PlanCode                     string
	AgentMonthlySpendingCapCents *int64
}

type AccountGroup

type AccountGroup struct {
	ID                   string
	OwnerAccountID       string  `audit:"account_id"`
	Name                 string  `audit:"name"`
	Description          *string `audit:"description"`
	CommissionPolicyCode string  `audit:"commission_policy_code"`
	FreightPolicyCode    string  `audit:"freight_policy_code"`
	AccountGroupTypeCode string  `audit:"account_group_type_code"`
	// DefaultLeadTimeDays is inherited by every customer in the group that has not set its own. Nil falls through to the account default.
	DefaultLeadTimeDays *int32 `audit:"default_lead_time_days"`
	RegistrationFlowID  *string
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

type AccountGroupProductLineAccess

type AccountGroupProductLineAccess struct {
	AccountGroupID   string
	AccountGroupName string            `audit:"account_group_name"`
	ProductLines     []ProductLineInfo `audit:"product_lines"`
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

type AccountGroupProductLineAccessSvc

type AccountGroupProductLineAccessSvc interface {
	// ListAccountGroupProductLineAccess returns a paginated list of product line access records grouped by account group.
	ListAccountGroupProductLineAccess(ctx context.Context, params ListAccountGroupProductLineAccessParams) (*ListAccountGroupProductLineAccessResult, *apierror.APIError)

	// GetAccountGroupProductLineAccess returns the product line access for a single account group.
	GetAccountGroupProductLineAccess(ctx context.Context, accountGroupID string) (*AccountGroupProductLineAccess, *apierror.APIError)

	// CreateAccountGroupProductLineAccess creates a new product line access record for an account group.
	CreateAccountGroupProductLineAccess(ctx context.Context, params CreateAccountGroupProductLineAccessParams) (*AccountGroupProductLineAccess, *apierror.APIError)

	// UpdateAccountGroupProductLineAccess replaces all product lines for an account group.
	UpdateAccountGroupProductLineAccess(ctx context.Context, params UpdateAccountGroupProductLineAccessParams) (*AccountGroupProductLineAccess, *apierror.APIError)

	// DeleteAccountGroupProductLineAccess removes all product line access for an account group.
	DeleteAccountGroupProductLineAccess(ctx context.Context, accountGroupID string) *apierror.APIError

	// BatchGetAccountGroupProductLineAccessByIDs returns access records for the given account_group_ids. Used by the api-gateway resourcekit resolver.
	BatchGetAccountGroupProductLineAccessByIDs(ctx context.Context, accountGroupIDs []string) ([]*AccountGroupProductLineAccess, *apierror.APIError)
}

type AccountGroupRepo

type AccountGroupRepo interface {
	List(ctx context.Context, params ListAccountGroupsParams) (*ListAccountGroupsResult, *apierror.APIError)
	Get(ctx context.Context, accountID, id string) (*AccountGroup, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*AccountGroup, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateAccountGroupParams) (*AccountGroup, *apierror.APIError)
	Update(ctx context.Context, params UpdateAccountGroupParams) (*AccountGroup, *apierror.APIError)
	Delete(ctx context.Context, params DeleteAccountGroupParams) *apierror.APIError
	CheckAccountGroupNotInUse(ctx context.Context, accountGroup *AccountGroup) *apierror.APIError
	DeleteAccountRelationPriceGroupsByAccountGroupID(ctx context.Context, accountGroupID string) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
}

type AccountGroupSvc

type AccountGroupSvc interface {
	// ListAccountGroups returns a paginated list of account groups for the caller's account.
	ListAccountGroups(ctx context.Context, params ListAccountGroupsParams) (*ListAccountGroupsResult, *apierror.APIError)

	// GetAccountGroup returns a single account group by ID.
	GetAccountGroup(ctx context.Context, accountGroupID string) (*AccountGroup, *apierror.APIError)

	// CreateAccountGroup creates a new account group.
	CreateAccountGroup(ctx context.Context, params CreateAccountGroupParams) (*AccountGroup, *apierror.APIError)

	// UpdateAccountGroup partially updates an account group.
	UpdateAccountGroup(ctx context.Context, params UpdateAccountGroupParams) (*AccountGroup, *apierror.APIError)

	// DeleteAccountGroup deletes an account group.
	DeleteAccountGroup(ctx context.Context, accountGroupID string) *apierror.APIError

	// BatchGetAccountGroupsByIDs returns account groups matching the input IDs that the caller's account is authorized to read. Used by the api-gateway resourcekit include resolver.
	BatchGetAccountGroupsByIDs(ctx context.Context, ids []string) ([]*AccountGroup, *apierror.APIError)
}

type AccountIntegration

type AccountIntegration struct {
	ID              string
	AccountID       string
	IntegrationCode constants.IntegrationCode `audit:"integration_code"`
	Name            string                    `audit:"name"`
	IsActive        bool                      `audit:"is_active"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

type AccountIntegrationRepo

type AccountIntegrationRepo interface {
	List(ctx context.Context, params ListAccountIntegrationsParams) (*ListAccountIntegrationsResult, *apierror.APIError)
	Get(ctx context.Context, accountID, id string) (*AccountIntegration, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*AccountIntegration, *apierror.APIError)
	FindByCode(ctx context.Context, accountID string, code constants.IntegrationCode) (*AccountIntegration, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateAccountIntegrationParams, encryptedCredentials string) (*AccountIntegration, *apierror.APIError)
	UpdateCredentials(ctx context.Context, accountID, id, name, encryptedCredentials string) (*AccountIntegration, *apierror.APIError)
	Update(ctx context.Context, params UpdateAccountIntegrationParams) (*AccountIntegration, *apierror.APIError)
	Delete(ctx context.Context, params DeleteAccountIntegrationParams) (*AccountIntegration, *apierror.APIError)
	GetEncryptedCredentials(ctx context.Context, accountID string, code constants.IntegrationCode) (credentials string, isActive bool, err *apierror.APIError)
	HasIntegration(ctx context.Context, accountID string, code constants.IntegrationCode) (bool, *apierror.APIError)
}

type AccountIntegrationSvc

type AccountIntegrationSvc interface {
	// ListAccountIntegrations returns a paginated list of integrations for the caller's account.
	ListAccountIntegrations(ctx context.Context, params ListAccountIntegrationsParams) (*ListAccountIntegrationsResult, *apierror.APIError)

	// CreateAccountIntegration creates or upserts an integration. If one with the same code exists, it updates name and credentials instead of inserting.
	CreateAccountIntegration(ctx context.Context, params CreateAccountIntegrationParams) (*AccountIntegration, *apierror.APIError)

	// UpdateAccountIntegration updates name and/or is_active on an integration.
	UpdateAccountIntegration(ctx context.Context, params UpdateAccountIntegrationParams) (*AccountIntegration, *apierror.APIError)

	// DeleteAccountIntegration deletes an integration and returns the deleted resource.
	DeleteAccountIntegration(ctx context.Context, params DeleteAccountIntegrationParams) (*AccountIntegration, *apierror.APIError)

	// GetStripePublishableKey returns the Stripe publishable key for the account.
	GetStripePublishableKey(ctx context.Context) (string, *apierror.APIError)

	// HasStripeIntegration returns whether the account has a Stripe integration.
	HasStripeIntegration(ctx context.Context) (bool, *apierror.APIError)

	// BatchGetAccountIntegrationsByIDs returns account integrations matching the input IDs that the caller's account is authorized to read. Used by the api-gateway resourcekit include resolver.
	BatchGetAccountIntegrationsByIDs(ctx context.Context, ids []string) ([]*AccountIntegration, *apierror.APIError)
}

type AccountPortal

type AccountPortal struct {
	ID        string
	Slug      string `audit:"slug"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

AccountPortal holds the portal metadata for an account.

type AccountPrice

type AccountPrice struct {
	ID                               string
	OwnerAccountID                   string
	RecipientAccountID               string `audit:"recipient_account_id"`
	RecipientAccountName             string `audit:"recipient_account_name"`
	RecipientAccountNumber           string
	RecipientAccountStatus           string
	RecipientAccountIsEdiEnabled     bool
	RecipientAccountCommissionPolicy string
	RecipientAccountRelationshipType string
	RecipientAccountCreatedAt        time.Time
	RecipientAccountUpdatedAt        time.Time
	ProductLineID                    string `audit:"product_line_id"`
	ProductLineName                  string `audit:"product_line_name"`
	ProductLineIsCommissionExempt    bool
	ProductLineIsFreightExempt       bool
	ProductLineCreatedAt             time.Time
	ProductLineUpdatedAt             time.Time
	RateID                           string
	RateValue                        string `audit:"rate_value"`
	RateCreatedAt                    time.Time
	RateUpdatedAt                    time.Time
	NumeratorUnitID                  string `audit:"numerator_unit_id"`
	NumeratorUnitName                string `audit:"numerator_unit_name"`
	NumeratorUnitAbbr                string `audit:"numerator_unit_abbr"`
	NumeratorUnitType                string `audit:"numerator_unit_type"`
	NumeratorUnitRatioNumerator      string
	NumeratorUnitRatioDenominator    string
	NumeratorUnitOffsetNumerator     string
	NumeratorUnitOffsetDenominator   string
	NumeratorUnitCreatedAt           time.Time
	NumeratorUnitUpdatedAt           time.Time
	DenominatorUnitID                string `audit:"denominator_unit_id"`
	DenominatorUnitName              string `audit:"denominator_unit_name"`
	DenominatorUnitAbbr              string `audit:"denominator_unit_abbr"`
	DenominatorUnitType              string `audit:"denominator_unit_type"`
	DenominatorUnitRatioNumerator    string
	DenominatorUnitRatioDenominator  string
	DenominatorUnitOffsetNumerator   string
	DenominatorUnitOffsetDenominator string
	DenominatorUnitCreatedAt         time.Time
	DenominatorUnitUpdatedAt         time.Time
	Categories                       []AccountPriceCategory  `audit:"categories"`
	Attributes                       []AccountPriceAttribute `audit:"attributes"`
	CreatedAt                        time.Time
	UpdatedAt                        time.Time
}

AccountPrice represents a customer-specific price for a product line.

type AccountPriceAttribute

type AccountPriceAttribute struct {
	ID        string
	Value     string
	ColorCode string
	CreatedAt time.Time
	UpdatedAt time.Time
}

AccountPriceAttribute represents an attribute association on an account price.

type AccountPriceCategory

type AccountPriceCategory struct {
	ID        string
	Name      string
	Type      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

AccountPriceCategory represents a category association on an account price.

type AccountPriceRepo

type AccountPriceRepo interface {
	List(ctx context.Context, params ListAccountPricesParams) (*ListAccountPricesResult, *apierror.APIError)
	// ResolveRecipientAccountIDs returns the customer plus its parent account, if it has one.
	ResolveRecipientAccountIDs(ctx context.Context, ownerAccountID, customerAccountID string) ([]string, *apierror.APIError)
	Get(ctx context.Context, accountID, accountPriceID string) (*AccountPrice, *apierror.APIError)
	Create(ctx context.Context, accountPriceID, rateID string, params CreateAccountPriceParams) (*AccountPrice, *apierror.APIError)
	Update(ctx context.Context, params UpdateAccountPriceParams) (*AccountPrice, *apierror.APIError)
	Delete(ctx context.Context, accountID, accountPriceID string) *apierror.APIError
}

type AccountPriceSvc

type AccountPriceSvc interface {
	// ExportPriceList accepts a price-list export for one customer and returns the job tracking it. Pricing a whole catalog is far too slow to hold a request open for, so the document is rendered by the export worker.
	ExportPriceList(ctx context.Context, params ExportPriceListParams) (*Job, *apierror.APIError)

	// BuildExportPriceList renders the PDF an accepted price-list export recorded.
	BuildExportPriceList(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// ListAccountPrices returns a paginated list of account prices for the caller's account. Customer actors can only see prices where they are the recipient.
	ListAccountPrices(ctx context.Context, params ListAccountPricesParams) (*ListAccountPricesResult, *apierror.APIError)

	// GetAccountPrice returns a single account price by ID.
	GetAccountPrice(ctx context.Context, accountPriceID string) (*AccountPrice, *apierror.APIError)

	// CreateAccountPrice creates a new account price with rate, category, and attribute associations.
	CreateAccountPrice(ctx context.Context, params CreateAccountPriceParams) (*AccountPrice, *apierror.APIError)

	// UpdateAccountPrice partially updates an account price. If categories or attributes are provided, they are replaced entirely (delete-all-then-recreate).
	UpdateAccountPrice(ctx context.Context, params UpdateAccountPriceParams) (*AccountPrice, *apierror.APIError)

	// DeleteAccountPrice deletes an account price and cascades to associations and rate.
	DeleteAccountPrice(ctx context.Context, accountPriceID string) *apierror.APIError
}

type AccountRelation

type AccountRelation struct {
	ID                    string
	OwnerAccountID        string
	CounterpartyAccountID string
	RoleCode              string
	// IsOwnerSide is true when the caller's account is the owner of the relation (i.e. the API key belongs to the merchant targeting a customer/supplier account).
	IsOwnerSide bool
}

type AccountRelationRepo

type AccountRelationRepo interface {
	FindByOwnerAccountAndUserID(ctx context.Context, ownerAccountID, userID string) (*AccountRelation, *apierror.APIError)
	FindByOwnerAccountAndAPIKeyID(ctx context.Context, ownerAccountID string, apiKeyID int64) (*AccountRelation, *apierror.APIError)
	FindByCounterpartyAccountAndUserID(ctx context.Context, counterpartyAccountID, ownerAccountID, userID string) (*AccountRelation, *apierror.APIError)
	FindByCounterpartyAccountAndAPIKeyID(ctx context.Context, counterpartyAccountID string, apiKeyID int64) (*AccountRelation, *apierror.APIError)
	FindCustomerByEmail(ctx context.Context, ownerAccountID, email string) (*CustomerByEmail, *apierror.APIError)
	FindContactsByEmail(ctx context.Context, ownerAccountID, email string) ([]ContactMatch, *apierror.APIError)
	HasRelation(ctx context.Context, ownerAccountID, counterpartyAccountID string) (bool, *apierror.APIError)
	CountOtherOwnerRelations(ctx context.Context, counterpartyAccountID, excludeOwnerAccountID string) (int64, *apierror.APIError)
	FindRelationByOwnerAndCounterparty(ctx context.Context, ownerAccountID, counterpartyAccountID string) (string, *apierror.APIError)
	CreateNotificationPreference(ctx context.Context, id, accountRelationID, recipientAccountUserID string, notificationTypeCode string) *apierror.APIError
	ListNotificationPreferences(ctx context.Context, accountRelationID, recipientAccountUserID string) ([]NotificationPreference, *apierror.APIError)
	ListNotificationRecipients(ctx context.Context, accountRelationID string) ([]NotificationRecipientRef, *apierror.APIError)
	DeleteNotificationPreference(ctx context.Context, accountRelationID, recipientAccountUserID, notificationTypeCode string) *apierror.APIError
	DeleteNotificationPreferencesByTypes(ctx context.Context, accountRelationID string, notificationTypeCodes []string) *apierror.APIError
	ListChildAccounts(ctx context.Context, params ListChildAccountsParams) (*ListChildAccountsResult, *apierror.APIError)
	GetChildAccountDetail(ctx context.Context, ownerAccountID, counterpartyAccountID string) (*ChildAccount, *apierror.APIError)
	GetChildAccountsByRelationIDs(ctx context.Context, ownerAccountID string, relationIDs []string) ([]*ChildAccount, *apierror.APIError)
	SetParentRelation(ctx context.Context, ownerAccountID, childRelationID, parentRelationID string) *apierror.APIError
	ClearParentRelation(ctx context.Context, ownerAccountID, childRelationID, parentRelationID string) *apierror.APIError
	GetParentRelationID(ctx context.Context, relationID string) (*string, *apierror.APIError)
	FindCustomerAccountsByVendorAndUser(ctx context.Context, vendorAccountID, userID string) ([]CustomerAccountSummary, *apierror.APIError)
}

type AccountRepo

type AccountRepo interface {
	Create(ctx context.Context, id, name string, accountTypeCode AccountType, planCode constants.PlanCode) *apierror.APIError
	GetPlanCode(ctx context.Context, id string) (constants.PlanCode, *apierror.APIError)
	GetAccountContext(ctx context.Context, accountID string) (*AccountContext, *apierror.APIError)
	// GetPlanIDAndPeriodEnd returns the account's active plan id (for limit lookups) and current subscription period end (for deriving billing-period start).
	GetPlanIDAndPeriodEnd(ctx context.Context, accountID string) (planID *string, periodEnd *time.Time, apiErr *apierror.APIError)
	Delete(ctx context.Context, id string) *apierror.APIError
	GetPlanTypeIDByCode(ctx context.Context, planCode string) (string, *apierror.APIError)
	UpdateSubscription(ctx context.Context, accountID string, status *string, planCode string, accountPlanID *string, stripeSubID *string, periodEnd *time.Time, stripeCustomerID *string, billingProfileID *string, billingCadenceID *string, pricingPlanSubscriptionID *string, servicingStatus *string, collectionStatus *string) *apierror.APIError
	ClearStripeCustomer(ctx context.Context, accountID string) *apierror.APIError
	ClearPricingPlanSubscription(ctx context.Context, accountID string) *apierror.APIError
	GetByStripeCustomerID(ctx context.Context, stripeCustomerID string) (accountID string, planCode string, err *apierror.APIError)
	GetSandboxLimit(ctx context.Context, accountID string) (*int32, *apierror.APIError)
	GetSeatLimitByPlanCode(ctx context.Context, planCode string) (*int32, *apierror.APIError)
	CountNonSandboxByPlanCode(ctx context.Context, planCode string) (int64, *apierror.APIError)
	UpdateAgentSpendingCap(ctx context.Context, accountID string, capCents *int64) *apierror.APIError
	GetAgentSpendingCap(ctx context.Context, accountID string) (*int64, *apierror.APIError)
	HasActiveBillingPlan(ctx context.Context, accountID string) (bool, *apierror.APIError)
	GetName(ctx context.Context, accountID string) (string, *apierror.APIError)
	GetPortalSlug(ctx context.Context, accountID string) (*string, *apierror.APIError)
	GetByID(ctx context.Context, accountID string) (*Account, *apierror.APIError)
	// GetByIDs returns accounts matching the given IDs. Caller authorization is enforced at the service layer.
	GetByIDs(ctx context.Context, ids []string) ([]*Account, *apierror.APIError)
	GetBySlug(ctx context.Context, slug string) (*PublicAccountBySlug, *apierror.APIError)
	UpdateName(ctx context.Context, accountID, name string) *apierror.APIError
	UpdateBranding(ctx context.Context, accountID string, params UpdateAccountParams) *apierror.APIError
	UpdatePortalSlug(ctx context.Context, accountID, slug string) *apierror.APIError
	ExistsPortalSlug(ctx context.Context, slug, excludeAccountID string) (bool, *apierror.APIError)
	UpdateBrandingLogoURL(ctx context.Context, accountID, logoURL string) *apierror.APIError
	GetBrandingLogoKey(ctx context.Context, accountID string) (*string, *apierror.APIError)
	UpdateBrandingFaviconURL(ctx context.Context, accountID, faviconURL string) *apierror.APIError
	GetBrandingFaviconKey(ctx context.Context, accountID string) (*string, *apierror.APIError)
	ListPlanLimits(ctx context.Context, accountPlanID string) (map[string]*int32, *apierror.APIError)
	ListPlanFeatures(ctx context.Context, accountPlanID string) (map[string]bool, *apierror.APIError)
}

type AccountStatus

type AccountStatus struct {
	ID        string
	Code      string
	Name      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type AccountStatusRepo

type AccountStatusRepo interface {
	List(ctx context.Context, params ListAccountStatusesParams) (*ListAccountStatusesResult, *apierror.APIError)
	Get(ctx context.Context, identifier string) (*AccountStatus, *apierror.APIError)
	GetByIDs(ctx context.Context, ids []string) ([]*AccountStatus, *apierror.APIError)
}

type AccountStatusSvc

type AccountStatusSvc interface {
	// ListAccountStatuses returns a paginated list of account statuses.
	ListAccountStatuses(ctx context.Context, params ListAccountStatusesParams) (*ListAccountStatusesResult, *apierror.APIError)

	// GetAccountStatus returns a single account status by ID or code.
	GetAccountStatus(ctx context.Context, identifier string) (*AccountStatus, *apierror.APIError)

	// BatchGetAccountStatusesByIDs returns account statuses by ID for the api-gateway include resolver.
	BatchGetAccountStatusesByIDs(ctx context.Context, ids []string) ([]*AccountStatus, *apierror.APIError)
}

type AccountSvc

type AccountSvc interface {
	// GetAccountContext returns contextual information for an account (including whether it is a sandbox).
	GetAccountContext(ctx context.Context, accountID string) (*AccountContext, *apierror.APIError)

	// GetUserAccountAccess returns the user's access to an account, including role and permissions.
	//
	// If the user has no relationship to the account, returns (nil, false, nil).
	GetUserAccountAccess(ctx context.Context, userID, accountID string) (*AccountUserAccess, bool, *apierror.APIError)

	// GetRolePermissions returns the permission map for the given role ID.
	GetRolePermissions(ctx context.Context, roleID string) (map[string]bool, *apierror.APIError)

	// GetRoleInfo returns a role's name and type code.
	GetRoleInfo(ctx context.Context, roleID string) (*RoleInfo, *apierror.APIError)

	// GetAccountRelationByUserID returns the relationship between the target account and the account implied by the user. actorAccountID is required for owner-side matches (the relation's owner_account_id must equal it); pass "" to skip the owner-side fallback entirely.
	GetAccountRelationByUserID(ctx context.Context, targetAccountID, actorAccountID, userID string) (*AccountRelation, *apierror.APIError)

	// GetAccountRelationByAPIKeyID returns the relationship between the owner account and the account implied by the API key.
	GetAccountRelationByAPIKeyID(ctx context.Context, ownerAccountID string, apiKeyID int64) (*AccountRelation, *apierror.APIError)

	// MarkAccountUserUsed records that the account user was recently used.
	MarkAccountUserUsed(ctx context.Context, accountUserID string) *apierror.APIError

	// ListUserAccountAffiliations returns the accounts the user is affiliated with.
	//
	// Also returns, if available, the user's last used account ID.
	ListUserAccountAffiliations(ctx context.Context, userID string) ([]AccountAffiliation, *string, *apierror.APIError)

	// GetAdminRole returns the role ID used for administrative access.
	GetAdminRole(ctx context.Context) (string, *apierror.APIError)

	// UpdateAccountSubscription updates subscription fields on an account, resolving the account_plan_id from the plan_code.
	UpdateAccountSubscription(ctx context.Context, accountID string, status *string, planCode string, stripeSubID *string, periodEnd *time.Time, stripeCustomerID *string, billingProfileID *string, billingCadenceID *string, pricingPlanSubscriptionID *string, servicingStatus *string, collectionStatus *string) *apierror.APIError

	// ClearAccountStripeCustomer removes all Stripe-related fields from an account.
	ClearAccountStripeCustomer(ctx context.Context, accountID string) *apierror.APIError

	// GetAccountByStripeCustomerID resolves an account from a Stripe customer ID.
	GetAccountByStripeCustomerID(ctx context.Context, stripeCustomerID string) (accountID string, planCode string, err *apierror.APIError)

	// CompleteRegistration creates the production account, sandbox, owner roles, account-user records, business address, and portal for a newly registered user. Returns the new account ID and sandbox account ID.
	CompleteRegistration(ctx context.Context, input CompleteRegistrationInput) (*CompleteRegistrationOutput, *apierror.APIError)

	// UpdateAgentSpendingCap sets or removes the monthly agent LLM spending cap for the caller's account. Pass nil to remove the cap.
	UpdateAgentSpendingCap(ctx context.Context, capCents *int64) (*int64, *apierror.APIError)

	// GetAccount returns the full account with optional branding and portal sub-resources.
	GetAccount(ctx context.Context, accountID string) (*Account, *apierror.APIError)

	// BatchGetAccountsByIDs returns accounts matching the given IDs that the caller is authorized to read. Used by the api-gateway include resolver for owner.account expansion across many parent resources.
	BatchGetAccountsByIDs(ctx context.Context, ids []string) ([]*Account, *apierror.APIError)

	// GetAccountBySlug returns a minimal public account by portal slug (unauthenticated).
	GetAccountBySlug(ctx context.Context, slug string) (*PublicAccountBySlug, *apierror.APIError)
	GetPortalProfileBySlug(ctx context.Context, slug string) (*PortalProfile, *apierror.APIError)

	// UpdateAccount partially updates an account's name, branding, and/or portal slug.
	UpdateAccount(ctx context.Context, params UpdateAccountParams) (*Account, *apierror.APIError)

	// UploadAccountPhoto uploads an account logo to S3 and updates the branding record.
	UploadAccountPhoto(ctx context.Context, accountID string, file []byte, contentType string) *apierror.APIError

	// GetAccountLogoURL returns a presigned S3 URL for the account's logo, or nil if none.
	GetAccountLogoURL(ctx context.Context, accountID string) (*string, *apierror.APIError)

	// UploadAccountFavicon uploads a customer-portal favicon to S3 and updates the branding record.
	UploadAccountFavicon(ctx context.Context, accountID string, file []byte, contentType string) *apierror.APIError

	// GetAccountFaviconURL returns a presigned S3 URL for the account's customer-portal favicon, or nil if none.
	GetAccountFaviconURL(ctx context.Context, accountID string) (*string, *apierror.APIError)
}

type AccountType

type AccountType string
const (
	AccountTypeSandbox AccountType = "sandbox"
	AccountTypeCompany AccountType = "company"
)

type AccountUser

type AccountUser struct {
	ID           string
	UserID       string
	DepartmentID *string
	RoleID       *string
	RoleType     *string
	RoleName     *string
	AccountID    string
	LastUsedAt   *time.Time
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

type AccountUserAccess

type AccountUserAccess struct {
	AccountUserID string
	AccountID     string
	RoleID        *string
	RoleType      *string
	RoleName      *string
	Permissions   map[string]bool
	LastUsedAt    *time.Time
}

type AccountUserDetail

type AccountUserDetail struct {
	ID                   string
	UserID               string
	Name                 *string `audit:"name"`
	Email                *string `audit:"email"`
	Username             *string `audit:"username"`
	ImageURL             *string `audit:"image_url"`
	EmailVerified        bool    `audit:"email_verified"`
	RoleID               *string `audit:"role_id"`
	RoleName             *string `audit:"role_name"`
	RoleType             *string `audit:"role_type_code"`
	DepartmentID         *string `audit:"department_id"`
	DepartmentName       *string `audit:"department_name"`
	DepartmentCreatedAt  *time.Time
	DepartmentUpdatedAt  *time.Time
	StatusCode           constants.AccountUserStatus `audit:"status_code"`
	IsCommissionEligible bool                        `audit:"is_commission_eligible"`
	LastUsedAt           *time.Time
	CreatedAt            time.Time
	UpdatedAt            time.Time
}

AccountUserDetail is an enriched account user model with joined user, role, and department data. Used by the account user management endpoints.

type AccountUserRef

type AccountUserRef struct {
	ID     string
	UserID string
}

AccountUserRef is a lightweight reference to an account user.

type AccountUserRepo

type AccountUserRepo interface {
	FindByAccountAndUserID(ctx context.Context, userID, accountID string) (*AccountUser, *apierror.APIError)
	// ResolveAccountUserID resolves either an account_user id or a user id to the account_user id within the given account.
	ResolveAccountUserID(ctx context.Context, accountID, userOrAccountUserID string) (string, *apierror.APIError)
	FindAffiliationsByUserID(ctx context.Context, userID string) ([]AccountAffiliation, *apierror.APIError)
	FindLastUsedAccountID(ctx context.Context, userID string) (string, *apierror.APIError)
	UpdateLastUsedAt(ctx context.Context, accountUserID string, lastUsedAt time.Time) *apierror.APIError
	GetAdminRoleID(ctx context.Context) (string, *apierror.APIError)
	DeactivateExcept(ctx context.Context, accountID, keepUserID string, limit int32) (int64, *apierror.APIError)
	EnsureActive(ctx context.Context, accountID, userID string) *apierror.APIError
	CountActive(ctx context.Context, accountID string) (int64, *apierror.APIError)
	ReactivateUsers(ctx context.Context, accountID string, limit int32) (int64, *apierror.APIError)
	List(ctx context.Context, params ListAccountUsersParams) (*ListAccountUsersResult, *apierror.APIError)
	GetDetail(ctx context.Context, accountID, userID string, includes []string) (*AccountUserDetail, *apierror.APIError)
	GetDetailByAccountAndID(ctx context.Context, accountID, accountUserID string, includes []string) (*AccountUserDetail, *apierror.APIError)
	Create(ctx context.Context, id, accountID, userID string, roleID, departmentID *string, isCommissionEligible bool) *apierror.APIError
	Update(ctx context.Context, accountUserID string, roleID, departmentID *string, isCommissionEligible bool) *apierror.APIError
	// ReactivateRemovedAccountUser reactivates a previously soft-removed link for (accountID, userID), setting its role/department, and returns the reactivated account_user id. Returns resource_not_found when no removed link exists.
	ReactivateRemovedAccountUser(ctx context.Context, accountID, userID string, roleID, departmentID *string, isCommissionEligible bool) (string, *apierror.APIError)
	SoftDelete(ctx context.Context, accountUserID string) *apierror.APIError
	UpdateStatus(ctx context.Context, accountUserID string, status constants.AccountUserStatus) *apierror.APIError
	CountByRoleID(ctx context.Context, accountID, roleID string) (int64, *apierror.APIError)
	RevokeRefreshTokensByUserID(ctx context.Context, userID string) *apierror.APIError
	FindFirstAccountIDByUserID(ctx context.Context, userID string) (string, *apierror.APIError)
	FindTenancyAccountsByUserID(ctx context.Context, userID string) ([]TenancyAccount, *apierror.APIError)
	MarkUsedByAccountAndUser(ctx context.Context, accountID, userID string) *apierror.APIError
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*AccountUserDetail, *apierror.APIError)
}

type AccountUserSvc

type AccountUserSvc interface {
	// ListAccountUsers returns a paginated list of account users.
	ListAccountUsers(ctx context.Context, params ListAccountUsersParams) (*ListAccountUsersResult, *apierror.APIError)

	// GetAccountUser returns a single account user by account_user ID.
	GetAccountUser(ctx context.Context, accountUserID string, includes []string) (*AccountUserDetail, *apierror.APIError)

	// CreateAccountUser creates a new account user.
	CreateAccountUser(ctx context.Context, params CreateAccountUserParams) (*AccountUserDetail, *apierror.APIError)

	// UpdateAccountUser partially updates an account user, optionally including notification preferences.
	UpdateAccountUser(ctx context.Context, params UpdateAccountUserParams, includes []string) (*AccountUserDetail, *apierror.APIError)

	// UpdateAccountUserStatus transitions an account user to the given target status.
	UpdateAccountUserStatus(ctx context.Context, accountUserID string, targetStatus constants.AccountUserStatus) *apierror.APIError

	// UpdateAccountUserPassword updates the password for a scanner-role account user.
	UpdateAccountUserPassword(ctx context.Context, accountUserID, requesterPassword, newPassword string) *apierror.APIError

	// BatchGetAccountUsersByIDs returns account users matching the given IDs.
	BatchGetAccountUsersByIDs(ctx context.Context, ids []string) ([]*AccountUserDetail, *apierror.APIError)
}

type AddBatchInput

type AddBatchInput struct {
	ID                string
	ItemID            string
	Quantity          CreateQuantityParams
	Seconds           *CreateQuantityParams
	Waste             *CreateQuantityParams
	ProductionStepID  *string
	ScanningStationID *string
}

AddBatchInput represents a single batch to add to a production run.

type AddBatchesToProductionRunParams

type AddBatchesToProductionRunParams struct {
	ProductionRunID string
	AccountID       string
	Batches         []AddBatchInput
}

AddBatchesToProductionRunParams holds the parameters for adding batches to a production run.

type AddItemAttributeParams

type AddItemAttributeParams struct {
	AccountID   string
	ItemID      string
	AttributeID string
}

AddItemAttributeParams holds parameters for adding an attribute to an item.

type AddItemCategoryPropertyParams

type AddItemCategoryPropertyParams struct {
	AccountID      string
	ItemCategoryID string
	PropertyID     string
}

type Address

type Address struct {
	ID         string
	Name       string  `audit:"name"`
	Phone      *string `audit:"phone"`
	Email      *string `audit:"email"`
	IsDropShip bool    `audit:"is_drop_ship"`
	// ReceiveCalendarID names the days this dock accepts freight, overriding the customer's own calendar. Set when one of a customer's sites keeps different days from the rest.
	ReceiveCalendarID *string      `audit:"receive_calendar_id"`
	Geolocation       *Geolocation `audit:"geolocation"`
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

Address represents an address with its associated geolocation.

type AddressComponents

type AddressComponents struct {
	AddressLine1 string
	AddressLine2 *string
	City         string
	State        string
	PostalCode   string
	Country      string
	CountryCode  string
}

AddressComponents represents parsed address components.

type AddressDetailsResult

type AddressDetailsResult struct {
	Address          *AddressComponents
	FormattedAddress string
}

AddressDetailsResult represents the result of a place details lookup.

type AddressRepo

type AddressRepo interface {
	List(ctx context.Context, params ListAddressesParams) (*ListAddressesResult, *apierror.APIError)
	Get(ctx context.Context, params GetAddressParams) (*Address, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Address, *apierror.APIError)
	Create(ctx context.Context, addressID, geolocationID, accountAddressID string, params CreateAddressParams) (*Address, *apierror.APIError)
	Update(ctx context.Context, params UpdateAddressParams) (*Address, *apierror.APIError)
	Delete(ctx context.Context, params DeleteAddressParams) *apierror.APIError
	IsInAccount(ctx context.Context, accountID, addressID string) (bool, *apierror.APIError)
	GetGeolocationSharedCount(ctx context.Context, geolocationID string) (int64, *apierror.APIError)
	GetGeolocationIDByAddressID(ctx context.Context, addressID string) (string, *apierror.APIError)
	CreateGeolocation(ctx context.Context, id string, params CreateAddressParams) *apierror.APIError
	UpdateGeolocation(ctx context.Context, geolocationID string, params UpdateAddressParams) *apierror.APIError
	RelinkGeolocation(ctx context.Context, addressID, geolocationID string) *apierror.APIError
	CheckAddressNotInUse(ctx context.Context, addressID string) *apierror.APIError
	// SwitchAccountDefaultAddressToRelation realigns any account default billing/shipping pointer at
	// the given address to the account-relation default (owner→this account), falling back to NULL
	// when the relation has no usable default. It keeps a non-active account from being left with a
	// dangling default when the address is deleted (there are no FKs to cascade). Call inside the
	// delete transaction.
	SwitchAccountDefaultAddressToRelation(ctx context.Context, addressID string) *apierror.APIError
}

type AddressSuggestion

type AddressSuggestion struct {
	ID            string
	Description   string
	MainText      string
	SecondaryText string
}

AddressSuggestion represents an autocomplete suggestion.

type AddressSvc

type AddressSvc interface {
	// ListAddresses returns a paginated list of addresses for an account.
	ListAddresses(ctx context.Context, params ListAddressesParams) (*ListAddressesResult, *apierror.APIError)

	// GetAddress returns a single address by ID within an account.
	GetAddress(ctx context.Context, params GetAddressParams) (*Address, *apierror.APIError)

	// CreateAddress creates a new address linked to an account.
	CreateAddress(ctx context.Context, params CreateAddressParams) (*Address, *apierror.APIError)

	// UpdateAddress partially updates an address within an account.
	UpdateAddress(ctx context.Context, params UpdateAddressParams) (*Address, *apierror.APIError)

	// DeleteAddress deletes an address from an account.
	DeleteAddress(ctx context.Context, params DeleteAddressParams) *apierror.APIError

	// BatchGetAddressesByIDs returns addresses matching the input IDs that the caller's account is authorized to read. Used by the api-gateway resourcekit include resolver.
	BatchGetAddressesByIDs(ctx context.Context, ids []string) ([]*Address, *apierror.APIError)
}

type AddressValidationSvc

type AddressValidationSvc interface {
	// Autocomplete returns address autocomplete suggestions.
	Autocomplete(ctx context.Context, input string, sessionToken *string) ([]AddressSuggestion, *apierror.APIError)

	// GetPlaceDetails returns parsed address components from a Google Places ID.
	GetPlaceDetails(ctx context.Context, placeID string, sessionToken *string) (*AddressDetailsResult, *apierror.APIError)

	// ValidateAddress validates an address using Google Address Validation API.
	ValidateAddress(ctx context.Context, addressLine1 string, addressLine2 *string, city, state, postalCode, country string) (*ValidatedAddress, *apierror.APIError)
}

type AdjustmentType

type AdjustmentType struct {
	ID        string
	Name      string
	Code      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type AdjustmentTypeRepo

type AdjustmentTypeRepo interface {
	List(ctx context.Context, params ListAdjustmentTypesParams) (*ListAdjustmentTypesResult, *apierror.APIError)
	GetByIDs(ctx context.Context, ids []string) ([]*AdjustmentType, *apierror.APIError)
}

type AdjustmentTypeSvc

type AdjustmentTypeSvc interface {
	// ListAdjustmentTypes returns a paginated list of adjustment types.
	ListAdjustmentTypes(ctx context.Context, params ListAdjustmentTypesParams) (*ListAdjustmentTypesResult, *apierror.APIError)
	// BatchGetAdjustmentTypesByIDs returns adjustment types by ID for the api-gateway include resolver.
	BatchGetAdjustmentTypesByIDs(ctx context.Context, ids []string) ([]*AdjustmentType, *apierror.APIError)
}

type AdminUpdateShipmentTrackingParams

type AdminUpdateShipmentTrackingParams struct {
	AccountID            string
	ShipmentID           string
	MasterTrackingNumber *string
	CarrierID            *string
	// Tri-state: unset keeps the current service level, null clears it.
	ServiceLevelID field.Clearable[string]
	Includes       []string
}

Carries the admin override that corrects a shipped shipment's tracking and routing.

type AdminUpdateShippingCaseTrackingParams

type AdminUpdateShippingCaseTrackingParams struct {
	AccountID      string
	ShippingCaseID string
	TrackingNumber *string
}

Carries the admin override that corrects a shipped case's tracking number.

type AllocateOpenIssuesEvent added in v1.3.0

type AllocateOpenIssuesEvent struct {
	AccountID      string    `json:"account_id"`
	ItemID         string    `json:"item_id"`
	AfterCreatedAt time.Time `json:"after_created_at"`
	AfterID        string    `json:"after_id"`
}

AllocateOpenIssuesEvent is the outbox command payload asking a consumer to allocate one page of an item's open inventory issues against available receipts, resuming after the (AfterCreatedAt, AfterID) cursor. AfterID is empty and AfterCreatedAt the zero time for the first page.

type AllocationEntry

type AllocationEntry struct {
	ID                string
	AmountValue       string
	AmountUnitAbbr    string
	CustomerName      string
	CustomerNumber    *string
	TransactionID     string
	TransactionType   string
	TransactionMethod *string
	AdjustmentType    *string
	InvoiceID         string
	InvoiceNumber     string
	Note              *string
	CreatedAt         time.Time
}

AllocationEntry represents a lightweight transaction allocation for list views.

type AnalyticsRepo

type AnalyticsRepo interface {
	GetSalesEntries(ctx context.Context, params AnalyzeSalesParams) ([]SalesEntry, *apierror.APIError)
	GetOpenBatchEntries(ctx context.Context, params AnalyzeOpenBatchesParams) ([]OpenBatchEntry, *apierror.APIError)
	GetProductionCostEntries(ctx context.Context, params AnalyzeProductionCostsParams) ([]ProductionCostEntry, *apierror.APIError)
	GetDeliveryAnalytics(ctx context.Context, params AnalyzeDeliveriesParams) (*DeliveryAnalyticsResult, *apierror.APIError)
	GetManufacturingMetric(ctx context.Context, params AnalyzeManufacturingParams) (float64, *apierror.APIError)
	GetManufacturingBatch(ctx context.Context, params AnalyzeManufacturingBatchParams) (*ManufacturingBatchResult, *apierror.APIError)
	GetOrderEntries(ctx context.Context, params AnalyzeOrdersParams) ([]OrderEntry, *apierror.APIError)
	GetQuarterlyOrders(ctx context.Context, params AnalyzeQuarterlyOrdersParams) ([]YearlyQuarterlyData, *apierror.APIError)
	GetMaterialAnalytics(ctx context.Context, params AnalyzeMaterialsParams) ([]MaterialAnalyticsEntry, *apierror.APIError)
	GetInventoryReceiptAnalytics(ctx context.Context, params AnalyzeInventoryReceiptsParams) ([]InventoryReceiptEntry, *apierror.APIError)
	GetNewCustomerEntries(ctx context.Context, params GetNewCustomersAnalyticsParams) ([]NewCustomerEntry, *apierror.APIError)
	GetDemandForecastMonthlyDemand(ctx context.Context, params GetDemandForecastWindowParams) ([]DemandForecastMonthlyDemandRow, *apierror.APIError)
	GetDemandForecastMonthlyRevenue(ctx context.Context, params GetDemandForecastWindowParams) ([]DemandForecastMonthlyRevenueRow, *apierror.APIError)
	GetOeeDepartmentData(ctx context.Context, params GetOeeWindowParams) ([]OeeDepartmentDataRow, *apierror.APIError)
	GetOeeEstimatedRuntime(ctx context.Context, params GetOeeWindowParams) ([]OeeEstimatedRuntimeRow, *apierror.APIError)
	GetOeeDowntimeByDepartment(ctx context.Context, params GetOeeWindowParams) ([]OeeDowntimeRow, *apierror.APIError)
	GetOeeTrendDepartmentDataByWeek(ctx context.Context, params GetOeeWindowParams) ([]OeeTrendDepartmentWeekRow, *apierror.APIError)
	GetOeeTrendDowntimeIntervals(ctx context.Context, params GetOeeWindowParams) ([]OeeDowntimeIntervalRow, *apierror.APIError)
	CountMachinesByDepartment(ctx context.Context, accountID string) ([]DepartmentMachineCountRow, *apierror.APIError)
	GetSaleProductItemIDs(ctx context.Context, accountID string) ([]SaleProductItemRow, *apierror.APIError)
	GetProductLineInfo(ctx context.Context, accountID string, productLineIDs []string) ([]ProductLineInfoRow, *apierror.APIError)
	GetOrderQuantityByProductLine(ctx context.Context, params GetOrderQuantityByProductLineParams) (*OrderQuantityByProductLineRow, *apierror.APIError)
}

type AnalyticsSvc

type AnalyticsSvc interface {
	AnalyzeSales(ctx context.Context, params AnalyzeSalesParams) ([]SalesEntry, *apierror.APIError)

	// AnalyzeRealizedMargins rolls invoiced lines up to one row per customer and SKU and flags those priced below their peers or under target margin.
	AnalyzeRealizedMargins(ctx context.Context, params AnalyzeRealizedMarginsParams) (*RealizedMarginAnalysis, *apierror.APIError)

	// AnalyzeCustomerPricing sweeps every contracted price and flags those below their peers or under target margin.
	AnalyzeCustomerPricing(ctx context.Context, params AnalyzeCustomerPricingParams) (*CustomerPricingAnalysis, *apierror.APIError)
	AnalyzeOpenBatches(ctx context.Context, params AnalyzeOpenBatchesParams) ([]OpenBatchEntry, *apierror.APIError)
	AnalyzeProductionCosts(ctx context.Context, params AnalyzeProductionCostsParams) ([]ProductionCostEntry, *apierror.APIError)
	AnalyzeDeliveries(ctx context.Context, params AnalyzeDeliveriesParams) (*DeliveryAnalyticsResult, *apierror.APIError)
	AnalyzeManufacturing(ctx context.Context, params AnalyzeManufacturingParams) (float64, *apierror.APIError)
	AnalyzeManufacturingBatch(ctx context.Context, params AnalyzeManufacturingBatchParams) (*ManufacturingBatchResult, *apierror.APIError)
	AnalyzeOrders(ctx context.Context, params AnalyzeOrdersParams) ([]OrderEntry, *apierror.APIError)
	AnalyzeQuarterlyOrders(ctx context.Context, params AnalyzeQuarterlyOrdersParams) ([]YearlyQuarterlyData, *apierror.APIError)
	AnalyzeMaterials(ctx context.Context, params AnalyzeMaterialsParams) ([]MaterialAnalyticsEntry, *apierror.APIError)
	AnalyzeInventoryReceipts(ctx context.Context, params AnalyzeInventoryReceiptsParams) ([]InventoryReceiptEntry, *apierror.APIError)
	GetNewCustomersAnalytics(ctx context.Context, params GetNewCustomersAnalyticsParams) ([]NewCustomerEntry, *apierror.APIError)
	// GetDemandForecast returns per-item demand, revenue and sales history with seasonal-EMA forecasts and confidence bands.
	GetDemandForecast(ctx context.Context, params GetDemandForecastParams) (*DemandForecastResult, *apierror.APIError)
	// AnalyzeOee computes Availability x Performance x Quality per department from planned time, logged downtime and batch-ticket scan intervals.
	AnalyzeOee(ctx context.Context, params AnalyzeOeeParams) ([]OeeDepartment, *apierror.APIError)
	AnalyzeOeeTrend(ctx context.Context, params AnalyzeOeeTrendParams) ([]OeeTrendPeriod, *apierror.APIError)

	// AnalyzeScheduleAttainment measures actual production against the plan that was live at the time.
	AnalyzeScheduleAttainment(ctx context.Context, params AnalyzeScheduleAttainmentParams) (*ScheduleAttainmentResult, *apierror.APIError)

	// AnalyzeDeliveryPerformance measures what was promised against what was shipped.
	AnalyzeDeliveryPerformance(ctx context.Context, params AnalyzeDeliveryPerformanceParams) (*DeliveryPerformanceResult, *apierror.APIError)
	// AnalyzeWeeksOfSales returns on-hand inventory expressed as weeks of average sales per product line.
	AnalyzeWeeksOfSales(ctx context.Context, params AnalyzeWeeksOfSalesParams) (*WeeksOfSalesResult, *apierror.APIError)
}

type AnalyzeCustomerPricingParams

type AnalyzeCustomerPricingParams struct {
	// CustomerIDs and CustomerGroupIDs narrow the reported findings, not the peer benchmark: a price must be compared against every comparable price, including those the caller did not ask about.
	CustomerIDs       []string
	CustomerGroupIDs  []string
	TargetGrossMargin *string
	OutlierTolerance  *string
}

AnalyzeCustomerPricingParams filters the contracted-pricing audit.

type AnalyzeDeliveriesParams

type AnalyzeDeliveriesParams struct {
	AccountID              string
	StartDate              time.Time
	EndDate                time.Time
	ProductLineIDs         []string
	CustomerIDs            []string
	CustomerGroupIDs       []string
	SalesRepIDs            []string
	TargetDeliveryTimeDays *int32
	OverridePromisedDates  *bool
}

type AnalyzeDeliveryPerformanceParams

type AnalyzeDeliveryPerformanceParams struct {
	AccountID   string
	StartDate   time.Time
	EndDate     time.Time
	Granularity string

	DeliveryFilters
}

AnalyzeDeliveryPerformanceParams scopes a delivery measurement to one account, window and slice of the order book.

type AnalyzeInventoryReceiptsParams

type AnalyzeInventoryReceiptsParams struct {
	AccountID   string
	ItemIDs     []string
	LocationIDs []string
	LotIDs      []string
}

type AnalyzeManufacturingBatchParams

type AnalyzeManufacturingBatchParams struct {
	AccountID           string
	StartDate           time.Time
	EndDate             time.Time
	ComparisonStartDate time.Time
	ComparisonEndDate   time.Time
	CustomerIDs         []string
	ProductLineIDs      []string
	CustomerGroupIDs    []string
	ItemIDs             []string
}

type AnalyzeManufacturingParams

type AnalyzeManufacturingParams struct {
	AccountID string
	StartDate time.Time
	EndDate   time.Time
	Type      string
}

type AnalyzeMaterialsParams

type AnalyzeMaterialsParams struct {
	AccountID     string
	SalesOrderIDs []string
	SupplierIDs   []string
}

type AnalyzeOeeParams

type AnalyzeOeeParams struct {
	AccountID     string
	StartDate     time.Time
	EndDate       time.Time
	DepartmentIDs []string
	// PlannedTimeHours is the scheduled production time per department for the window. Without it Availability has no denominator, so the OEE ratios are returned nil rather than guessed. Keyed by department ID.
	PlannedTimeHours map[string]float64
}

type AnalyzeOeeTrendParams

type AnalyzeOeeTrendParams struct {
	AccountID     string
	StartDate     time.Time
	EndDate       time.Time
	DepartmentIDs []string
}

AnalyzeOeeTrendParams bounds an OEE trend read: the same window and department filter as AnalyzeOee, bucketed into production weeks.

type AnalyzeOpenBatchesParams

type AnalyzeOpenBatchesParams struct {
	AccountID      string
	ItemIDs        []string
	ProductLineIDs []string
}

type AnalyzeOrdersParams

type AnalyzeOrdersParams struct {
	AccountID        string
	SalesRepIDs      []string
	ProductLineIDs   []string
	CustomerIDs      []string
	CustomerGroupIDs []string
	IsSalesRep       bool
}

type AnalyzeProductionCostsParams

type AnalyzeProductionCostsParams struct {
	AccountID      string
	StartDate      *time.Time
	EndDate        *time.Time
	ItemIDs        []string
	ProductLineIDs []string
	DepartmentIDs  []string
	CategoryIDs    []string
}

type AnalyzeQuarterlyOrdersParams

type AnalyzeQuarterlyOrdersParams struct {
	AccountID        string
	SalesRepIDs      []string
	ItemIDs          []string
	ProductLineIDs   []string
	CustomerIDs      []string
	CustomerGroupIDs []string
}

type AnalyzeRealizedMarginsParams

type AnalyzeRealizedMarginsParams struct {
	StartDate time.Time
	EndDate   time.Time
	// CustomerIDs and CustomerGroupIDs narrow the reported findings, not the peer benchmark: a customer must be compared against everyone who bought the SKU, including those the caller did not ask about.
	CustomerIDs       []string
	CustomerGroupIDs  []string
	ProductLineIDs    []string
	TargetGrossMargin *string
	OutlierTolerance  *string
}

AnalyzeRealizedMarginsParams filters the realized-margin audit.

type AnalyzeSalesParams

type AnalyzeSalesParams struct {
	AccountID        string
	StartDate        time.Time
	EndDate          time.Time
	ProductLineIDs   []string
	CustomerIDs      []string
	SalesRepIDs      []string
	CustomerGroupIDs []string
	Query            *string
	IsSalesRep       bool
}

type AnalyzeScheduleAttainmentParams

type AnalyzeScheduleAttainmentParams struct {
	AccountID     string
	StartDate     time.Time
	EndDate       time.Time
	GroupBy       string
	MachineIDs    []string
	DepartmentIDs []string
}

type AnalyzeWeeksOfSalesParams

type AnalyzeWeeksOfSalesParams struct {
	AccountID     string
	PeriodInWeeks int32
}

type AttainmentActualRow

type AttainmentActualRow struct {
	WeekStartDate  time.Time
	MachineID      *string
	ItemID         string
	DepartmentID   *string
	ActualQuantity float64
	WasteQuantity  float64
	BatchCount     int64
}

AttainmentActualRow is what was actually produced per (week, machine, item), bucketed to the Monday of the scan week.

type AttainmentBaselineRow

type AttainmentBaselineRow struct {
	ScheduleID       string
	Version          int32
	HorizonStartDate time.Time
	HorizonEndDate   time.Time
	// PublishedAt is nil for a version that was never published — a draft was never a commitment.
	PublishedAt       *time.Time
	FrozenThroughDate *time.Time
	FrozenLineCount   int32
	// FrozenPlannedQuantity is the quantity captured at publish, pre-converted from its decimal column.
	FrozenPlannedQuantity float64
}

AttainmentBaselineRow is one published schedule version whose horizon overlaps the window. Rows arrive newest-publish-first.

type AttainmentBucket

type AttainmentBucket struct {
	// Key identifies the bucket within the chosen grouping — an ISO week start, a machine id, a department id or an item id.
	Key   string
	Label string

	WeekStartDate *time.Time

	PlannedQuantity float64
	ActualQuantity  float64
	// MatchedQuantity is SUM(LEAST(actual, planned)) — the attainment numerator.
	MatchedQuantity float64
	WasteQuantity   float64
	// UnplannedQuantity is production with no matching planned line. It is surfaced rather than discarded: it is the schedule-breaker number.
	UnplannedQuantity float64

	PlannedRunHours float64
	PlannedLines    int64
	BatchCount      int64

	// Nil when the denominator is zero — a week nobody planned has no attainment, which is not the same as 0%.
	AttainmentPct  *float64
	OutputRatioPct *float64
}

AttainmentBucket is one row of the breakdown.

Both ratios are reported because they answer different questions and either alone is misleading: attainment caps every SKU at what was asked for, so over-building one easy item cannot paper over a total miss on another; output ratio does not cap, so it is the only one that shows over-production.

type AttainmentDeviationRow

type AttainmentDeviationRow struct {
	ProductionScheduleID string
	DeviationCount       int64
	AddedCount           float64
	AbsDeltaQuantity     float64
}

AttainmentDeviationRow counts frozen-week changes for one baseline version.

type AttainmentLabelRow

type AttainmentLabelRow struct {
	ID    string
	Label string
}

AttainmentLabelRow resolves a type id to the name the UI should show for it.

type AttainmentPlannedRow

type AttainmentPlannedRow struct {
	WeekStartDate   time.Time
	MachineID       string
	ItemID          string
	DepartmentID    *string
	PlannedQuantity float64
	PlannedRunHours float64
	LineCount       int64
}

AttainmentPlannedRow is planned quantity and run hours per (week, machine, item) for one baseline version.

type Attribute

type Attribute struct {
	ID         string
	Value      string `audit:"value"`
	PropertyID string
	AccountID  string
	ColorCode  string `audit:"color_code"`
	SortOrder  int32  `audit:"sort_order"`
	IsPublic   bool   `audit:"is_public"`
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

Attribute represents a value option within a property.

type AttributeRepo

type AttributeRepo interface {
	List(ctx context.Context, params ListAttributesParams) (*ListAttributesResult, *apierror.APIError)
	ListByPropertyIDs(ctx context.Context, accountID string, propertyIDs []string) ([]*Attribute, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Attribute, *apierror.APIError)
	Get(ctx context.Context, params GetAttributeParams) (*Attribute, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateAttributeParams) (*Attribute, *apierror.APIError)
	Update(ctx context.Context, params UpdateAttributeParams) (*Attribute, *apierror.APIError)
	Delete(ctx context.Context, params DeleteAttributeParams) *apierror.APIError
	ExistsByValueInAccount(ctx context.Context, accountID, value string, excludeID *string) (bool, *apierror.APIError)
	FindByTextsInAccount(ctx context.Context, accountID string, texts []string) ([]*AttributeTextMatch, *apierror.APIError)
	CountByProperty(ctx context.Context, propertyID, accountID string) (int64, *apierror.APIError)
	ShiftOrdersUp(ctx context.Context, propertyID, accountID string, fromOrder int32) *apierror.APIError
	ShiftOrdersDown(ctx context.Context, propertyID, accountID string, afterOrder int32) *apierror.APIError
	ShiftOrdersUpBounded(ctx context.Context, propertyID, accountID string, fromOrder, toOrder int32) *apierror.APIError
	ShiftOrdersDownBounded(ctx context.Context, propertyID, accountID string, afterOrder, upToOrder int32) *apierror.APIError
}

type AttributeSvc

type AttributeSvc interface {
	// ListAttributes returns a paginated list of attributes for a property.
	ListAttributes(ctx context.Context, params ListAttributesParams) (*ListAttributesResult, *apierror.APIError)

	// GetAttribute returns a single attribute by ID within a property.
	GetAttribute(ctx context.Context, propertyID, attributeID string) (*Attribute, *apierror.APIError)

	// BatchGetAttributesByIDs returns attributes matching the input IDs that belong to the caller's account.
	BatchGetAttributesByIDs(ctx context.Context, ids []string) ([]*Attribute, *apierror.APIError)

	// CreateAttribute creates a new attribute under a property.
	CreateAttribute(ctx context.Context, params CreateAttributeParams) (*Attribute, *apierror.APIError)

	// UpdateAttribute partially updates an attribute.
	UpdateAttribute(ctx context.Context, params UpdateAttributeParams) (*Attribute, *apierror.APIError)

	// DeleteAttribute deletes an attribute.
	DeleteAttribute(ctx context.Context, params DeleteAttributeParams) *apierror.APIError
}

type AttributeTextMatch

type AttributeTextMatch struct {
	ID           string
	Text         string
	PropertyID   string
	PropertyName string
}

AttributeTextMatch is an existing attribute matched by its text within an account, with its owning property named. Used by bulk upsert to enforce the account-wide attribute value uniqueness the manual create path enforces.

type BaseBatch

type BaseBatch struct {
	ID              string
	Item            LightItem             `audit:"item"`
	Quantity        BatchQuantity         `audit:"quantity"`
	Seconds         *BatchQuantity        `audit:"seconds"`
	Waste           *BatchQuantity        `audit:"waste"`
	ScanningStation *LightScanningStation `audit:"scanning_station"`
	DepartmentID    *string               `audit:"department_id"`
	DepartmentName  *string               `audit:"department_name"`
	ProductionStep  *LightProductionStep  `audit:"production_step"`
	ProductionRun   *LightProductionRun   `audit:"production_run"`
	ProductionRunID *string
	ClosedAt        *time.Time `audit:"closed_at"`
	ScannedAt       *time.Time `audit:"scanned_at"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

BaseBatch is a lighter version of Batch used for mutation responses.

type Batch

type Batch struct {
	ID              string
	Item            LightItem             `audit:"item"`
	Quantity        BatchQuantity         `audit:"quantity"`
	Seconds         *BatchQuantity        `audit:"seconds"`
	Waste           *BatchQuantity        `audit:"waste"`
	ScanningStation *LightScanningStation `audit:"scanning_station"`
	DepartmentID    *string               `audit:"department_id"`
	DepartmentName  *string               `audit:"department_name"`
	ProductionStep  *LightProductionStep  `audit:"production_step"`
	ProductionRun   *LightProductionRun   `audit:"production_run"`
	Machines        []LightMachine
	Lots            []BatchLot
	InputBatchIDs   []string
	OutputBatchIDs  []string
	ClosedAt        *time.Time `audit:"closed_at"`
	ScannedAt       *time.Time `audit:"scanned_at"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

Batch is the full batch domain model with all associated data.

type BatchFlowChildRow

type BatchFlowChildRow struct {
	ParentBatchID string
	BatchID       string
	ItemID        string
}

BatchFlowChildRow is one immediate downstream batch in the genealogy.

type BatchFlowNode

type BatchFlowNode struct {
	Batch          Batch
	InputBatchIDs  []string
	OutputBatchIDs []string
}

BatchFlowNode is a batch with its input and output batch IDs for flow graph rendering.

type BatchLot

type BatchLot struct {
	LotNumber string
	Type      string // "material" or "productionRun"
}

BatchLot represents a lot associated with a batch.

type BatchQuantity

type BatchQuantity struct {
	ID      string
	Measure decimal.Decimal
	Unit    LightUnit
}

BatchQuantity represents a quantity with a unit.

type BatchRepo

type BatchRepo interface {
	Find(ctx context.Context, accountID, batchID string) (*Batch, *apierror.APIError)
	FindBatchFlow(ctx context.Context, accountID, batchID string) ([]BatchFlowNode, *apierror.APIError)
	FindByScanningStation(ctx context.Context, params ListBatchesByScanningStationParams) (*ListBatchesByScanningStationResult, *apierror.APIError)
	FindPossibleNextSteps(ctx context.Context, accountID, scanningStationID, batchID string) ([]ScanningProductionStepInfo, *apierror.APIError)
	FindOpenBatches(ctx context.Context, accountID string, itemIDs, productLineIDs []string) ([]OpenBatchSummary, *apierror.APIError)
	FindFurthestRightBatchInFlow(ctx context.Context, accountID, batchID string) (*BaseBatch, *apierror.APIError)
	FindNextAvailableBatchInFlow(ctx context.Context, accountID, batchID, productionStepID string) (*BaseBatch, *apierror.APIError)
	FindAvailableBatchesInFlow(ctx context.Context, accountID string, batchIDs []string, productionStepID string) ([]BaseBatch, *apierror.APIError)
	FindOutputBatches(ctx context.Context, accountID, batchID string) ([]BaseBatch, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateBatchParams) (*BaseBatch, *apierror.APIError)
	MarkAsScanned(ctx context.Context, accountID, batchID string) *apierror.APIError
	ConnectProductionStep(ctx context.Context, accountID, batchID, productionStepID string) *apierror.APIError
	ConnectScanningStation(ctx context.Context, accountID, batchID, scanningStationID string) *apierror.APIError
	ConnectOneToOne(ctx context.Context, accountID, sourceBatchID, targetBatchID string, autoClose bool) *apierror.APIError
	ConnectManyToOne(ctx context.Context, accountID string, sourceBatchIDs []string, targetBatchID string, autoClose bool) *apierror.APIError
	Close(ctx context.Context, accountID, batchID string) (*BaseBatch, *apierror.APIError)
	CloseIfLastStep(ctx context.Context, accountID, batchID, productionStepID string) *apierror.APIError
	CloseIfFullyUsed(ctx context.Context, accountID string, batch BaseBatch, producedUnit LightUnit, productionStepID string) *apierror.APIError
	Delete(ctx context.Context, accountID, batchID string) (*BaseBatch, *apierror.APIError)
	DeleteMany(ctx context.Context, accountID string, batchIDs []string) *apierror.APIError
	// CountDownstreamBatches reports how many batches were fed by this one. A batch something downstream still feeds on cannot be undone.
	CountDownstreamBatches(ctx context.Context, batchID string) (int64, *apierror.APIError)
	// FindInputBatchIDs returns the batches that fed the given one.
	FindInputBatchIDs(ctx context.Context, batchID string) ([]string, *apierror.APIError)
	// FindLineageShortfall walks up a batch's lineage for the production run it belongs to and the seconds and waste accumulated along the way.
	FindLineageShortfall(ctx context.Context, batchID string) (*LineageShortfall, *apierror.APIError)
	// Unscan returns a batch to the state it was in before it was scanned, leaving the row in place so the production run that created it still holds that unit of work.
	Unscan(ctx context.Context, accountID, batchID string) (*BaseBatch, *apierror.APIError)
	// Reopen clears a batch's closed_at.
	Reopen(ctx context.Context, accountID, batchID string) *apierror.APIError
	// ReassignMachine points a batch at one machine and drops any other machine link it had, for a ticket moved to a campaign running somewhere else.
	ReassignMachine(ctx context.Context, accountID, batchID, machineID string) *apierror.APIError
	// ReopenIfNotFullyUsed reopens a batch that is no longer fully consumed — the mirror of CloseIfFullyUsed, run after a downstream batch is deleted and the quantity it was holding comes back.
	ReopenIfNotFullyUsed(ctx context.Context, accountID string, batch BaseBatch, producedUnit LightUnit, productionStepID string) *apierror.APIError
}

BatchRepo handles all batch data access.

type BatchScannedEvent

type BatchScannedEvent struct {
	// AccountID owns the batch. Carried on the payload as well as the identity so a subscriber that
	// re-publishes or replays the event does not depend on the envelope surviving intact.
	AccountID string `json:"account_id"`
	// BatchID is the batch the operator scanned, and the tag every ledger row written in reaction
	// carries, which is what lets an undo find them again.
	BatchID string `json:"batch_id"`

	ProductionStepID  string `json:"production_step_id"`
	ScanningStationID string `json:"scanning_station_id"`
	// ItemID is what the batch is of, used to confirm the step still produces what was scanned.
	ItemID string `json:"item_id"`

	// Measure and UnitID are what the operator recorded, in the unit they recorded it in. Conversion
	// into the step's production unit belongs to the subscriber, which knows the step.
	Measure string `json:"measure"`
	UnitID  string `json:"unit_id"`

	// SecondsMeasure and WasteMeasure are in the same unit as Measure. Empty means none.
	SecondsMeasure string `json:"seconds_measure,omitempty"`
	WasteMeasure   string `json:"waste_measure,omitempty"`

	ResponsibleUserID *string `json:"responsible_user_id,omitempty"`

	// ScannedAt is when the operator scanned, not when the event was published or handled. Receipts
	// are dated from it so a message that waits in the queue still lands on the day it happened.
	ScannedAt time.Time `json:"scanned_at"`
}

BatchScannedEvent states what an operator recorded at a station. It is the fact the scan happened, not an instruction, so it carries the measures and leaves every subscriber to decide what follows.

Seconds and waste travel with the scan rather than in a message of their own. The command this replaces could only describe one effect at a time, so a batch with scrap needed a second message with produce_inventory=false, and the two could be processed apart — leaving the receipt credited and the reservation it should have released still standing. Here one message carries the whole scan, and its subscriber commits both halves together or neither.

func (BatchScannedEvent) SecondsDecimal

func (e BatchScannedEvent) SecondsDecimal() (decimal.Decimal, error)

SecondsDecimal returns the seconds measure, treating an absent value as zero.

func (BatchScannedEvent) WasteDecimal

func (e BatchScannedEvent) WasteDecimal() (decimal.Decimal, error)

WasteDecimal returns the waste measure, treating an absent value as zero.

type BatchSvc

type BatchSvc interface {
	// GetBatchFlow returns the flow graph for a batch.
	GetBatchFlow(ctx context.Context, batchID string) ([]BatchFlowNode, *apierror.APIError)

	// ListBatchesByScanningStation returns a paginated list of batches for a scanning station.
	ListBatchesByScanningStation(ctx context.Context, params ListBatchesByScanningStationParams) (*ListBatchesByScanningStationResult, *apierror.APIError)

	// GetPossibleNextSteps returns the possible next production steps for a batch at a scanning station.
	GetPossibleNextSteps(ctx context.Context, scanningStationID, batchID string) ([]ScanningProductionStepInfo, *apierror.APIError)

	// AnalyzeOpenBatches returns aggregated open batch summaries for analytics.
	AnalyzeOpenBatches(ctx context.Context, itemIDs, productLineIDs []string) ([]OpenBatchSummary, *apierror.APIError)

	// InitializeBatch initializes a batch at a scanning station.
	InitializeBatch(ctx context.Context, batchID, scanningStationID string) (*BaseBatch, *apierror.APIError)

	// MoveBatches moves one or more batches to a new production step.
	MoveBatches(ctx context.Context, params MoveBatchesParams) (*BaseBatch, *apierror.APIError)

	// MergeBatches merges multiple batches into a single batch.
	MergeBatches(ctx context.Context, params MergeBatchesParams) (*BaseBatch, *apierror.APIError)

	// SplitBatch splits a batch into firsts, seconds, and waste.
	SplitBatch(ctx context.Context, params SplitBatchParams) (*BaseBatch, *apierror.APIError)

	// GetRemainingQuantityToSplit returns the remaining quantity available to split from a batch flow.
	GetRemainingQuantityToSplit(ctx context.Context, batchIDs []string, productionStepID string) (*BatchQuantity, *apierror.APIError)

	// GetScanningStationConsumption returns consumption demand for a scanning station.
	GetScanningStationConsumption(ctx context.Context, params GetConsumptionParams) ([]ScanningConsumption, *apierror.APIError)

	// CloseBatch closes a batch.
	CloseBatch(ctx context.Context, batchID string) (*BaseBatch, *apierror.APIError)

	// DeleteBatch deletes a single batch.
	DeleteBatch(ctx context.Context, batchID string) (*BaseBatch, *apierror.APIError)

	// DeleteManyBatches deletes multiple batches.
	DeleteManyBatches(ctx context.Context, batchIDs []string) *apierror.APIError
}

BatchSvc handles all batch-related business logic.

type BillingPublisher

type BillingPublisher interface {
	// PublishSyncSeats writes a sync-seats command to the outbox for the given account.
	PublishSyncSeats(ctx context.Context, accountID string) *apierror.APIError
	// PublishReportSeatChange writes a report-seat-change command to the outbox for usage metering with the billing provider.
	PublishReportSeatChange(ctx context.Context, accountID string) *apierror.APIError
	// Writes a report-invoice-created command to the outbox for usage metering with the billing provider.
	PublishReportInvoiceCreated(ctx context.Context, accountID, invoiceID string) *apierror.APIError
}

BillingPublisher publishes billing-related commands via the outbox pattern.

type BulkCreateBatchParams

type BulkCreateBatchParams struct {
	Item             ItemIdentifier
	QuantityValue    string
	QuantityUnit     UnitIdentifier
	SecondsValue     *string
	SecondsUnit      *UnitIdentifier
	WasteValue       *string
	WasteUnit        *UnitIdentifier
	ProductionStepID *string
	ScanningStation  *ObjectIdentifier
}

BulkCreateBatchParams is a single batch in a bulk production run create, with the item referenced by SKU (resolved server-side) and everything else by ID — all validated server-side.

type BulkCreateConsumptionInput

type BulkCreateConsumptionInput struct {
	SKU          string
	Measure      string
	Instructions *string
}

BulkCreateConsumptionInput represents a consumption input in a bulk create operation (resolved by SKU).

type BulkCreateItemInput

type BulkCreateItemInput struct {
	SKU            string
	Description    *string
	ItemCategoryID string
	ProductLineID  *string
	// AttributeIDs are connected to the new (or existing upserted) item in the same tx.
	AttributeIDs []string
}

BulkCreateItemInput represents a single item to create in a bulk operation.

type BulkCreateItemResult

type BulkCreateItemResult struct {
	SKU     string
	Success bool
	Error   *string
	ItemID  *string
}

BulkCreateItemResult represents the result of creating a single item in a bulk operation.

type BulkCreateItemsParams

type BulkCreateItemsParams struct {
	AccountID string
	Items     []BulkCreateItemInput
	Type      string
}

BulkCreateItemsParams holds parameters for bulk creating items.

type BulkCreateProductionInput

type BulkCreateProductionInput struct {
	SKU     string
	Measure string
}

BulkCreateProductionInput represents a production output input in a bulk create operation (resolved by SKU).

type BulkCreateProductionRunEventBatch

type BulkCreateProductionRunEventBatch struct {
	BatchID           string
	ItemID            string
	QuantityValue     string
	QuantityUnitID    string
	SecondsValue      *string
	SecondsUnitID     *string
	WasteValue        *string
	WasteUnitID       *string
	ProductionStepID  *string
	ScanningStationID *string
}

BulkCreateProductionRunEventBatch is one batch in a bulk create event.

type BulkCreateProductionRunEventRun

type BulkCreateProductionRunEventRun struct {
	ProductionRunID   string
	ResponsibleUserID string
	Batches           []BulkCreateProductionRunEventBatch
}

BulkCreateProductionRunEventRun is one resolved run stored on the bulk create job.

type BulkCreateProductionRunParams

type BulkCreateProductionRunParams struct {
	ResponsibleUserID string
	Batches           []BulkCreateBatchParams
}

BulkCreateProductionRunParams is a single production run in a bulk create, owning the batches created with it. The run number is auto-assigned sequentially.

type BulkCreateProductionRunsParams

type BulkCreateProductionRunsParams struct {
	ProductionRuns []BulkCreateProductionRunParams
}

BulkCreateProductionRunsParams holds the parameters for bulk creating production runs with their batches.

type BulkCreateProductionStepInput

type BulkCreateProductionStepInput struct {
	Name           string
	Consumptions   []BulkCreateConsumptionInput
	Productions    []BulkCreateProductionInput
	LaborRate      string
	LaborTime      string
	LaborTimeUnit  *string
	OverheadRate   string
	Allowances     *string
	LevelingFactor *string
	Station        *string
}

BulkCreateProductionStepInput represents a single production step to create in a bulk operation.

type BulkCreateProductionStepResult

type BulkCreateProductionStepResult struct {
	Name             string
	Success          bool
	Error            *string
	ProductionStepID *string
	Action           string // "created", "updated", or "skipped"
}

BulkCreateProductionStepResult represents the result of creating a single production step.

type BulkCreateProductionStepsParams

type BulkCreateProductionStepsParams struct {
	AccountID string
	Steps     []BulkCreateProductionStepInput
}

BulkCreateProductionStepsParams holds parameters for bulk creating production steps.

type BulkDeleteCustomersParams

type BulkDeleteCustomersParams struct {
	OwnerAccountID string
	CustomerIDs    []string
}

BulkDeleteCustomersParams holds the parameters for bulk deleting customers.

type BulkDeletePurchaseOrdersParams

type BulkDeletePurchaseOrdersParams struct {
	PurchaseOrderIDs []string
	AccountID        string
}

BulkDeletePurchaseOrdersParams holds the parameters for bulk deleting purchase orders.

type BulkDeleteSalesOrdersParams

type BulkDeleteSalesOrdersParams struct {
	SalesOrderIDs []string
	AccountID     string
}

BulkDeleteSalesOrdersParams holds the parameters for bulk deleting sales orders.

type BulkDeleteSuppliersParams

type BulkDeleteSuppliersParams struct {
	OwnerAccountID string
	SupplierIDs    []string
}

BulkDeleteSuppliersParams holds the parameters for bulk deleting suppliers.

type BulkOnHandInventory

type BulkOnHandInventory struct {
	ItemID           string
	OnHandQuantity   float64
	UnitID           string
	UnitAbbreviation string
	UnitType         string
}

BulkOnHandInventory represents bulk on-hand inventory for multiple items.

type BulkOperationJobEvent

type BulkOperationJobEvent struct {
	JobID string
}

BulkOperationJobEvent is the message every async bulk operation enqueues: only the job's ID. The resolved payload lives on the job row, and the account comes from the identity restored alongside the message — so there is exactly one copy of each.

The AMQP body is marshaled and unmarshaled by our own producer and consumer against this same type, so it carries no wire tags: serialization lives at the boundary, the domain stays a plain value object.

type BulkReconcileItemInput

type BulkReconcileItemInput struct {
	SKU     string
	Unit    string
	Measure decimal.Decimal
}

BulkReconcileItemInput represents a single item to reconcile.

type BulkReconcileItemsParams

type BulkReconcileItemsParams struct {
	AccountID         string
	Data              []BulkReconcileItemInput
	ReconcileType     string // "addition" or "force"
	ResponsibleUserID *string
}

BulkReconcileItemsParams holds parameters for bulk reconciling item inventory.

type BulkReconcileItemsResult

type BulkReconcileItemsResult struct {
	ReconciledItems []ReconciledItem
	SkippedItems    []SkippedItem
	Errors          []ReconcileError
}

BulkReconcileItemsResult holds the results of a bulk reconciliation.

type BulkResolveHubspotReviewsParams

type BulkResolveHubspotReviewsParams struct {
	JobID   string
	Reviews []ResolveHubspotReviewParams
}

BulkResolveHubspotReviewsParams resolves many company reviews in one job, the path a spreadsheet of decisions comes back through.

type BulkUpsertDepartmentsParams

type BulkUpsertDepartmentsParams struct {
	Departments []UpsertDepartmentParams
}

BulkUpsertDepartmentsParams holds the parameters for bulk upserting departments.

type BulkUpsertItemCategoriesParams

type BulkUpsertItemCategoriesParams struct {
	ItemCategories []UpsertItemCategoryParams
}

carries the rows of a bulk item category upsert

type BulkUpsertLocationsParams

type BulkUpsertLocationsParams struct {
	Locations []UpsertLocationParams
}

type BulkUpsertMachinesParams

type BulkUpsertMachinesParams struct {
	Machines []UpsertMachineParams
}

BulkUpsertMachinesParams holds the parameters for bulk upserting machines.

type BulkUpsertMaterialsParams

type BulkUpsertMaterialsParams struct {
	Materials []UpsertMaterialParams
}

BulkUpsertMaterialsParams holds parameters for bulk upserting materials, matched by SKU.

type BulkUpsertPartsParams

type BulkUpsertPartsParams struct {
	Parts []UpsertPartParams
}

BulkUpsertPartsParams holds parameters for bulk upserting parts, matched by SKU.

type BulkUpsertProductLinesParams

type BulkUpsertProductLinesParams struct {
	ProductLines []UpsertProductLineParams
}

BulkUpsertProductLinesParams is the input for a bulk upsert of product lines.

type BulkUpsertProductionStepsParams

type BulkUpsertProductionStepsParams struct {
	ProductionSteps []UpsertProductionStepParams
}

BulkUpsertProductionStepsParams holds the parameters for bulk upserting production steps.

type BulkUpsertProductionStepsResult

type BulkUpsertProductionStepsResult struct {
	CreatedIDs []string
	UpdatedIDs []string
}

BulkUpsertProductionStepsResult is the aggregate result of a bulk production step upsert.

type BulkUpsertProductsParams

type BulkUpsertProductsParams struct {
	Products []UpsertProductParams
}

BulkUpsertProductsParams holds parameters for bulk upserting products, matched by SKU.

type BulkUpsertPropertiesParams

type BulkUpsertPropertiesParams struct {
	Properties []UpsertPropertyParams
}

holds the input for a bulk upsert of properties

type BulkUpsertScanningStationsParams

type BulkUpsertScanningStationsParams struct {
	ScanningStations []UpsertScanningStationParams
}

type BulkUpsertUnitGroupsParams

type BulkUpsertUnitGroupsParams struct {
	UnitGroups []UpsertUnitGroupParams
}

type BulkUpsertUnitsParams

type BulkUpsertUnitsParams struct {
	Units []UpsertUnitParams
}

type BurnRateConsumptionLog

type BurnRateConsumptionLog struct {
	Value     string
	UnitID    string
	CreatedAt time.Time
}

BurnRateConsumptionLog is a single negative consumption entry used to compute burn rate.

type BurnRateMed

type BurnRateMed interface {
	// RecalculateFromHistory updates the item's burn_rate from consumption change logs over the last 30 days. No-op when there is insufficient history.
	//
	//  1. Load the item and resolve its category's base unit.
	//  2. List the item's consumption change logs; no-op when fewer than two exist.
	//  3. Sum the absolute consumption quantities, converting each to the base unit.
	//  4. Divide the total by the days elapsed between the first and last log.
	//  5. Persist the resulting per-day rate to the item's burn rate.
	RecalculateFromHistory(ctx context.Context, accountID, itemID string) *apierror.APIError
}

type CancelJobParams

type CancelJobParams struct {
	JobID string
}

type Carrier

type Carrier struct {
	ID                     string
	Name                   string  `audit:"name"`
	Code                   *string `audit:"code"`
	ShippoCarrierAccountID *string
	AccountNumber          *string `audit:"account_number"`
	IsPortalEnabled        bool    `audit:"is_portal_enabled"`
	AccountID              *string
	DeletedAt              *time.Time
	ServiceLevels          []*ServiceLevel
	CreatedAt              time.Time
	UpdatedAt              time.Time

	// Populated only by BatchGetCarriersByIDs when a positive service_levels_limit was requested. Not persisted; transient on the response path so the gRPC layer can mirror them into CarrierInfo's service_level_ids_preview / service_levels_has_more fields.
	ServiceLevelIDsPreview []string `audit:"-"`
	ServiceLevelsHasMore   bool     `audit:"-"`
}

type CarrierRepo

type CarrierRepo interface {
	List(ctx context.Context, params ListCarriersParams) (*ListCarriersResult, *apierror.APIError)
	Get(ctx context.Context, params GetCarrierParams) (*Carrier, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Carrier, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateCarrierParams) (*Carrier, *apierror.APIError)
	Update(ctx context.Context, params UpdateCarrierParams) (*Carrier, *apierror.APIError)
	SoftDelete(ctx context.Context, accountID, carrierID string) *apierror.APIError
	DeleteOptionsByCarrierID(ctx context.Context, accountID, carrierID string) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	ListOptionsByCarrierID(ctx context.Context, accountID, carrierID string) ([]*ServiceLevel, *apierror.APIError)
	// ListOptionIDsForCarriers returns all carrier_option IDs grouped by carrier_id, ordered (carrier_id, created_at ASC, id ASC) — callers truncate to a per-carrier preview limit in Go.
	ListOptionIDsForCarriers(ctx context.Context, accountID string, carrierIDs []string) (map[string][]string, *apierror.APIError)
	// GetOptionsByIDs returns full ServiceLevel records by id with the same account-scoping rule as ListOptionsByCarrierID (the parent carrier must be the caller's own or a system carrier).
	GetOptionsByIDs(ctx context.Context, accountID string, ids []string) ([]*ServiceLevel, *apierror.APIError)
}

type CarrierSvc

type CarrierSvc interface {
	// ListCarriers returns a paginated list of carriers visible to the caller's account.
	ListCarriers(ctx context.Context, params ListCarriersParams) (*ListCarriersResult, *apierror.APIError)

	// GetCarrier returns a single carrier by ID.
	GetCarrier(ctx context.Context, params GetCarrierParams) (*Carrier, *apierror.APIError)

	// BatchGetCarriersByIDs returns carriers by ID for the api-gateway include resolver. Authorization matches GetCarrier (caller's own account + system carriers). When serviceLevelsLimit > 0, each returned carrier carries a preview of up to N service_level IDs plus a has_more flag.
	BatchGetCarriersByIDs(ctx context.Context, ids []string, serviceLevelsLimit int32) ([]*Carrier, *apierror.APIError)

	// BatchGetServiceLevelsByIDs returns service levels by ID for the api-gateway include resolver. Authorization follows the parent carrier's account scope.
	BatchGetServiceLevelsByIDs(ctx context.Context, ids []string) ([]*ServiceLevel, *apierror.APIError)

	// CreateCarrier creates a new carrier, optionally registering with Shippo.
	CreateCarrier(ctx context.Context, params CreateCarrierParams) (*Carrier, *apierror.APIError)

	// UpdateCarrier partially updates a carrier.
	UpdateCarrier(ctx context.Context, params UpdateCarrierParams) (*Carrier, *apierror.APIError)

	// DeleteCarrier soft-deletes a carrier and cascades to options.
	DeleteCarrier(ctx context.Context, carrierID string) *apierror.APIError

	// InitiateOAuth starts the OAuth flow for a Shippo-managed carrier.
	InitiateOAuth(ctx context.Context, carrierID, redirectURI string, state *string) (string, *apierror.APIError)

	// GetOAuthStatus returns the OAuth connection status for a carrier.
	GetOAuthStatus(ctx context.Context, carrierID string) (string, *apierror.APIError)

	// SyncOptions syncs service levels from Shippo service levels.
	SyncOptions(ctx context.Context, carrierID string) (*Carrier, *apierror.APIError)
}

type CarrierTransitCandidates

type CarrierTransitCandidates struct {
	// LaneDays is the cached carrier estimate for this exact lane, nil when it has never been warmed.
	LaneDays *int
	// LaneSourceCode says how the cached row was obtained, so a refresh knows whether it may overwrite it.
	LaneSourceCode string
	// LaneRefreshedAt is when the cached row was last written, used to judge staleness.
	LaneRefreshedAt *time.Time
	// ServiceLevelDefaultDays is the fallback configured on the service level, nil when none is set.
	ServiceLevelDefaultDays *int
}

CarrierTransitCandidates is what the database knows about a lane: the cached estimate if one has ever been warmed, and the service level's standing default. Which one wins is a policy decision made above the repository, because it depends on how stale the cached row is.

type CarrierTransitEstimateRepo

type CarrierTransitEstimateRepo interface {
	// Resolve returns both transit candidates for a lane in one round trip. A lane whose service level does not exist (or belongs to another account) resolves to nil rather than an error: the caller's fallback is to stamp no transit at all.
	Resolve(ctx context.Context, accountID string, lane TransitLane) (*CarrierTransitCandidates, *apierror.APIError)
	// Upsert writes a harvested estimate, leaving an operator-entered row for the same lane untouched.
	Upsert(ctx context.Context, params UpsertTransitEstimateParams) *apierror.APIError
}

type CarryForwardBatch

type CarryForwardBatch struct {
	BatchID             string
	ProductionRunID     string
	ProductionRunNumber string
	ProductionStepID    *string
	Quantity            float64
	UnitID              string
}

CarryForwardBatch is an unworked ticket an earlier week issued, and a candidate to be moved into the run being released.

type CatalogAttribute

type CatalogAttribute struct {
	ID           string
	Name         string
	PropertyID   string
	PropertyName string
}

CatalogAttribute represents an attribute of a product in the catalog.

type CatalogCategory

type CatalogCategory struct {
	ID         string
	Name       string
	Properties []*CatalogProperty
	Products   []*CatalogProduct
}

CatalogCategory represents a category of products in the catalog, grouped by item category.

type CatalogProduct

type CatalogProduct struct {
	ItemID      string
	SKU         string
	Description string
	Attributes  []*CatalogAttribute
}

CatalogProduct represents a product in the catalog.

type CatalogProductLine

type CatalogProductLine struct {
	ID   string
	Name string
}

CatalogProductLine represents a product line available in the catalog.

type CatalogProperty

type CatalogProperty struct {
	ID   string
	Name string
}

CatalogProperty represents a property associated with an item category.

type CatalogRepo

type CatalogRepo interface {
	// ListProductLines returns the distinct product lines that have portal-ready products for a given account.
	ListProductLines(ctx context.Context, accountID string) ([]*CatalogProductLine, *apierror.APIError)

	// ListProductLinesForCustomer returns the distinct product lines that the given customer has access to.
	ListProductLinesForCustomer(ctx context.Context, accountID, customerAccountID string) ([]*CatalogProductLine, *apierror.APIError)

	// ListProducts returns products in a specific product line grouped by item category.
	ListProducts(ctx context.Context, accountID, productLineID string) ([]*CatalogCategory, *apierror.APIError)

	// ListProductsForCustomer returns products in a specific product line that the given customer has access to.
	ListProductsForCustomer(ctx context.Context, accountID, customerAccountID, productLineID string) ([]*CatalogCategory, *apierror.APIError)
}

type CatalogSvc

type CatalogSvc interface {
	// ListCatalogProductLines returns a paginated list of product lines available in the catalog. Supports both internal and customer actors via CheckIsAssignedActor.
	ListCatalogProductLines(ctx context.Context, params ListCatalogProductLinesParams) (*ListCatalogProductLinesResult, *apierror.APIError)

	// ListCatalogProducts returns a paginated list of products in a specific product line, grouped by item category. Supports both internal and customer actors via CheckIsAssignedActor.
	ListCatalogProducts(ctx context.Context, params ListCatalogProductsParams) (*ListCatalogProductsResult, *apierror.APIError)
}

type CategoryRef

type CategoryRef struct {
	BaseUnitID           string
	ItemCategoryTypeCode string
}

CategoryRef is the lightweight category lookup used by item create paths and bulk upsert validation: the category's base unit and its type code (material_category / product_category), which constrains which item types may use it.

type ChangeItemCategoryParams

type ChangeItemCategoryParams struct {
	AccountID  string
	ItemID     string
	CategoryID string
}

ChangeItemCategoryParams holds parameters for changing an item's category.

type ChangeItemCategoryUnitGroupParams

type ChangeItemCategoryUnitGroupParams struct {
	AccountID      string
	ItemCategoryID string
	UnitGroupID    string
}

type ChangeProductProductLineParams

type ChangeProductProductLineParams struct {
	AccountID     string
	ProductID     string
	ProductLineID string
	Includes      []string
}

ChangeProductProductLineParams holds parameters for changing a product's product line.

type ChangePurchaseOrderStatusParams

type ChangePurchaseOrderStatusParams struct {
	PurchaseOrderID string
	AccountID       string
	StatusChange    string
	SendEmail       bool
	Includes        []string
}

ChangePurchaseOrderStatusParams holds the parameters for changing a purchase order status.

type ChangeSalesOrderStatusParams

type ChangeSalesOrderStatusParams struct {
	SalesOrderID string
	AccountID    string
	StatusChange string
	SendEmail    bool
	Includes     []string
}

ChangeSalesOrderStatusParams holds the parameters for changing a sales order status.

type ChartDataPoint

type ChartDataPoint struct {
	X float64
	Y float64
}

type CheckDuplicateParams

type CheckDuplicateParams struct {
	Type         DuplicateCheckType
	RecordNumber string
	CustomerID   *string
}

CheckDuplicateParams holds parameters for a duplicate check.

type CheckDuplicateResult

type CheckDuplicateResult struct {
	IsDuplicate bool
	Message     *string
}

CheckDuplicateResult holds the result of a duplicate check.

type CheckoutLineItem

type CheckoutLineItem struct {
	Name        string
	Description string
	AmountCents int64
	Quantity    int64
}

CheckoutLineItem represents a line item in a Stripe checkout session.

type CheckoutSalesOrderParams

type CheckoutSalesOrderParams struct {
	SalesOrderID string
	AccountID    string
	Email        string
}

CheckoutSalesOrderParams holds the parameters for checking out a sales order.

type CheckoutSalesOrderResult

type CheckoutSalesOrderResult struct {
	CheckoutURL string
}

CheckoutSalesOrderResult holds the result of a checkout operation.

type ChildAccount

type ChildAccount struct {
	RelationID     string
	AccountID      string
	AccountName    string  `audit:"account_name"`
	ExternalNumber string  `audit:"external_number"`
	Email          *string `audit:"email"`
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

type ChildAccountSvc

type ChildAccountSvc interface {
	// ListChildAccounts returns a paginated list of child accounts for the target account.
	ListChildAccounts(ctx context.Context, cursor *string, limit int32, query *string) (*ListChildAccountsResult, *apierror.APIError)

	// AddChildAccount adds a child account relationship to the target account.
	AddChildAccount(ctx context.Context, childAccountID string) (*ChildAccount, *apierror.APIError)

	// RemoveChildAccount removes a child account relationship from the target account.
	RemoveChildAccount(ctx context.Context, childAccountID string) *apierror.APIError

	// BatchGetChildAccountsByIDs returns child account relations matching the input relation IDs. Used by the api-gateway resourcekit include resolver.
	BatchGetChildAccountsByIDs(ctx context.Context, relationIDs []string) ([]*ChildAccount, *apierror.APIError)
}

type ClosureWindowQuery

type ClosureWindowQuery struct {
	AccountID   string
	CalendarIDs []string
	From        time.Time
	To          time.Time
}

ClosureWindowQuery is a bounded date range of closures across a set of calendars. Bounded on purpose: resolving one commitment needs the months around its ship-by date, never an account's whole history.

type CommitmentStep

type CommitmentStep struct {
	Code      string
	Date      time.Time
	DaysMoved int
	Detail    string
}

CommitmentStep is one rule's contribution to a ship-by date.

type CompleteJobParams

type CompleteJobParams struct {
	JobID   string
	Results []RowResult
}

type CompleteRegistrationInput

type CompleteRegistrationInput struct {
	UserID               string
	PlanCode             string
	StripeCustomerID     string
	StripeSubscriptionID string
	UserName             string
	UserEmail            string
	AccountData          RegistrationAccountData
	BusinessAddress      *RegistrationAddress
}

CompleteRegistrationInput carries the data needed to finalize a registration.

type CompleteRegistrationOutput

type CompleteRegistrationOutput struct {
	AccountID string
	SandboxID string
}

CompleteRegistrationOutput holds the IDs of the newly created accounts.

type ConnectProductionStepsByNameParams

type ConnectProductionStepsByNameParams struct {
	AccountID         string
	ScanningStationID string
	Name              string
}

type ConstraintBatchRow

type ConstraintBatchRow struct {
	Measurement scheduling.BatchMeasurement
	// QuantityUnitID is the unit the batch was scanned in; nil when the batch carries no quantity unit.
	QuantityUnitID *string
	// QuantityUnitRatio is the scan unit's ratio to its unit group's base unit (e.g. 2 for a pair counted in eaches); 0 when the batch carries no quantity unit.
	QuantityUnitRatio float64
	// ProductionStepID mirrors the raw column: nil when the batch has no step. Kept distinct from the mapped measurement so presence is not conflated with an empty string.
	ProductionStepID *string
}

ConstraintBatchRow is one historical batch as read from the database: the measurement the solver consumes plus the raw scan metadata the input assembly needs alongside it.

type Consumption

type Consumption struct {
	ID               string
	ItemID           string   `audit:"item_id"`
	ItemSKU          string   `audit:"item_sku"`
	ItemDescription  *string  `audit:"item_description"`
	ItemTypeCode     string   `audit:"item_type_code"`
	Quantity         Quantity `audit:"quantity"`
	WasteQuantity    Quantity `audit:"waste_quantity"`
	Instructions     *string  `audit:"instructions"`
	ProductionStepID string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

Consumption represents a material consumed by a production step.

type ConsumptionAllocationParams

type ConsumptionAllocationParams struct {
	OrderID   string
	AccountID string
	ItemID    string
	Measure   decimal.Decimal
	UnitID    string
	// ProducedBatchID tags the issues this consumption creates with the batch that caused them, which is what lets deleting that batch find the reservations it drew down and hand them back.
	ProducedBatchID string
}

ConsumptionAllocationParams describes a reservation allocation for material consumption.

type ConsumptionAllocationResult

type ConsumptionAllocationResult struct {
	// RemainingMeasure is the quantity that could not be allocated from existing reservations and must be deducted from general inventory instead.
	RemainingMeasure decimal.Decimal
	RemainingUnitID  string
}

ConsumptionAllocationResult is the result of allocating reservations for consumption.

type ConsumptionRepo

type ConsumptionRepo interface {
	Get(ctx context.Context, accountID, productionStepID, consumptionID string) (*Consumption, *apierror.APIError)
	Create(ctx context.Context, consumptionID, quantityID, wasteQuantityID string, params CreateConsumptionParams) (*Consumption, *apierror.APIError)
	UpdateItem(ctx context.Context, accountID, consumptionID, itemID string, instructions *string) *apierror.APIError
	UpdateQuantity(ctx context.Context, quantityID, value, unitID string) *apierror.APIError
	Delete(ctx context.Context, accountID, consumptionID string) *apierror.APIError
	IsInAccount(ctx context.Context, accountID, consumptionID string) (bool, *apierror.APIError)
	GetQuantityIDs(ctx context.Context, consumptionID string) (quantityID string, wasteQuantityID string, apiErr *apierror.APIError)
	InsertQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	DeleteQuantity(ctx context.Context, id string) *apierror.APIError
	GetItemID(ctx context.Context, consumptionID string) (string, *apierror.APIError)
	GetInstructions(ctx context.Context, consumptionID string) (*string, *apierror.APIError)
}

type ConsumptionSvc

type ConsumptionSvc interface {
	// GetConsumption returns a single consumption by ID within a production step.
	GetConsumption(ctx context.Context, productionStepID, consumptionID string) (*Consumption, *apierror.APIError)

	// CreateConsumption creates a new consumption within a production step.
	CreateConsumption(ctx context.Context, params CreateConsumptionParams) (*Consumption, *apierror.APIError)

	// UpdateConsumption partially updates a consumption.
	UpdateConsumption(ctx context.Context, params UpdateConsumptionParams) (*Consumption, *apierror.APIError)

	// DeleteConsumption deletes a consumption from a production step and returns it.
	DeleteConsumption(ctx context.Context, params DeleteConsumptionParams) (*Consumption, *apierror.APIError)
}

type ContactMatch

type ContactMatch struct {
	AccountUserID string
	UserID        string
	AccountID     string
	RoleID        *string
	DepartmentID  *string
	StatusCode    string
	LastUsedAt    *time.Time
	CreatedAt     time.Time
	UpdatedAt     time.Time
	Email         string
	Relationship  string
}

ContactMatch is an account user matched by email on an account the caller has a relationship with — one of its customers, suppliers, or its own account. Relationship is "customer", "supplier", or "self".

type CoreAuthClient

type CoreAuthClient interface {
	// GetIncompleteRegistrationSession returns the user's most recent incomplete registration session, or (nil, nil) if none exists.
	GetIncompleteRegistrationSession(ctx context.Context, userID string) (*IncompleteRegistrationSession, *apierror.APIError)
}

CoreAuthClient is the core-service's client for calling into auth-service.

type CostFlowConsumption

type CostFlowConsumption struct {
	ConsumedItemType    string          // e.g. "material", "part", "product"
	ConsumptionQuantity decimal.Decimal // quantity consumed
	WasteQuantity       decimal.Decimal // waste quantity
	UnitCost            decimal.Decimal // consumed item's unit cost
}

CostFlowConsumption represents a single consumption with cost-relevant data.

type CreateAccountGroupParams

type CreateAccountGroupParams struct {
	AccountID            string
	Name                 string
	Description          *string
	AccountGroupTypeCode string
	CommissionPolicyCode string
	FreightPolicyCode    string
	DefaultLeadTimeDays  *int32
}

type CreateAccountGroupProductLineAccessParams

type CreateAccountGroupProductLineAccessParams struct {
	AccountID      string
	AccountGroupID string
	ProductLineIDs []string
}

type CreateAccountIntegrationParams

type CreateAccountIntegrationParams struct {
	AccountID       string
	IntegrationCode constants.IntegrationCode
	Name            string
	Credentials     string // raw JSON credentials before encryption
}

type CreateAccountParams

type CreateAccountParams struct {
	ID                   string
	Name                 string
	PlanCode             string
	StripeCustomerID     string
	StripeSubscriptionID string
}

CreateAccountParams holds the parameters for creating a production account during registration.

type CreateAccountPriceParams

type CreateAccountPriceParams struct {
	AccountID             string
	RecipientAccountID    string
	ProductLineID         string
	RateValue             string
	RateNumeratorUnitID   string
	RateDenominatorUnitID string
	CategoryIDs           []string
	AttributeIDs          []string
}

type CreateAccountUserParams

type CreateAccountUserParams struct {
	AccountID               string
	Name                    *string
	Email                   *string
	Username                *string
	Password                *string // #nosec G117 -- domain model field, not a hardcoded credential
	RoleID                  *string
	DepartmentID            *string
	IsCommissionEligible    *bool
	NotificationPreferences []NotificationPreferenceItem
}

CreateAccountUserParams are the parameters for creating an account user.

type CreateAddressParams

type CreateAddressParams struct {
	AccountID         string
	Name              string
	Phone             *string
	Email             *string
	IsDropShip        bool
	ReceiveCalendarID *string
	StreetLine1       *string
	StreetLine2       *string
	Locality          *string
	State             *string
	PostalCode        *string
	Country           string
}

CreateAddressParams contains the parameters for creating an address.

type CreateAttributeParams

type CreateAttributeParams struct {
	Value      string
	PropertyID string
	AccountID  string
	ColorCode  string
	SortOrder  int32
}

CreateAttributeParams holds the parameters for creating an attribute.

type CreateBatchParams

type CreateBatchParams struct {
	AccountID         string
	ItemID            string
	Quantity          CreateQuantityParams
	Seconds           *CreateQuantityParams
	Waste             *CreateQuantityParams
	ProductionStepID  string
	ScanningStationID string
	ProductionRunID   string
	// MachineIDs are the machines the batch runs on. Attainment attributes production through this link, so a batch created without it is work no machine gets credit for.
	MachineIDs []string
}

CreateBatchParams holds the parameters for creating a new batch.

type CreateCarrierParams

type CreateCarrierParams struct {
	AccountID              string
	Name                   string
	Code                   *string
	ShippoCarrierAccountID *string
	AccountNumber          *string
	IsPortalEnabled        bool
	ServiceLevels          []CreateServiceLevelParams
	Includes               []string
}

type CreateCarrierResult

type CreateCarrierResult struct {
	Carrier *Carrier
}

type CreateCheckoutSessionParams

type CreateCheckoutSessionParams struct {
	// StripeCustomerID, when set, bills the session to that existing Stripe customer
	// (and enables saving the payment method). When empty, CustomerEmail is used
	// instead. Stripe rejects supplying both, so exactly one is sent.
	StripeCustomerID string
	CustomerEmail    string
	LineItems        []CheckoutLineItem
	SuccessURL       *string
	CancelURL        *string
	// Metadata to attach to the payment intent (e.g. orderID, customerID).
	PaymentIntentMetadata map[string]string
}

CreateCheckoutSessionParams holds the parameters for creating a Stripe checkout session.

type CreateConsumptionParams

type CreateConsumptionParams struct {
	AccountID           string
	ProductionStepID    string
	ItemID              string
	QuantityValue       string
	QuantityUnitID      string
	WasteQuantityValue  string
	WasteQuantityUnitID string
	Instructions        *string
}

CreateConsumptionParams holds the parameters for creating a consumption.

type CreateCustomerCheckoutSessionParams

type CreateCustomerCheckoutSessionParams struct {
	OrderID         string
	OrderNumber     string
	OrderTotalCents int64
	CustomerPO      *string
}

CreateCustomerCheckoutSessionParams holds the parameters for customer checkout.

type CreateCustomerCheckoutSessionResult

type CreateCustomerCheckoutSessionResult struct {
	ClientSecret string // #nosec G117 -- Stripe ephemeral client secret
}

CreateCustomerCheckoutSessionResult holds the result of customer checkout.

type CreateCustomerParams

type CreateCustomerParams struct {
	OwnerAccountID        string
	Name                  string
	Number                *string
	Note                  *string
	Email                 *string
	Phone                 *string
	URL                   *string
	StatusCode            *string
	IsEdiEnabled          *bool
	CommissionPolicy      *constants.CommissionPolicy
	FreightPolicy         *constants.FreightPolicy
	DefaultLeadTimeDays   *int32
	ReceiveCalendarID     *string
	FulfillmentPolicy     *constants.FulfillmentPolicy
	DefaultCarrierID      *string
	DefaultServiceLevelID *string
	DefaultPaymentTermID  *string
	DefaultShippingTermID *string
	DefaultPriorityCode   *string
	DefaultSalesRepID     *string
	BillToAddressID       *string
	ShipToAddressID       *string
	BillToAddress         *CreateAddressParams
	ShipToAddress         *CreateAddressParams
	CustomerPriceGroupIDs []string
	CustomerTypeGroupID   *string
	CarrierBillingType    *string
	CarrierBillingAccount *string
	CreditLimitValue      *string
	CreditLimitUnitID     *string
	CreditLimitID         *string
	Includes              []string
}

CreateCustomerParams holds the parameters for creating a customer.

type CreateCustomerProductLineAccessParams

type CreateCustomerProductLineAccessParams struct {
	AccountID      string
	CustomerID     string
	ProductLineIDs []string
}

type CreateDCLocationParams

type CreateDCLocationParams struct {
	OwnerAccountID string
	AccountID      string
	Location       string
}

type CreateDemandOverrideParams

type CreateDemandOverrideParams struct {
	AccountID        string
	ScopeCode        string
	ScopeRefID       string
	PeriodStartDate  time.Time
	PeriodEndDate    time.Time
	OverrideTypeCode string
	Value            float64
	UnitID           *string
	ReasonCode       *string
	Note             *string
	EffectiveFrom    *time.Time
	ExpiresAt        *time.Time
	IsActive         *bool
	CreatedByID      string
}

type CreateDepartmentParams

type CreateDepartmentParams struct {
	AccountID  string
	Name       string
	Notes      *string
	LocationID *string
	LaborRate  *CreateRateParams
	// LaborRateID is the rate row the service created from LaborRate; the repo only links it.
	LaborRateID        *string
	ScanningStationIDs []string
	MachineIDs         []string
}

type CreateEmbeddedCheckoutSessionParams

type CreateEmbeddedCheckoutSessionParams struct {
	StripeCustomerID string
	AccountSlug      string
	CustomerID       string
	OrderNumber      string
	CustomerPO       *string
	OrderTotalCents  int64
	OrderID          string
	ReturnURL        string
}

CreateEmbeddedCheckoutSessionParams holds the parameters for creating an embedded checkout.

type CreateGeneratingScheduleParams

type CreateGeneratingScheduleParams struct {
	ID               string
	AccountID        string
	Version          int32
	Name             *string
	PlanningAsOf     time.Time
	HorizonStartDate time.Time
	HorizonEndDate   time.Time
	HorizonWeeks     int32
	FrozenWeeks      int32
	DemandBasisCode  string
}

CreateGeneratingScheduleParams creates the placeholder row a queued solve fills in.

The row exists before the message is published so a tick that enqueued and then died still leaves a visible record; the reaper can then fail it rather than the generation vanishing without trace.

type CreateHubspotCompanyReviewParams

type CreateHubspotCompanyReviewParams struct {
	JobID            string
	AccountID        string
	AugnoCustomerID  string
	CustomerName     string
	CustomerEmail    *string
	CustomerURL      *string
	CandidateMatches json.RawMessage
	Status           string
}

type CreateHubspotSyncJobParams

type CreateHubspotSyncJobParams struct {
	AccountID      string
	Status         string
	GoLiveCutoffAt *time.Time
}

type CreateInventoryChangeLogParams

type CreateInventoryChangeLogParams struct {
	AccountID         string
	ItemID            string
	Measure           decimal.Decimal
	UnitID            string
	ActionType        string
	ScanningStationID *string
	ResponsibleUserID *string
	InventoryLogID    *string
}

CreateInventoryChangeLogParams holds parameters for creating an inventory change audit entry.

type CreateInventoryIssueParams

type CreateInventoryIssueParams struct {
	AccountID  string
	ItemID     string
	Measure    decimal.Decimal
	UnitID     string
	LocationID *string
	LotID      *string
}

CreateInventoryIssueParams holds parameters for creating an inventory issue.

type CreateInventoryLogParams

type CreateInventoryLogParams struct {
	AccountID string
	ItemID    string
	Measure   decimal.Decimal
	UnitID    string
}

CreateInventoryLogParams holds parameters for creating an inventory snapshot log.

type CreateInventoryReceiptParams

type CreateInventoryReceiptParams struct {
	AccountID       string
	OwnerAccountID  string
	HolderAccountID string
	ItemID          string
	Measure         decimal.Decimal
	UnitID          string
	LocationID      *string
	LotID           *string
}

CreateInventoryReceiptParams holds parameters for creating an inventory receipt.

type CreateInvoiceFromShipmentParams

type CreateInvoiceFromShipmentParams struct {
	AccountID    string
	InvoiceID    string
	Number       string
	SalesOrderID string
	ShippedLines []InvoiceLineDraft
}

Carries everything CreateFromShipment needs, resolved by the service inside the ship transaction.

type CreateItemCategoryParams

type CreateItemCategoryParams struct {
	AccountID            string
	Name                 string
	Notes                *string
	ItemCategoryTypeCode string
	UnitGroupID          string
	Includes             []string
}

type CreateJobRepositoryParams

type CreateJobRepositoryParams struct {
	JobID        string
	JobItems     json.RawMessage
	Type         constants.JobType
	ResourceType constants.ObjectType
	AccountID    string
	CreatedByID  *string
	Results      []RowResult
}

type CreateJobServiceParams

type CreateJobServiceParams struct {
	Type         constants.JobType
	ResourceType constants.ObjectType
	JobItems     json.RawMessage
	CreatedByID  *string
	Results      []RowResult
}

type CreateLabelParams

type CreateLabelParams struct {
	CarrierAccountObjectID string
	ServiceLevelToken      string
	FromAddress            ShippingAddress
	ToAddress              ShippingAddress
	// Holds one entry per shipping case, in case order; the result packages match this order.
	Parcels []Parcel
	Billing *ShippingBilling
}

Carries everything needed to buy carrier labels for a shipment's cases.

type CreateLineOrderParams

type CreateLineOrderParams struct {
	ProductionScheduleLineID string
	SalesOrderID             string
	SalesOrderLineID         string
	AllocatedQuantity        float64
}

CreateLineOrderParams is one link to write.

type CreateLocationParams

type CreateLocationParams struct {
	AccountID string
	Name      string
	TypeCode  string
	ParentID  *string
	ChildIDs  []string
	Includes  []string
}

CreateLocationParams contains the parameters for creating a location.

type CreateMachineDowntimeEventParams

type CreateMachineDowntimeEventParams struct {
	AccountID  string
	MachineID  string
	ReasonCode string
	StartedAt  time.Time
	EndedAt    *time.Time
	// Duration is an alternative way of saying when the stoppage ended: the end is derived from the start plus this. Supplying both is rejected rather than reconciled, because the two disagreeing is a caller bug and picking a winner would hide it.
	Duration        *DowntimeDurationInput
	ItemID          *string
	ProductionRunID *string
	BatchID         *string
	Note            *string
	SourceCode      *string
	ReportedByID    string
}

type CreateMachineParams

type CreateMachineParams struct {
	AccountID    string
	Name         string
	SerialNumber string
	Notes        *string
	DepartmentID string
}

type CreateMaterialParams

type CreateMaterialParams struct {
	AccountID    string
	SKU          string
	Description  *string
	Notes        *string
	CategoryID   string
	OrderPoint   *QuantityInput
	LeadTime     *QuantityInput
	UnitPrice    *CreateRateParams
	UnitCost     *CreateRateParams
	AttributeIDs []string
	Includes     []string
}

type CreateMaterialReservationParams

type CreateMaterialReservationParams struct {
	AccountID string
	ItemID    string
	Measure   decimal.Decimal
	UnitID    string
	OrderID   string
}

CreateMaterialReservationParams holds parameters for creating a reserved inventory issue for a material demand linked to a sales order.

type CreateNewCustomerAccountParams

type CreateNewCustomerAccountParams struct {
	AccountID       string
	CustomerName    string
	CustomerNumber  string
	CustomerGroupID string
	PaymentTermID   string
	ShippingTermID  string
	Email           string
	Phone           *string
	Address         CustomerRegistrationAddressParams
}

type CreateOperatingCalendarParams

type CreateOperatingCalendarParams struct {
	ID         string
	AccountID  string
	Code       string
	Name       string
	KindCode   string
	DaysOfWeek string
	CutoffAt   *string
	Timezone   *string
	IsDefault  bool
}

CreateOperatingCalendarParams is a new calendar.

type CreateOrderDiscountParams

type CreateOrderDiscountParams struct {
	AccountID    string
	Name         string
	Code         string
	Percentage   *string
	Amount       *string
	DiscountType string
}

type CreatePartParams

type CreatePartParams struct {
	AccountID    string
	SKU          string
	Description  *string
	Notes        *string
	CategoryID   string
	UnitPrice    *CreateRateParams
	UnitCost     *CreateRateParams
	AttributeIDs []string
	Includes     []string
}

type CreatePaymentTermParams

type CreatePaymentTermParams struct {
	AccountID string
	Name      string
}

type CreatePortalRegistrationSessionParams

type CreatePortalRegistrationSessionParams struct {
	UserID             string
	SellerAccountID    string
	SellerSlug         string
	IsExistingCustomer *bool
	Step               constants.PortalRegistrationStep
	SessionData        PortalRegistrationSessionData
}

CreatePortalRegistrationSessionParams holds the inputs to start a session.

type CreateProductLineParams

type CreateProductLineParams struct {
	AccountID             string
	Name                  string
	UnitGroupID           string
	CommissionPolicy      constants.CommissionPolicy
	FreightPolicy         constants.FreightPolicy
	DefaultLot            *LotQuantityInput
	Includes              []string
	FulfillmentPolicyCode *string
}

type CreateProductParams

type CreateProductParams struct {
	AccountID       string
	SKU             string
	Description     *string
	Notes           *string
	ProductTypeCode string
	ProductLineID   *string
	CategoryID      string
	IsPortalReady   bool
	// UnitPrice / UnitCost are initial rate values written into the unit_value and unit_cost Rate records. When nil they default to "0" against the category's base unit on both sides. When set, both enforce the currency-numerator / non-currency-denominator rule. Burn rate is always initialized to "0" per day and recomputed from inventory history.
	UnitPrice *CreateRateParams
	UnitCost  *CreateRateParams
	// AttributeIDs are connected to the new item at creation time.
	AttributeIDs []string
	Includes     []string
}

CreateProductParams holds parameters for creating a new product.

type CreateProductTypeParams

type CreateProductTypeParams struct {
	Name string
	Code string
}

type CreateProductionParams

type CreateProductionParams struct {
	ItemID         string
	QuantityValue  string
	QuantityUnitID string
}

CreateProductionParams holds the parameters for creating a production output.

type CreateProductionRunParams

type CreateProductionRunParams struct {
	AccountID         string
	ResponsibleUserID string
}

CreateProductionRunParams holds the parameters for creating a production run.

type CreateProductionScheduleLineParams

type CreateProductionScheduleLineParams struct {
	AccountID  string
	ScheduleID string
	WeekIndex  int32
	MachineID  string
	ItemID     string
	Quantity   float64
	Lots       *int32
	RunHours   *float64
	ReasonCode *string
	ReasonNote *string
}

type CreateProductionStepParams

type CreateProductionStepParams struct {
	AccountID         string
	Name              string
	Notes             *string
	LevelingFactor    string
	Allowances        string
	ScanningStationID *string
	DepartmentID      *string
	LaborRate         CreateRateParams
	LaborTime         CreateRateParams
	OverheadRate      CreateRateParams
	Production        CreateProductionParams
	Consumptions      []CreateStepConsumptionParams
}

CreateProductionStepParams holds the parameters for creating a production step.

type CreatePropertyParams

type CreatePropertyParams struct {
	AccountID string
	Name      string
}

CreatePropertyParams holds the parameters for creating a property.

type CreatePurchaseOrderLineInput

type CreatePurchaseOrderLineInput struct {
	ProductID                  string
	ItemID                     *string
	ProductSKU                 string
	ProductDescription         *string
	QuantityValue              string
	QuantityUnitID             string
	UnitPriceValue             string
	UnitPriceNumeratorUnitID   string
	UnitPriceDenominatorUnitID string
	UnitCostValue              *string
	UnitCostNumeratorUnitID    *string
	UnitCostDenominatorUnitID  *string
}

CreatePurchaseOrderLineInput represents a line to create with a new purchase order.

type CreatePurchaseOrderLineParams

type CreatePurchaseOrderLineParams struct {
	SalesOrderID               string
	AccountID                  string
	ProductID                  string
	ItemID                     *string
	ProductSKU                 string
	ProductDescription         *string
	QuantityValue              string
	QuantityUnitID             string
	UnitPriceValue             string
	UnitPriceNumeratorUnitID   string
	UnitPriceDenominatorUnitID string
	UnitCostValue              *string
	UnitCostNumeratorUnitID    *string
	UnitCostDenominatorUnitID  *string
}

CreatePurchaseOrderLineParams holds the parameters for creating a purchase order line.

type CreatePurchaseOrderParams

type CreatePurchaseOrderParams struct {
	AccountID             string
	SupplierAccountID     string
	Includes              []string
	Number                string
	SalesOrderStatusCode  string
	BillingAddressID      string
	ShippingAddressID     string
	Note                  *string
	CarrierID             *string
	ServiceLevelID        *string
	CarrierBillingType    *string
	CarrierBillingAccount *string
	PriorityCode          string
	ShippingTermID        *string
	PaymentTermID         *string
	PromisedAt            *string
	BillToName            *string
	BillToStreetLine1     *string
	BillToStreetLine2     *string
	BillToLocality        *string
	BillToState           *string
	BillToPostalCode      *string
	BillToCountry         *string
	ShipToName            *string
	ShipToStreetLine1     *string
	ShipToStreetLine2     *string
	ShipToLocality        *string
	ShipToState           *string
	ShipToPostalCode      *string
	ShipToCountry         *string
	Lines                 []CreatePurchaseOrderLineInput
	ContactAccountUserIDs []string
}

CreatePurchaseOrderParams holds the parameters for creating a purchase order.

type CreateQuantityParams

type CreateQuantityParams struct {
	Measure decimal.Decimal
	UnitID  string
}

CreateQuantityParams holds the parameters for creating a quantity record.

type CreateRateParams

type CreateRateParams struct {
	Value             string
	NumeratorUnitID   string
	DenominatorUnitID string
}

CreateRateParams holds the parameters for creating a rate record.

type CreateRegistrationFlowParams

type CreateRegistrationFlowParams struct {
	AccountID        string
	Name             string
	CustomerGroupIDs []string
	PaymentTermIDs   []string
	ShippingTermIDs  []string
}

type CreateRoleParams

type CreateRoleParams struct {
	AccountID   string
	Name        string
	Permissions []CreateRolePermissionInput
}

CreateRoleParams are the parameters for creating a role.

type CreateRolePermissionInput

type CreateRolePermissionInput struct {
	PermissionCode string
	Create         bool
	Read           bool
	Update         bool
	Delete         bool
}

CreateRolePermissionInput represents a single permission to attach to a role.

type CreateSalesOrderLineInput

type CreateSalesOrderLineInput struct {
	ProductID      string
	QuantityValue  string
	QuantityUnitID string
	// ProductSKU / ProductDescription default to the product's when nil.
	ProductSKU         *string
	ProductDescription *string
	// Overrides the server-computed price; honored only for internal actors.
	UnitPrice *RateValue
}

CreateSalesOrderLineInput represents a line to create with a new sales order. The item, SKU/description defaults, unit cost, and (unless an internal user overrides) the unit price are all resolved server-side from the product.

type CreateSalesOrderLineParams

type CreateSalesOrderLineParams struct {
	SalesOrderID               string
	AccountID                  string
	ProductID                  string
	ItemID                     *string
	ProductSKU                 string
	ProductDescription         *string
	QuantityValue              string
	QuantityUnitID             string
	UnitPriceValue             string
	UnitPriceNumeratorUnitID   string
	UnitPriceDenominatorUnitID string
	UnitCostValue              *string
	UnitCostNumeratorUnitID    *string
	UnitCostDenominatorUnitID  *string
	EdiLineItemID              *string
}

CreateSalesOrderLineParams holds the parameters for creating a sales order line.

type CreateSalesOrderParams

type CreateSalesOrderParams struct {
	AccountID             string
	BuyerAccountID        string
	Includes              []string
	SellerAccountID       string
	OwnerAccountID        string
	Number                string
	SalesOrderStatusCode  string
	BillingAddressID      string
	ShippingAddressID     string
	CustomerPONumber      *string
	Note                  *string
	CarrierID             *string
	ServiceLevelID        *string
	CarrierBillingType    *string
	CarrierBillingAccount *string
	PriorityCode          string
	SalesRepID            *string
	ShippingTermID        *string
	PaymentTermID         *string
	OrderDiscountID       *string
	PromisedAt            *time.Time
	// LeadTimeOverrideDays and ShipByOverrideDate are the alternatives to PromisedAt. At most one of the three may be set; the service rejects more.
	LeadTimeOverrideDays *int32
	ShipByOverrideDate   *time.Time
	// Existing bill-to / ship-to address IDs the order references. The addresses must belong to the order's owner or buyer account (matching Dashboard, which only accepts address IDs — addresses are persisted separately).
	BillToAddressID string
	ShipToAddressID string
	Lines           []CreateSalesOrderLineInput
	// Email contact recipients to write into order_email_contact on create.
	AcknowledgementEmailContacts []SalesOrderEmailContactInput
	InvoiceEmailContacts         []SalesOrderEmailContactInput
}

CreateSalesOrderParams holds the parameters for creating a sales order.

type CreateSalesOrderProductionRunParams

type CreateSalesOrderProductionRunParams struct {
	SalesOrderID string
	AccountID    string
}

CreateSalesOrderProductionRunParams holds the parameters for creating a production run from a sales order.

type CreateSalesOrderProductionRunResult

type CreateSalesOrderProductionRunResult struct {
	ProductionRun *ProductionRun
}

CreateSalesOrderProductionRunResult holds the result of creating a production run.

type CreateSalesTargetParams

type CreateSalesTargetParams struct {
	AccountID    string
	SalesRepID   string
	StartDate    time.Time
	EndDate      time.Time
	AmountValue  string
	AmountUnitID string
}

CreateSalesTargetParams are the parameters for creating a sales target.

type CreateScanningStationParams

type CreateScanningStationParams struct {
	AccountID           string
	Name                string
	Notes               *string
	Type                constants.ScanningStationType
	LabelSizeCode       *string
	LabelTypeCode       *string
	OperatorRequirement constants.OperatorRequirement
	DepartmentID        string
	Includes            []string
}

type CreateServiceLevelParams

type CreateServiceLevelParams struct {
	AccountID          string
	CarrierID          string
	Name               string
	Code               string
	ServiceLevelToken  *string
	IsPortalEnabled    bool
	IsDefault          bool
	DefaultTransitDays *int32
}

type CreateSettlementAllocationParams

type CreateSettlementAllocationParams struct {
	TransactionID string
	InvoiceID     string
	Amount        string
	Note          *string
}

CreateSettlementAllocationParams holds parameters for a single allocation in a settlement.

type CreateSettlementParams

type CreateSettlementParams struct {
	AccountID         string
	ResponsibleUserID string
	Allocations       []CreateSettlementAllocationParams
}

CreateSettlementParams holds parameters for creating a settlement.

type CreateShipmentFromPickParams

type CreateShipmentFromPickParams struct {
	ID                string
	Number            string
	SalesOrderID      string
	CarrierID         string
	ServiceLevelID    *string
	ShippingAddressID string
	StatusCode        string
	AccountID         string
}

CreateShipmentFromPickParams holds the parameters for creating a shipment during pack.

type CreateShipmentLineEndpointParams

type CreateShipmentLineEndpointParams struct {
	AccountID        string
	ShipmentID       string
	SalesOrderLineID string
	QuantityValue    string
	QuantityUnitID   string
}

CreateShipmentLineEndpointParams holds the parameters for creating a shipment line via the API.

type CreateShipmentLineParams

type CreateShipmentLineParams struct {
	ID               string
	ShipmentID       string
	SalesOrderLineID string
	QuantityID       string
}

CreateShipmentLineParams holds the parameters for creating a shipment line during pack.

type CreateShippingCaseParams

type CreateShippingCaseParams struct {
	ID              string
	Number          string
	FreightAmountID string
	FreightWeightID string
	ShipmentID      string
	CarrierID       string
	AccountID       string
}

CreateShippingCaseParams holds the parameters for creating a shipping case during pack.

type CreateShippingTermParams

type CreateShippingTermParams struct {
	AccountID                   string
	Name                        string
	Type                        constants.ShippingTermType
	FlatRate                    *QuantityInput
	MinimumOrderValue           *QuantityInput
	FreeShippingServiceLevelIDs []string
	FlatRateID                  *string
	MinimumOrderID              *string
	Includes                    []string
}

type CreateStepConsumptionParams

type CreateStepConsumptionParams struct {
	ItemID              string
	QuantityValue       string
	QuantityUnitID      string
	WasteQuantityValue  string
	WasteQuantityUnitID string
	Instructions        *string
}

CreateStepConsumptionParams holds the parameters for creating a consumption within a production step create.

type CreateStripeCustomerParams

type CreateStripeCustomerParams struct {
	Email      string
	Name       string
	Number     string
	CustomerID string
}

CreateStripeCustomerParams holds the parameters for creating a Stripe customer.

type CreateSupplierMaterialParams

type CreateSupplierMaterialParams struct {
	OwnerAccountID      string
	MaterialID          string
	SupplierAccountID   string
	SupplierPartNumber  string
	SupplierDescription *string
	IsActive            bool
}

type CreateSupplierParams

type CreateSupplierParams struct {
	OwnerAccountID string
	Name           string
	Number         string
	Note           *string
	BillToAddress  *CreateAddressParams
	ShipToAddress  *CreateAddressParams
	Includes       []string
}

CreateSupplierParams holds the parameters for creating a supplier.

type CreateTerritoryParams

type CreateTerritoryParams struct {
	AccountID     string
	State         string
	StartZipcode  *int32
	EndZipcode    *int32
	SalesRepID    string
	ProductLineID *string
	Includes      []string
}

CreateTerritoryParams contains the parameters for creating a territory.

type CreateTransactionParams

type CreateTransactionParams struct {
	AccountID             string
	CustomerID            string
	TransactionTypeCode   string
	Amount                string
	TransactionMethodCode *string
	AdjustmentTypeCode    *string
	ResponsibleUserID     *string
	Note                  *string
	StripePaymentID       *string
}

CreateTransactionParams holds parameters for creating a transaction.

type CreateUnitGroupParams

type CreateUnitGroupParams struct {
	AccountID       string
	Name            string
	Notes           *string
	Type            string
	BaseUnitID      string
	UnitConversions []CreateUnitGroupUnitParams
	Includes        []string
}

CreateUnitGroupParams is the service-level params for creating a unit group with its initial conversions.

type CreateUnitGroupUnitParams

type CreateUnitGroupUnitParams struct {
	UnitID             string
	DiscountPercentage string
	DiscountFixed      string
	IsVisible          bool
}

CreateUnitGroupUnitParams describes a single unit conversion to attach to a group.

type CreateUnitParams

type CreateUnitParams struct {
	AccountID         string
	Name              string
	Abbreviation      string
	UnitDimensionCode string
	RatioNumerator    string
	RatioDenominator  string
	OffsetNumerator   string
	OffsetDenominator string
	IsBaseUnit        bool
}

type CreateUserRecordParams

type CreateUserRecordParams struct {
	Name           *string
	Email          *string
	Username       *string
	HashedPassword *string
}

CreateUserRecordParams are the parameters for creating a user record.

type CreateVolumeDiscountCustomerGroupParams

type CreateVolumeDiscountCustomerGroupParams struct {
	ID             string
	AccountGroupID string
}

type CreateVolumeDiscountParams

type CreateVolumeDiscountParams struct {
	AccountID      string
	Name           string
	Tiers          []CreateVolumeDiscountTierParams
	CustomerGroups []CreateVolumeDiscountCustomerGroupParams
	ProductLineIDs []string
	CategoryIDs    []string
	AttributeIDs   []string
	UnitIDs        []string
	Includes       []string
}

type CreateVolumeDiscountTierParams

type CreateVolumeDiscountTierParams struct {
	ID                 string
	Name               string
	DiscountPercentage string
	Threshold          string
	ParentTierID       *string
}

type Customer

type Customer struct {
	ID                  string
	Name                string                      `audit:"name"`
	Number              string                      `audit:"number"`
	Status              constants.AccountStatusCode `audit:"status"`
	IsEdiEnabled        bool                        `audit:"is_edi_enabled"`
	IsParentAccount     bool                        `audit:"is_parent_account"`
	CommissionPolicy    constants.CommissionPolicy  `audit:"commission_policy"`
	FreightPolicy       constants.FreightPolicy     `audit:"freight_policy"`
	DefaultLeadTimeDays *int32                      `audit:"default_lead_time_days"`
	// ReceiveCalendarID is the days this customer's dock accepts freight, in the same chain as the lead time above.
	ReceiveCalendarID *string `audit:"receive_calendar_id"`
	// FulfillmentPolicy marks the customer make-to-order: when make_to_order, their history is left out of the production-schedule forecast and their orders are built only when placed. Nil inherits the account group's policy, then make-to-stock.
	FulfillmentPolicy                  *constants.FulfillmentPolicy  `audit:"fulfillment_policy_code"`
	Note                               *string                       `audit:"note"`
	Email                              *string                       `audit:"email"`
	Phone                              *string                       `audit:"phone"`
	URL                                *string                       `audit:"url"`
	CarrierBillingType                 *constants.CarrierBillingType `audit:"carrier_billing_type"`
	CarrierBillingAccount              *string                       `audit:"carrier_billing_account"`
	CreditLimitID                      *string                       `audit:"credit_limit_id"`
	CreditLimitValue                   *string
	CreditLimitUnitID                  *string
	CreditLimitUnitAbbreviation        *string
	CreditLimitUnitName                *string
	CreditLimitUnitType                *string
	AcceptsInvoiceEmails               bool    `audit:"accepts_invoice_emails"`
	DefaultCarrierID                   *string `audit:"default_carrier_id"`
	DefaultCarrierName                 *string
	DefaultCarrierIsPortalEnabled      *bool
	DefaultCarrierCreatedAt            *time.Time
	DefaultCarrierUpdatedAt            *time.Time
	DefaultServiceLevelID              *string `audit:"default_service_level_id"`
	DefaultServiceLevelName            *string
	DefaultServiceLevelToken           *string
	DefaultServiceLevelIsPortalEnabled *bool
	DefaultServiceLevelCreatedAt       *time.Time
	DefaultServiceLevelUpdatedAt       *time.Time
	DefaultPaymentTermID               *string `audit:"default_payment_term_id"`
	DefaultPaymentTermName             *string
	DefaultPaymentTermIsActive         *bool
	DefaultPaymentTermCreatedAt        *time.Time
	DefaultPaymentTermUpdatedAt        *time.Time
	DefaultShippingTermID              *string `audit:"default_shipping_term_id"`
	DefaultShippingTermName            *string
	DefaultShippingTermType            *constants.ShippingTermType
	DefaultShippingTermCreatedAt       *time.Time
	DefaultShippingTermUpdatedAt       *time.Time
	DefaultPriorityID                  *string
	DefaultPriorityCode                *constants.PriorityCode `audit:"default_priority_code"`
	DefaultPriorityName                *string
	DefaultSalesRepID                  *string `audit:"default_sales_rep_id"`
	DefaultSalesRepName                *string
	DefaultSalesRepStatus              *constants.AccountUserStatus
	DefaultSalesRepCreatedAt           *time.Time
	DefaultSalesRepUpdatedAt           *time.Time
	BillToAddressID                    *string `audit:"bill_to_address_id"`
	ShipToAddressID                    *string `audit:"ship_to_address_id"`
	BillToAddress                      *CustomerAddress
	ShipToAddress                      *CustomerAddress
	TypeGroupID                        *string `audit:"type_group_id"`
	TypeGroupName                      *string
	TypeGroupCommissionPolicy          *constants.CommissionPolicy
	TypeGroupFreightPolicy             *constants.FreightPolicy
	TypeGroupType                      *constants.AccountGroupType
	TypeGroupCreatedAt                 *time.Time
	TypeGroupUpdatedAt                 *time.Time
	PriceGroups                        []CustomerAccountGroup `audit:"price_groups"`
	ParentAccountID                    *string                `audit:"parent_account_id"`
	ParentAccountName                  *string
	ParentAccountNumber                *string
	ParentAccountCreatedAt             *time.Time
	ParentAccountUpdatedAt             *time.Time
	ChildAccounts                      []CustomerChildAccount
	CreatedAt                          time.Time
	UpdatedAt                          time.Time
}

Customer represents a full customer record from the database.

type CustomerAccountGroup

type CustomerAccountGroup struct {
	ID               string
	Name             string
	CommissionPolicy constants.CommissionPolicy
	FreightPolicy    constants.FreightPolicy
	Type             constants.AccountGroupType
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

CustomerAccountGroup is a lightweight account group reference.

type CustomerAccountSummary

type CustomerAccountSummary struct {
	ID   string
	Name string
}

CustomerAccountSummary represents a customer account summary.

type CustomerAddress

type CustomerAddress struct {
	ID          string
	Name        string
	Phone       *string
	Email       *string
	IsDropShip  bool
	Geolocation *CustomerGeolocation
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

CustomerAddress represents a customer's address with geolocation.

type CustomerByEmail

type CustomerByEmail struct {
	RelationID            string
	OwnerAccountID        string
	CounterpartyAccountID string
	RoleCode              string
	Alias                 string
	Email                 string
	UserName              string
}

type CustomerChildAccount

type CustomerChildAccount struct {
	ID        string
	Name      string
	Number    string
	CreatedAt time.Time
	UpdatedAt time.Time
}

CustomerChildAccount is the lightweight stub returned when `?include=child_accounts` is requested on a customer resource.

type CustomerDemandRow

type CustomerDemandRow struct {
	ProductID      string
	BuyerAccountID string
	Year           int
	Month          int
	Quantity       float64
}

CustomerDemandRow is one product's sold quantity to one customer in one calendar month.

type CustomerFulfillmentProfile

type CustomerFulfillmentProfile struct {
	CustomerAccountID string
	CustomerName      string
	// LeadTimeDays is resolved customer -> account group -> account, the same chain an order's ship-by is stamped from.
	LeadTimeDays int
	// FulfillmentPolicyCode is empty when neither the customer nor its group states one.
	FulfillmentPolicyCode string
}

CustomerFulfillmentProfile is how one customer buys: the time they allow and the policy they state, each already resolved through its own chain.

type CustomerGeolocation

type CustomerGeolocation struct {
	ID          string
	StreetLine1 *string
	StreetLine2 *string
	Locality    *string
	State       *string
	PostalCode  *string
	Country     string
}

CustomerGeolocation represents a geolocation record.

type CustomerLeadTime

type CustomerLeadTime struct {
	CustomerAccountID string
	Days              int
	SourceCode        string
	// AccountGroupID is set only when the group is the rule that won.
	AccountGroupID *string
	// ParentCustomerAccountID is set only when the parent account is the rule that won.
	ParentCustomerAccountID *string
}

CustomerLeadTime is the ship-by commitment a new order for one customer would be given, and the rule that produced it.

type CustomerLeadTimeChain

type CustomerLeadTimeChain struct {
	AccountRelationID string
	AccountGroupID    *string
	// ParentCustomerAccountID is the buyer's parent account, set whether or not the parent carries a lead time.
	ParentCustomerAccountID    *string
	CustomerLeadTimeDays       *int
	ParentCustomerLeadTimeDays *int
	AccountGroupLeadTimeDays   *int
}

CustomerLeadTimeChain is what a buyer's ship-by commitment can be resolved from, every level together.

All of them are returned rather than only the winner because the source is stamped onto the order beside the date: an order has to be able to say which rule produced its commitment, not just what the commitment was.

type CustomerPricingAnalysis

type CustomerPricingAnalysis struct {
	Findings               []CustomerPricingFinding
	PricesAnalyzed         int
	BelowPeerMedianCount   int
	BelowTargetMarginCount int
	MarginNotAssessedCount int
	Notes                  []string
}

CustomerPricingAnalysis is the swept result: the flagged prices plus what the sweep covered.

type CustomerPricingFinding

type CustomerPricingFinding struct {
	AccountPriceID          string
	CustomerID              string
	ProductLineID           string
	AttributeIDs            []string
	UnitPrice               string
	NumeratorUnitID         string
	NumeratorUnitAbbr       string
	DenominatorUnitID       string
	DenominatorAbbr         string
	PeerMedianPrice         *string
	BelowPeerMedianFraction *string
	GrossMargin             *string
	Origin                  string
	Reason                  string
}

CustomerPricingFinding is one contracted price flagged by the audit.

type CustomerProductLineAccess

type CustomerProductLineAccess struct {
	CustomerID     string
	CustomerName   string            `audit:"customer_name"`
	CustomerNumber string            `audit:"customer_number"`
	ProductLines   []ProductLineInfo `audit:"product_lines"`
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

type CustomerProductLineAccessSvc

type CustomerProductLineAccessSvc interface {
	// ListCustomerProductLineAccess returns a paginated list of product line access records grouped by customer.
	ListCustomerProductLineAccess(ctx context.Context, params ListCustomerProductLineAccessParams) (*ListCustomerProductLineAccessResult, *apierror.APIError)

	// GetCustomerProductLineAccess returns the product line access for a single customer.
	GetCustomerProductLineAccess(ctx context.Context, customerID string) (*CustomerProductLineAccess, *apierror.APIError)

	// CreateCustomerProductLineAccess creates a new product line access record for a customer.
	CreateCustomerProductLineAccess(ctx context.Context, params CreateCustomerProductLineAccessParams) (*CustomerProductLineAccess, *apierror.APIError)

	// UpdateCustomerProductLineAccess replaces all product lines for a customer.
	UpdateCustomerProductLineAccess(ctx context.Context, params UpdateCustomerProductLineAccessParams) (*CustomerProductLineAccess, *apierror.APIError)

	// DeleteCustomerProductLineAccess removes all product line access for a customer.
	DeleteCustomerProductLineAccess(ctx context.Context, customerID string) *apierror.APIError

	// BatchGetCustomerProductLineAccessByIDs returns access records for the given customer_ids. Used by the api-gateway resourcekit resolver.
	BatchGetCustomerProductLineAccessByIDs(ctx context.Context, customerIDs []string) ([]*CustomerProductLineAccess, *apierror.APIError)
}

type CustomerRegistrar

type CustomerRegistrar interface {
	RegisterCustomer(ctx context.Context, params RegisterCustomerParams) *apierror.APIError
}

CustomerRegistrar registers the authenticated buyer as a customer of a seller account. Implemented by the registration-flow service; injected into the portal registration-session service so completion reuses the existing one-shot registration logic.

type CustomerRegistrationAddress

type CustomerRegistrationAddress struct {
	StreetLine1 string
	StreetLine2 *string
	Locality    string
	State       string
	PostalCode  string
	Country     string
	Name        *string
}

type CustomerRegistrationAddressParams

type CustomerRegistrationAddressParams struct {
	Name        *string
	StreetLine1 string
	StreetLine2 *string
	Locality    string
	State       string
	PostalCode  string
	Country     string
}

CustomerRegistrationAddressParams holds the address data needed for customer registration.

type CustomerRegistrationData

type CustomerRegistrationData struct {
	Number          *string
	Name            *string
	CustomerGroupID *string
	Phone           *string
	Address         *CustomerRegistrationAddress
	ShippingTermID  *string
	PaymentTermID   *string
}

type CustomerRegistrationRepo

type CustomerRegistrationRepo interface {
	FindCustomerAccountByExternalNumber(ctx context.Context, ownerAccountID, externalNumber string) (string, *apierror.APIError)
	CreateAccountUserLink(ctx context.Context, linkID, accountID, userID string) *apierror.APIError
	// AllocateNextCustomerNumber reserves the account's next customer number in one locked statement.
	AllocateNextCustomerNumber(ctx context.Context, sysPropertyID, accountID string) (int64, *apierror.APIError)
	CreateNewCustomerAccount(ctx context.Context, params CreateNewCustomerAccountParams) (string, *apierror.APIError)
	GetUserEmailByID(ctx context.Context, userID string) (string, *apierror.APIError)
}

type CustomerRepo

type CustomerRepo interface {
	List(ctx context.Context, params ListCustomersParams) (*ListCustomersResult, *apierror.APIError)
	Get(ctx context.Context, ownerAccountID, customerAccountID string, includes []string) (*Customer, *apierror.APIError)
	Create(ctx context.Context, accountID, relationID, brandingID string, params CreateCustomerParams, customerNumber string) (*Customer, *apierror.APIError)
	Update(ctx context.Context, relationID string, params UpdateCustomerParams) *apierror.APIError
	UpdateName(ctx context.Context, customerAccountID, name string) *apierror.APIError
	UpdateBranding(ctx context.Context, customerAccountID string, email, phone, url *string) *apierror.APIError
	Delete(ctx context.Context, ownerAccountID, customerAccountID string) *apierror.APIError
	BulkDelete(ctx context.Context, ownerAccountID string, customerIDs []string) *apierror.APIError
	IsCommissionExempt(ctx context.Context, ownerAccountID, customerAccountID string) (bool, *apierror.APIError)
	ExistsByNumber(ctx context.Context, ownerAccountID, number string, excludeID *string) (bool, *apierror.APIError)
	// AllocateNextCustomerNumber reserves the account's next customer number in one locked statement, so two registrations landing together cannot be handed the same one.
	AllocateNextCustomerNumber(ctx context.Context, sysPropertyID, accountID string) (int64, *apierror.APIError)
	InsertPriceGroup(ctx context.Context, id, relationID, groupID string) *apierror.APIError
	DeletePriceGroups(ctx context.Context, relationID string) *apierror.APIError
	GetFrequentlyOrderedProducts(ctx context.Context, ownerAccountID, customerAccountID string) ([]*FrequentlyOrderedProduct, *apierror.APIError)
	GetRelationID(ctx context.Context, ownerAccountID, customerAccountID string) (string, *apierror.APIError)
	MergeOrders(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeInvoices(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeShipments(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeDeliveries(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeTransactions(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeAccountPrices(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeInventoryReceipts(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeReceivingOrders(ctx context.Context, ownerAccountID, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	MergeInventoryIssues(ctx context.Context, targetAccountID string, sourceAccountIDs []string) *apierror.APIError
	DeleteNotificationPreferences(ctx context.Context, relationIDs []string) *apierror.APIError
	DeleteProductLineAccess(ctx context.Context, relationIDs []string) *apierror.APIError
	GetRelationPriceGroupIDs(ctx context.Context, relationID string) ([]string, *apierror.APIError)
	GetRelationsPriceGroups(ctx context.Context, relationIDs []string) ([]RelationPriceGroup, *apierror.APIError)
	MoveRelationPriceGroups(ctx context.Context, targetRelationID string, ids []string) *apierror.APIError
	DeletePriceGroupsByIDs(ctx context.Context, ids []string) *apierror.APIError
	GetRelationProductLineIDs(ctx context.Context, relationID string) ([]string, *apierror.APIError)
	GetRelationsProductLines(ctx context.Context, relationIDs []string) ([]RelationProductLine, *apierror.APIError)
	MoveRelationProductLines(ctx context.Context, targetRelationID string, ids []string) *apierror.APIError
	DeleteProductLinesByIDs(ctx context.Context, ids []string) *apierror.APIError
	ReparentChildRelations(ctx context.Context, targetRelationID string, sourceRelationIDs []string) *apierror.APIError
	GetAccountAddressIDs(ctx context.Context, accountID string) ([]string, *apierror.APIError)
	InsertAccountAddress(ctx context.Context, id, accountID, addressID string) *apierror.APIError
	DeleteAccountAddresses(ctx context.Context, accountID string) *apierror.APIError
	GetAccountUsers(ctx context.Context, accountID string) ([]AccountUserRef, *apierror.APIError)
	MoveAccountUsers(ctx context.Context, targetAccountID string, ids []string) *apierror.APIError
	DeleteAccountUsers(ctx context.Context, accountID string) *apierror.APIError
	GetStripeCustomerID(ctx context.Context, ownerAccountID, customerAccountID string) (stripeCustomerID *string, stripeEmail *string, err *apierror.APIError)
	SetStripeCustomerID(ctx context.Context, ownerAccountID, customerAccountID, stripeCustomerID, stripeEmail string) *apierror.APIError
	GetCustomerEmail(ctx context.Context, customerAccountID string) (*string, *apierror.APIError)
	InsertCreditLimitQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	UpdateCreditLimitQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	DeleteCreditLimitQuantity(ctx context.Context, id string) *apierror.APIError
}

type CustomerSvc

type CustomerSvc interface {
	// ListCustomers returns a paginated list of customers for the caller's account.
	ListCustomers(ctx context.Context, params ListCustomersParams) (*ListCustomersResult, *apierror.APIError)

	// GetCustomer returns a single customer by account ID. Supports customer actor access.
	GetCustomer(ctx context.Context, customerAccountID string, includes []string) (*Customer, *apierror.APIError)

	// CreateCustomer creates a new customer account.
	CreateCustomer(ctx context.Context, params CreateCustomerParams) (*Customer, *apierror.APIError)

	// DeleteCustomer deletes a customer and its associated relations.
	DeleteCustomer(ctx context.Context, params DeleteCustomerParams) *apierror.APIError

	// BulkDeleteCustomers deletes multiple customers at once.
	BulkDeleteCustomers(ctx context.Context, params BulkDeleteCustomersParams) *apierror.APIError

	// GetFrequentlyOrderedProducts returns the most frequently ordered products for a customer.
	GetFrequentlyOrderedProducts(ctx context.Context, customerAccountID string) ([]*FrequentlyOrderedProduct, *apierror.APIError)

	// GetCustomerLeadTime resolves the ship-by lead time a new order for this customer would be committed to.
	GetCustomerLeadTime(ctx context.Context, customerAccountID string) (*CustomerLeadTime, *apierror.APIError)

	// ListCustomerNotificationRecipients returns the default order-notification recipients configured for a customer relationship.
	ListCustomerNotificationRecipients(ctx context.Context, customerAccountID string) ([]NotificationRecipient, *apierror.APIError)

	// UpdateCustomerNotificationRecipients replaces the default order-notification recipients configured for a customer relationship.
	UpdateCustomerNotificationRecipients(ctx context.Context, params UpdateCustomerNotificationRecipientsParams) ([]NotificationRecipient, *apierror.APIError)

	// UpdateCustomer partially updates a customer.
	UpdateCustomer(ctx context.Context, params UpdateCustomerParams) (*Customer, *apierror.APIError)

	// MergeCustomers merges source customers into a target customer.
	MergeCustomers(ctx context.Context, params MergeCustomersParams) (*Customer, *apierror.APIError)
}

type DCLocation

type DCLocation struct {
	ID             string
	Location       string `audit:"location"`
	AccountID      string `audit:"account_id"`
	CustomerName   string `audit:"customer_name"`
	OwnerAccountID string
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

type DeleteAccountGroupParams

type DeleteAccountGroupParams struct {
	AccountID      string
	AccountGroupID string
}

type DeleteAccountIntegrationParams

type DeleteAccountIntegrationParams struct {
	AccountID string
	ID        string
}

type DeleteAddressParams

type DeleteAddressParams struct {
	AccountID string
	AddressID string
}

DeleteAddressParams contains the parameters for deleting an address.

type DeleteAttributeParams

type DeleteAttributeParams struct {
	AttributeID string
	PropertyID  string
	AccountID   string
}

DeleteAttributeParams holds the parameters for deleting an attribute.

type DeleteConsumptionParams

type DeleteConsumptionParams struct {
	AccountID        string
	ProductionStepID string
	ConsumptionID    string
}

DeleteConsumptionParams holds the parameters for deleting a consumption.

type DeleteCustomerParams

type DeleteCustomerParams struct {
	OwnerAccountID    string
	CustomerAccountID string
}

DeleteCustomerParams holds the parameters for deleting a customer.

type DeleteDCLocationParams

type DeleteDCLocationParams struct {
	OwnerAccountID string
	DCLocationID   string
}

type DeleteDemandOverrideParams

type DeleteDemandOverrideParams struct {
	AccountID  string
	OverrideID string
}

type DeleteDepartmentParams

type DeleteDepartmentParams struct {
	AccountID    string
	DepartmentID string
}

type DeleteItemCategoryParams

type DeleteItemCategoryParams struct {
	AccountID      string
	ItemCategoryID string
}

type DeleteLocationParams

type DeleteLocationParams struct {
	AccountID  string
	LocationID string
}

DeleteLocationParams contains the parameters for deleting a location.

type DeleteMachineDowntimeEventParams

type DeleteMachineDowntimeEventParams struct {
	AccountID string
	EventID   string
}

type DeleteMachineParams

type DeleteMachineParams struct {
	AccountID string
	MachineID string
}

type DeleteMaterialParams

type DeleteMaterialParams struct {
	AccountID  string
	MaterialID string
}

type DeleteOrderDiscountParams

type DeleteOrderDiscountParams struct {
	AccountID       string
	OrderDiscountID string
}

type DeletePartParams

type DeletePartParams struct {
	AccountID string
	PartID    string
}

type DeletePaymentTermParams

type DeletePaymentTermParams struct {
	AccountID     string
	PaymentTermID string
}

type DeleteProductLineParams

type DeleteProductLineParams struct {
	AccountID     string
	ProductLineID string
}

type DeleteProductParams

type DeleteProductParams struct {
	AccountID string
	ProductID string
}

DeleteProductParams holds parameters for soft-deleting a product.

type DeleteProductionRunParams

type DeleteProductionRunParams struct {
	ProductionRunID string
	AccountID       string
}

DeleteProductionRunParams holds the parameters for deleting a production run.

type DeleteProductionScheduleLineParams

type DeleteProductionScheduleLineParams struct {
	AccountID  string
	ScheduleID string
	LineID     string
	ReasonCode *string
	ReasonNote *string
}

type DeletePropertyParams

type DeletePropertyParams struct {
	PropertyID string
	AccountID  string
}

DeletePropertyParams holds the parameters for deleting a property.

type DeletePurchaseOrderLineParams

type DeletePurchaseOrderLineParams struct {
	PurchaseOrderLineID string
	SalesOrderID        string
	AccountID           string
}

DeletePurchaseOrderLineParams holds the parameters for deleting a purchase order line.

type DeletePurchaseOrderParams

type DeletePurchaseOrderParams struct {
	PurchaseOrderID string
	AccountID       string
}

DeletePurchaseOrderParams holds the parameters for deleting a purchase order.

type DeleteRegistrationFlowParams

type DeleteRegistrationFlowParams struct {
	AccountID          string
	RegistrationFlowID string
}

type DeleteSalesOrderLineParams

type DeleteSalesOrderLineParams struct {
	SalesOrderLineID string
	SalesOrderID     string
	AccountID        string
}

DeleteSalesOrderLineParams holds the parameters for deleting a sales order line.

type DeleteSalesOrderParams

type DeleteSalesOrderParams struct {
	SalesOrderID string
	AccountID    string
}

DeleteSalesOrderParams holds the parameters for deleting a sales order.

type DeleteScanningStationParams

type DeleteScanningStationParams struct {
	AccountID         string
	ScanningStationID string
}

type DeleteSettlementParams

type DeleteSettlementParams struct {
	AccountID    string
	SettlementID string
}

DeleteSettlementParams holds parameters for deleting a settlement.

type DeleteShipmentLineEndpointParams

type DeleteShipmentLineEndpointParams struct {
	AccountID      string
	ShipmentID     string
	ShipmentLineID string
}

DeleteShipmentLineEndpointParams holds the parameters for deleting a shipment line.

type DeleteShipmentParams

type DeleteShipmentParams struct {
	AccountID  string
	ShipmentID string
}

DeleteShipmentParams holds the parameters for deleting a shipment.

type DeleteShippingTermParams

type DeleteShippingTermParams struct {
	AccountID      string
	ShippingTermID string
}

type DeleteSupplierMaterialParams

type DeleteSupplierMaterialParams struct {
	OwnerAccountID    string
	SupplierAccountID string
	MaterialID        string
}

type DeleteSupplierParams

type DeleteSupplierParams struct {
	OwnerAccountID string
	SupplierID     string
}

DeleteSupplierParams holds the parameters for deleting a supplier.

type DeleteTerritoryParams

type DeleteTerritoryParams struct {
	AccountID   string
	TerritoryID string
}

DeleteTerritoryParams contains the parameters for deleting a territory.

type DeleteTransactionAllocationParams

type DeleteTransactionAllocationParams struct {
	AccountID    string
	AllocationID string
}

DeleteTransactionAllocationParams holds parameters for deleting a transaction allocation.

type DeleteTransactionParams

type DeleteTransactionParams struct {
	AccountID     string
	TransactionID string
}

DeleteTransactionParams holds parameters for deleting a transaction.

type DeleteUnitGroupParams

type DeleteUnitGroupParams struct {
	AccountID   string
	UnitGroupID string
}

type DeleteUnitGroupUnitParams

type DeleteUnitGroupUnitParams struct {
	AccountID       string
	UnitGroupID     string
	UnitGroupUnitID string
}

type DeleteUnitParams

type DeleteUnitParams struct {
	AccountID string
	UnitID    string
}

type DeleteVolumeDiscountParams

type DeleteVolumeDiscountParams struct {
	AccountID        string
	VolumeDiscountID string
}

type DeletedRecordRepo

type DeletedRecordRepo interface {
	Create(ctx context.Context, resourceType constants.DeletedRecordResourceType, resourceID string, data any) *apierror.APIError
	Exists(ctx context.Context, resourceType constants.DeletedRecordResourceType, resourceID string) (bool, *apierror.APIError)
}

type Delivery

type Delivery struct {
	ID                  string
	Number              string
	PurchaseOrderID     string
	PurchaseOrderNumber string
	Status              string
	Lines               []*DeliveryLine
	AcceptedAt          *time.Time
	RejectedAt          *time.Time
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

Delivery represents a full delivery with its lines.

type DeliveryAnalyticsResult

type DeliveryAnalyticsResult struct {
	Statistics DeliveryStatistics
	ChartData  DeliveryChartData
}

type DeliveryChartData

type DeliveryChartData struct {
	OnTimeDelivery           []ChartDataPoint
	AverageDeliveryTime      []ChartDataPoint
	AverageFirstShipmentTime []ChartDataPoint
}

type DeliveryEntry

type DeliveryEntry struct {
	InvoiceNumber string
	IssuedAt      *time.Time
	InvoicedAt    *time.Time
	CompletedAt   *time.Time
	FirstShipAt   *time.Time
	PromisedAt    *time.Time
}

type DeliveryFilters

type DeliveryFilters struct {
	CustomerIDs      []string
	CustomerGroupIDs []string
	ProductLineIDs   []string
	SalesRepIDs      []string
}

DeliveryFilters narrows a delivery measurement to part of the order book. Every filter is empty-means-all, and they combine with AND.

type DeliveryLine

type DeliveryLine struct {
	ID                        string
	ItemID                    *string
	ItemSKU                   *string
	ItemDescription           *string
	QuantityID                string
	QuantityValue             string
	QuantityUnitID            string
	QuantityUnitAbbreviation  string
	UnitCostID                string
	UnitCostValue             string
	UnitCostNumeratorUnitID   string
	UnitCostDenominatorUnitID string
	LocationID                *string
	LocationName              *string
	LotID                     *string
	LotNumber                 *string
	AcceptedAt                *time.Time
	RejectedAt                *time.Time
	CreatedAt                 time.Time
	UpdatedAt                 time.Time
}

DeliveryLine represents a line item in a delivery.

type DeliveryPerformanceResult

type DeliveryPerformanceResult struct {
	Overall scheduling.DeliveryPerformance
	Periods []scheduling.DeliveryPerformance
	Backlog []scheduling.BacklogBucket
	// Lateness bands every miss by how far it missed by. An average cannot tell "everything slips a day" from "four orders are two months late", and those are opposite problems.
	Lateness []scheduling.LatenessBucket

	// The same window sliced four ways. Each is ordered worst-first, so the row that needs a conversation is the first one.
	ByCustomer         []scheduling.DeliveryBreakdown
	ByCustomerGroup    []scheduling.DeliveryBreakdown
	ByProductLine      []scheduling.DeliveryBreakdown
	ByCommitmentSource []scheduling.DeliveryBreakdown

	// UncommittedOrderCount is issued orders in the window carrying no ship-by date, excluded from every rate above. Reported so the exclusion is visible rather than silent.
	UncommittedOrderCount int
}

DeliveryPerformanceResult is the whole delivery picture for one window.

type DeliveryRepo

type DeliveryRepo interface {
	List(ctx context.Context, params ListDeliveriesParams) (*ListDeliveriesResult, *apierror.APIError)
	Get(ctx context.Context, params GetDeliveryParams) (*Delivery, *apierror.APIError)
	CountByPurchaseOrder(ctx context.Context, purchaseOrderID string) (int64, *apierror.APIError)
	CreateDelivery(ctx context.Context, id, number, salesOrderID, accountID, statusCode string, acceptedAt, rejectedAt *time.Time) *apierror.APIError
	CreateDeliveryLine(ctx context.Context, id, deliveryID, receivingOrderLineID, quantityID, unitCostID string, storageLocationID, lotID *string, acceptedAt, rejectedAt *time.Time) *apierror.APIError
}

type DeliveryStatistics

type DeliveryStatistics struct {
	AverageTimeToFirstShipment            *float64
	AverageTimeToCompletion               *float64
	OnTimeDeliveryPercentage              *float64
	OnTimeFirstShipmentPercentage         *float64
	TotalOrders                           int32
	OrdersWithFirstShipment               int32
	OrdersWithCompletion                  int32
	OrdersWithPromiseDate                 int32
	OrdersPartiallyFulfilledInPromiseDate int32
	OrdersCompletedWithinPromiseDate      int32
}

type DeliverySummary

type DeliverySummary struct {
	ID                  string
	Number              string
	PurchaseOrderID     string
	PurchaseOrderNumber string
	Status              string
	LineCount           int32
	AcceptedAt          *time.Time
	RejectedAt          *time.Time
	CreatedAt           time.Time
	UpdatedAt           time.Time
	// Lines (populated only when the list request includes "lines").
	Lines []*DeliveryLine
}

DeliverySummary represents a delivery with line count instead of full lines.

type DeliverySvc

type DeliverySvc interface {
	// ListDeliveries returns a paginated list of deliveries for the caller's account.
	ListDeliveries(ctx context.Context, params ListDeliveriesParams) (*ListDeliveriesResult, *apierror.APIError)

	// GetDelivery returns a single delivery by ID within the caller's account.
	GetDelivery(ctx context.Context, params GetDeliveryParams) (*Delivery, *apierror.APIError)
}

type DemandForecastItem

type DemandForecastItem struct {
	ItemID              string
	ProductLineID       *string
	ProductSku          string
	ProductDescription  *string
	Unit                string
	Currency            string
	History             []DemandHistoryPoint
	Forecast            []DemandForecastPoint
	RevenueHistory      []RevenueHistoryPoint
	RevenueForecast     []RevenueForecastPoint
	SalesHistory        []RevenueHistoryPoint
	SalesForecast       []RevenueForecastPoint
	CurrentMonthDemand  float64
	CurrentMonthRevenue float64
	CurrentMonthSales   float64
}

type DemandForecastMonthlyDemandRow

type DemandForecastMonthlyDemandRow struct {
	ItemID             string
	ProductSku         string
	ProductDescription *string
	ProductLineID      *string
	Unit               string
	Currency           string
	DemandYear         int32
	DemandMonth        int32
	MonthlyDemand      float64
	MonthlyRevenue     float64
}

DemandForecastMonthlyDemandRow is one item-month of order-based demand and revenue.

type DemandForecastMonthlyRevenueRow

type DemandForecastMonthlyRevenueRow struct {
	ItemID         string
	RevenueYear    int32
	RevenueMonth   int32
	MonthlyRevenue float64
}

DemandForecastMonthlyRevenueRow is one item-month of invoice-based revenue.

type DemandForecastPoint

type DemandForecastPoint struct {
	Date       time.Time
	Forecast   float64
	LowerBound float64
	UpperBound float64
}

type DemandForecastResult

type DemandForecastResult struct {
	Items                []DemandForecastItem
	CurrentMonthFraction float64
}

type DemandHistoryPoint

type DemandHistoryPoint struct {
	Date   time.Time
	Demand float64
}

type DemandOverride

type DemandOverride struct {
	ID        string
	AccountID string

	ScopeCode  string `audit:"scope_code"`
	ScopeRefID string `audit:"scope_ref_id"`
	// ScopeName and ScopeHandle label whatever the scope points at — an item's description and SKU, or a product line's name — so a list can be rendered without a second round trip per row. Resolved on read, never stored.
	ScopeName   *string
	ScopeHandle *string

	// PeriodStartDate and PeriodEndDate bound the demand months the override applies to. They are dates rather than a single month because a merchant thinks in "Q3" or "through year end" far more often than in single months.
	PeriodStartDate time.Time `audit:"period_start_date"`
	PeriodEndDate   time.Time `audit:"period_end_date"`

	OverrideTypeCode string  `audit:"override_type_code"`
	Value            float64 `audit:"value"`
	UnitID           *string `audit:"unit_id"`

	ReasonCode *string `audit:"reason_code"`
	Note       *string `audit:"note"`

	CreatedByID string

	// EffectiveFrom and ExpiresAt bound when the override is *consulted*, which is a different axis from the period it applies to: "as of today, plan for an extra 5,000 units in Q4" stops being true once the deal is signed and real orders exist.
	EffectiveFrom time.Time  `audit:"effective_from"`
	ExpiresAt     *time.Time `audit:"expires_at"`
	IsActive      bool       `audit:"is_active"`

	CreatedAt time.Time
	UpdatedAt time.Time
}

type DemandOverrideSvc

type DemandOverrideSvc interface {
	// ListDemandOverrideTypes returns the global override type taxonomy.
	ListDemandOverrideTypes(ctx context.Context) ([]*DemandOverrideType, *apierror.APIError)

	// ListDemandOverrides returns a paginated list of demand overrides for the caller's account.
	ListDemandOverrides(ctx context.Context, params ListDemandOverridesParams) (*ListDemandOverridesResult, *apierror.APIError)

	// GetDemandOverride returns a single demand override by ID.
	GetDemandOverride(ctx context.Context, overrideID string) (*DemandOverride, *apierror.APIError)

	// CreateDemandOverride records demand the forecast cannot see. The scope reference is validated so an override can never silently match nothing.
	CreateDemandOverride(ctx context.Context, params CreateDemandOverrideParams) (*DemandOverride, *apierror.APIError)

	// UpdateDemandOverride partially updates an override. Type and value are validated as a pair against the resulting row.
	UpdateDemandOverride(ctx context.Context, params UpdateDemandOverrideParams) (*DemandOverride, *apierror.APIError)

	// DeleteDemandOverride removes an override.
	DeleteDemandOverride(ctx context.Context, overrideID string) *apierror.APIError

	// BatchGetDemandOverridesByIDs returns demand overrides by their IDs for include resolution.
	BatchGetDemandOverridesByIDs(ctx context.Context, ids []string) ([]*DemandOverride, *apierror.APIError)
}

type DemandOverrideType

type DemandOverrideType struct {
	ID        string
	Code      string
	Name      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Department

type Department struct {
	ID               string
	Name             string  `audit:"name"`
	Notes            *string `audit:"notes"`
	LocationID       *string `audit:"location_id"`
	LocationName     *string `audit:"location_name"`
	LocationTypeCode *string `audit:"location_type_code"`
	// LaborRate is the hourly cost of work done in this department (e.g. a changeover tech), used by production scheduling to cost changeovers. Nil when the department has none.
	LaborRate        *ProductionStepRate         `audit:"labor_rate"`
	ScanningStations []DepartmentScanningStation `audit:"scanning_stations"`
	Machines         []DepartmentMachine         `audit:"machines"`
	AccountID        string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

type DepartmentMachine

type DepartmentMachine struct {
	ID           string
	Name         string
	SerialNumber string
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

DepartmentMachine is a machine sub-resource attached to a department.

type DepartmentMachineCountRow

type DepartmentMachineCountRow struct {
	DepartmentID string
	MachineCount int64
}

DepartmentMachineCountRow is the number of machines in one department, the scheduled-time denominator for OEE.

type DepartmentRepo

type DepartmentRepo interface {
	List(ctx context.Context, params ListDepartmentsParams) (*ListDepartmentsResult, *apierror.APIError)
	Export(ctx context.Context, params ExportDepartmentsParams) ([]*Department, *apierror.APIError)
	Get(ctx context.Context, params GetDepartmentParams) (*Department, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Department, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateDepartmentParams) (*Department, *apierror.APIError)
	Update(ctx context.Context, params UpdateDepartmentParams) (*Department, *apierror.APIError)
	Delete(ctx context.Context, params DeleteDepartmentParams) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	FindByNames(ctx context.Context, accountID string, names []string) ([]*Department, *apierror.APIError)
	SetMachinesDepartmentID(ctx context.Context, departmentID, accountID string, machineIDs []string) *apierror.APIError
	SetScanningStationsDepartmentID(ctx context.Context, departmentID, accountID string, scanningStationIDs []string) *apierror.APIError
	InsertLaborRate(ctx context.Context, rateID string, params CreateRateParams) *apierror.APIError
	UpdateLaborRate(ctx context.Context, rateID string, params CreateRateParams) *apierror.APIError
}

type DepartmentScanningStation

type DepartmentScanningStation struct {
	ID                  string
	Name                string
	Type                string
	OperatorRequirement string
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

type DepartmentSvc

type DepartmentSvc interface {
	// ListDepartments returns a paginated list of departments for the caller's account.
	ListDepartments(ctx context.Context, params ListDepartmentsParams) (*ListDepartmentsResult, *apierror.APIError)

	ExportDepartments(ctx context.Context, params ExportDepartmentsParams) (*Job, *apierror.APIError)
	// BuildExportDepartments renders the file an accepted export recorded.
	BuildExportDepartments(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// GetDepartment returns a single department by ID.
	GetDepartment(ctx context.Context, departmentID string) (*Department, *apierror.APIError)

	// CreateDepartment creates a new department.
	CreateDepartment(ctx context.Context, params CreateDepartmentParams) (*Department, *apierror.APIError)

	// UpdateDepartment partially updates a department.
	UpdateDepartment(ctx context.Context, params UpdateDepartmentParams) (*Department, *apierror.APIError)

	// BulkUpsertDepartments accepts a bulk upsert of departments and returns the job to poll.
	BulkUpsertDepartments(ctx context.Context, params BulkUpsertDepartmentsParams) (*Job, *apierror.APIError)

	// ExecuteBulkUpsertDepartments performs the writes for an enqueued bulk upsert.
	ExecuteBulkUpsertDepartments(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// DeleteDepartment deletes a department.
	DeleteDepartment(ctx context.Context, departmentID string) *apierror.APIError

	// BatchGetDepartmentsByIDs returns departments matching the given IDs.
	BatchGetDepartmentsByIDs(ctx context.Context, ids []string) ([]*Department, *apierror.APIError)
}

type DowntimeDurationInput

type DowntimeDurationInput struct {
	Value  string
	UnitID string
}

DowntimeDurationInput is how long a machine was down on its way in: a decimal string and the unit of time it counts.

Carried as a quantity rather than a minute count so an operator can say "two days" without doing the arithmetic, and so the unit the number was entered in is the one that gets validated.

type DuplicateCheckType

type DuplicateCheckType string

DuplicateCheckType represents the type of duplicate check to perform.

const (
	DuplicateCheckTypeInvoiceNumber DuplicateCheckType = "invoice_number"
	DuplicateCheckTypeOrderNumber   DuplicateCheckType = "order_number"
	DuplicateCheckTypeCustomerPO    DuplicateCheckType = "customer_po_number"
)

func (DuplicateCheckType) EnumValues

func (t DuplicateCheckType) EnumValues() []string

func (DuplicateCheckType) IsValid

func (t DuplicateCheckType) IsValid() bool

type EDIRepo

type EDIRepo interface {
	ListDCLocations(ctx context.Context, params ListDCLocationsParams) (*ListDCLocationsResult, *apierror.APIError)
	GetDCLocation(ctx context.Context, params GetDCLocationParams) (*DCLocation, *apierror.APIError)
	GetDCLocationsByIDs(ctx context.Context, ownerAccountID string, ids []string) ([]*DCLocation, *apierror.APIError)
	CreateDCLocation(ctx context.Context, id string, params CreateDCLocationParams) (*DCLocation, *apierror.APIError)
	UpdateDCLocation(ctx context.Context, params UpdateDCLocationParams) (*DCLocation, *apierror.APIError)
	DeleteDCLocation(ctx context.Context, params DeleteDCLocationParams) *apierror.APIError
	ListEDIRuns(ctx context.Context, params ListEDIRunsParams) (*ListEDIRunsResult, *apierror.APIError)
	GetEDIRun(ctx context.Context, accountID, ediRunID string) (*EDIRun, *apierror.APIError)
	GetEDIRunsByIDs(ctx context.Context, accountID string, ids []string) ([]*EDIRun, *apierror.APIError)
}

type EDIRun

type EDIRun struct {
	ID           string
	CompletedAt  time.Time
	HasSucceeded bool
	AccountID    string
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

type EDISvc

type EDISvc interface {
	// ListDCLocations returns a paginated list of DC locations.
	ListDCLocations(ctx context.Context, params ListDCLocationsParams) (*ListDCLocationsResult, *apierror.APIError)

	// GetDCLocation returns a single DC location by ID.
	GetDCLocation(ctx context.Context, dcLocationID string) (*DCLocation, *apierror.APIError)

	// CreateDCLocation creates a new DC location.
	CreateDCLocation(ctx context.Context, params CreateDCLocationParams) (*DCLocation, *apierror.APIError)

	// UpdateDCLocation partially updates a DC location.
	UpdateDCLocation(ctx context.Context, params UpdateDCLocationParams) (*DCLocation, *apierror.APIError)

	// DeleteDCLocation deletes a DC location.
	DeleteDCLocation(ctx context.Context, dcLocationID string) *apierror.APIError

	// ListEDIRuns returns a paginated list of EDI runs.
	ListEDIRuns(ctx context.Context, params ListEDIRunsParams) (*ListEDIRunsResult, *apierror.APIError)

	// GetEDIRun returns a single EDI run by ID.
	GetEDIRun(ctx context.Context, ediRunID string) (*EDIRun, *apierror.APIError)

	// PullOrders processes EDI operations (pull orders from FTP, process invoices).
	PullOrders(ctx context.Context) *apierror.APIError

	// ResubmitInvoice resubmits an invoice via EDI.
	ResubmitInvoice(ctx context.Context, invoiceID string) *apierror.APIError

	// BatchGetDCLocationsByIDs returns DC locations matching the input IDs. Used by the api-gateway resourcekit include resolver.
	BatchGetDCLocationsByIDs(ctx context.Context, ids []string) ([]*DCLocation, *apierror.APIError)

	// BatchGetEDIRunsByIDs returns EDI runs matching the input IDs. Used by the api-gateway resourcekit include resolver.
	BatchGetEDIRunsByIDs(ctx context.Context, ids []string) ([]*EDIRun, *apierror.APIError)
}

type EditAccessMed

type EditAccessMed interface {
	// CheckEditAccess verifies that the actor account has edit access to the target account. Same-account access is always allowed. Cross-account access requires: the target has no active billing plan, a relation exists between the accounts, and the target has no other owner relations.
	//
	//  1. Allow access when the actor and target accounts are the same.
	//  2. Reject when the target has an active billing plan.
	//  3. Require a relation between the actor and target accounts.
	//  4. Reject when the target has owner relations with other accounts.
	CheckEditAccess(ctx context.Context, actorAccountID, targetAccountID string) *apierror.APIError
}

type EffectiveScheduleSettings

type EffectiveScheduleSettings struct {
	Settings               scheduling.Settings
	DemandWindowMonths     int
	ForecastHistoryMonths  int
	ForecastMonths         int
	DemandBasisCode        string
	ForecastZ              float64
	ConstraintDepartmentID string
	ItemSettings           map[string]ProductionScheduleItemSetting
	// DefaultFulfillmentPolicy is the account-wide fallback for how a SKU is produced.
	DefaultFulfillmentPolicy string
	// RecommendationThresholds are the cut points the make-to-order recommendation is drawn against.
	RecommendationThresholds scheduling.RecommendationThresholds
	// DefaultCustomerLeadTimeDays is the last resort in a customer's ship-by chain.
	DefaultCustomerLeadTimeDays int
}

EffectiveScheduleSettings is the merchant's planning assumptions with code defaults already applied, so callers never have to handle "not configured".

type EmailLog

type EmailLog struct {
	ID           string
	HasSent      bool
	Recipients   []string
	Subject      *string
	Filename     *string
	SESMessageID *string
	SentBy       *EmailLogActor
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

type EmailLogActor

type EmailLogActor struct {
	ID        string
	ActorType string
	Name      *string
	// Handle is the human-readable identifier for the actor — email for users, redacted value for API keys.
	Handle *string
}

EmailLogActor identifies the actor who sent an email. Today this is always a user, but the shape mirrors other actor references so future senders (API keys, agents) can be represented without another schema change.

type EmailLogRepo

type EmailLogRepo interface {
	List(ctx context.Context, params ListEmailLogsParams) (*ListEmailLogsResult, *apierror.APIError)
	Get(ctx context.Context, params GetEmailLogParams) (*EmailLog, *apierror.APIError)
}

type EmailLogSvc

type EmailLogSvc interface {
	// ListEmailLogs returns a paginated list of email logs for the caller's account.
	ListEmailLogs(ctx context.Context, params ListEmailLogsParams) (*ListEmailLogsResult, *apierror.APIError)

	// GetEmailLog returns a single email log by ID within the caller's account.
	GetEmailLog(ctx context.Context, params GetEmailLogParams) (*EmailLog, *apierror.APIError)
}

type EmailReceivablesParams

type EmailReceivablesParams struct {
	CustomerAccountID string
	RecipientEmails   []string
}

EmailReceivablesParams holds parameters for emailing receivables to a customer.

type EmailRecordParams

type EmailRecordParams struct {
	ID   string
	Type EmailRecordType
}

EmailRecordParams holds parameters for emailing a record.

type EmailRecordType

type EmailRecordType string

EmailRecordType represents the type of record to email.

const (
	EmailRecordTypeInvoice       EmailRecordType = "invoice"
	EmailRecordTypeSalesOrder    EmailRecordType = "sales_order"
	EmailRecordTypePurchaseOrder EmailRecordType = "purchase_order"
)

func (EmailRecordType) EnumValues

func (t EmailRecordType) EnumValues() []string

func (EmailRecordType) IsValid

func (t EmailRecordType) IsValid() bool

type EnqueueGenerationParams

type EnqueueGenerationParams struct {
	AccountID string
	// ScheduleID is the placeholder row the consumer solves into. It exists before the message is published, so a tick that enqueued and then died still leaves a record the reaper can fail rather than the generation vanishing without trace.
	ScheduleID   string
	PlanningAsOf time.Time
	AutoPublish  bool
}

type EstimateRateParams

type EstimateRateParams struct {
	AccountID      string
	CarrierID      string
	ServiceLevelID string
	ProductLineIDs []string
	CustomerID     *string
	FromAddress    ShippingAddress
	ToAddress      ShippingAddress
	Parcels        []Parcel
	OrderTotal     *float64
	// Billing, when set, bills freight to a third party (matches Dashboard's
	// createShippingLine, which passes THIRD_PARTY billing to Shippo for
	// third-party-billed orders).
	Billing *ShippingBilling
}

EstimateRateParams holds the parameters for estimating a shipping rate.

type ExecuteProductionStepEvent

type ExecuteProductionStepEvent struct {
	ProductionStepID  string  `json:"production_step_id"`
	ScanningStationID string  `json:"scanning_station_id"`
	ItemID            string  `json:"item_id"`
	BatchQuantityID   string  `json:"batch_quantity_id"`
	BatchMeasure      string  `json:"batch_measure"`
	BatchUnitID       string  `json:"batch_unit_id"`
	ResponsibleUserID *string `json:"responsible_user_id,omitempty"`
	ProducedBatchID   *string `json:"produced_batch_id,omitempty"`
	ProduceInventory  bool    `json:"produce_inventory"`
}

ExecuteProductionStepEvent is the outbox event payload for executing a production step side-effect.

Superseded by BatchScannedEvent, which states the scan as a fact and lets any number of consumers react, rather than naming one reaction and needing a second message to carry seconds and waste. Not marked deprecated because the Go batch service still has nothing else to publish.

TODO: migrate batch_service.go's enqueueExecuteProductionStep to publish BatchScannedEvent. The mapping is not one-to-one: the pairs of calls that follow a scrapped batch — one with ProduceInventory true, one false carrying the seconds and waste — collapse into a single event with those measures on it. Once nothing publishes this, the type, its queue and ExecuteProductionStepConsumer can all go.

type Export

type Export struct {
	ContentType string
	Body        []byte
	RowCount    int32
}

carries a rendered export (name is derived from the job)

type ExportBuilder

type ExportBuilder func(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

builds an export's file from the filters its job recorded

type ExportDepartmentsParams

type ExportDepartmentsParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

DepartmentScanningStation is a scanning station sub-resource attached to a department. carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportHubspotCompanyReviewsParams

type ExportHubspotCompanyReviewsParams struct {
	JobID  string
	Status *string
}

ExportHubspotCompanyReviewsParams filters which of a job's reviews land in the exported file. There is no account field: the export engine narrows to the caller's account, and the job's own ownership check is what scopes the rows.

type ExportInventoryChangeLogsParams

type ExportInventoryChangeLogsParams struct {
	AccountID        string
	ItemIDs          []string
	ActionTypeCodes  []string
	ChangedByUserIDs []string
	StartDate        *time.Time
	EndDate          *time.Time
}

ExportInventoryChangeLogsParams contains the parameters for exporting inventory change logs.

type ExportItem

type ExportItem struct {
	Item
	OnHandQuantity string
	OnHandUnitID   string
}

ExportItem represents an item with inventory for export.

type ExportItemCategoriesParams

type ExportItemCategoriesParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

ItemCategoryFull represents a full item category with optional joined data. carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportItemsResult

type ExportItemsResult struct {
	Items []*ExportItem
	Count int64
}

ExportItemsResult represents the export response.

type ExportLocationsParams

type ExportLocationsParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

Location represents a location within an account. carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportMachinesParams

type ExportMachinesParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportMaterialsParams

type ExportMaterialsParams struct {
	AccountID    string
	Query        *string
	CategoryIDs  []string
	AttributeIDs []string
	StartDate    *time.Time
	EndDate      *time.Time
}

ExportMaterialsParams holds filter parameters for a full (unpaginated) material export.

type ExportPartsParams

type ExportPartsParams struct {
	AccountID    string
	Query        *string
	CategoryIDs  []string
	AttributeIDs []string
	StartDate    *time.Time
	EndDate      *time.Time
}

ExportPartsParams holds filter parameters for a full (unpaginated) part export.

type ExportPriceListParams

type ExportPriceListParams struct {
	CustomerAccountID string
}

ExportPriceListParams names the customer whose price list is being exported.

type ExportProductLinesParams

type ExportProductLinesParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportProductionRunsParams

type ExportProductionRunsParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

ProductionRun represents a full production run domain model. carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportProductionStepsParams

type ExportProductionStepsParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

ProductionStepDetail is the full production step with its production and consumptions. carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportProductsParams

type ExportProductsParams struct {
	AccountID      string
	Query          *string
	CustomerIDs    []string
	ProductLineIDs []string
	CategoryIDs    []string
	AttributeIDs   []string
	StartDate      *time.Time
	EndDate        *time.Time
	IsPortalReady  *bool
}

ExportProductsParams holds filter parameters for a full (unpaginated) product export.

type ExportPropertiesParams

type ExportPropertiesParams struct {
	AccountID string
	Query     *string
}

filters which properties land in an exported file

type ExportScanningStationsParams

type ExportScanningStationsParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportSvc

type ExportSvc interface {
	DownloadURL(ctx context.Context, job *Job) (string, *apierror.APIError)
}

serves the read side of an export. The job passed in was already read under permission, so nothing here checks one.

type ExportUnitGroupsParams

type ExportUnitGroupsParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

UnitGroupFull represents a full unit group with its base unit and conversions. carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type ExportUnitsParams

type ExportUnitsParams struct {
	AccountID string
	Query     *string
	Limit     int32
}

carries an export's filters — the list params without pagination, plus the cap that keeps one request from building an unbounded workbook

type FailJobParams

type FailJobParams struct {
	JobID  string
	ApiErr *apierror.APIError
}

type FetchAllShippingRatesParams

type FetchAllShippingRatesParams struct {
	CarrierAccountObjectID string
	FromAddress            ShippingAddress
	ToAddress              ShippingAddress
	Parcels                []Parcel
}

FetchAllShippingRatesParams contains the parameters for fetching all shipping rates.

type FetchShippingRateParams

type FetchShippingRateParams struct {
	CarrierAccountObjectID string
	ServiceLevelToken      string
	FromAddress            ShippingAddress
	ToAddress              ShippingAddress
	Parcels                []Parcel
	// Billing, when set, bills freight to a third party (Shippo shipment extra).
	Billing *ShippingBilling
}

FetchShippingRateParams contains the parameters for fetching a shipping rate.

type FindOrderDiscountByCodeParams

type FindOrderDiscountByCodeParams struct {
	AccountID      string
	Code           string
	BuyerAccountID *string
	SalesOrderID   *string
}

type FinishingBatchRow

type FinishingBatchRow struct {
	Measurement scheduling.BatchMeasurement
	// QuantityUnitID and QuantityUnitRatio are the unit the finished good is scanned in. The plan is denominated in the greige's unit, so a SKU scanned in a different one has its rate converted rather than taken at face value.
	QuantityUnitID    *string
	QuantityUnitRatio float64
	ProductionStepID  *string
	// StepDepartmentID is the room the step belongs to, carried out so a finishing line can name where it runs without a second query.
	StepDepartmentID *string
}

FinishingBatchRow is one historical second-stage batch, plus the scan metadata the input assembly needs alongside the measurement.

type FlowRate

type FlowRate struct {
	ID                string
	Value             string
	NumeratorUnitID   string
	DenominatorUnitID string
}

FlowRate represents a rate value with numerator and denominator unit references.

type FrequentlyOrderedProduct

type FrequentlyOrderedProduct struct {
	ItemID           string
	ProductName      string
	UnitID           *string
	UnitAbbreviation *string
	OrderCount       int32
}

FrequentlyOrderedProduct represents a product frequently ordered by a customer.

type FrozenAdherence

type FrozenAdherence struct {
	ScheduleID      string
	Version         int32
	FrozenLineCount int64
	// FrozenPlannedQuantity is the quantity captured at publish, never recomputed, so the denominator cannot drift as lines are added later.
	FrozenPlannedQuantity float64

	DeviatedLines int64
	AddedLines    int64
	AbsDeltaUnits float64
	// OffPlanLines counts campaigns the floor ran inside the frozen window on a scheduled machine that the frozen plan never called for. Working around a commitment breaks it as surely as editing it does, so it scores the same way.
	OffPlanLines    int64
	OffPlanQuantity float64
	LineAdherence   *float64
	UnitsAdherence  *float64
	FrozenThroughAt *time.Time
}

FrozenAdherence measures how well a published commitment survived contact with the week it covered.

type FrozenLineTotals

type FrozenLineTotals struct {
	LineCount       int64
	PlannedQuantity float64
}

type FulfillmentRecommendation

type FulfillmentRecommendation struct {
	scheduling.Recommendation
	// Description is the item's own description, carried for display only — a SKU alone does not tell a planner what they are deciding about. Empty when the item has none.
	Description string
	// ProductLineID is the line the item sells under, empty when it sells under none.
	ProductLineID string
	// MixedStreamShare is the percentage of this item's demand coming from customers whose own policy disagrees with the recommendation. A high share means the single-policy-per-SKU model is straining on this item.
	MixedStreamShare float64
}

FulfillmentRecommendation is the engine's advice for one item, with the measurements behind it.

type GenerateProductionScheduleParams

type GenerateProductionScheduleParams struct {
	AccountID    string
	PlanningAsOf time.Time
	HorizonWeeks int
	DemandBasis  string
	Name         *string
	SourceCode   string
}

GenerateProductionScheduleParams drives a solve-and-persist.

type GenerationCadence

type GenerationCadence struct {
	AccountID       string
	Cron            string
	Timezone        string
	AutoPublish     bool
	LastGeneratedAt *time.Time
	CreatedAt       time.Time
}

GenerationCadence is one account's request for a schedule on a timer.

type Geolocation

type Geolocation struct {
	ID            string
	StreetLine1   *string  `audit:"street_line_1"`
	StreetLine2   *string  `audit:"street_line_2"`
	Locality      *string  `audit:"locality"`
	State         *string  `audit:"state"`
	PostalCode    *string  `audit:"postal_code"`
	Country       string   `audit:"country"`
	GooglePlaceID *string  `audit:"google_place_id"`
	Latitude      *float64 `audit:"latitude"`
	Longitude     *float64 `audit:"longitude"`
	// Timezone is the IANA zone resolved from country and state on write. Nil means it has not been resolved yet, and readers fall back to deriving it.
	Timezone *string `audit:"timezone"`
}

Geolocation represents a geographic location.

type GetAddressParams

type GetAddressParams struct {
	AccountID string
	AddressID string
}

GetAddressParams contains the parameters for getting a single address.

type GetAttributeParams

type GetAttributeParams struct {
	AttributeID string
	PropertyID  string
	AccountID   string
}

GetAttributeParams holds the parameters for getting a single attribute.

type GetCarrierParams

type GetCarrierParams struct {
	AccountID string
	CarrierID string
	Includes  []string
}

type GetConstraintBatchMeasurementsParams

type GetConstraintBatchMeasurementsParams struct {
	AccountID   string
	WindowStart time.Time
	WindowEnd   time.Time
	MachineIDs  []string
	// ConstraintDepartmentID scopes measurements to batches whose production step belongs to the constraint department, so scans from other stages recorded against a constraint machine do not enter the plan.
	ConstraintDepartmentID string
}

GetConstraintBatchMeasurementsParams scopes the batch-history read to one account, one demand window and the constraint machines.

type GetConsumptionParams

type GetConsumptionParams struct {
	ScanningStationID string
	BatchIDs          []string
	ProductionStepID  *string
	SplitQuantity     *BatchQuantity
}

GetConsumptionParams holds the parameters for getting scanning station consumption.

type GetDCLocationParams

type GetDCLocationParams struct {
	OwnerAccountID string
	DCLocationID   string
}

type GetDeliveryParams

type GetDeliveryParams struct {
	AccountID  string
	DeliveryID string
}

GetDeliveryParams holds parameters for getting a single delivery.

type GetDemandForecastParams

type GetDemandForecastParams struct {
	AccountID      string
	ProductLineIDs []string
	ItemIDs        []string
	HistoryMonths  *int32
	ForecastMonths *int32
}

type GetDemandForecastWindowParams

type GetDemandForecastWindowParams struct {
	AccountID string
	StartDate time.Time
	EndDate   time.Time
}

GetDemandForecastWindowParams bounds the raw monthly demand/revenue reads used to build the demand forecast.

type GetDemandOverrideParams

type GetDemandOverrideParams struct {
	AccountID  string
	OverrideID string
}

type GetDepartmentParams

type GetDepartmentParams struct {
	AccountID    string
	DepartmentID string
}

type GetEmailLogParams

type GetEmailLogParams struct {
	AccountID  string
	EmailLogID string
	Includes   []string
}

type GetFinishingBatchMeasurementsParams

type GetFinishingBatchMeasurementsParams struct {
	AccountID   string
	WindowStart time.Time
	WindowEnd   time.Time
	// ItemIDs are the finished goods to measure. Scoped by item rather than by machine because a finished good passes through several rooms and the plan needs its whole cost, not one room's share.
	ItemIDs []string
	// ConstraintDepartmentID is excluded: a knitting scan recorded against a finishing machine is not a measurement of finishing.
	ConstraintDepartmentID string
}

GetFinishingBatchMeasurementsParams asks for the second stage's production history: scans of the given finished goods anywhere outside the constraint department.

type GetInvoiceParams

type GetInvoiceParams struct {
	AccountID string
	InvoiceID string
	Includes  []string
}

GetInvoiceParams holds parameters for getting a single invoice.

type GetItemCategoryParams

type GetItemCategoryParams struct {
	AccountID      string
	ItemCategoryID string
	Includes       []string
}

type GetItemParams

type GetItemParams struct {
	AccountID string
	ItemID    string
	Includes  []string
}

type GetLocationParams

type GetLocationParams struct {
	AccountID  string
	LocationID string
	Includes   []string
}

GetLocationParams contains the parameters for getting a single location.

type GetLocationTypeParams

type GetLocationTypeParams struct {
	Identifier string
}

GetLocationTypeParams contains the parameters for getting a single location type.

type GetMachineDowntimeEventParams

type GetMachineDowntimeEventParams struct {
	AccountID string
	EventID   string
}

type GetMachineParams

type GetMachineParams struct {
	AccountID string
	MachineID string
}

type GetMaterialParams

type GetMaterialParams struct {
	AccountID  string
	MaterialID string
	Includes   []string
}

type GetNewCustomersAnalyticsParams

type GetNewCustomersAnalyticsParams struct {
	AccountID        string
	StartDate        time.Time
	EndDate          time.Time
	CustomerGroupIDs []string
	SalesRepIDs      []string
}

type GetOeeWindowParams

type GetOeeWindowParams struct {
	AccountID string
	StartDate time.Time
	EndDate   time.Time
}

GetOeeWindowParams bounds the raw OEE reads for one account and reporting window.

type GetOrderDiscountParams

type GetOrderDiscountParams struct {
	AccountID       string
	OrderDiscountID string
}

type GetOrderQuantityByProductLineParams

type GetOrderQuantityByProductLineParams struct {
	AccountID     string
	ProductLineID string
	StartDate     time.Time
	EndDate       time.Time
}

GetOrderQuantityByProductLineParams scopes ordered-quantity aggregation to one product line and time window.

type GetPartParams

type GetPartParams struct {
	AccountID string
	PartID    string
	Includes  []string
}

type GetPaymentTermParams

type GetPaymentTermParams struct {
	AccountID     string
	PaymentTermID string
}

type GetPickShipmentsParams

type GetPickShipmentsParams struct {
	AccountID string
	PickID    string
	Query     *string
	Limit     int32
	Offset    int32
}

GetPickShipmentsParams holds the parameters for getting shipment numbers for a pick.

type GetPooledOrderDemandParams

type GetPooledOrderDemandParams struct {
	AccountID   string
	WindowStart time.Time
	WindowEnd   time.Time
	ProductIDs  []string
}

GetPooledOrderDemandParams scopes the order-demand read to one account, one history window and a set of products.

type GetProductFullParams

type GetProductFullParams struct {
	AccountID string
	ProductID string
	Includes  []string
}

GetProductFullParams holds parameters for retrieving a single product.

type GetProductLineParams

type GetProductLineParams struct {
	AccountID     string
	ProductLineID string
	Includes      []string
}

type GetProductionRunParams

type GetProductionRunParams struct {
	ProductionRunID string
	AccountID       string
}

GetProductionRunParams holds the parameters for getting a single production run.

type GetProductionScheduleParams

type GetProductionScheduleParams struct {
	AccountID  string
	ScheduleID string
}

type GetPropertyParams

type GetPropertyParams struct {
	PropertyID string
	AccountID  string
}

GetPropertyParams holds the parameters for getting a single property.

type GetPurchaseOrderParams

type GetPurchaseOrderParams struct {
	PurchaseOrderID string
	AccountID       string
	Includes        []string
}

GetPurchaseOrderParams holds the parameters for getting a single purchase order.

type GetReceivingOrderParams

type GetReceivingOrderParams struct {
	AccountID        string
	ReceivingOrderID string
}

GetReceivingOrderParams holds parameters for getting a single receiving order.

type GetSalesOrderParams

type GetSalesOrderParams struct {
	SalesOrderID   string
	AccountID      string
	BuyerAccountID *string
	Includes       []string
}

GetSalesOrderParams holds the parameters for getting a single sales order.

type GetScanningStationParams

type GetScanningStationParams struct {
	AccountID         string
	ScanningStationID string
	Includes          []string
}

type GetSeedBatchesParams

type GetSeedBatchesParams struct {
	AccountID   string
	ItemIDs     []string
	WindowStart time.Time
	WindowEnd   time.Time
}

GetSeedBatchesParams bounds the genealogy seeds to the demand window, matching the batch-measurement window.

type GetSettlementParams

type GetSettlementParams struct {
	AccountID    string
	SettlementID string
	Includes     []string
}

GetSettlementParams holds parameters for getting a single settlement.

type GetShipmentParams

type GetShipmentParams struct {
	AccountID  string
	ShipmentID string
	Includes   []string
}

GetShipmentParams holds the parameters for getting a shipment.

type GetShippingTermParams

type GetShippingTermParams struct {
	AccountID      string
	ShippingTermID string
	Includes       []string
}

type GetSupplierParams

type GetSupplierParams struct {
	OwnerAccountID string
	SupplierID     string
	Includes       []string
}

GetSupplierParams holds the parameters for retrieving a single supplier.

type GetTerritoryParams

type GetTerritoryParams struct {
	AccountID   string
	TerritoryID string
	Includes    []string
}

GetTerritoryParams contains the parameters for getting a territory.

type GetTransactionParams

type GetTransactionParams struct {
	AccountID     string
	TransactionID string
	Includes      []string
}

GetTransactionParams holds parameters for getting a single transaction.

type GetUnitGroupParams

type GetUnitGroupParams struct {
	AccountID   string
	UnitGroupID string
	Includes    []string
}

type GetUnitGroupUnitParams

type GetUnitGroupUnitParams struct {
	AccountID       string
	UnitGroupID     string
	UnitGroupUnitID string
	Includes        []string
}

type GetUnitParams

type GetUnitParams struct {
	AccountID string
	UnitID    string
}

type GetVolumeDiscountParams

type GetVolumeDiscountParams struct {
	AccountID         string
	VolumeDiscountID  string
	CustomerAccountID *string
	Includes          []string
}

type HandleStripeWebhookParams

type HandleStripeWebhookParams struct {
	AccountID       string
	RawPayload      []byte
	StripeSignature string
}

HandleStripeWebhookParams holds the parameters for processing an account Stripe webhook.

type HubspotClient

type HubspotClient interface {
	// EnsureDealProperties creates any custom deal properties the sync depends on (e.g. augno_sales_order_id) if absent. Idempotent.
	EnsureDealProperties(ctx context.Context) *apierror.APIError

	SearchCompaniesByDomain(ctx context.Context, domain string) ([]HubspotCompany, *apierror.APIError)
	SearchCompaniesByName(ctx context.Context, name string) ([]HubspotCompany, *apierror.APIError)
	// ListCompanies returns one page of companies and the cursor for the next page ("" when exhausted). Used by the backfill.
	ListCompanies(ctx context.Context, cursor string) (page []HubspotCompany, next string, err *apierror.APIError)
	CreateCompany(ctx context.Context, company HubspotCompany) (*HubspotCompany, *apierror.APIError)
	UpdateCompany(ctx context.Context, id string, company HubspotCompany) *apierror.APIError

	// UpsertContactByEmail creates or updates a contact keyed on email (HubSpot's native dedupe key).
	UpsertContactByEmail(ctx context.Context, contact HubspotContact) (*HubspotContact, *apierror.APIError)

	// SearchDealBySalesOrderID finds an existing deal by its augno_sales_order_id property, or returns (nil, nil).
	SearchDealBySalesOrderID(ctx context.Context, salesOrderID string) (*HubspotDeal, *apierror.APIError)
	CreateDeal(ctx context.Context, deal HubspotDeal) (*HubspotDeal, *apierror.APIError)
	UpdateDeal(ctx context.Context, id string, deal HubspotDeal) *apierror.APIError

	// Associate links two CRM objects using the default association type (e.g. deals→companies). Types are HubSpot plural object names.
	Associate(ctx context.Context, fromType, fromID, toType, toID string) *apierror.APIError
}

HubspotClient performs HubSpot CRM operations for a single account's connected integration.

type HubspotClientFactory

type HubspotClientFactory interface {
	Build(accessToken string) HubspotClient
}

HubspotClientFactory builds HubspotClient instances from a decrypted access token.

type HubspotCompany

type HubspotCompany struct {
	ID     string
	Name   string
	Domain string
	// Lifecycle, when non-empty, sets the company's lifecyclestage (e.g. "customer"). Empty leaves it unchanged.
	Lifecycle string
}

HubspotCompany is the subset of a HubSpot company the sync reads or writes.

type HubspotCompanyReview

type HubspotCompanyReview struct {
	ID              string
	JobID           string `audit:"job_id"`
	AccountID       string `audit:"account_id"`
	AugnoCustomerID string `audit:"augno_customer_id"`
	CustomerName    string `audit:"customer_name"`
	// CustomerEmail and CustomerURL snapshot the customer's contact details at preview time, so a reviewer resolving a match has what they need to identify the company without a second lookup.
	CustomerEmail     *string `audit:"customer_email"`
	CustomerURL       *string `audit:"customer_url"`
	CandidateMatches  json.RawMessage
	Status            string  `audit:"status"`
	Resolution        *string `audit:"resolution"`
	ResolvedHubspotID *string `audit:"resolved_hubspot_id"`
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

HubspotCompanyReview is one customer that needs human resolution before the backfill can create/link its HubSpot company.

type HubspotContact

type HubspotContact struct {
	ID        string
	Email     string
	FirstName string
	LastName  string
	Phone     string
	// Lifecycle, when non-empty, sets the contact's lifecyclestage. Empty leaves it unchanged.
	Lifecycle string
}

HubspotContact is the subset of a HubSpot contact the sync reads or writes.

type HubspotCredentials

type HubspotCredentials struct {
	AccessToken string `json:"access_token"` // #nosec G117 -- field carries encrypted credentials, not a hardcoded secret
}

HubspotCredentials holds the parsed HubSpot credential fields used for validation.

type HubspotDeal

type HubspotDeal struct {
	ID   string
	Name string
	// Amount is the deal value as a decimal string, written to HubSpot's standard `amount` property.
	Amount    string
	CloseDate time.Time
	// PipelineID and StageID select the deal's pipeline and stage (e.g. Closed Won).
	PipelineID string
	StageID    string
	// SalesOrderID is the OpenMRP order id, stored on the deal's augno_sales_order_id property for idempotent upserts.
	SalesOrderID string
}

HubspotDeal is the subset of a HubSpot deal the sync reads or writes.

type HubspotSyncJob

type HubspotSyncJob struct {
	ID             string
	AccountID      string     `audit:"account_id"`
	Status         string     `audit:"status"`
	GoLiveCutoffAt *time.Time `audit:"go_live_cutoff_at"`
	Cursors        json.RawMessage
	Counts         json.RawMessage
	LastError      *string    `audit:"last_error"`
	StartedAt      *time.Time `audit:"started_at"`
	CompletedAt    *time.Time `audit:"completed_at"`
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

HubspotSyncJob is one backfill/reconciliation run for an account. See the hubspot_sync_job table and the hubspotsync package for the state machine.

type HubspotSyncPublisher

type HubspotSyncPublisher interface {
	// PublishPreview writes a preview command to the outbox for the given backfill job.
	PublishPreview(ctx context.Context, data messaging.HubspotSyncCommandData) *apierror.APIError
	// PublishExecute writes an execute command to the outbox for the given backfill job.
	PublishExecute(ctx context.Context, data messaging.HubspotSyncCommandData) *apierror.APIError
}

HubspotSyncPublisher publishes HubSpot backfill commands via the outbox pattern, so the command commits atomically with the job row.

type HubspotSyncRecord

type HubspotSyncRecord struct {
	ID        string
	AccountID string
	AugnoType string
	AugnoID   string
	// AugnoName is the display name of the mapped OpenMRP entity, resolved by the list query. Empty when the entity no longer exists or was not joined.
	AugnoName    string
	HubspotType  string
	HubspotID    string
	SyncHash     *string
	LastSyncedAt *time.Time
	LastError    *string
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

HubspotSyncRecord maps one OpenMRP entity to its HubSpot counterpart, making sync idempotent across replays and re-runs.

type HubspotSyncRepo

type HubspotSyncRepo interface {
	CreateJob(ctx context.Context, params CreateHubspotSyncJobParams) (*HubspotSyncJob, *apierror.APIError)
	GetJob(ctx context.Context, accountID, id string) (*HubspotSyncJob, *apierror.APIError)
	GetLatestJobForAccount(ctx context.Context, accountID string) (*HubspotSyncJob, *apierror.APIError)
	UpdateJob(ctx context.Context, params UpdateHubspotSyncJobParams) *apierror.APIError
	// ClaimJobForExecute atomically moves a review_pending/failed job to executing, reporting whether this caller won the transition. Losing means another execute already claimed the job.
	ClaimJobForExecute(ctx context.Context, accountID, jobID string) (bool, *apierror.APIError)

	UpsertRecord(ctx context.Context, params UpsertHubspotSyncRecordParams) *apierror.APIError
	GetRecord(ctx context.Context, accountID, augnoType, augnoID string) (*HubspotSyncRecord, *apierror.APIError)
	// ListRecords pages the account's mappings for one OpenMRP type, resolving each entity's display name.
	ListRecords(ctx context.Context, params ListHubspotSyncRecordsParams) (*ListHubspotSyncRecordsResult, *apierror.APIError)

	CreateReview(ctx context.Context, params CreateHubspotCompanyReviewParams) (*HubspotCompanyReview, *apierror.APIError)
	GetReview(ctx context.Context, accountID, id string) (*HubspotCompanyReview, *apierror.APIError)
	// GetReviewsByIDs reads many reviews at once, so a bulk resolution can validate every id it was handed in a single round trip.
	GetReviewsByIDs(ctx context.Context, accountID string, ids []string) ([]*HubspotCompanyReview, *apierror.APIError)
	ListReviewsForJob(ctx context.Context, jobID string, status *string) ([]*HubspotCompanyReview, *apierror.APIError)
	CountPendingReviews(ctx context.Context, jobID string) (int64, *apierror.APIError)
	ResolveReview(ctx context.Context, params ResolveHubspotCompanyReviewParams) *apierror.APIError
}

HubspotSyncRepo persists the HubSpot backfill state: jobs (state machine), the generic OpenMRP->HubSpot id mapping, and the company-match review queue.

type HubspotSyncSvc

type HubspotSyncSvc interface {
	StartBackfill(ctx context.Context, params StartHubspotBackfillParams) (*HubspotSyncJob, *apierror.APIError)
	// GetCurrentJob returns the account's most recent backfill job, or a not-found error when none exists. Used by the dashboard to resume an in-progress sync after a refresh.
	GetCurrentJob(ctx context.Context) (*HubspotSyncJob, *apierror.APIError)
	GetJob(ctx context.Context, jobID string) (*HubspotSyncJob, *apierror.APIError)
	ListReviews(ctx context.Context, jobID string, status *string) ([]*HubspotCompanyReview, *apierror.APIError)
	// ListRecords returns what the sync has actually written to HubSpot for the caller's account — the mapping the engine keeps, which is otherwise invisible.
	ListRecords(ctx context.Context, params ListHubspotSyncRecordsParams) (*ListHubspotSyncRecordsResult, *apierror.APIError)
	ResolveReview(ctx context.Context, params ResolveHubspotReviewParams) (*HubspotCompanyReview, *apierror.APIError)
	// BulkResolveReviews records many decisions as one async job, so a reviewed spreadsheet applies in a single request instead of one per row.
	BulkResolveReviews(ctx context.Context, params BulkResolveHubspotReviewsParams) (*Job, *apierror.APIError)
	// ExecuteBulkResolveReviews performs the writes for an enqueued bulk resolution.
	ExecuteBulkResolveReviews(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError
	// ExportReviews accepts an export of a job's review queue and returns the job that tracks it.
	ExportReviews(ctx context.Context, params ExportHubspotCompanyReviewsParams) (*Job, *apierror.APIError)
	// BuildExportHubspotCompanyReviews renders the file an accepted export recorded.
	BuildExportHubspotCompanyReviews(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)
	StartExecute(ctx context.Context, jobID string) (*HubspotSyncJob, *apierror.APIError)
	// CancelJob force-fails an in-flight job, releasing the account to start a new backfill after a worker died without recording an outcome.
	CancelJob(ctx context.Context, jobID string) (*HubspotSyncJob, *apierror.APIError)
}

HubspotSyncSvc is the application service for the HubSpot backfill: starting a job (which dispatches the preview command), reading job status, managing the company-review queue, and triggering execute. The target account and authorization are derived from the request identity.

type IdempotencyKey

type IdempotencyKey struct {
	ID             int64
	TypeID         string
	ServiceName    string
	Handler        string
	IdempotencyKey string
	ActorID        *string
	IdentityType   string
	ScopeHash      string
	ResponseCode   *int
	ResponseBody   json.RawMessage
	RecoveryPoint  string
}

func (*IdempotencyKey) HasResponse

func (k *IdempotencyKey) HasResponse() bool

func (*IdempotencyKey) IsFinished

func (k *IdempotencyKey) IsFinished() bool

type IdempotencyKeyRepo

type IdempotencyKeyRepo interface {
	GetByScopeHash(ctx context.Context, scopeHash string) (*IdempotencyKey, *apierror.APIError)
	Create(ctx context.Context, key *IdempotencyKey) (*IdempotencyKey, *apierror.APIError)
	AdvanceRecoveryPoint(ctx context.Context, typeID string, recoveryPoint RecoveryPoint) *apierror.APIError
	GetRecoveryPoint(ctx context.Context, typeID string) (RecoveryPoint, *apierror.APIError)
	SetResponse(ctx context.Context, typeID string, code int, body json.RawMessage, recoveryPoint RecoveryPoint) *apierror.APIError
}

type IdempotencyMed

type IdempotencyMed interface {
	// UpsertIdempotencyKey returns the existing idempotency key for the request scope, or creates one if it does not exist.
	//
	//  1. Resolve the idempotency key from the request context, falling back to the request ID.
	//  2. Compute the scope hash from the actor, target account, service, handler, and key.
	//  3. Return the existing key for the scope hash when one exists.
	//  4. Otherwise persist a new key at the Started recovery point, re-fetching the existing row if a concurrent request inserted the same scope hash first.
	UpsertIdempotencyKey(ctx context.Context, identity *types.Identity) (*IdempotencyKey, *apierror.APIError)

	// CacheErrorResponse caches a non-transient error response for the given idempotency key and returns the original error.
	//
	//  1. Return transient errors uncached so the client can retry.
	//  2. Persist non-transient errors as the cached response and mark the key finished.
	CacheErrorResponse(ctx context.Context, typeID string, apiErr *apierror.APIError) *apierror.APIError

	// CacheSuccessResponse caches a successful response for the given idempotency key.
	//
	//  1. Marshal the response data to JSON.
	//  2. Persist it as the cached response and mark the key finished.
	CacheSuccessResponse(ctx context.Context, typeID string, data any) *apierror.APIError
}

type IncompleteRegistrationSession

type IncompleteRegistrationSession struct {
	SessionID string
	PlanCode  string
	Step      string
	CreatedAt time.Time
}

IncompleteRegistrationSession is the subset of a pending registration session returned to the tenancy response.

type InsertMaterialItemParams

type InsertMaterialItemParams struct {
	ItemID          string
	AccountID       string
	SKU             string
	Description     *string
	Notes           *string
	CategoryID      string
	UnitValueRateID string
	UnitCostRateID  string
	BurnRateRateID  string
}

InsertMaterialItemParams is the input for writing a material's item row. It carries the service-generated IDs (item id + the three rate ids) alongside the item's caller-provided fields, so the generated IDs stay out of CreateMaterialParams.

type InsertProductItemParams

type InsertProductItemParams struct {
	ItemID          string
	AccountID       string
	SKU             string
	Description     *string
	Notes           *string
	CategoryID      string
	UnitValueRateID string
	UnitCostRateID  string
	BurnRateRateID  string
}

InsertProductItemParams is the input for writing a product's item row. It carries the service-generated IDs (item id + the three rate ids) alongside the item's caller-provided fields, so the generated IDs stay out of CreateProductParams.

type InventoryChangeLog

type InventoryChangeLog struct {
	ID                            string
	ItemID                        string
	ItemSKU                       string
	ItemCreatedAt                 time.Time
	ItemUpdatedAt                 time.Time
	QuantityID                    string
	QuantityValue                 string
	QuantityUnitID                string
	QuantityUnitName              string
	QuantityUnitAbbreviation      string
	QuantityUnitType              string
	QuantityUnitRatioNumerator    string
	QuantityUnitRatioDenominator  string
	QuantityUnitOffsetNumerator   string
	QuantityUnitOffsetDenominator string
	QuantityUnitCreatedAt         time.Time
	QuantityUnitUpdatedAt         time.Time
	ActionTypeCode                string
	ScanningStationID             *string
	ScanningStationName           *string
	ScanningStationType           *string
	ScanningStationCreatedAt      *time.Time
	ScanningStationUpdatedAt      *time.Time
	ItemTypeCode                  *string
	ResponsibleUserID             *string
	ResponsibleUserName           *string
	ResponsibleUserCreatedAt      *time.Time
	ResponsibleUserUpdatedAt      *time.Time
	AccountID                     string
	CreatedAt                     time.Time
	UpdatedAt                     time.Time
}

InventoryChangeLog represents a single inventory change log entry.

type InventoryChangeLogSvc

type InventoryChangeLogSvc interface {
	// ListInventoryChangeLogs returns a paginated list of inventory change logs for the caller's account.
	ListInventoryChangeLogs(ctx context.Context, params ListInventoryChangeLogsParams) (*ListInventoryChangeLogsResult, *apierror.APIError)

	// GetInventoryChangeLog returns a single inventory change log by ID.
	GetInventoryChangeLog(ctx context.Context, id string) (*InventoryChangeLog, *apierror.APIError)

	// ExportInventoryChangeLogs returns all inventory change logs matching the provided filters for the caller's account.
	ExportInventoryChangeLogs(ctx context.Context, params ExportInventoryChangeLogsParams) ([]*InventoryChangeLog, *apierror.APIError)
}

type InventoryItemResult

type InventoryItemResult struct {
	Item             *Item
	OnHandQuantity   float64
	OnHandUnitID     string
	OnHandUnitAbbrev string
	OnHandUnitType   string
}

InventoryItemResult represents an item with its on-hand inventory quantity.

type InventoryMutationRepo

type InventoryMutationRepo interface {
	// UpdateInventory creates an inventory receipt (positive measure) or issue (negative measure) for the given item. This is the core inventory mutation used by the executeProductionStep consumer.
	UpdateInventory(ctx context.Context, params InventoryUpdateParams) *apierror.APIError
	// CreateInventoryReceipt creates an inventory receipt for positive delta.
	CreateInventoryReceipt(ctx context.Context, params CreateInventoryReceiptParams) *apierror.APIError
	// CreateInventoryIssue creates an inventory issue for negative delta.
	CreateInventoryIssue(ctx context.Context, params CreateInventoryIssueParams) *apierror.APIError
	// CreateInventoryLog creates a point-in-time inventory snapshot log.
	CreateInventoryLog(ctx context.Context, params CreateInventoryLogParams) *apierror.APIError
	// CreateInventoryChangeLog creates an audit trail entry for an inventory change.
	CreateInventoryChangeLog(ctx context.Context, params CreateInventoryChangeLogParams) *apierror.APIError
	// CreateQuantityForInventory creates a quantity record for use in inventory operations.
	CreateQuantityForInventory(ctx context.Context, quantityID, value, unitID string) *apierror.APIError
	// CreateRateForInventory creates a rate record for use in inventory operations.
	CreateRateForInventory(ctx context.Context, rateID, value, numeratorUnitID, denominatorUnitID string) *apierror.APIError
	// ReverseInventoryForBatch undoes every inventory movement a scan recorded against a batch and returns the corrections it made, so the caller can write the audit trail and re-run allocation. Refuses when the batch's output has already been drawn on, since reversing it would drive inventory negative.
	ReverseInventoryForBatch(ctx context.Context, params ReverseInventoryForBatchParams) ([]InventoryReversalDelta, *apierror.APIError)
	// CountAllocatedReceiptsForBatch reports how many of a batch's produced receipts have already been drawn against. Used as a pre-flight guard before a batch is deleted.
	CountAllocatedReceiptsForBatch(ctx context.Context, accountID, batchID string) (int64, *apierror.APIError)
	// ReverseInventoryForOrderItem hands a consumed measure back to the order's reservation, walking the issues it opened newest first and splitting the last one when it overshoots. The caller re-runs FIFO allocation so the freed receipts can cover other open issues.
	ReverseInventoryForOrderItem(ctx context.Context, accountID, orderID, itemID string, measure decimal.Decimal) *apierror.APIError
}

InventoryMutationRepo handles inventory receipt and issue creation for production step execution.

type InventoryQueryRepo

type InventoryQueryRepo interface {
	FetchCurrentInventory(ctx context.Context, itemID, ownerAccountID string) (*InventorySnapshot, *apierror.APIError)
	FetchOnHandInventoryBulk(ctx context.Context, itemIDs []string, ownerAccountID string) ([]*BulkOnHandInventory, *apierror.APIError)
	FetchPhysicalInventory(ctx context.Context, itemID, ownerAccountID, unitID string) (decimal.Decimal, *apierror.APIError)
	// FetchPhysicalInventoryBaseForItems returns each item's physical inventory in base units, so the batch-scan audit trail can level many items with one query instead of one per item.
	FetchPhysicalInventoryBaseForItems(ctx context.Context, accountID string, itemIDs []string) (map[string]decimal.Decimal, *apierror.APIError)
}

InventoryQueryRepo provides read-only access to inventory data.

type InventoryReceiptEntry

type InventoryReceiptEntry struct {
	ItemID                          string
	ProductSku                      string
	ProductDescription              *string
	LocationID                      *string
	LocationName                    *string
	LotID                           *string
	LotNumber                       *string
	OwnerAccountID                  string
	OwnerAccountName                string
	HolderAccountID                 string
	HolderAccountName               string
	RemainingQuantity               float64
	WeightedAverageUnitCost         float64
	InventoryValue                  float64
	OldestReceiptAt                 *time.Time
	NewestReceiptAt                 *time.Time
	Unit                            string
	UnitName                        string
	CostNumeratorUnitAbbreviation   string
	CostNumeratorUnitName           string
	CostDenominatorUnitAbbreviation string
	CostDenominatorUnitName         string
}

type InventoryReceivedEvent

type InventoryReceivedEvent struct {
	AccountID string `json:"account_id"`
	// ItemIDs are the items whose stock moved. Carried as a set because one cause — a scan, a
	// receipt against a purchase order — usually moves several at once, and a message per item would
	// multiply the round trips without changing what gets done.
	ItemIDs []string `json:"item_ids"`
	// Reason names what moved the stock, for tracing rather than for logic.
	Reason string `json:"reason,omitempty"`
}

InventoryReceivedEvent states that stock of an item became available.

Allocation is one reaction: an issue that went short because the shelf could not cover it is filled when what it was waiting for arrives, rather than whenever a nightly sweep next runs.

type InventoryReservationRepo

type InventoryReservationRepo interface {
	// CreateMaterialReservation creates a reserved inventory issue for a material demand linked to an order.
	CreateMaterialReservation(ctx context.Context, params CreateMaterialReservationParams) *apierror.APIError
	// ReduceReservedForOrderItem reduces the reserved quantity for an order item by the given shortfall amount.
	ReduceReservedForOrderItem(ctx context.Context, params OrderReservationReductionParams) *apierror.APIError
	// ReduceReservedForOrderMaterials reduces reserved quantities for upstream materials of an order.
	ReduceReservedForOrderMaterials(ctx context.Context, orderID, accountID string, demands []MaterialDemandItem) *apierror.APIError
	// AllocateReservationsForConsumption allocates existing reservations for consumed materials. Returns the remaining quantity that could not be allocated from reservations.
	AllocateReservationsForConsumption(ctx context.Context, params ConsumptionAllocationParams) (*ConsumptionAllocationResult, *apierror.APIError)
	// AllocateOpenIssuesForItem performs FIFO allocation of all open inventory issues for the given item against available receipts. Used after receiving inventory.
	AllocateOpenIssuesForItem(ctx context.Context, accountID, itemID string) *apierror.APIError
	// AllocateOpenIssuesForItemPage allocates one page (up to limit, oldest first, resuming after the (afterCreatedAt, afterID) cursor) of the item's open issues against available receipts. Returns the (created_at, id) of the last issue processed and how many the page held.
	AllocateOpenIssuesForItemPage(ctx context.Context, accountID, itemID string, afterCreatedAt time.Time, afterID string, limit int32) (time.Time, string, int, *apierror.APIError)
}

InventoryReservationRepo manages inventory reservations for orders during production step execution.

type InventoryReversalDelta

type InventoryReversalDelta struct {
	ItemID  string
	Measure decimal.Decimal
	UnitID  string
}

InventoryReversalDelta is one correction the reversal made: the signed quantity that moved back, in the unit the reversed row was recorded in. What the batch produced comes back out (negative), what it consumed goes back in (positive).

type InventorySnapshot

type InventorySnapshot struct {
	AvailableToPromiseMeasure          decimal.Decimal
	AvailableToPromiseUnitAbbreviation string
}

InventorySnapshot represents a point-in-time inventory measure for an item.

type InventoryUpdateParams

type InventoryUpdateParams struct {
	AccountID         string
	ItemID            string
	Measure           decimal.Decimal
	UnitID            string
	ActionType        string
	ScanningStationID string
	ResponsibleUserID *string
	BatchID           *string
}

InventoryUpdateParams describes a single inventory change (receipt or issue) to apply after a production step execution. Positive measure = receipt; negative = issue.

type Invoice

type Invoice struct {
	ID                       string
	Number                   string                 `audit:"number"`
	Note                     *string                `audit:"note"`
	OrderID                  string                 `audit:"order_id"`
	OrderNumber              string                 `audit:"order_number"`
	PriorityCode             constants.PriorityCode `audit:"priority_code"`
	CustomerID               string                 `audit:"customer_id"`
	CustomerName             string                 `audit:"customer_name"`
	CustomerNumber           string                 `audit:"customer_number"`
	CustomerStatusCode       *string                `audit:"customer_status_code"`
	CustomerCommissionPolicy *string                `audit:"customer_commission_policy"`
	CustomerIsEdiEnabled     bool                   `audit:"customer_is_edi_enabled"`
	PaymentTermID            *string                `audit:"payment_term_id"`
	PaymentTermName          *string                `audit:"payment_term_name"`
	PaymentTermIsActive      *bool                  `audit:"payment_term_is_active"`
	BillingAddressID         string                 `audit:"billing_address_id"`
	BillingAddressName       *string                `audit:"billing_address_name"`
	BillingAddressLine1      *string                `audit:"billing_address_line_1"`
	BillingAddressLine2      *string                `audit:"billing_address_line_2"`
	BillingAddressCity       *string                `audit:"billing_address_city"`
	BillingAddressState      *string                `audit:"billing_address_state"`
	BillingAddressZip        *string                `audit:"billing_address_zip"`
	BillingAddressCountry    string                 `audit:"billing_address_country"`
	ShipmentID               *string                `audit:"shipment_id"`
	ShipmentNumber           *string                `audit:"shipment_number"`
	LineCount                int32                  `audit:"line_count"`
	TotalInvoiced            string                 `audit:"total_invoiced"`
	IsPaidInFull             bool                   `audit:"is_paid_in_full"`
	IsOverPaid               bool                   `audit:"is_over_paid"`
	IsEdiSent                bool                   `audit:"is_edi_sent"`
	HasBeenSent              bool                   `audit:"has_been_sent"`
	AcceptsInvoiceEmails     bool                   `audit:"accepts_invoice_emails"`
	Lines                    []*InvoiceLine
	Allocations              []*InvoiceAllocation
	CreatedAt                time.Time
	UpdatedAt                time.Time
}

Bills a customer for goods shipped against a sales order; read, list and update all return it.

type InvoiceAllocation

type InvoiceAllocation struct {
	ID             string
	TransactionID  string
	AmountID       string
	AmountValue    string
	AmountUnitID   string
	AmountUnitAbbr string
	Note           *string
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

InvoiceAllocation represents a transaction allocation against an invoice.

type InvoiceAllocationEntry

type InvoiceAllocationEntry struct {
	InvoiceNumber string
	Amount        string
}

InvoiceAllocationEntry represents an allocation against an invoice for the open credits view.

type InvoiceForPayment

type InvoiceForPayment struct {
	ID                 string
	Number             string
	CustomerPO         *string
	CustomerID         string
	CustomerName       string
	CustomerNumber     string
	IsParentAccount    bool
	ParentAccountID    *string
	IsPrepaid          bool
	BillingAddressID   *string
	BillingAddressName *string
	InvoiceTotal       string
	IsPaidInFull       bool
	Allocations        []*InvoiceAllocation
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

InvoiceForPayment represents an invoice in the customer payment context.

type InvoiceLine

type InvoiceLine struct {
	ID                   string
	QuantityID           string
	QuantityValue        string
	QuantityUnitID       string
	QuantityUnitAbbr     string
	QuantityUnitName     string
	UnitPriceID          string
	UnitPriceValue       string
	UnitPriceNumUnit     string
	UnitPriceDenUnit     string
	OrderLineID          string
	OrderLineItemID      *string
	OrderLineItemNumber  *int32
	OrderLineProductID   *string
	OrderLineQtyOrdered  string
	OrderLineItemSKU     *string
	OrderLineDescription *string
	CreatedAt            time.Time
	UpdatedAt            time.Time
}

InvoiceLine represents a line item in an invoice.

type InvoiceLineDraft

type InvoiceLineDraft struct {
	SalesOrderLineID string
	QuantityValue    string
	QuantityUnitID   string
}

Describes one line to write: the order line billed and the quantity billed for it.

type InvoicePaymentFlags

type InvoicePaymentFlags struct {
	InvoiceID    string
	IsPaidInFull bool
	IsOverPaid   bool
}

InvoicePaymentFlags holds the recomputed payment flags for a single invoice, derived from its transaction allocations vs. its invoiced total.

type InvoiceRepo

type InvoiceRepo interface {
	List(ctx context.Context, params ListInvoicesParams) (*ListInvoicesResult, *apierror.APIError)
	Get(ctx context.Context, params GetInvoiceParams) (*Invoice, *apierror.APIError)
	CountSince(ctx context.Context, accountID string, since time.Time) (int64, *apierror.APIError)
	GetLines(ctx context.Context, invoiceID string) ([]*InvoiceLine, *apierror.APIError)
	GetAllocations(ctx context.Context, invoiceID string) ([]*InvoiceAllocation, *apierror.APIError)
	GetAllocationsForInvoices(ctx context.Context, invoiceIDs []string) (map[string][]*InvoiceAllocation, *apierror.APIError)
	Update(ctx context.Context, params UpdateInvoiceParams) (*Invoice, *apierror.APIError)
	ListByCustomer(ctx context.Context, params ListCustomerInvoicesParams) (*ListCustomerInvoicesResult, *apierror.APIError)
	IsDuplicateNumber(ctx context.Context, accountID, number string) (bool, *apierror.APIError)
	GetEmailRecipients(ctx context.Context, invoiceID string) ([]string, *apierror.APIError)
	MarkEmailSent(ctx context.Context, accountID, invoiceID string) *apierror.APIError
	DeleteLinesByInvoice(ctx context.Context, invoiceID string) *apierror.APIError
	Delete(ctx context.Context, accountID, invoiceID string) *apierror.APIError
	// CreateFromShipment writes the invoice a shipment bills for: one line per shipped line plus the
	// order's non-shippable lines (freight/tax/discount/service) at full ordered quantity. Returns
	// the new invoice id.
	CreateFromShipment(ctx context.Context, params CreateInvoiceFromShipmentParams) (string, *apierror.APIError)
}

type InvoiceSvc

type InvoiceSvc interface {
	// ListInvoices returns a paginated list of invoices for the caller's account.
	ListInvoices(ctx context.Context, params ListInvoicesParams) (*ListInvoicesResult, *apierror.APIError)

	// GetInvoice returns a single invoice by ID within the caller's account. Lines and allocations are fetched conditionally based on the includes parameter.
	GetInvoice(ctx context.Context, params GetInvoiceParams) (*Invoice, *apierror.APIError)

	// UpdateInvoice partially updates an invoice with idempotency support.
	UpdateInvoice(ctx context.Context, params UpdateInvoiceParams) (*Invoice, *apierror.APIError)

	// ListCustomerInvoices returns a paginated list of invoices for a customer account.
	ListCustomerInvoices(ctx context.Context, params ListCustomerInvoicesParams) (*ListCustomerInvoicesResult, *apierror.APIError)
}

type Item

type Item struct {
	ID             string
	SKU            string  `audit:"sku"`
	Description    *string `audit:"description"`
	Notes          *string `audit:"notes"`
	ItemTypeCode   string  `audit:"item_type_code"`
	ItemCategoryID string  `audit:"item_category_id"`
	CategoryName   string  `audit:"category_name"`
	UnitValueID    string
	UnitCostID     string
	BurnRateID     string
	AccountID      string
	IsDirty        bool
	CreatedAt      time.Time
	UpdatedAt      time.Time
	DeletedAt      *time.Time

	// Joined data (populated when listing/getting items)
	UnitValue *Rate
	UnitCost  *Rate
	BurnRate  *Rate
	Category  *ItemCategory

	// Many-to-many joined data
	Attributes []*ItemAttribute `audit:"attributes"`
}

Item represents an inventory item (product, material, or part).

type ItemAttribute

type ItemAttribute struct {
	ID         string
	Value      string
	ColorCode  *string
	Order      int32
	PropertyID string
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

ItemAttribute represents an attribute on an item (joined via _item_attributes).

type ItemCategory

type ItemCategory struct {
	ID                   string
	Name                 string
	ItemCategoryTypeCode string
	UnitGroupID          string
	CreatedAt            time.Time
	UpdatedAt            time.Time

	// Joined from unit_group when loading items/materials/products/parts.
	UnitGroupName       string
	UnitGroupTypeCode   string
	UnitGroupBaseUnitID string
	UnitGroupCreatedAt  time.Time
	UnitGroupUpdatedAt  time.Time
	Properties          []ItemCategoryProperty

	// Populated when category.unit_group.base_unit is included.
	UnitGroupBaseUnit *LightUnit
	// Populated when category.unit_group.associated_units is included.
	UnitGroupAssociatedUnits []*UnitGroupUnit
}

ItemCategory represents an item category (joined data).

type ItemCategoryFull

type ItemCategoryFull struct {
	ID                   string
	Name                 string  `audit:"name"`
	Notes                *string `audit:"notes"`
	ItemCategoryTypeCode string  `audit:"item_category_type_code"`
	UnitGroupID          string  `audit:"unit_group_id"`
	AccountID            *string
	CreatedAt            time.Time
	UpdatedAt            time.Time

	// Expandable sub-resources (populated via includes)
	Properties []*ItemCategoryProperty `audit:"properties"`
	UnitGroup  *ItemCategoryUnitGroup
}

type ItemCategoryProperty

type ItemCategoryProperty struct {
	ID        string
	Name      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

ItemCategoryProperty represents a property associated with an item category.

type ItemCategoryRepo

type ItemCategoryRepo interface {
	List(ctx context.Context, params ListItemCategoriesParams) (*ListItemCategoriesResult, *apierror.APIError)
	Export(ctx context.Context, params ExportItemCategoriesParams) ([]*ItemCategoryFull, *apierror.APIError)
	Get(ctx context.Context, params GetItemCategoryParams) (*ItemCategoryFull, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateItemCategoryParams) (*ItemCategoryFull, *apierror.APIError)
	Update(ctx context.Context, params UpdateItemCategoryParams) (*ItemCategoryFull, *apierror.APIError)
	UpdateWithUnitGroup(ctx context.Context, params UpdateItemCategoryWithUnitGroupParams) (*ItemCategoryFull, *apierror.APIError)
	Delete(ctx context.Context, params DeleteItemCategoryParams) *apierror.APIError
	IsInAccount(ctx context.Context, accountID, itemCategoryID string) (bool, *apierror.APIError)
	FindByNames(ctx context.Context, accountID string, names []string) ([]*ItemCategoryFull, *apierror.APIError)
	AddProperty(ctx context.Context, params AddItemCategoryPropertyParams) *apierror.APIError
	UpsertProperty(ctx context.Context, itemCategoryID, propertyID string) *apierror.APIError
	RemoveProperty(ctx context.Context, params RemoveItemCategoryPropertyParams) *apierror.APIError
	ChangeUnitGroup(ctx context.Context, params ChangeItemCategoryUnitGroupParams) *apierror.APIError
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*ItemCategoryFull, *apierror.APIError)
	GetProperties(ctx context.Context, itemCategoryID string) ([]*ItemCategoryProperty, *apierror.APIError)
	GetUnitGroup(ctx context.Context, unitGroupID string, includes []string) (*ItemCategoryUnitGroup, *apierror.APIError)
	IsPropertyInAccount(ctx context.Context, accountID, propertyID string) (bool, *apierror.APIError)
	PropertyExistsByNameInCategory(ctx context.Context, accountID, itemCategoryID, name string, excludePropertyID *string) (bool, *apierror.APIError)
}

type ItemCategorySvc

type ItemCategorySvc interface {
	// ListItemCategories returns a paginated list of item categories visible to the caller's account.
	ListItemCategories(ctx context.Context, params ListItemCategoriesParams) (*ListItemCategoriesResult, *apierror.APIError)

	ExportItemCategories(ctx context.Context, params ExportItemCategoriesParams) (*Job, *apierror.APIError)
	// BuildExportItemCategories renders the file an accepted export recorded.
	BuildExportItemCategories(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// GetItemCategory returns a single item category by ID.
	GetItemCategory(ctx context.Context, params GetItemCategoryParams) (*ItemCategoryFull, *apierror.APIError)

	// CreateItemCategory creates a new item category.
	CreateItemCategory(ctx context.Context, params CreateItemCategoryParams) (*ItemCategoryFull, *apierror.APIError)

	// UpdateItemCategory partially updates an item category. Default categories cannot be updated.
	UpdateItemCategory(ctx context.Context, params UpdateItemCategoryParams) (*ItemCategoryFull, *apierror.APIError)

	// DeleteItemCategory deletes an item category. Default categories cannot be deleted.
	DeleteItemCategory(ctx context.Context, itemCategoryID string) *apierror.APIError

	// AddItemCategoryProperty adds a property to an item category.
	AddItemCategoryProperty(ctx context.Context, params AddItemCategoryPropertyParams) *apierror.APIError

	// RemoveItemCategoryProperty removes a property from an item category.
	RemoveItemCategoryProperty(ctx context.Context, params RemoveItemCategoryPropertyParams) *apierror.APIError

	// ChangeItemCategoryUnitGroup changes the unit group of an item category.
	ChangeItemCategoryUnitGroup(ctx context.Context, params ChangeItemCategoryUnitGroupParams) *apierror.APIError

	// BatchGetItemCategoriesByIDs returns item categories by ID for the api-gateway include resolver. Always populates properties and unit group with full tree.
	BatchGetItemCategoriesByIDs(ctx context.Context, ids []string) ([]*ItemCategoryFull, *apierror.APIError)

	// accepts a bulk upsert of item categories and returns the job that carries it out,
	// matching by name (case-insensitive) within the caller's account.
	BulkUpsertItemCategories(ctx context.Context, params BulkUpsertItemCategoriesParams) (*Job, *apierror.APIError)

	// performs the writes for an enqueued bulk item category upsert.
	ExecuteBulkUpsertItemCategories(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError
}

type ItemCategoryUnitGroup

type ItemCategoryUnitGroup struct {
	ID         string
	Name       string
	BaseUnitID string
	Type       string
	CreatedAt  time.Time
	UpdatedAt  time.Time

	// Populated when unit_group.base_unit is included.
	BaseUnit *LightUnit
	// Populated when unit_group.associated_units is included.
	AssociatedUnits []*UnitGroupUnit
}

ItemCategoryUnitGroup represents the unit group associated with an item category.

type ItemCostBasisChangedEvent

type ItemCostBasisChangedEvent struct {
	AccountID string `json:"account_id"`
	// ItemID is where the change happened: the material whose cost moved, or the item produced by
	// the step that was edited.
	ItemID string `json:"item_id"`
	Reason string `json:"reason,omitempty"`
}

ItemCostBasisChangedEvent states that something an item's cost is derived from has moved: the unit cost of a material, or the make-up of a production step.

It names the item at the point of change, not the items that need recomputing. Which those are is a property of the production graph at the moment the event is handled, and the publisher has no business knowing it.

type ItemCosts

type ItemCosts struct {
	DirectMaterialCost string
	DirectLaborCost    string
	OverheadCost       string
	TotalCost          string
	UnitID             string
}

ItemCosts represents cost breakdown for an item.

type ItemIdentifier

type ItemIdentifier struct {
	ID  string
	SKU string
}

ItemIdentifier identifies an item by its ID or SKU. Precedence: ID, then SKU. The zero value means no item was provided.

type ItemInventory

type ItemInventory struct {
	OnHand             string
	OnHandUnitID       string
	Reserved           string
	ReservedUnitID     string
	AvailableToPromise string
	ATPUnitID          string
	Short              string
	ShortUnitID        string
	UnitAbbreviation   string
	UnitType           string
}

ItemInventory represents inventory quantities for an item.

type ItemLotDefault

type ItemLotDefault struct {
	ItemID   string
	Quantity float64
	UnitID   string
	// Source names the rule that produced this lot: item_override, product_line, downstream_product_line or account_default.
	Source string
	// ProductLineID is the line the convention came from, empty for the account default.
	ProductLineID string
}

ItemLotDefault is the lot one item is made in, resolved through the whole chain.

Quantity is zero when nothing anywhere supplies a lot: the caller gets a unit and no number, so a form defaults to empty rather than to a size nobody chose.

type ItemProductLineRow

type ItemProductLineRow struct {
	ItemID        string
	ProductLineID string
}

ItemProductLineRow maps one item to the product line it sells under.

type ItemRepo

type ItemRepo interface {
	List(ctx context.Context, params ListItemsParams) (*ListItemsResult, *apierror.APIError)
	Get(ctx context.Context, params GetItemParams) (*Item, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Item, *apierror.APIError)
	GetInventory(ctx context.Context, accountID, itemID string) (*ItemInventory, *apierror.APIError)
	GetCostFlowConsumptions(ctx context.Context, stepID string) ([]CostFlowConsumption, *apierror.APIError)
	// FindItemsProducedFromConsumed returns the items produced by every step that consumes any of the given ones — one generation outwards in the cost graph.
	FindItemsProducedFromConsumed(ctx context.Context, accountID string, itemIDs []string) ([]string, *apierror.APIError)
	UpdateUnitCost(ctx context.Context, accountID, itemID string, cost decimal.Decimal, denominatorUnitID string) *apierror.APIError
	GetTrends(ctx context.Context, accountID, itemID, trendType string) (*ItemTrends, *apierror.APIError)
	ExportWithInventory(ctx context.Context, accountID string) (*ExportItemsResult, *apierror.APIError)
	Update(ctx context.Context, params UpdateItemParams) *apierror.APIError
	CheckSKUExists(ctx context.Context, accountID, sku, excludeID string) (bool, *apierror.APIError)
	AddAttribute(ctx context.Context, params AddItemAttributeParams) *apierror.APIError
	RemoveAttribute(ctx context.Context, params RemoveItemAttributeParams) *apierror.APIError
	ChangeCategory(ctx context.Context, params ChangeItemCategoryParams) *apierror.APIError
	UpdateRateUnits(ctx context.Context, accountID, itemID, newUnitID string) *apierror.APIError
	UpdateMaterialOrderPointUnit(ctx context.Context, accountID, itemID, newUnitID string) *apierror.APIError
	UpdateConsumptionProductionQuantityUnits(ctx context.Context, accountID, itemID, newUnitID string) *apierror.APIError
	// GetCategoryBaseUnitID resolves a category's base unit id and its category type
	// code, so create paths can enforce item-type/category-type matching.
	GetCategoryBaseUnitID(ctx context.Context, categoryID string) (string, string, *apierror.APIError)
	// GetCategoryBaseUnitIDs batch-resolves category base unit ids and category type
	// codes. Existing categories map to their ref (base unit id empty when the unit
	// group has no base unit); missing categories are absent from the map. Used by
	// bulk upsert category validation.
	GetCategoryBaseUnitIDs(ctx context.Context, categoryIDs []string) (map[string]CategoryRef, *apierror.APIError)
	ListConsumptionChangeLogsForBurnRate(ctx context.Context, accountID, itemID string) ([]BurnRateConsumptionLog, *apierror.APIError)
	FetchItemsBySKU(ctx context.Context, accountID string, skus []string) ([]ItemSKUInfo, *apierror.APIError)
	// FindBySKU returns the existing item's ID and its unit_value rate ID for the given SKU within the account. Returns (nil, nil, nil) when no match exists. Used by bulk upsert flows.
	FindBySKU(ctx context.Context, accountID, sku string) (itemID *string, unitValueRateID *string, apiErr *apierror.APIError)
	// UpdateRateValue updates a rate's numeric value in place.
	UpdateRateValue(ctx context.Context, rateID, value string) *apierror.APIError
	// UpdateRate updates value and unit IDs on an existing rate row.
	UpdateRate(ctx context.Context, rateID string, params CreateRateParams) *apierror.APIError
	// ClearItemDirtyFlag sets is_dirty = 0 on an item (e.g. after manual unit cost edit).
	ClearItemDirtyFlag(ctx context.Context, accountID, itemID string) *apierror.APIError
	// LoadAttributes fetches the attributes for an item and populates item.Attributes.
	LoadAttributes(ctx context.Context, item *Item) *apierror.APIError
}

type ItemRunRateSample added in v1.4.1

type ItemRunRateSample struct {
	// MachineID is empty for a scan recorded against no machine.
	MachineID      string
	LaborTimeValue float64
	LaborTimeUnit  string
}

ItemRunRateSample is what one of an item's past scans says its run rate was: the labor time of the step it was produced at, and the machine it ran on.

type ItemSKUInfo

type ItemSKUInfo struct {
	SKU        string
	ItemID     string
	BaseUnitID string
}

ItemSKUInfo represents minimal item info fetched by SKU for bulk operations.

type ItemSvc

type ItemSvc interface {
	// GetItemLotDefault resolves the lot an item is made in — how many, counted in what.
	GetItemLotDefault(ctx context.Context, itemID string) (*ItemLotDefault, *apierror.APIError)

	// ListItems returns a paginated list of items for the caller's account. Supports filtering by type, category, attribute, supplier, date range, and full-text search.
	ListItems(ctx context.Context, params ListItemsParams) (*ListItemsResult, *apierror.APIError)

	// GetItem returns a single item by ID within the caller's account.
	GetItem(ctx context.Context, itemID string, includes []string) (*Item, *apierror.APIError)

	// GetItemInventory returns inventory quantities (on-hand, reserved, ATP, short) for an item.
	GetItemInventory(ctx context.Context, itemID string) (*ItemInventory, *apierror.APIError)

	// GetItemCosts returns production cost breakdown for an item.
	GetItemCosts(ctx context.Context, itemID string) (*ItemCosts, *apierror.APIError)

	// RecomputeItemCosts is GetItemCosts for callers that have no request identity to authorize — event consumers restating costs after an input moved. The account is named rather than read off the caller.
	RecomputeItemCosts(ctx context.Context, accountID, itemID string) (*ItemCosts, *apierror.APIError)

	// GetItemTrends returns historical trend data for an item.
	GetItemTrends(ctx context.Context, itemID string, trendType string) (*ItemTrends, *apierror.APIError)

	// ExportItems returns all items with on-hand inventory for the caller's account.
	ExportItems(ctx context.Context) (*ExportItemsResult, *apierror.APIError)

	// UpdateItem partially updates an item (sku, description, notes).
	UpdateItem(ctx context.Context, params UpdateItemParams) (*Item, *apierror.APIError)

	// AddItemAttribute adds an attribute to an item.
	AddItemAttribute(ctx context.Context, itemID, attributeID string, includes []string) (*Item, *apierror.APIError)

	// RemoveItemAttribute removes an attribute from an item.
	RemoveItemAttribute(ctx context.Context, itemID, attributeID string, includes []string) (*Item, *apierror.APIError)

	// ChangeItemCategory changes the category of an item and updates rate units.
	ChangeItemCategory(ctx context.Context, itemID, categoryID string, includes []string) (*Item, *apierror.APIError)

	// UpdateItemInventory adjusts or reconciles inventory for an item.
	UpdateItemInventory(ctx context.Context, params UpdateItemInventoryParams) *apierror.APIError

	// BulkCreateItems creates multiple items in a single operation.
	BulkCreateItems(ctx context.Context, params BulkCreateItemsParams) ([]BulkCreateItemResult, *apierror.APIError)

	// BulkReconcileItems reconciles inventory for multiple items by SKU.
	BulkReconcileItems(ctx context.Context, params BulkReconcileItemsParams) (*BulkReconcileItemsResult, *apierror.APIError)

	// BatchGetItemsByIDs returns items by ID for the api-gateway include resolver. Always populates rates and attributes.
	BatchGetItemsByIDs(ctx context.Context, ids []string) ([]*Item, *apierror.APIError)

	// ListInventories returns all items with their on-hand inventory quantities.
	ListInventories(ctx context.Context, params ListInventoriesParams) (*ListInventoriesResult, *apierror.APIError)
}

type ItemTrend

type ItemTrend struct {
	Date  time.Time
	Value string
}

ItemTrend represents a single trend data point.

type ItemTrends

type ItemTrends struct {
	TrendType string
	Points    []*ItemTrend
}

ItemTrends represents historical trend data for an item.

type Job

type Job struct {
	ID           string
	Type         constants.JobType
	ResourceType constants.ObjectType
	AccountID    *string
	CreatedByID  *string
	JobItems     json.RawMessage
	Results      []RowResult
	// ResultsTruncated reports that the executor produced more rows than Results carries.
	ResultsTruncated bool
	// Error is the failure that sank the job as a whole. A row that failed carries its
	// own on its RowResult instead.
	Error       *apierror.ResponseError
	StartedAt   *time.Time
	CompletedAt *time.Time
	FailedAt    *time.Time
	CancelledAt *time.Time
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

func (*Job) IsTerminal

func (j *Job) IsTerminal() bool

func (*Job) Status

func (j *Job) Status() constants.JobStatus

type JobRepo

type JobRepo interface {
	Get(ctx context.Context, jobID, accountID string) (*Job, *apierror.APIError)
	Create(ctx context.Context, params CreateJobRepositoryParams) *apierror.APIError
	// returns the number of rows changed; the query guards on the terminal timestamps, so an
	// already-settled job matches zero rows, which serializes a cancel against a completion.
	Update(ctx context.Context, params UpdateJobRepositoryParams) (int64, *apierror.APIError)
}

type JobSvc

type JobSvc interface {
	GetJob(ctx context.Context, jobID string) (*Job, *apierror.APIError)
	GetJobForExecution(ctx context.Context, jobID string) (*Job, *apierror.APIError)
	CreateJob(ctx context.Context, params CreateJobServiceParams) (*Job, *apierror.APIError)
	UpdateJob(ctx context.Context, params UpdateJobServiceParams) (*Job, *apierror.APIError)
	StartJob(ctx context.Context, params StartJobParams) (time.Time, *apierror.APIError)
	CompleteJob(ctx context.Context, params CompleteJobParams) *apierror.APIError
	FailJob(ctx context.Context, params FailJobParams)
	CancelJob(ctx context.Context, params CancelJobParams) (*Job, *apierror.APIError)
}

type JobSvcFactory

type JobSvcFactory interface {
	Build(RepoFactory) JobSvc
}

JobSvcFactory builds the job service bound to a given repository factory, the same way MediatorFactory does, and for the same reason.

Settling a job is the checkpoint for the work it tracks, and a checkpoint commits as part of its phase's transaction. That transaction is carried by the RepoFactory, so settling a job inside one means holding a job service built from it — while the same caller's marks outside the transaction need one built from the root factory. A single injected JobSvc cannot be both.

type LabelPackage

type LabelPackage struct {
	TrackingNumber      string
	LabelURL            string
	ShippoTransactionID string
}

Holds a single case's purchased label.

type LabelResult

type LabelResult struct {
	MasterTrackingNumber string
	NegotiatedRate       float64
	// Holds one purchased label per parcel, in the same order as CreateLabelParams.Parcels.
	Packages []LabelPackage
}

Reports the outcome of a label purchase across a shipment's cases.

type LightItem

type LightItem struct {
	ID  string
	SKU string
	// Type is the item_type_code (e.g. "material", "part", "finished_good"). Populated where the query provides it; empty otherwise.
	Type string
}

LightItem is a lightweight item reference returned as a sub-resource.

type LightMachine

type LightMachine struct {
	ID   string
	Name string
}

LightMachine is a lightweight machine reference returned as a sub-resource.

type LightProductionRun

type LightProductionRun struct {
	ID     string
	Number string
}

LightProductionRun is a lightweight production run reference returned as a sub-resource.

type LightProductionStep

type LightProductionStep struct {
	ID   string
	Name string
}

LightProductionStep is a lightweight production step reference returned as a sub-resource.

type LightScanningStation

type LightScanningStation struct {
	ID   string
	Name string
}

LightScanningStation is a lightweight scanning station reference returned as a sub-resource.

type LightUnit

type LightUnit struct {
	ID                string
	Name              string
	Abbreviation      string
	Type              string
	RatioNumerator    string
	RatioDenominator  string
	OffsetNumerator   string
	OffsetDenominator string
	IsBaseUnit        bool
	AccountID         *string
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

LightUnit is a lightweight unit reference returned as a sub-resource.

type LineageShortfall

type LineageShortfall struct {
	ProductionRunID string
	Seconds         decimal.Decimal
	Waste           decimal.Decimal
}

LineageShortfall is the production run a batch belongs to and the scrap accumulated across its upstream lineage. A scan releases reservations for that scrap; undoing the scan puts the same amount back.

func (LineageShortfall) Total

func (l LineageShortfall) Total() decimal.Decimal

Total is the quantity that will never be produced, and so the quantity whose reservation moves.

type ListAccountGroupProductLineAccessParams

type ListAccountGroupProductLineAccessParams struct {
	AccountID string
	Query     *string
	Cursor    *string
	Limit     int32
}

type ListAccountGroupProductLineAccessResult

type ListAccountGroupProductLineAccessResult struct {
	Items    []*AccountGroupProductLineAccess
	PageInfo pagination.PageInfo
}

type ListAccountGroupsParams

type ListAccountGroupsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Type      *string
}

type ListAccountGroupsResult

type ListAccountGroupsResult struct {
	AccountGroups []*AccountGroup
	PageInfo      pagination.PageInfo
}

type ListAccountIntegrationsParams

type ListAccountIntegrationsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListAccountIntegrationsResult

type ListAccountIntegrationsResult struct {
	AccountIntegrations []*AccountIntegration
	PageInfo            pagination.PageInfo
}

type ListAccountPricesParams

type ListAccountPricesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	// RecipientAccountIDs, when non-empty, restricts results to prices offered to one of
	// these accounts. The service expands a requested customer into that customer plus its
	// parent, since a price on the parent applies to orders its children place.
	RecipientAccountIDs []string
}

type ListAccountPricesResult

type ListAccountPricesResult struct {
	AccountPrices []*AccountPrice
	PageInfo      pagination.PageInfo
}

type ListAccountStatusesParams

type ListAccountStatusesParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

type ListAccountStatusesResult

type ListAccountStatusesResult struct {
	AccountStatuses []*AccountStatus
	PageInfo        pagination.PageInfo
}

type ListAccountTransactionsParams

type ListAccountTransactionsParams struct {
	AccountID         string
	CustomerAccountID string
	Cursor            *string
	Limit             int32
	Query             *string
	Status            *string
	Type              *string
}

ListAccountTransactionsParams holds parameters for listing transactions by customer account.

type ListAccountTransactionsResult

type ListAccountTransactionsResult struct {
	Transactions []*Transaction
	PageInfo     pagination.PageInfo
}

ListAccountTransactionsResult holds the result of listing customer transactions.

type ListAccountUsersParams

type ListAccountUsersParams struct {
	AccountID            string
	Query                *string
	Cursor               *string
	Limit                int32
	RoleType             *string
	IsCommissionEligible *bool
	IncludeRemoved       bool
	Includes             []string
}

ListAccountUsersParams are the parameters for listing account users.

type ListAccountUsersResult

type ListAccountUsersResult struct {
	Items      []*AccountUserDetail
	PageInfo   pagination.PageInfo
	TotalCount int64
}

ListAccountUsersResult is the result of listing account users.

type ListAddressesParams

type ListAddressesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	DropShip  *bool
}

ListAddressesParams contains the parameters for listing addresses.

type ListAddressesResult

type ListAddressesResult struct {
	Addresses []*Address
	PageInfo  pagination.PageInfo
}

ListAddressesResult contains the result of listing addresses.

type ListAdjustmentTypesParams

type ListAdjustmentTypesParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

type ListAdjustmentTypesResult

type ListAdjustmentTypesResult struct {
	AdjustmentTypes []*AdjustmentType
	PageInfo        pagination.PageInfo
}

type ListAllocationEntriesParams

type ListAllocationEntriesParams struct {
	AccountID       string
	Cursor          *string
	Limit           int32
	Query           *string
	TransactionType *string
	StartDate       *time.Time
	EndDate         *time.Time
}

ListAllocationEntriesParams holds parameters for listing allocation entries.

type ListAllocationEntriesResult

type ListAllocationEntriesResult struct {
	Entries  []*AllocationEntry
	PageInfo pagination.PageInfo
}

ListAllocationEntriesResult holds the result of listing allocation entries.

type ListAttributesParams

type ListAttributesParams struct {
	AccountID  string
	PropertyID string
	Query      *string
	Cursor     *string
	Limit      int32
}

ListAttributesParams holds the parameters for listing attributes.

type ListAttributesResult

type ListAttributesResult struct {
	Attributes []*Attribute
	PageInfo   pagination.PageInfo
}

ListAttributesResult holds the result of listing attributes.

type ListBatchesByProductionRunParams

type ListBatchesByProductionRunParams struct {
	ProductionRunID string
	AccountID       string
	Cursor          *string
	Limit           int32
	SearchQuery     *string
}

ListBatchesByProductionRunParams holds the parameters for listing batches by production run.

type ListBatchesByProductionRunResult

type ListBatchesByProductionRunResult struct {
	Batches  []*Batch
	PageInfo pagination.PageInfo
}

ListBatchesByProductionRunResult holds paginated batches for a production run.

type ListBatchesByScanningStationParams

type ListBatchesByScanningStationParams struct {
	AccountID         string
	ScanningStationID string
	Cursor            *string
	Limit             int32
	Query             *string
}

ListBatchesByScanningStationParams holds the parameters for listing batches by scanning station.

type ListBatchesByScanningStationResult

type ListBatchesByScanningStationResult struct {
	Batches  []*Batch
	PageInfo pagination.PageInfo
}

ListBatchesByScanningStationResult holds the result of listing batches by scanning station.

type ListCarriersParams

type ListCarriersParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Includes  []string
}

type ListCarriersResult

type ListCarriersResult struct {
	Carriers []*Carrier
	PageInfo pagination.PageInfo
}

type ListCarryForwardBatchesParams

type ListCarryForwardBatchesParams struct {
	AccountID string
	ItemID    string
	// WeekStartDate is the week being released. Only runs from weeks strictly before it are eligible: a week still ahead has not been missed, it simply has not been worked.
	WeekStartDate time.Time
	Limit         int32
}

ListCarryForwardBatchesParams asks for one item's unworked tickets from weeks that have already begun.

type ListCatalogProductLinesParams

type ListCatalogProductLinesParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

ListCatalogProductLinesParams contains parameters for listing catalog product lines.

type ListCatalogProductLinesResult

type ListCatalogProductLinesResult struct {
	ProductLines []*CatalogProductLine
	PageInfo     pagination.PageInfo
}

ListCatalogProductLinesResult contains the result of listing catalog product lines.

type ListCatalogProductsParams

type ListCatalogProductsParams struct {
	ProductLineID string
	Cursor        *string
	Limit         int32
	Query         *string
}

ListCatalogProductsParams contains parameters for listing catalog products.

type ListCatalogProductsResult

type ListCatalogProductsResult struct {
	Categories []*CatalogCategory
	PageInfo   pagination.PageInfo
}

ListCatalogProductsResult contains the result of listing catalog products.

type ListChildAccountsParams

type ListChildAccountsParams struct {
	OwnerAccountID  string
	ParentAccountID string
	Cursor          *string
	Limit           int32
	Query           *string
}

type ListChildAccountsResult

type ListChildAccountsResult struct {
	Items    []*ChildAccount
	PageInfo pagination.PageInfo
}

type ListCustomerInvoicesParams

type ListCustomerInvoicesParams struct {
	AccountID         string
	CustomerAccountID string
	Cursor            *string
	Limit             int32
	Query             *string
	Includes          []string
}

ListCustomerInvoicesParams holds parameters for listing invoices by customer.

type ListCustomerInvoicesResult

type ListCustomerInvoicesResult struct {
	Invoices []*InvoiceForPayment
	PageInfo pagination.PageInfo
}

ListCustomerInvoicesResult holds the result of listing customer invoices.

type ListCustomerProductLineAccessParams

type ListCustomerProductLineAccessParams struct {
	AccountID string
	Query     *string
	Cursor    *string
	Limit     int32
}

type ListCustomerProductLineAccessResult

type ListCustomerProductLineAccessResult struct {
	Items    []*CustomerProductLineAccess
	PageInfo pagination.PageInfo
}

type ListCustomersParams

type ListCustomersParams struct {
	AccountID             string
	Cursor                *string
	Limit                 int32
	Query                 *string
	CustomerGroupIDs      []string
	PricingGroupIDs       []string
	SalesRepIDs           []string
	StatusCodes           []string
	ShippingTermIDs       []string
	PaymentTermIDs        []string
	CommissionPolicyCodes []string
	FreightPolicyCodes    []string
	CarrierIDs            []string
	ServiceLevelIDs       []string
	IsParentAccount       *bool
	City                  *string
	State                 *string
	PostalCode            *string
	StartDate             *time.Time
	EndDate               *time.Time
	Includes              []string
}

ListCustomersParams holds the parameters for listing customers.

type ListCustomersResult

type ListCustomersResult struct {
	Items    []*Customer
	PageInfo pagination.PageInfo
}

ListCustomersResult holds the result of listing customers.

type ListDCLocationsParams

type ListDCLocationsParams struct {
	OwnerAccountID string
	Cursor         *string
	Limit          int32
	Query          *string
}

type ListDCLocationsResult

type ListDCLocationsResult struct {
	DCLocations []*DCLocation
	PageInfo    pagination.PageInfo
}

type ListDeliveriesParams

type ListDeliveriesParams struct {
	AccountID   string
	Cursor      *string
	Limit       int32
	Query       *string
	Status      *string
	ItemIDs     []string
	SupplierIDs []string
	StartDate   *time.Time
	EndDate     *time.Time
	Includes    []string
}

ListDeliveriesParams holds parameters for listing deliveries.

type ListDeliveriesResult

type ListDeliveriesResult struct {
	Deliveries []*DeliverySummary
	PageInfo   pagination.PageInfo
}

ListDeliveriesResult holds the result of listing deliveries.

type ListDemandOverridesParams

type ListDemandOverridesParams struct {
	AccountID         string
	Cursor            *string
	Limit             int32
	Query             *string
	ScopeCodes        []string
	ScopeRefIDs       []string
	OverrideTypeCodes []string
	IsActive          *bool
	PeriodStart       *time.Time
	PeriodEnd         *time.Time
}

type ListDemandOverridesResult

type ListDemandOverridesResult struct {
	Overrides []*DemandOverride
	PageInfo  pagination.PageInfo
}

type ListDepartmentsParams

type ListDepartmentsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListDepartmentsResult

type ListDepartmentsResult struct {
	Departments []*Department
	PageInfo    pagination.PageInfo
}

type ListDerivedLinesParams

type ListDerivedLinesParams struct {
	AccountID     string
	ScheduleID    string
	DepartmentIDs []string
	WeekIndex     *int32
}

type ListEDIRunsParams

type ListEDIRunsParams struct {
	AccountID    string
	Cursor       *string
	Limit        int32
	HasSucceeded *bool
	Query        *string
}

type ListEDIRunsResult

type ListEDIRunsResult struct {
	EDIRuns  []*EDIRun
	PageInfo pagination.PageInfo
}

type ListEmailLogsParams

type ListEmailLogsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Includes  []string
}

type ListEmailLogsResult

type ListEmailLogsResult struct {
	EmailLogs []*EmailLog
	PageInfo  pagination.PageInfo
}

type ListHubspotSyncRecordsParams

type ListHubspotSyncRecordsParams struct {
	AccountID string
	AugnoType string
	Cursor    *string
	Limit     int32
}

ListHubspotSyncRecordsParams pages the account's OpenMRP->HubSpot mappings. AugnoType is required: it keeps the keyset on the (account_id, augno_type, augno_id) index.

type ListHubspotSyncRecordsResult

type ListHubspotSyncRecordsResult struct {
	Items    []*HubspotSyncRecord
	PageInfo pagination.PageInfo
}

ListHubspotSyncRecordsResult is one page of mappings.

type ListInventoriesParams

type ListInventoriesParams struct {
	Cursor    *string
	Limit     int32
	Query     *string
	AccountID string
}

ListInventoriesParams contains the parameters for listing inventories.

type ListInventoriesResult

type ListInventoriesResult struct {
	Items    []*InventoryItemResult
	Count    int64
	PageInfo pagination.PageInfo
}

ListInventoriesResult represents the result of listing all items with inventory.

type ListInventoryChangeLogsParams

type ListInventoryChangeLogsParams struct {
	AccountID        string
	Cursor           *string
	Limit            int32
	Query            *string
	ItemIDs          []string
	ActionTypeCodes  []string
	ChangedByUserIDs []string
	StartDate        *time.Time
	EndDate          *time.Time
}

ListInventoryChangeLogsParams contains the parameters for listing inventory change logs.

type ListInventoryChangeLogsResult

type ListInventoryChangeLogsResult struct {
	Items    []*InventoryChangeLog
	PageInfo pagination.PageInfo
}

ListInventoryChangeLogsResult contains the paginated result of listing inventory change logs.

type ListInvoicesParams

type ListInvoicesParams struct {
	AccountID        string
	Cursor           *string
	Limit            int32
	Query            *string
	Status           *string
	ItemIDs          []string
	CustomerIDs      []string
	ProductLineIDs   []string
	CustomerGroupIDs []string
	SalesRepIDs      []string
	StartDate        *time.Time
	EndDate          *time.Time
	Includes         []string
}

ListInvoicesParams holds parameters for listing invoices.

type ListInvoicesResult

type ListInvoicesResult struct {
	Invoices []*Invoice
	PageInfo pagination.PageInfo
}

Holds one page of invoices plus its cursors.

type ListItemCategoriesParams

type ListItemCategoriesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Type      *string
	Includes  []string
}

type ListItemCategoriesResult

type ListItemCategoriesResult struct {
	ItemCategories []*ItemCategoryFull
	PageInfo       pagination.PageInfo
}

type ListItemsParams

type ListItemsParams struct {
	AccountID                string
	Cursor                   *string
	Limit                    int32
	Query                    *string
	Types                    []string
	CategoryIDs              []string
	AttributeIDs             []string
	SupplierID               *string
	StartDate                *time.Time
	EndDate                  *time.Time
	IsExactMatch             bool
	OnlyInitialSubassemblies bool
	Includes                 []string
	ProductLineIDs           []string
	CustomerIDs              []string
}

type ListItemsResult

type ListItemsResult struct {
	Items    []*Item
	PageInfo pagination.PageInfo
}

type ListLocationTypesParams

type ListLocationTypesParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

ListLocationTypesParams contains the parameters for listing location types.

type ListLocationTypesResult

type ListLocationTypesResult struct {
	LocationTypes []*LocationType
	PageInfo      pagination.PageInfo
}

ListLocationTypesResult contains the result of listing location types.

type ListLocationsParams

type ListLocationsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Includes  []string
}

ListLocationsParams contains the parameters for listing locations.

type ListLocationsResult

type ListLocationsResult struct {
	Locations []*Location
	PageInfo  pagination.PageInfo
}

ListLocationsResult contains the result of listing locations.

type ListMachineDowntimeEventsParams

type ListMachineDowntimeEventsParams struct {
	AccountID     string
	Cursor        *string
	Limit         int32
	Query         *string
	MachineIDs    []string
	DepartmentIDs []string
	ReasonCodes   []string
	OpenOnly      bool
	StartDate     *time.Time
	EndDate       *time.Time
}

type ListMachineDowntimeEventsResult

type ListMachineDowntimeEventsResult struct {
	Events   []*MachineDowntimeEvent
	PageInfo pagination.PageInfo
}

type ListMachineStatusParams

type ListMachineStatusParams struct {
	AccountID string
	// AsOf defaults to now. Present so a caller can ask what a given week looked like.
	AsOf time.Time
	// DepartmentIDs narrows to one part of the plant; empty means every machine.
	DepartmentIDs []string
}

ListMachineStatusParams asks for the floor at a moment.

type ListMachinesParams

type ListMachinesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListMachinesResult

type ListMachinesResult struct {
	Machines []*Machine
	PageInfo pagination.PageInfo
}

type ListMaterialsParams

type ListMaterialsParams struct {
	AccountID    string
	Cursor       *string
	Limit        int32
	Query        *string
	CategoryIDs  []string
	AttributeIDs []string
	StartDate    *time.Time
	EndDate      *time.Time
	Includes     []string
}

type ListMaterialsResult

type ListMaterialsResult struct {
	Materials []*Material
	PageInfo  pagination.PageInfo
}

type ListOpenCreditsParams

type ListOpenCreditsParams struct {
	AccountID   string
	StartDate   *time.Time
	EndDate     *time.Time
	CustomerIDs []string
	SearchQuery *string
	Cursor      *string
	Limit       int32
}

ListOpenCreditsParams holds parameters for listing open credits.

type ListOpenCreditsResult

type ListOpenCreditsResult struct {
	Entries  []*OpenCreditEntry
	PageInfo pagination.PageInfo
}

ListOpenCreditsResult holds a page of open credit entries.

type ListOperatingCalendarsParams

type ListOperatingCalendarsParams struct {
	AccountID string
	KindCode  *string
}

ListOperatingCalendarsParams filters a listing. A nil KindCode returns both kinds.

type ListOrderDiscountsParams

type ListOrderDiscountsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListOrderDiscountsResult

type ListOrderDiscountsResult struct {
	OrderDiscounts []*OrderDiscount
	PageInfo       pagination.PageInfo
}

type ListPartsParams

type ListPartsParams struct {
	AccountID    string
	Cursor       *string
	Limit        int32
	Query        *string
	CategoryIDs  []string
	AttributeIDs []string
	StartDate    *time.Time
	EndDate      *time.Time
	Includes     []string
}

type ListPartsResult

type ListPartsResult struct {
	Parts    []*Part
	PageInfo pagination.PageInfo
}

type ListPaymentTermsParams

type ListPaymentTermsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListPaymentTermsResult

type ListPaymentTermsResult struct {
	PaymentTerms []*PaymentTerm
	PageInfo     pagination.PageInfo
}

type ListPermissionGroupsParams

type ListPermissionGroupsParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

type ListPermissionGroupsResult

type ListPermissionGroupsResult struct {
	PermissionGroups []*PermissionGroup
	PageInfo         pagination.PageInfo
}

type ListPicksParams

type ListPicksParams struct {
	AccountID        string
	Cursor           *string
	Limit            int32
	Query            *string
	Status           *string // "open", "closed", or nil for all
	CustomerIDs      []string
	ProductLineIDs   []string
	CustomerGroupIDs []string
	DepartmentIDs    []string
	StartDate        *string
	EndDate          *string
	Includes         []string
	// Empty means the default, soonest ship-by date first.
	Sort constants.PickSort
}

ListPicksParams holds the parameters for listing picks.

type ListPicksResult

type ListPicksResult struct {
	Picks    []*Pick
	PageInfo pagination.PageInfo
}

ListPicksResult holds the result of listing picks.

type ListPortalRegistrationSessionsParams

type ListPortalRegistrationSessionsParams struct {
	// SellerAccountID scopes the list to one seller account.
	SellerAccountID string
	// Cursor / Limit drive keyset pagination.
	Cursor *string
	Limit  int32
	// StatusFilter, when set, restricts to one derived status (in_progress | completed | abandoned | expired).
	StatusFilter *string
	// SearchTerm, when set, matches the registrant's captured customer name/number or the session id.
	SearchTerm *string
	// ExpiryThreshold is the created-at boundary (now - TTL) below which an incomplete session counts as expired. Supplied by the service so the TTL is single-sourced.
	ExpiryThreshold time.Time
}

ListPortalRegistrationSessionsParams lists a seller's buyer-registration sessions for the customer-service follow-up view.

type ListPortalRegistrationSessionsResult

type ListPortalRegistrationSessionsResult struct {
	Sessions []*PortalRegistrationSession
	PageInfo pagination.PageInfo
}

ListPortalRegistrationSessionsResult is a page of registration sessions.

type ListPrioritiesParams

type ListPrioritiesParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

type ListPrioritiesResult

type ListPrioritiesResult struct {
	Priorities []*Priority
	PageInfo   pagination.PageInfo
}

type ListProductLinesParams

type ListProductLinesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Includes  []string
}

type ListProductLinesResult

type ListProductLinesResult struct {
	ProductLines []*ProductLineFull
	PageInfo     pagination.PageInfo
}

type ListProductTypesParams

type ListProductTypesParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

type ListProductTypesResult

type ListProductTypesResult struct {
	ProductTypes []*ProductType
	PageInfo     pagination.PageInfo
}

type ListProductionRunsParams

type ListProductionRunsParams struct {
	Cursor     *string
	Limit      int32
	Query      *string
	Status     *string
	ItemIDs    []string
	MachineIDs []string
	StartDate  *string
	EndDate    *string
	AccountID  string
}

ListProductionRunsParams holds the parameters for listing production runs.

type ListProductionRunsResult

type ListProductionRunsResult struct {
	ProductionRuns []*ProductionRunSummary
	PageInfo       pagination.PageInfo
}

ListProductionRunsResult holds the result of listing production runs.

type ListProductionScheduleDeviationsParams

type ListProductionScheduleDeviationsParams struct {
	AccountID  string
	ScheduleID string
	Cursor     *string
	Limit      int32
	Query      *string
	// FrozenOnly filters to (or away from) frozen-week deviations. Nil returns both.
	FrozenOnly *bool
}

type ListProductionScheduleDeviationsResult

type ListProductionScheduleDeviationsResult struct {
	Deviations []*ProductionScheduleDeviation
	PageInfo   pagination.PageInfo
}

type ListProductionScheduleFinishingLinesParams

type ListProductionScheduleFinishingLinesParams struct {
	AccountID  string
	ScheduleID string
	WeekIndex  *int32
	ItemID     *string
}

ListProductionScheduleFinishingLinesParams narrows a version's finishing plan to one week or one finished SKU.

type ListProductionScheduleLinesParams

type ListProductionScheduleLinesParams struct {
	AccountID  string
	ScheduleID string
	MachineIDs []string
	WeekIndex  *int32
}

type ListProductionSchedulesParams

type ListProductionSchedulesParams struct {
	AccountID   string
	Cursor      *string
	Limit       int32
	Query       *string
	StatusCodes []string
}

type ListProductionSchedulesResult

type ListProductionSchedulesResult struct {
	Schedules []*ProductionSchedule
	PageInfo  pagination.PageInfo
}

type ListProductionStepsParams

type ListProductionStepsParams struct {
	AccountID          string
	Cursor             *string
	Limit              int32
	Query              *string
	ItemIDs            []string
	MachineIDs         []string
	ScanningStationIDs []string
	InputStepIDs       []string
	OutputStepIDs      []string
	StartDate          *time.Time
	EndDate            *time.Time
}

ListProductionStepsParams holds the parameters for listing production steps.

type ListProductionStepsResult

type ListProductionStepsResult struct {
	Steps    []*ProductionStep
	PageInfo pagination.PageInfo
}

ListProductionStepsResult holds the result of listing production steps.

type ListProductsFullParams

type ListProductsFullParams struct {
	AccountID      string
	Cursor         *string
	Limit          int32
	Query          *string
	CustomerIDs    []string
	ProductLineIDs []string
	CategoryIDs    []string
	AttributeIDs   []string
	StartDate      *time.Time
	EndDate        *time.Time
	IsPortalReady  *bool
	Includes       []string
}

ListProductsFullParams holds parameters for listing products with pagination and filtering.

type ListProductsFullResult

type ListProductsFullResult struct {
	Products []*ProductFull
	PageInfo pagination.PageInfo
}

ListProductsFullResult contains a page of products plus pagination info.

type ListPropertiesParams

type ListPropertiesParams struct {
	AccountID string
	Query     *string
	Cursor    *string
	Limit     int32
}

ListPropertiesParams holds the parameters for listing properties.

type ListPropertiesResult

type ListPropertiesResult struct {
	Properties []*Property
	PageInfo   pagination.PageInfo
}

ListPropertiesResult holds the result of listing properties.

type ListPurchaseOrdersParams

type ListPurchaseOrdersParams struct {
	Cursor      *string
	Limit       int32
	Query       *string
	StatusCodes []string
	ItemIDs     []string
	SupplierIDs []string
	StartDate   *string
	EndDate     *string
	AccountID   string
	Includes    []string
}

ListPurchaseOrdersParams holds the parameters for listing purchase orders.

type ListPurchaseOrdersResult

type ListPurchaseOrdersResult struct {
	PurchaseOrders []*PurchaseOrderSummary
	PageInfo       pagination.PageInfo
}

ListPurchaseOrdersResult holds the result of listing purchase orders.

type ListReceivablesByCustomerParams

type ListReceivablesByCustomerParams struct {
	AccountID         string
	CustomerAccountID string
	CutoffDate        *time.Time
	Cursor            *string
	Limit             int32
	Query             *string
}

ListReceivablesByCustomerParams holds parameters for listing receivables by customer.

type ListReceivablesByCustomerResult

type ListReceivablesByCustomerResult struct {
	Items      []ReceivableEntry
	PageString *string
}

ListReceivablesByCustomerResult holds the result of listing receivables by customer.

type ListReceivablesParams

type ListReceivablesParams struct {
	AccountID  string
	CutoffDate *time.Time
	Cursor     *string
	Limit      int32
	Query      *string
}

ListReceivablesParams holds parameters for listing receivables.

type ListReceivablesResult

type ListReceivablesResult struct {
	Items      []ReceivableEntry
	PageString *string
}

ListReceivablesResult holds the result of listing receivables.

type ListReceivingOrdersParams

type ListReceivingOrdersParams struct {
	AccountID   string
	Cursor      *string
	Limit       int32
	Query       *string
	Status      *string
	ItemIDs     []string
	SupplierIDs []string
	StartDate   *time.Time
	EndDate     *time.Time
	Includes    []string
}

ListReceivingOrdersParams holds parameters for listing receiving orders.

type ListReceivingOrdersResult

type ListReceivingOrdersResult struct {
	ReceivingOrders []*ReceivingOrderSummary
	PageInfo        pagination.PageInfo
}

ListReceivingOrdersResult holds the result of listing receiving orders.

type ListRegistrationFlowsParams

type ListRegistrationFlowsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListRegistrationFlowsResult

type ListRegistrationFlowsResult struct {
	RegistrationFlows []*RegistrationFlow
	PageInfo          pagination.PageInfo
}

type ListRolesPage

type ListRolesPage struct {
	Roles    []*Role
	PageInfo pagination.PageInfo
}

ListRolesPage is the paginated result from the role repository.

type ListRolesParams

type ListRolesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	RoleTypes []string
	Includes  []string
}

ListRolesParams are the parameters for listing roles.

type ListRolesResult

type ListRolesResult struct {
	Roles    []*RoleWithPermissions
	PageInfo pagination.PageInfo
}

ListRolesResult is the result of listing roles, including permissions.

type ListSalesOrderStatusesParams

type ListSalesOrderStatusesParams struct {
	Cursor *string
	Limit  int32
	Query  *string
}

type ListSalesOrderStatusesResult

type ListSalesOrderStatusesResult struct {
	SalesOrderStatuses []*SalesOrderStatus
	PageInfo           pagination.PageInfo
}

type ListSalesOrdersParams

type ListSalesOrdersParams struct {
	Cursor           *string
	Limit            int32
	Query            *string
	StatusCodes      []string
	ItemIDs          []string
	ProductLineIDs   []string
	CustomerIDs      []string
	CustomerGroupIDs []string
	SalesRepIDs      []string
	StartDate        *string
	EndDate          *string
	ShipByAfter      *string
	ShipByBefore     *string
	PastDue          *bool
	AccountID        string
	BuyerAccountID   *string
	// Includes to expand (e.g. "lines"); inline-joined fields are always present.
	Includes []string
}

ListSalesOrdersParams holds the parameters for listing sales orders.

type ListSalesOrdersResult

type ListSalesOrdersResult struct {
	SalesOrders []*SalesOrder
	PageInfo    pagination.PageInfo
}

ListSalesOrdersResult holds the result of listing sales orders.

type ListSalesTargetsParams

type ListSalesTargetsParams struct {
	AccountID  string
	SalesRepID string
	Query      *string
	Limit      int32
	Offset     int32
}

ListSalesTargetsParams are the parameters for listing sales targets.

type ListSalesTargetsResult

type ListSalesTargetsResult struct {
	SalesTargets []SalesTarget
	Total        int64
}

ListSalesTargetsResult is the result of listing sales targets.

type ListSandboxAccountsResult

type ListSandboxAccountsResult struct {
	Sandboxes []*SandboxAccount
	PageInfo  pagination.PageInfo
}

type ListScanningStationsParams

type ListScanningStationsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Includes  []string
}

type ListScanningStationsResult

type ListScanningStationsResult struct {
	ScanningStations []*ScanningStation
	PageInfo         pagination.PageInfo
}

type ListScheduleLinesForStatusParams

type ListScheduleLinesForStatusParams struct {
	AccountID            string
	ProductionScheduleID string
	FromWeek             time.Time
}

ListScheduleLinesForStatusParams scopes the plan read to one published version from a week forward.

type ListServiceLevelsParams

type ListServiceLevelsParams struct {
	AccountID string
	CarrierID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListServiceLevelsResult

type ListServiceLevelsResult struct {
	ServiceLevels []*ServiceLevel
	PageInfo      pagination.PageInfo
}

type ListSettlementsParams

type ListSettlementsParams struct {
	AccountID      string
	Cursor         *string
	Limit          int32
	Query          *string
	TransactionIDs []string
	InvoiceIDs     []string
	StartDate      *time.Time
	EndDate        *time.Time
}

ListSettlementsParams holds parameters for listing settlements.

type ListSettlementsResult

type ListSettlementsResult struct {
	Settlements []*SettlementSummary
	PageInfo    pagination.PageInfo
}

ListSettlementsResult holds the result of listing settlements.

type ListShipmentLinesParams

type ListShipmentLinesParams struct {
	AccountID  string
	ShipmentID string
	Cursor     *string
	Limit      int32
	Query      *string
}

ListShipmentLinesParams holds the parameters for listing shipment lines.

type ListShipmentLinesResult

type ListShipmentLinesResult struct {
	Lines    []*ShipmentLine
	PageInfo pagination.PageInfo
}

ListShipmentLinesResult holds the result of listing shipment lines.

type ListShipmentsParams

type ListShipmentsParams struct {
	AccountID        string
	Cursor           *string
	Limit            int32
	Query            *string
	Status           *string
	ItemIDs          []string
	CustomerIDs      []string
	ProductLineIDs   []string
	CustomerGroupIDs []string
	SalesRepIDs      []string
	StartDate        *string
	EndDate          *string
	Includes         []string
}

ListShipmentsParams holds the parameters for listing shipments.

type ListShipmentsResult

type ListShipmentsResult struct {
	Shipments []*Shipment
	PageInfo  pagination.PageInfo
}

ListShipmentsResult holds the result of listing shipments.

type ListShippingTermsParams

type ListShippingTermsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Includes  []string
}

type ListShippingTermsResult

type ListShippingTermsResult struct {
	ShippingTerms []*ShippingTerm
	PageInfo      pagination.PageInfo
}

type ListSupplierMaterialsParams

type ListSupplierMaterialsParams struct {
	SupplierAccountID string
	OwnerAccountID    string
	Cursor            *string
	Limit             int32
	Query             *string
}

type ListSupplierMaterialsResult

type ListSupplierMaterialsResult struct {
	SupplierMaterials []*SupplierMaterial
	PageInfo          pagination.PageInfo
}

type ListSuppliersParams

type ListSuppliersParams struct {
	OwnerAccountID string
	Cursor         *string
	Limit          int32
	Query          *string
	ItemIDs        []string
	StartDate      *time.Time
	EndDate        *time.Time
	Includes       []string
}

ListSuppliersParams holds the parameters for listing suppliers.

type ListSuppliersResult

type ListSuppliersResult struct {
	Items    []*SupplierSummary
	PageInfo pagination.PageInfo
}

ListSuppliersResult holds the result of listing suppliers.

type ListSysPropertiesParams

type ListSysPropertiesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
}

type ListSysPropertiesResult

type ListSysPropertiesResult struct {
	SysProperties []*SysProperty
	PageInfo      pagination.PageInfo
}

type ListTerritoriesParams

type ListTerritoriesParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Includes  []string
}

ListTerritoriesParams contains the parameters for listing territories.

type ListTerritoriesResult

type ListTerritoriesResult struct {
	Territories []*Territory
	PageInfo    pagination.PageInfo
}

ListTerritoriesResult contains the result of listing territories.

type ListTransactionsParams

type ListTransactionsParams struct {
	AccountID           string
	Cursor              *string
	Limit               int32
	Query               *string
	Status              *string
	TypeCodes           []string
	AdjustmentTypeCodes []string
	MethodCodes         []string
	CustomerIDs         []string
	CustomerGroupIDs    []string
	StartDate           *time.Time
	EndDate             *time.Time
}

ListTransactionsParams holds parameters for listing transactions.

type ListTransactionsResult

type ListTransactionsResult struct {
	Transactions []*TransactionSummary
	PageInfo     pagination.PageInfo
}

ListTransactionsResult holds the result of listing transactions.

type ListUnitGroupsParams

type ListUnitGroupsParams struct {
	AccountID string
	Cursor    *string
	Limit     int32
	Query     *string
	Type      *string
	Includes  []string
}

type ListUnitGroupsResult

type ListUnitGroupsResult struct {
	UnitGroups []*UnitGroupFull
	PageInfo   pagination.PageInfo
}

type ListUnitsParams

type ListUnitsParams struct {
	AccountID    string
	Cursor       *string
	Limit        int32
	Query        *string
	Type         *string
	UnitGroupIDs []string
}

type ListUnitsResult

type ListUnitsResult struct {
	Units    []*Unit
	PageInfo pagination.PageInfo
}

type ListVolumeDiscountsParams

type ListVolumeDiscountsParams struct {
	AccountID         string
	CustomerAccountID *string
	Cursor            *string
	Limit             int32
	Query             *string
	Includes          []string
}

type ListVolumeDiscountsResult

type ListVolumeDiscountsResult struct {
	VolumeDiscounts []*VolumeDiscount
	PageInfo        pagination.PageInfo
}

type LoadPricingBundleParams

type LoadPricingBundleParams struct {
	OwnerAccountID string
	BuyerAccountID string
	ProductIDs     []string
	// OrderedUnitIDs are the per-line ordered unit ids; combined with the products' base denominator units to fetch all needed conversion units.
	OrderedUnitIDs []string
}

LoadPricingBundleParams identifies what to load for a pricing computation.

type LoadSolverInputParams

type LoadSolverInputParams struct {
	AccountID    string
	PlanningAsOf time.Time
	Settings     scheduling.Settings

	DemandWindowMonths    int
	ForecastHistoryMonths int
	ForecastMonths        int
	DemandBasisCode       string
	ForecastZ             float64

	// ConstraintDepartmentID is the department that sets the pace of the factory. Every machine in it is planned; everything downstream responds.
	ConstraintDepartmentID string

	ItemSettings map[string]ProductionScheduleItemSetting

	// DefaultFulfillmentPolicy is the last resort in the policy chain. Empty means make-to-stock.
	DefaultFulfillmentPolicy string

	// PinnedCampaigns are hand-edited campaigns already on the plan a regenerate is keeping; the solver plans around them.
	PinnedCampaigns []scheduling.PinnedCampaign
}

LoadSolverInputParams is everything needed to assemble a solve.

type Location

type Location struct {
	ID             string
	Name           string  `audit:"name"`
	TypeCode       string  `audit:"type_code"`
	ParentID       *string `audit:"parent_id"`
	ParentName     *string `audit:"parent_name"`
	ParentTypeCode *string `audit:"parent_type_code"`
	Children       []LocationChild
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

type LocationChild

type LocationChild struct {
	ID       string
	Name     string
	TypeCode string
}

LocationChild is a lightweight child reference.

type LocationRef

type LocationRef struct {
	ExistingID string
	BatchName  string
}

LocationRef is a resolved parent/child reference in a bulk upsert. It points either at a pre-existing location (ExistingID) or at another row in the same batch (BatchName — the lowercased row name), which the write phase resolves to that row's id once every row has been upserted. Exactly one field is set. No JSON tags: it round-trips job_items.

type LocationRepo

type LocationRepo interface {
	List(ctx context.Context, params ListLocationsParams) (*ListLocationsResult, *apierror.APIError)
	Export(ctx context.Context, params ExportLocationsParams) ([]*Location, *apierror.APIError)
	Get(ctx context.Context, params GetLocationParams) (*Location, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Location, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateLocationParams) (*Location, *apierror.APIError)
	Update(ctx context.Context, params UpdateLocationParams) (*Location, *apierror.APIError)
	Delete(ctx context.Context, params DeleteLocationParams) *apierror.APIError
	FindByNames(ctx context.Context, accountID string, names []string) ([]*Location, *apierror.APIError)
	LinkParent(ctx context.Context, accountID, childID, parentID string) *apierror.APIError
	ListTypes(ctx context.Context, params ListLocationTypesParams) (*ListLocationTypesResult, *apierror.APIError)
	GetType(ctx context.Context, idOrCode string) (*LocationType, *apierror.APIError)
	IsInAccount(ctx context.Context, accountID, id string) (bool, *apierror.APIError)
	CountChildren(ctx context.Context, accountID, parentID string) (int64, *apierror.APIError)
}

type LocationSvc

type LocationSvc interface {
	ListLocations(ctx context.Context, params ListLocationsParams) (*ListLocationsResult, *apierror.APIError)
	ExportLocations(ctx context.Context, params ExportLocationsParams) (*Job, *apierror.APIError)
	// BuildExportLocations renders the file an accepted export recorded.
	BuildExportLocations(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)
	GetLocation(ctx context.Context, params GetLocationParams) (*Location, *apierror.APIError)
	CreateLocation(ctx context.Context, params CreateLocationParams) (*Location, *apierror.APIError)
	UpdateLocation(ctx context.Context, params UpdateLocationParams) (*Location, *apierror.APIError)
	DeleteLocation(ctx context.Context, params DeleteLocationParams) *apierror.APIError
	BulkUpsertLocations(ctx context.Context, params BulkUpsertLocationsParams) (*Job, *apierror.APIError)
	ExecuteBulkUpsertLocations(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError
	ListLocationTypes(ctx context.Context, params ListLocationTypesParams) (*ListLocationTypesResult, *apierror.APIError)
	GetLocationType(ctx context.Context, params GetLocationTypeParams) (*LocationType, *apierror.APIError)
	BatchGetLocationsByIDs(ctx context.Context, ids []string) ([]*Location, *apierror.APIError)
}

type LocationType

type LocationType struct {
	ID        string
	Code      string
	Name      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

LocationType represents a location type.

type LotQuantityInput

type LotQuantityInput struct {
	Value  string
	UnitID string
}

LotQuantityInput is a lot on its way in: a decimal string and the unit it counts.

Both are required together. A size with no unit cannot say whether 60 means pairs or eaches, which is the distinction the whole setting exists to draw.

type Machine

type Machine struct {
	ID                  string
	Name                string  `audit:"name"`
	SerialNumber        string  `audit:"serial_number"`
	Notes               *string `audit:"notes"`
	DepartmentID        *string
	DepartmentName      *string `audit:"department_name"`
	DepartmentCreatedAt *time.Time
	DepartmentUpdatedAt *time.Time
	ProductionStepID    *string `audit:"production_step_id"`
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

type MachineCampaign

type MachineCampaign struct {
	ProductionScheduleLineID string
	ItemID                   string
	SKU                      string
	WeekStartDate            time.Time
	WeekIndex                int32
	PlannedQuantity          float64
	ScannedQuantity          float64
	// RemainingQuantity never goes below zero: an over-run is reported through the scanned figure rather than by making what is left negative.
	RemainingQuantity  float64
	Unit               string
	ReleasedBatchCount int64
	ScannedBatchCount  int64
	PlannedRunHours    float64
	StatusCode         string
	ProductionRunID    *string
}

MachineCampaign is one campaign on a machine, with how far through it the floor is.

type MachineDowntimeEvent

type MachineDowntimeEvent struct {
	ID        string
	AccountID string
	MachineID string `audit:"machine_id"`
	// DepartmentID and ProductionStepID are resolved from the machine at write time so downtime rolls up by department without joining through machine on read.
	DepartmentID     *string
	ProductionStepID *string

	ReasonCode      string `audit:"reason_code"`
	ReasonName      *string
	ReasonOeeBucket *string
	ReasonIsPlanned *bool

	StartedAt time.Time  `audit:"started_at"`
	EndedAt   *time.Time `audit:"ended_at"`
	// DurationSeconds is materialized when the event closes; nil while still down.
	DurationSeconds *int32

	ShiftDate time.Time
	ShiftCode *string

	ItemID          *string `audit:"item_id"`
	ProductionRunID *string `audit:"production_run_id"`
	BatchID         *string `audit:"batch_id"`
	ScheduleLineID  *string

	Note         *string `audit:"note"`
	ReportedByID string
	SourceCode   string `audit:"source_code"`

	CreatedAt time.Time
	UpdatedAt time.Time
}

func (*MachineDowntimeEvent) IsOpen

func (e *MachineDowntimeEvent) IsOpen() bool

IsOpen reports whether the machine is still down.

type MachineDowntimeReason

type MachineDowntimeReason struct {
	ID        string
	Code      string
	Name      string
	OeeBucket string
	IsPlanned bool
	SortOrder int32
	CreatedAt time.Time
	UpdatedAt time.Time
}

type MachineDowntimeRepo

type MachineDowntimeRepo interface {
	ListReasons(ctx context.Context) ([]*MachineDowntimeReason, *apierror.APIError)
	GetReason(ctx context.Context, code string) (*MachineDowntimeReason, *apierror.APIError)
	List(ctx context.Context, params ListMachineDowntimeEventsParams) (*ListMachineDowntimeEventsResult, *apierror.APIError)
	Get(ctx context.Context, params GetMachineDowntimeEventParams) (*MachineDowntimeEvent, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*MachineDowntimeEvent, *apierror.APIError)
	// GetOpenForMachine returns the machine's currently-open event, or nil when the machine is running. Used to reject a second concurrent open event.
	GetOpenForMachine(ctx context.Context, accountID, machineID string) (*MachineDowntimeEvent, *apierror.APIError)
	Create(ctx context.Context, id string, event *MachineDowntimeEvent) (*MachineDowntimeEvent, *apierror.APIError)
	Update(ctx context.Context, event *MachineDowntimeEvent) (*MachineDowntimeEvent, *apierror.APIError)
	Delete(ctx context.Context, params DeleteMachineDowntimeEventParams) *apierror.APIError
}

type MachineDowntimeSummary

type MachineDowntimeSummary struct {
	EventID    string
	Reason     string
	ReasonName string
	OEEBucket  string
	StartedAt  time.Time
	Note       *string
}

MachineDowntimeSummary is an open stoppage, as a floor display needs it.

type MachineDowntimeSvc

type MachineDowntimeSvc interface {
	// ListDowntimeReasons returns the global downtime reason taxonomy, ordered for display.
	ListDowntimeReasons(ctx context.Context) ([]*MachineDowntimeReason, *apierror.APIError)

	// ListDowntimeEvents returns a paginated list of downtime events for the caller's account.
	ListDowntimeEvents(ctx context.Context, params ListMachineDowntimeEventsParams) (*ListMachineDowntimeEventsResult, *apierror.APIError)

	// GetDowntimeEvent returns a single downtime event by ID.
	GetDowntimeEvent(ctx context.Context, eventID string) (*MachineDowntimeEvent, *apierror.APIError)

	// CreateDowntimeEvent logs a stoppage. Department and production step are resolved from the machine; an open event (no end) records that the machine is still down.
	CreateDowntimeEvent(ctx context.Context, params CreateMachineDowntimeEventParams) (*MachineDowntimeEvent, *apierror.APIError)

	// UpdateDowntimeEvent closes or reclassifies an event.
	UpdateDowntimeEvent(ctx context.Context, params UpdateMachineDowntimeEventParams) (*MachineDowntimeEvent, *apierror.APIError)

	// DeleteDowntimeEvent removes a mis-logged event.
	DeleteDowntimeEvent(ctx context.Context, eventID string) *apierror.APIError

	// BatchGetDowntimeEventsByIDs returns downtime events by their IDs for include resolution.
	BatchGetDowntimeEventsByIDs(ctx context.Context, ids []string) ([]*MachineDowntimeEvent, *apierror.APIError)
}

type MachineForStatusRow

type MachineForStatusRow struct {
	ID   string
	Name string
	// DepartmentID is NOT NULL on machine, so an empty string is the "unassigned" case.
	DepartmentID   string
	DepartmentName *string
}

MachineForStatusRow is one machine as stored, before any plan or downtime is attached to it.

type MachineRepo

type MachineRepo interface {
	List(ctx context.Context, params ListMachinesParams) (*ListMachinesResult, *apierror.APIError)
	// Export returns every matching machine up to params.Limit, unpaginated.
	Export(ctx context.Context, params ExportMachinesParams) ([]*Machine, *apierror.APIError)
	Get(ctx context.Context, params GetMachineParams) (*Machine, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Machine, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateMachineParams) (*Machine, *apierror.APIError)
	Update(ctx context.Context, params UpdateMachineParams) (*Machine, *apierror.APIError)
	Delete(ctx context.Context, params DeleteMachineParams) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	// FindByNames resolves existing machines by name (case-insensitive) in one query.
	// Used by bulk upsert; names must be pre-lowercased by the caller.
	FindByNames(ctx context.Context, accountID string, names []string) ([]*Machine, *apierror.APIError)
	// ExistsBySerialNumber reports whether another machine in the account already
	// uses the serial number (case-insensitive), optionally excluding one machine.
	ExistsBySerialNumber(ctx context.Context, accountID, serialNumber string, excludeID *string) (bool, *apierror.APIError)
	// FindBySerialNumbers resolves existing machines by serial number
	// (case-insensitive) in one query.
	FindBySerialNumbers(ctx context.Context, accountID string, serialNumbers []string) ([]*Machine, *apierror.APIError)
}

type MachineStatus

type MachineStatus struct {
	MachineID      string
	MachineName    string
	DepartmentID   *string
	DepartmentName *string
	Status         constants.MachineWorkStatus
	Downtime       *MachineDowntimeSummary
	// Current is the campaign being worked: the earliest released one with batches still unscanned. A machine whose released work is all scanned has finished it, so the next campaign becomes current instead.
	Current *MachineCampaign
	// Next is what follows Current in the plan, so an operator can set up for it.
	Next *MachineCampaign
	// This week's totals for the machine, which is the number management tracks.
	WeekPlannedQuantity float64
	WeekScannedQuantity float64
	WeekPlannedRunHours float64
	Unit                string
}

MachineStatus is one machine's whole picture: what it is on, what is left, what is next.

type MachineStatusRepo

type MachineStatusRepo interface {
	// ListMachinesForStatus returns every machine that can carry work, whether or not the plan has given it any, ordered by name then id.
	ListMachinesForStatus(ctx context.Context, accountID string) ([]MachineForStatusRow, *apierror.APIError)
	// ListOpenDowntimeForStatus returns the machines that are down right now — one row per machine, as the open-event guard enforces on write.
	ListOpenDowntimeForStatus(ctx context.Context, accountID string) ([]OpenDowntimeForStatusRow, *apierror.APIError)
	// ListScheduleLinesForStatus returns a published schedule's lines from the given week forward, with per-campaign scan progress, ordered by machine, week, sequence, id.
	ListScheduleLinesForStatus(ctx context.Context, params ListScheduleLinesForStatusParams) ([]ScheduleLineForStatusRow, *apierror.APIError)
}

MachineStatusRepo reads the raw pieces the floor-status view is assembled from.

type MachineStatusResult

type MachineStatusResult struct {
	// ProductionScheduleID is the published version the picture is read from, empty when nothing is published — in which case every machine is idle rather than the endpoint failing, since the floor still exists when planning has not caught up.
	ProductionScheduleID string
	WeekStartDate        time.Time
	Machines             []MachineStatus
}

MachineStatusResult is the whole floor at one moment.

type MachineStatusSvc

type MachineStatusSvc interface {
	ListMachineStatus(ctx context.Context, params ListMachineStatusParams) (*MachineStatusResult, *apierror.APIError)
}

MachineStatusSvc answers "what is the floor doing right now".

type MachineSvc

type MachineSvc interface {
	// ListMachines returns a paginated list of machines for the caller's account.
	ListMachines(ctx context.Context, params ListMachinesParams) (*ListMachinesResult, *apierror.APIError)

	// ExportMachines accepts an export and returns the job that tracks it.
	ExportMachines(ctx context.Context, params ExportMachinesParams) (*Job, *apierror.APIError)
	// BuildExportMachines renders the file an accepted export recorded.
	BuildExportMachines(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// GetMachine returns a single machine by ID.
	GetMachine(ctx context.Context, machineID string) (*Machine, *apierror.APIError)

	// CreateMachine creates a new machine.
	CreateMachine(ctx context.Context, params CreateMachineParams) (*Machine, *apierror.APIError)

	// UpdateMachine partially updates a machine.
	UpdateMachine(ctx context.Context, params UpdateMachineParams) (*Machine, *apierror.APIError)

	// accepts a bulk upsert of machines returns the job to poll.
	BulkUpsertMachines(ctx context.Context, params BulkUpsertMachinesParams) (*Job, *apierror.APIError)

	// performs the writes for an enqueued bulk upsert.
	ExecuteBulkUpsertMachines(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// DeleteMachine deletes a machine.
	DeleteMachine(ctx context.Context, machineID string) *apierror.APIError

	// BatchGetMachinesByIDs returns machines by their IDs for include resolution.
	BatchGetMachinesByIDs(ctx context.Context, ids []string) ([]*Machine, *apierror.APIError)
}

type ManufacturingBatchResult

type ManufacturingBatchResult struct {
	Current    ManufacturingMetrics
	Comparison ManufacturingMetrics
}

type ManufacturingMetrics

type ManufacturingMetrics struct {
	Production      float64
	CostsPerUnit    float64
	Margin          float64
	Quality         float64
	LaborEfficiency float64
}

type Material

type Material struct {
	ID         string
	ItemID     string
	Item       *Item     `audit:"item"`
	OrderPoint *Quantity `audit:"order_point"`
	LeadTime   *Quantity `audit:"lead_time"`
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

Material represents a material entity, which extends an Item with order point and lead time quantities.

type MaterialAnalyticsEntry

type MaterialAnalyticsEntry struct {
	MaterialID          string
	ItemID              string
	Sku                 string
	Description         *string
	QuantityInInventory MaterialBaseQuantity
	OrderPoint          *MaterialBaseQuantity
	LeadTime            *MaterialBaseQuantity
	QuantityInDemand    MaterialBaseQuantity
	UnitGroup           MaterialUnitGroup
	SupplierNames       []string
	SupplierPartNumbers []string
}

type MaterialBaseQuantity

type MaterialBaseQuantity struct {
	Measure          float64
	UnitName         string
	UnitAbbreviation string
	UnitType         string
}

type MaterialDemandItem

type MaterialDemandItem struct {
	ItemID  string
	Measure decimal.Decimal
	UnitID  string
}

MaterialDemandItem represents a single material demand entry from a BOM explosion.

type MaterialDemandLineInput

type MaterialDemandLineInput struct {
	ItemID  string
	Measure decimal.Decimal
	UnitID  string
}

MaterialDemandLineInput is one order line to explode when computing aggregated material demand.

type MaterialDemandRepo

type MaterialDemandRepo interface {
	// GetMaterialDemand calculates the material demand for producing the given items.
	GetMaterialDemand(ctx context.Context, accountID string, productItemID string, measure decimal.Decimal, unitID string) ([]MaterialDemandItem, *apierror.APIError)
	// GetMaterialDemandForOrder calculates the aggregated material demand across a set of order lines (one entry per material).
	GetMaterialDemandForOrder(ctx context.Context, accountID string, lines []MaterialDemandLineInput) ([]MaterialDemandItem, *apierror.APIError)
}

MaterialDemandRepo calculates material demand from a bill of materials.

type MaterialRepo

type MaterialRepo interface {
	List(ctx context.Context, params ListMaterialsParams) (*ListMaterialsResult, *apierror.APIError)
	Export(ctx context.Context, params ExportMaterialsParams) ([]*Material, *apierror.APIError)
	GetByID(ctx context.Context, params GetMaterialParams) (*Material, *apierror.APIError)
	GetByItemID(ctx context.Context, accountID, itemID string) (*Material, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Material, *apierror.APIError)
	Create(ctx context.Context, materialID, itemID, orderPointID, leadTimeID string) *apierror.APIError
	Update(ctx context.Context, params UpdateMaterialParams) *apierror.APIError
	DeleteByID(ctx context.Context, accountID, materialID string) *apierror.APIError
	DeleteByItemID(ctx context.Context, accountID, itemID string) *apierror.APIError
	InsertQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	UpdateQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	InsertRate(ctx context.Context, id, value, numeratorUnitID, denominatorUnitID string) *apierror.APIError
	InsertItem(ctx context.Context, params InsertMaterialItemParams) *apierror.APIError
	// FindBySKUs batch-resolves existing materials by SKU within the account, returning the
	// IDs needed to update them. Used by bulk upsert.
	FindBySKUs(ctx context.Context, accountID string, skus []string) ([]*MaterialSKUMatch, *apierror.APIError)
	UpdateItem(ctx context.Context, params UpdateMaterialParams) *apierror.APIError
}

type MaterialSKUMatch

type MaterialSKUMatch struct {
	MaterialID      string
	ItemID          string
	SKU             string
	CategoryID      string
	UnitValueRateID string
	UnitCostRateID  string
}

MaterialSKUMatch is an existing material keyed by SKU, with the IDs needed to update it.

type MaterialSvc

type MaterialSvc interface {
	// ListMaterials returns a paginated list of materials for the caller's account.
	ListMaterials(ctx context.Context, params ListMaterialsParams) (*ListMaterialsResult, *apierror.APIError)

	// ExportMaterials accepts an export and returns the job that tracks it.
	ExportMaterials(ctx context.Context, params ExportMaterialsParams) (*Job, *apierror.APIError)
	// BuildExportMaterials renders the file an accepted export recorded.
	BuildExportMaterials(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// GetMaterial returns a single material by ID.
	GetMaterial(ctx context.Context, params GetMaterialParams) (*Material, *apierror.APIError)

	// CreateMaterial creates a new material.
	CreateMaterial(ctx context.Context, params CreateMaterialParams) (*Material, *apierror.APIError)

	// UpdateMaterial partially updates a material.
	UpdateMaterial(ctx context.Context, params UpdateMaterialParams) (*Material, *apierror.APIError)

	// BulkUpsertMaterials creates or updates multiple materials in one atomic transaction, matched by SKU.
	BulkUpsertMaterials(ctx context.Context, params BulkUpsertMaterialsParams) (*Job, *apierror.APIError)

	// performs the writes for an enqueued bulk material upsert.
	ExecuteBulkUpsertMaterials(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// DeleteMaterial soft-deletes a material by its item ID.
	DeleteMaterial(ctx context.Context, itemID string) (*Material, *apierror.APIError)

	// BatchGetMaterialsByIDs returns materials by their IDs for include resolution.
	BatchGetMaterialsByIDs(ctx context.Context, ids []string) ([]*Material, *apierror.APIError)
}

type MaterialUnitGroup

type MaterialUnitGroup struct {
	ID    string
	Name  string
	Units []MaterialUnitGroupUnit
}

type MaterialUnitGroupUnit

type MaterialUnitGroupUnit struct {
	ID               string
	Name             string
	Abbreviation     string
	ConversionFactor float64
	IsBaseUnit       bool
}

type MeasureSvc

type MeasureSvc interface {
	UpdateQuantity(ctx context.Context, params UpdateQuantityParams) (*Quantity, *apierror.APIError)
	UpdateRate(ctx context.Context, params UpdateRateParams) (*Rate, *apierror.APIError)
}

type MediatorFactory

type MediatorFactory interface {
	Build(RepoFactory) Mediators
}

MediatorFactory builds mediators bound to a given repository factory (e.g., per transaction).

type Mediators

type Mediators struct {
	Sandbox        SandboxMed
	Idempotency    IdempotencyMed
	ReadAccess     ReadAccessMed
	EditAccess     EditAccessMed
	ProductionFlow ProductionFlowMed
	BurnRate       BurnRateMed
}

Mediators groups all mediator dependencies built for a specific repository factory.

type MergeBatchesParams

type MergeBatchesParams struct {
	BatchIDs          []string
	ScanningStationID string
	ProductionStepID  string
}

MergeBatchesParams holds the parameters for merging batches.

type MergeCustomersParams

type MergeCustomersParams struct {
	OwnerAccountID    string
	TargetCustomerID  string
	SourceCustomerIDs []string
	Includes          []string
}

MergeCustomersParams holds the parameters for merging customers.

type MoveBatchesParams

type MoveBatchesParams struct {
	BatchIDs          []string
	ProductionStepID  string
	ScanningStationID string
}

MoveBatchesParams holds the parameters for moving batches.

type NewCustomerEntry

type NewCustomerEntry struct {
	CreatedAt time.Time
}

type NextStepQuantitiesResult

type NextStepQuantitiesResult struct {
	Quantity       decimal.Decimal
	ItemID         string
	ProducedUnitID string
}

NextStepQuantitiesResult holds the result of calculating quantities for the next production step.

type NotificationPreference

type NotificationPreference struct {
	ID                   string
	NotificationTypeCode string
}

NotificationPreference represents a stored notification preference.

type NotificationPreferenceItem

type NotificationPreferenceItem struct {
	NotificationTypeCode string
	Enabled              bool
}

NotificationPreferenceItem represents a single preference toggle.

type NotificationPublisher

type NotificationPublisher interface {
	// PublishSendEmail writes a send-email command to the outbox for reliable delivery.
	PublishSendEmail(ctx context.Context, data messaging.EmailSendData) *apierror.APIError
}

NotificationPublisher publishes email notification messages via the outbox pattern.

type NotificationRecipient

type NotificationRecipient struct {
	AccountUser           *AccountUserDetail
	NotificationTypeCodes []string
}

NotificationRecipient is a default order-notification recipient for a customer relationship: the hydrated account user (on the customer's account) and the notification types they receive.

type NotificationRecipientInput

type NotificationRecipientInput struct {
	AccountUserID         string
	NotificationTypeCodes []string
}

NotificationRecipientInput is a requested recipient when replacing a relationship's defaults: an account user id and the notification types to configure for them.

type NotificationRecipientRef

type NotificationRecipientRef struct {
	AccountUserID         string
	NotificationTypeCodes []string
}

NotificationRecipientRef is a raw (recipient account user id, notification types) grouping from storage, before the account user is hydrated.

type ObjectIdentifier

type ObjectIdentifier struct {
	ID   string
	Name string
}

ObjectIdentifier identifies an object by its ID or name. Precedence: ID, then name.

type OeeDepartment

type OeeDepartment struct {
	DepartmentID          string
	DepartmentName        string
	GoodUnits             float64
	WasteUnits            float64
	SecondsUnits          float64
	EstimatedRuntimeHours float64

	// StandardSecondsEarned is the time the period's output should have taken at each production step's own labor rate: ideal cycle time multiplied by units produced. It is the numerator of Performance.
	StandardSecondsEarned float64

	// Measured downtime, split by the OEE term each reason charges. NotScheduled is removed from the denominator rather than counted as a loss.
	AvailabilityLossSeconds float64
	PerformanceLossSeconds  float64
	QualityLossSeconds      float64
	NotScheduledSeconds     float64
	ChangeoverSeconds       float64
	DowntimeEventCount      int64
	DowntimeBreakdown       []OeeDowntimeReason

	// ScheduledSeconds is planned time net of not-scheduled downtime; RunTimeSeconds is scheduled time net of availability losses.
	ScheduledSeconds float64
	RunTimeSeconds   float64

	// Ratios are nil when their denominator is zero or planned time is unknown. A department with no scheduled time has no OEE, which is not the same as 0% OEE.
	AvailabilityPct *float64
	PerformancePct  *float64
	QualityPct      *float64
	OeePct          *float64

	// HasDowntimeData is false when nothing was logged for this department in the window. Callers must surface that: a department that logs no downtime computes 100% Availability, which reads as an improvement rather than missing data.
	HasDowntimeData bool
	// HasPerformanceAnomaly flags Performance > 1, which always means a stale run rate. The raw value is still reported rather than clamped, so the data-quality problem stays visible.
	HasPerformanceAnomaly bool
}

type OeeDepartmentDataRow

type OeeDepartmentDataRow struct {
	DepartmentID          string
	DepartmentName        string
	GoodUnits             float64
	WasteUnits            float64
	SecondsUnits          float64
	StandardSecondsEarned float64
}

OeeDepartmentDataRow is one department's unit counts and standard time earned in the window.

type OeeDowntimeIntervalRow

type OeeDowntimeIntervalRow struct {
	DepartmentID string
	OeeBucket    string
	StartedAt    time.Time
	EndedAt      time.Time
}

OeeDowntimeIntervalRow is one department's logged downtime window, unclipped: open events arrive already coalesced to now.

type OeeDowntimeReason

type OeeDowntimeReason struct {
	ReasonCode      string
	OeeBucket       string
	DowntimeSeconds float64
	EventCount      int64
}

OeeDowntimeReason is one reason's contribution to a department's downtime.

type OeeDowntimeRow

type OeeDowntimeRow struct {
	DepartmentID    string
	ReasonCode      string
	OeeBucket       string
	DowntimeSeconds int64
	EventCount      int64
}

OeeDowntimeRow is one department-reason aggregate of logged downtime, clipped to the reporting window.

type OeeEstimatedRuntimeRow

type OeeEstimatedRuntimeRow struct {
	DepartmentID   string
	RuntimeSeconds float64
}

OeeEstimatedRuntimeRow is one department's estimated runtime in the window.

type OeeTrendDepartmentWeekRow

type OeeTrendDepartmentWeekRow struct {
	WeekStart             time.Time
	DepartmentID          string
	DepartmentName        string
	GoodUnits             float64
	WasteUnits            float64
	SecondsUnits          float64
	StandardSecondsEarned float64
}

OeeTrendDepartmentWeekRow is one department's output in one production week.

type OeeTrendPeriod

type OeeTrendPeriod struct {
	StartsAt time.Time
	// EndsAt is exclusive, and is clipped to the requested window so the first and last weeks of a range report against the part of the week that was actually asked for.
	EndsAt time.Time

	GoodUnits             float64
	WasteUnits            float64
	SecondsUnits          float64
	StandardSecondsEarned float64

	ScheduledSeconds        float64
	RunTimeSeconds          float64
	AvailabilityLossSeconds float64
	NotScheduledSeconds     float64

	AvailabilityPct *float64
	PerformancePct  *float64
	QualityPct      *float64
	OeePct          *float64

	// HasDowntimeData is false when nothing was logged in this week, which makes its Availability an estimate rather than a measurement — the same distinction AnalyzeOee draws per department.
	HasDowntimeData    bool
	DowntimeEventCount int64
}

OeeTrendPeriod is one production week of OEE, rolled up across the departments that had scheduled time in it.

The roll-up is weighted by seconds rather than averaged across departments: a room that ran an hour must not weigh as heavily as one that ran all week.

type OpenBatchEntry

type OpenBatchEntry struct {
	BatchID             string
	BatchNumber         string
	ItemID              string
	ProductSku          string
	ProductDescription  *string
	ScanningStationName *string
	ScanningStationID   *string
	Quantity            float64
	Unit                string
	CreatedAt           time.Time
}

type OpenBatchSummary

type OpenBatchSummary struct {
	DepartmentName    string
	ItemName          string
	ItemID            string
	ScanningStationID string
	Count             decimal.Decimal
	Unit              string
}

OpenBatchSummary represents an aggregated open batch summary for analytics.

type OpenCredit

type OpenCredit struct {
	ID             string
	Number         string
	CreatedAt      time.Time
	OriginalAmount string
	LeftoverAmount string
}

OpenCredit represents an open credit memo or payment with remaining balance.

type OpenCreditEntry

type OpenCreditEntry struct {
	ID                  string
	Number              string
	OriginalAmount      string
	AllocatedAmount     string
	LeftoverAmount      string
	CustomerID          string
	CustomerName        string
	CustomerNumber      *string
	TransactionType     string
	TransactionMethod   *string
	AdjustmentType      *string
	ResponsibleUserName *string
	Note                *string
	StripePaymentID     *string
	InvoiceAllocations  []InvoiceAllocationEntry
	CreatedAt           time.Time
}

OpenCreditEntry represents an open (not fully allocated) credit transaction.

type OpenDowntimeForStatusRow

type OpenDowntimeForStatusRow struct {
	ID         string
	MachineID  string
	ReasonCode string
	ReasonName *string
	OEEBucket  *string
	StartedAt  time.Time
	Note       *string
}

OpenDowntimeForStatusRow is an open stoppage as stored.

type OpenInventoryIssue

type OpenInventoryIssue struct {
	ID            string
	QuantityID    string
	QuantityValue string
	UnitID        string
	LocationID    *string
	LotID         *string
}

OpenInventoryIssue represents an open inventory issue for FIFO allocation.

type OpenOrderRequirementRow

type OpenOrderRequirementRow struct {
	SalesOrderID     string
	SalesOrderNumber string
	SalesOrderLineID string
	ProductID        string
	ShipByDate       *time.Time
	OutstandingQty   float64
}

OpenOrderRequirementRow is one issued order line's outstanding quantity and the date it is due to ship.

This is demand the plan owes rather than demand it forecasts. ShipByDate is nil for orders issued before commitments were tracked.

type OperatingCalendar

type OperatingCalendar struct {
	ID        string `audit:"id"`
	AccountID string `audit:"account_id"`
	Code      string `audit:"code"`
	Name      string `audit:"name"`
	KindCode  string `audit:"operating_calendar_kind_code"`
	// DaysOfWeek is an ISO Mon-Sun bitmask, '1' for an open day.
	DaysOfWeek string `audit:"days_of_week"`
	// CutoffAt is the local time freight has to be tendered by, as "15:00". Ship calendars only.
	CutoffAt *string `audit:"cutoff_at"`
	// Timezone is the IANA zone the cutoff is read in. Nil on a receive calendar means derive it from the ship-to address.
	Timezone  *string `audit:"timezone"`
	IsDefault bool    `audit:"is_default"`
	CreatedAt time.Time
	UpdatedAt time.Time

	// Closures are the calendar's dated shutdowns, populated only when a caller asked for a window of them.
	Closures []OperatingCalendarClosure
}

OperatingCalendar is the set of days one party to a shipment operates.

type OperatingCalendarClosure

type OperatingCalendarClosure struct {
	ID         string    `audit:"id"`
	AccountID  string    `audit:"account_id"`
	CalendarID string    `audit:"operating_calendar_id"`
	ClosedOn   time.Time `audit:"closed_on"`
	Name       string    `audit:"name"`
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

OperatingCalendarClosure is one date a calendar is shut.

type OperatingCalendarReferences

type OperatingCalendarReferences struct {
	Addresses int64
	Customers int64
	Groups    int64
	Settings  int64
}

OperatingCalendarReferences counts what still points at a calendar, so a delete can explain what it would break rather than silently returning links to a missing row.

func (OperatingCalendarReferences) Total

Total is how many links exist in all.

type OperatingCalendarRepo

type OperatingCalendarRepo interface {
	Get(ctx context.Context, accountID, calendarID string) (*OperatingCalendar, *apierror.APIError)
	GetByCode(ctx context.Context, accountID, code string) (*OperatingCalendar, *apierror.APIError)
	List(ctx context.Context, params ListOperatingCalendarsParams) ([]OperatingCalendar, *apierror.APIError)
	// ResolveShip returns the calendar the account tenders freight on, preferring an explicitly configured one over the account default. Nil means none is configured, and the caller falls back to Monday-to-Friday.
	ResolveShip(ctx context.Context, accountID string) (*OperatingCalendar, *apierror.APIError)
	// ResolveReceive walks address -> customer -> customer's group -> account setting -> account default in one query. Nil means none is configured anywhere on the chain.
	ResolveReceive(ctx context.Context, query ReceiveCalendarQuery) (*OperatingCalendar, *apierror.APIError)
	// ListClosures returns closures for a set of calendars inside a bounded window, keyed by calendar ID.
	ListClosures(ctx context.Context, query ClosureWindowQuery) (map[string][]OperatingCalendarClosure, *apierror.APIError)
	Create(ctx context.Context, params CreateOperatingCalendarParams) *apierror.APIError
	Update(ctx context.Context, params UpdateOperatingCalendarParams) *apierror.APIError
	// ClearDefault demotes every other calendar of the same kind, so exactly one default survives per kind.
	ClearDefault(ctx context.Context, accountID, kindCode, keepID string) *apierror.APIError
	// Delete is a soft delete: an issued order's commitment was resolved against this calendar, and a hard delete would orphan the links that explain it.
	Delete(ctx context.Context, accountID, calendarID string) *apierror.APIError
	CountReferences(ctx context.Context, accountID, calendarID string) (*OperatingCalendarReferences, *apierror.APIError)
	GetClosure(ctx context.Context, accountID, closureID string) (*OperatingCalendarClosure, *apierror.APIError)
	// GetClosureByDate reads a closure back by the key it is unique on, so a re-closed date returns the row that was already there rather than a discarded ID.
	GetClosureByDate(ctx context.Context, accountID, calendarID string, closedOn time.Time) (*OperatingCalendarClosure, *apierror.APIError)
	// UpsertClosures is idempotent, so re-seeding a year neither duplicates a closure nor renames one an operator has relabelled.
	UpsertClosures(ctx context.Context, closures []UpsertClosureParams) *apierror.APIError
	DeleteClosure(ctx context.Context, accountID, closureID string) *apierror.APIError
}

OperatingCalendarRepo reads and writes the day-sets a commitment is resolved against.

type OperatingCalendarSvc

type OperatingCalendarSvc interface {
	ListOperatingCalendars(ctx context.Context, kindCode *string) ([]OperatingCalendar, *apierror.APIError)
	GetOperatingCalendar(ctx context.Context, calendarID string) (*OperatingCalendar, *apierror.APIError)
	CreateOperatingCalendar(ctx context.Context, params CreateOperatingCalendarParams) (*OperatingCalendar, *apierror.APIError)
	UpdateOperatingCalendar(ctx context.Context, params UpdateOperatingCalendarParams) (*OperatingCalendar, *apierror.APIError)
	// DeleteOperatingCalendar refuses while anything still references the calendar, rather than silently returning every affected customer to Monday-to-Friday.
	DeleteOperatingCalendar(ctx context.Context, calendarID string) *apierror.APIError
	ListOperatingCalendarClosures(ctx context.Context, calendarID string, from, to *time.Time) ([]OperatingCalendarClosure, *apierror.APIError)
	CreateOperatingCalendarClosure(ctx context.Context, calendarID string, closedOn time.Time, name string) (*OperatingCalendarClosure, *apierror.APIError)
	DeleteOperatingCalendarClosure(ctx context.Context, closureID string) *apierror.APIError
}

OperatingCalendarSvc manages the day-sets a ship-by commitment is resolved against.

Internal-only throughout: a customer has no business seeing which days their supplier's plant runs, and the calendars are account configuration rather than anything about a particular order.

type OrderDiscount

type OrderDiscount struct {
	ID               string
	Name             string `audit:"name"`
	Code             string `audit:"code"`
	Percentage       string `audit:"percentage"`
	Amount           string `audit:"amount"`
	DiscountTypeCode string `audit:"discount_type_code"`
	OrderCount       int32  `audit:"order_count"`
	AccountID        string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

type OrderDiscountRepo

type OrderDiscountRepo interface {
	List(ctx context.Context, params ListOrderDiscountsParams) (*ListOrderDiscountsResult, *apierror.APIError)
	Get(ctx context.Context, params GetOrderDiscountParams) (*OrderDiscount, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*OrderDiscount, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateOrderDiscountParams) (*OrderDiscount, *apierror.APIError)
	Update(ctx context.Context, params UpdateOrderDiscountParams) (*OrderDiscount, *apierror.APIError)
	Delete(ctx context.Context, params DeleteOrderDiscountParams) (*OrderDiscount, *apierror.APIError)
	ExistsByCode(ctx context.Context, accountID, code string, excludeID *string) (bool, *apierror.APIError)
	FindByCode(ctx context.Context, accountID, code string) (*OrderDiscount, *apierror.APIError)
	CheckDuplicateUsage(ctx context.Context, accountID, buyerAccountID, orderDiscountID string, salesOrderID *string) (bool, *apierror.APIError)
}

type OrderDiscountSvc

type OrderDiscountSvc interface {
	// ListOrderDiscounts returns a paginated list of order discounts for the caller's account.
	ListOrderDiscounts(ctx context.Context, params ListOrderDiscountsParams) (*ListOrderDiscountsResult, *apierror.APIError)

	// GetOrderDiscount returns a single order discount by ID.
	GetOrderDiscount(ctx context.Context, orderDiscountID string) (*OrderDiscount, *apierror.APIError)

	// CreateOrderDiscount creates a new order discount.
	CreateOrderDiscount(ctx context.Context, params CreateOrderDiscountParams) (*OrderDiscount, *apierror.APIError)

	// UpdateOrderDiscount partially updates an order discount.
	UpdateOrderDiscount(ctx context.Context, params UpdateOrderDiscountParams) (*OrderDiscount, *apierror.APIError)

	// DeleteOrderDiscount deletes an order discount and returns the deleted resource.
	DeleteOrderDiscount(ctx context.Context, orderDiscountID string) (*OrderDiscount, *apierror.APIError)

	// FindOrderDiscountByCode finds an order discount by its code. Supports both internal and customer actors.
	FindOrderDiscountByCode(ctx context.Context, params FindOrderDiscountByCodeParams) (*OrderDiscount, *apierror.APIError)

	// BatchGetOrderDiscountsByIDs returns order discounts matching the input IDs that the caller's account is authorized to read. Used by the api-gateway resourcekit include resolver.
	BatchGetOrderDiscountsByIDs(ctx context.Context, ids []string) ([]*OrderDiscount, *apierror.APIError)
}

type OrderEntry

type OrderEntry struct {
	ID                  string
	IssuedAt            *time.Time
	CompletedAt         *time.Time
	FirstShipAt         *time.Time
	PromisedAt          *time.Time
	CustomerPO          *string
	OrderNumber         string
	OrderID             string
	SalesRepID          *string
	SalesRepUsername    *string
	CustomerID          string
	ParentCustomerID    *string
	CustomerName        string
	CustomerNumber      string
	CustomerCreatedAt   time.Time
	CustomerTypeGroupID *string
	CustomerGroupName   *string
	ProductLineID       *string
	ProductTypeCode     string
	ItemID              string
	ProductSku          string
	ProductDescription  *string
	CategoryName        string
	ProductLine         *string
	QuantityOrdered     float64
	QuantityInvoiced    float64
	QuantityBackOrdered float64
	Unit                string
	UnitCost            float64
	UnitPrice           float64
	UnitProfit          float64
	TotalInvoiced       float64
	TotalCost           float64
	TotalProfit         float64
	TotalOrdered        float64
	TotalBackOrdered    float64
	ShipToState         *string
	ShipToCity          *string
	ShipToZipcode       *string
	ShipToCountry       *string
	OrderDiscountCode   *string
}

type OrderPaymentIntent

type OrderPaymentIntent struct {
	ID              string
	PaymentIntentID string
	SalesOrderID    string
}

OrderPaymentIntent links a Stripe payment intent to a sales order.

type OrderPaymentIntentRepo

type OrderPaymentIntentRepo interface {
	Create(ctx context.Context, id, paymentIntentID, salesOrderID string) *apierror.APIError
	FindByPaymentIntentID(ctx context.Context, paymentIntentID string) (*OrderPaymentIntent, *apierror.APIError)
	Delete(ctx context.Context, id string) *apierror.APIError
}

type OrderQuantityByProductLineRow

type OrderQuantityByProductLineRow struct {
	TotalQuantity    float64
	UnitAbbreviation string
	UnitType         string
}

OrderQuantityByProductLineRow is the aggregate ordered quantity for a product line within a window.

type OrderQueryRepo

type OrderQueryRepo interface {
	// FindIDByProductionRun returns the order ID for the given production run, or nil if no order exists.
	FindIDByProductionRun(ctx context.Context, accountID, productionRunID string) (*string, *apierror.APIError)
}

OrderQueryRepo provides read-only queries for orders needed by the batch/production system.

type OrderReservationReductionParams

type OrderReservationReductionParams struct {
	OrderID   string
	AccountID string
	ItemID    string
	Measure   decimal.Decimal
	UnitID    string
}

OrderReservationReductionParams describes a shortfall reduction on an order item's reservation.

type PackPickJob

type PackPickJob struct {
	PickID            string
	ShipmentCaseCount int32
}

Records what a pack was accepted to do. Stored on the job, so it carries only resolved ids.

type Parcel

type Parcel struct {
	Weight string
	Length string
	Width  string
	Height string
}

Parcel represents a package for rate estimation.

type Part

type Part struct {
	ID        string
	ItemID    string
	Item      *Item
	CreatedAt time.Time
	UpdatedAt time.Time
}

Part represents a part entity (specialization of Item).

type PartRepo

type PartRepo interface {
	Create(ctx context.Context, partID, itemID string, params CreatePartParams) (*Part, *apierror.APIError)
	Get(ctx context.Context, params GetPartParams) (*Part, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Part, *apierror.APIError)
	List(ctx context.Context, params ListPartsParams) (*ListPartsResult, *apierror.APIError)
	Export(ctx context.Context, params ExportPartsParams) ([]*Part, *apierror.APIError)
	Delete(ctx context.Context, params DeletePartParams) *apierror.APIError
	ExistsBySKU(ctx context.Context, accountID, sku string, excludeItemID *string) (bool, *apierror.APIError)
	// FindBySKUs batch-resolves existing parts by SKU within the account, returning the
	// part/item IDs and unit_value/unit_cost rate IDs needed to update them.
	FindBySKUs(ctx context.Context, accountID string, skus []string) ([]*PartSKUMatch, *apierror.APIError)
	InsertRate(ctx context.Context, id, value, numeratorUnitID, denominatorUnitID string) *apierror.APIError
	InsertItem(ctx context.Context, itemID string, params CreatePartParams, unitValueID, burnRateID, unitCostID string) *apierror.APIError
	TouchUpdatedAt(ctx context.Context, partID string) *apierror.APIError
	UpdateItem(ctx context.Context, params PartUpdateItemParams) *apierror.APIError
}

type PartSKUMatch

type PartSKUMatch struct {
	PartID          string
	ItemID          string
	SKU             string
	CategoryID      string
	UnitValueRateID string
	UnitCostRateID  string
}

PartSKUMatch is an existing part keyed by SKU, with the IDs needed to update it.

type PartSvc

type PartSvc interface {
	// CreatePart creates a new part with its associated item and rates.
	CreatePart(ctx context.Context, params CreatePartParams) (*Part, *apierror.APIError)

	// GetPart returns a single part by ID.
	GetPart(ctx context.Context, params GetPartParams) (*Part, *apierror.APIError)

	// ListParts returns a paginated list of parts for the caller's account.
	ListParts(ctx context.Context, params ListPartsParams) (*ListPartsResult, *apierror.APIError)

	// ExportParts accepts an export and returns the job that tracks it.
	ExportParts(ctx context.Context, params ExportPartsParams) (*Job, *apierror.APIError)
	// BuildExportParts renders the file an accepted export recorded.
	BuildExportParts(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// UpdatePart partially updates a part's item fields.
	UpdatePart(ctx context.Context, params UpdatePartParams) (*Part, *apierror.APIError)

	// accepts a bulk upsert of parts and returns the job that carries it out, matching by
	// SKU within the account.
	BulkUpsertParts(ctx context.Context, params BulkUpsertPartsParams) (*Job, *apierror.APIError)

	// performs the writes for an enqueued bulk part upsert.
	ExecuteBulkUpsertParts(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// DeletePart soft-deletes a part by its item ID.
	DeletePart(ctx context.Context, itemID string) (*Part, *apierror.APIError)

	// BatchGetPartsByIDs returns parts by their IDs for include resolution.
	BatchGetPartsByIDs(ctx context.Context, ids []string) ([]*Part, *apierror.APIError)
}

type PartUpdateItemParams

type PartUpdateItemParams struct {
	AccountID   string
	ItemID      string
	SKU         *string
	Description field.Clearable[string]
	Notes       field.Clearable[string]
}

type PaymentTerm

type PaymentTerm struct {
	ID        string
	Name      string                      `audit:"name"`
	Status    constants.PaymentTermStatus `audit:"status"`
	AccountID *string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type PaymentTermRepo

type PaymentTermRepo interface {
	List(ctx context.Context, params ListPaymentTermsParams) (*ListPaymentTermsResult, *apierror.APIError)
	Get(ctx context.Context, params GetPaymentTermParams) (*PaymentTerm, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*PaymentTerm, *apierror.APIError)
	Create(ctx context.Context, id string, params CreatePaymentTermParams) (*PaymentTerm, *apierror.APIError)
	Update(ctx context.Context, params UpdatePaymentTermParams) (*PaymentTerm, *apierror.APIError)
	Delete(ctx context.Context, params DeletePaymentTermParams) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
}

type PaymentTermSvc

type PaymentTermSvc interface {
	// ListPaymentTerms returns a paginated list of payment terms visible to the caller's account. Includes both account-specific and default (system) payment terms.
	ListPaymentTerms(ctx context.Context, params ListPaymentTermsParams) (*ListPaymentTermsResult, *apierror.APIError)

	// GetPaymentTerm returns a single payment term by ID. The payment term must belong to the caller's account or be a default (global) payment term.
	GetPaymentTerm(ctx context.Context, paymentTermID string) (*PaymentTerm, *apierror.APIError)

	// BatchGetPaymentTermsByIDs returns payment terms by ID for the api-gateway include resolver. Authorization matches GetPaymentTerm (caller's account + system terms).
	BatchGetPaymentTermsByIDs(ctx context.Context, ids []string) ([]*PaymentTerm, *apierror.APIError)

	// CreatePaymentTerm creates a new account-owned payment term.
	CreatePaymentTerm(ctx context.Context, params CreatePaymentTermParams) (*PaymentTerm, *apierror.APIError)

	// UpdatePaymentTerm partially updates an account-owned payment term. Default payment terms cannot be updated.
	UpdatePaymentTerm(ctx context.Context, params UpdatePaymentTermParams) (*PaymentTerm, *apierror.APIError)

	// DeletePaymentTerm deletes an account-owned payment term. Default payment terms cannot be deleted.
	DeletePaymentTerm(ctx context.Context, paymentTermID string) *apierror.APIError
}

type Permission

type Permission struct {
	ID                  string
	Code                string
	Name                string
	Description         *string
	PermissionGroupCode string
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

type PermissionGroup

type PermissionGroup struct {
	ID          string
	Code        string
	Name        string
	Description *string
	Permissions []*Permission
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

type PermissionGroupRepo

type PermissionGroupRepo interface {
	List(ctx context.Context, params ListPermissionGroupsParams) (*ListPermissionGroupsResult, *apierror.APIError)
	GetByIDs(ctx context.Context, ids []string) ([]*PermissionGroup, *apierror.APIError)
}

type PermissionGroupSvc

type PermissionGroupSvc interface {
	// ListPermissionGroups returns a paginated list of permission groups with their nested permissions. Permission groups are global (not account-scoped).
	ListPermissionGroups(ctx context.Context, params ListPermissionGroupsParams) (*ListPermissionGroupsResult, *apierror.APIError)

	// BatchGetPermissionGroupsByIDs returns permission groups by their IDs for include resolution.
	BatchGetPermissionGroupsByIDs(ctx context.Context, ids []string) ([]*PermissionGroup, *apierror.APIError)
}

type Pick

type Pick struct {
	ID               string
	Number           string `audit:"number"`
	SalesOrderID     string
	SalesOrderNumber string
	AccountID        string
	FinishedAt       *time.Time `audit:"finished_at"`
	CreatedAt        time.Time
	UpdatedAt        time.Time

	// Joined fields for reads
	CustomerID     string
	CustomerName   string
	CustomerNumber string
	PriorityID     string
	PriorityCode   constants.PriorityCode
	PriorityName   string

	// Server-computed roll-ups, so a row can show counts and progress without expanding its lines.
	LineCount        int32
	LastShippedAt    *time.Time
	PickedCompletion float64
	PackedCompletion float64

	// Ship-to carried from the sales order, so a pick renders its header without fetching the order.
	PromisedAt *time.Time
	// The order's delivery commitment and the rules that produced it, carried so a pick can explain
	// its dates without fetching the order.
	ShipByDate                 *time.Time
	LeadTimeDays               *int32
	LeadTimeSource             *constants.LeadTimeSource
	TransitDays                *int32
	TransitSource              *constants.TransitSource
	ShippingAddressID          string
	ShippingAddressName        *string
	ShippingAddressPhone       *string
	ShippingAddressEmail       *string
	ShippingAddressIsDropShip  *bool
	ShippingAddressGeolocation *string
	ShippingAddressStreetLine1 *string
	ShippingAddressStreetLine2 *string
	ShippingAddressLocality    *string
	ShippingAddressState       *string
	ShippingAddressPostalCode  *string
	ShippingAddressCountry     *string

	// Populated conditionally
	Lines       []*PickLine
	Departments []*PickDepartment
	ShipmentIDs []string
}

Pick represents a pick domain model with joined fields for reads.

type PickDepartment

type PickDepartment struct {
	ID   string
	Name string
}

PickDepartment represents a department associated with a pick.

type PickLine

type PickLine struct {
	// OrderLineItemID is the item on the originating order line, so lines.item resolves.
	OrderLineItemID          *string
	ID                       string
	PickID                   string
	SalesOrderLineID         string
	QuantityID               string
	QuantityValue            string `audit:"quantity_value"`
	QuantityUnitID           string
	QuantityUnitName         string
	QuantityUnitAbbreviation string
	PackedAt                 *time.Time `audit:"packed_at"`
	CreatedAt                time.Time
	UpdatedAt                time.Time

	// Joined order line info
	OrderLineItemNumber       int32
	OrderLineSKU              string
	OrderLineDescription      *string
	OrderLineProductID        *string
	OrderedQuantityID         string
	OrderedQuantityValue      string
	OrderedQuantityUnitID     string
	OrderedQuantityUnitName   string
	OrderedQuantityUnitAbbrev string

	UnitPriceID                          string
	UnitPriceValue                       string
	UnitPriceNumeratorUnitID             string
	UnitPriceNumeratorUnitAbbreviation   string
	UnitPriceDenominatorUnitID           string
	UnitPriceDenominatorUnitAbbreviation string
}

PickLine represents a pick line domain model with joined fields.

type PickLineRepo

type PickLineRepo interface {
	Get(ctx context.Context, pickLineID string) (*PickLine, *apierror.APIError)
	// UpdateQuantity writes the line's picked quantity; a nil value or unit leaves that half unchanged.
	UpdateQuantity(ctx context.Context, pickLineID string, quantityValue, quantityUnitID *string) *apierror.APIError
	PickRemainingQuantity(ctx context.Context, pickLineID string) *apierror.APIError
	VoidLine(ctx context.Context, pickLineID string) *apierror.APIError
	IsInPick(ctx context.Context, pickLineID, pickID string) (bool, *apierror.APIError)
	CreateForRemaining(ctx context.Context, id, quantityID, pickID, orderLineID string) *apierror.APIError
	CalculateRemainingForOrderLine(ctx context.Context, orderLineID string) (remainingValue string, unitID string, apiErr *apierror.APIError)
	HasUnpackedPickLineForOrderLine(ctx context.Context, orderLineID string) (bool, *apierror.APIError)
	// GetOrderLinePackProgress returns the order line's ordered quantity, the total already packed, and the quantity unit. outstanding = ordered - packed decides whether an open pick line is still needed.
	GetOrderLinePackProgress(ctx context.Context, orderLineID string) (orderedValue string, packedValue string, unitID string, apiErr *apierror.APIError)
	// DeleteUnpackedForOrderLine deletes every unpacked (open) pick line for the order line, along with their quantity rows. Packed lines are left untouched.
	DeleteUnpackedForOrderLine(ctx context.Context, orderLineID string) *apierror.APIError
	UnpackByShipment(ctx context.Context, shipmentID string) *apierror.APIError
}

type PickLineSvc

type PickLineSvc interface {
	// UpdatePickLine updates a pick line's quantity value.
	UpdatePickLine(ctx context.Context, params UpdatePickLineParams) (*PickLine, *apierror.APIError)

	// PickPickLine picks a single line to its remaining quantity.
	PickPickLine(ctx context.Context, pickID, pickLineID string) (*PickLine, *apierror.APIError)

	// VoidPickLine voids a single pick line by setting its quantity to zero.
	VoidPickLine(ctx context.Context, pickID, pickLineID string) (*PickLine, *apierror.APIError)
}

type PickProgress

type PickProgress struct {
	PickedCompletion float64
	PackedCompletion float64
}

Carries the picked/packed completion fractions for one pick, aggregated over its sale lines.

type PickRepo

type PickRepo interface {
	List(ctx context.Context, params ListPicksParams) (*ListPicksResult, *apierror.APIError)
	Get(ctx context.Context, accountID, pickID string) (*Pick, *apierror.APIError)
	GetLines(ctx context.Context, pickID string) ([]*PickLine, *apierror.APIError)
	GetShipmentNumbers(ctx context.Context, params GetPickShipmentsParams) (*PickShipmentsResult, *apierror.APIError)
	GetProgress(ctx context.Context, pickIDs []string) (map[string]PickProgress, *apierror.APIError)
	GetDepartments(ctx context.Context, pickID string) ([]*PickDepartment, *apierror.APIError)
	UpdateNumber(ctx context.Context, accountID, pickID, number string) *apierror.APIError
	UpdateFinishedAt(ctx context.Context, accountID, pickID string, finishedAt time.Time) *apierror.APIError
	HasShippedItems(ctx context.Context, accountID, pickID string) (bool, *apierror.APIError)
	VoidAllLines(ctx context.Context, pickID string) *apierror.APIError
	DeleteDuplicatePickLines(ctx context.Context, accountID, pickID string) *apierror.APIError
	ClearFinishedAt(ctx context.Context, accountID, pickID string) *apierror.APIError
	PickAllLines(ctx context.Context, pickID string) *apierror.APIError
	// GetShipmentIDs returns the ids of shipments raised against the pick's order, oldest first.
	GetShipmentIDs(ctx context.Context, accountID, pickID string) ([]string, *apierror.APIError)
	IsInAccount(ctx context.Context, accountID, pickID string) (bool, *apierror.APIError)
	FindLinesToPack(ctx context.Context, pickID string) ([]*PickLine, *apierror.APIError)
	PackLines(ctx context.Context, pickID string) *apierror.APIError
	MarkFinishedIfAllPacked(ctx context.Context, pickID string) *apierror.APIError
	// CloseOpenPickLines packs every still-open pick line (used when the order is closed).
	CloseOpenPickLines(ctx context.Context, pickID string) *apierror.APIError
	// ReopenIncompletePickLines reopens pick lines whose picked quantity is below the ordered quantity (used when a fulfilled order is reopened).
	ReopenIncompletePickLines(ctx context.Context, pickID string) *apierror.APIError
	CountLines(ctx context.Context, pickID string) (int64, *apierror.APIError)
	CountShipmentsByOrder(ctx context.Context, salesOrderID string) (int64, *apierror.APIError)
	GetSalesOrderForPick(ctx context.Context, accountID, pickID string) (*PickSalesOrder, *apierror.APIError)
	CreateShipment(ctx context.Context, params CreateShipmentFromPickParams) *apierror.APIError
	CreateShipmentLine(ctx context.Context, params CreateShipmentLineParams) *apierror.APIError
	CreateShippingCase(ctx context.Context, params CreateShippingCaseParams) *apierror.APIError
	CreateQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	FindIDByShipmentOrder(ctx context.Context, accountID, shipmentID string) (string, *apierror.APIError)
}

type PickSalesOrder

type PickSalesOrder struct {
	ID                string
	Number            string
	CarrierID         string
	ServiceLevelID    *string
	ShippingAddressID string
}

PickSalesOrder holds order info needed for shipment creation during pack.

type PickShipmentsResult

type PickShipmentsResult struct {
	ShipmentNumbers []string
	Count           int32
}

PickShipmentsResult holds the result of getting shipment numbers for a pick.

type PickSvc

type PickSvc interface {
	// ListPicks returns a paginated list of picks for the caller's account.
	ListPicks(ctx context.Context, params ListPicksParams) (*ListPicksResult, *apierror.APIError)

	// GetPick returns a single pick by ID, optionally including lines and departments.
	GetPick(ctx context.Context, pickID string, includes []string) (*Pick, *apierror.APIError)

	// UpdatePick partially updates a pick's metadata (number).
	UpdatePick(ctx context.Context, params UpdatePickParams) (*Pick, *apierror.APIError)

	// PickAllLines picks all unpacked lines to their remaining quantities.
	PickAllLines(ctx context.Context, pickID string) (*Pick, *apierror.APIError)

	// VoidPick voids all lines in a pick, setting quantities to zero.
	VoidPick(ctx context.Context, pickID string) (*Pick, *apierror.APIError)

	// PackPick accepts a pack and returns the job tracking it; the shipment is created by ExecutePackPick.
	PackPick(ctx context.Context, pickID string, shipmentCaseCount int32) (*Job, *apierror.APIError)

	// ExecutePackPick runs an accepted pack: the shipment, its lines and its cases.
	ExecutePackPick(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// GetPickShipments returns shipment numbers associated with a pick's order.
	GetPickShipments(ctx context.Context, params GetPickShipmentsParams) (*PickShipmentsResult, *apierror.APIError)
}

type PooledMonthlyDemandRow

type PooledMonthlyDemandRow struct {
	ProductID string
	Year      int
	Month     int
	Quantity  float64
}

PooledMonthlyDemandRow is one product's sold quantity for one calendar month.

type PortalDNSRecord

type PortalDNSRecord struct {
	Type  constants.DNSRecordType `json:"type"`
	Name  string                  `json:"name"`
	Value string                  `json:"value"`
	// Reason explains why the record is needed: routing points traffic at the provider; ownership proves domain control when the domain is claimed elsewhere.
	Reason constants.DNSRecordReason `json:"reason"`
}

PortalDNSRecord is a DNS record the customer must publish for their portal domain to route and verify.

type PortalDomain

type PortalDomain struct {
	ID         string
	AccountID  string
	Domain     string                       `audit:"domain"`
	Status     constants.PortalDomainStatus `audit:"status"`
	DNSRecords []PortalDNSRecord
	VerifiedAt *time.Time
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

PortalDomain represents a customer-supplied custom domain that serves the account's customer portal. Terminal provider rejections mark the domain failed; transient DNS misconfiguration stays pending.

type PortalDomainProvider

type PortalDomainProvider interface {
	// AddDomain attaches the domain to the portal project and returns its current state. Adding an already-attached domain succeeds.
	AddDomain(ctx context.Context, domain string) (*PortalDomainProviderState, *apierror.APIError)
	// GetDomainState returns the domain's verification/configuration state and currently required DNS records.
	GetDomainState(ctx context.Context, domain string) (*PortalDomainProviderState, *apierror.APIError)
	// RemoveDomain detaches the domain from the portal project. Removing an unknown domain succeeds.
	RemoveDomain(ctx context.Context, domain string) *apierror.APIError
}

PortalDomainProvider is the serving/TLS provider (Vercel) for customer portal custom domains. All methods are idempotent so the provider-registration phase of a create can be safely retried.

type PortalDomainProviderState

type PortalDomainProviderState struct {
	Verified      bool
	Misconfigured bool
	// Serving reports whether the domain answers over HTTPS with a valid TLS certificate. It is only meaningful once the domain is verified and routing (not misconfigured); until the certificate is issued a routed domain is verified+routing but not yet serving.
	Serving    bool
	DNSRecords []PortalDNSRecord
}

PortalDomainProviderState is the serving provider's view of a portal domain: whether it is verified and routing, whether it is actually serving over HTTPS, and which DNS records the customer must publish.

type PortalDomainRepo

type PortalDomainRepo interface {
	Create(ctx context.Context, portalDomainID, accountID, domainName string) (*PortalDomain, *apierror.APIError)
	GetByID(ctx context.Context, accountID, portalDomainID string) (*PortalDomain, *apierror.APIError)
	GetByAccountID(ctx context.Context, accountID string) (*PortalDomain, *apierror.APIError)
	// GetByDomain looks a domain up without account scoping; used for global-uniqueness checks.
	GetByDomain(ctx context.Context, domainName string) (*PortalDomain, *apierror.APIError)
	ListByAccount(ctx context.Context, accountID string) ([]*PortalDomain, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*PortalDomain, *apierror.APIError)
	// UpdateProviderState persists the latest required DNS records and status reported by the serving provider.
	UpdateProviderState(ctx context.Context, portalDomainID string, status constants.PortalDomainStatus, dnsRecords []PortalDNSRecord) *apierror.APIError
	MarkVerified(ctx context.Context, portalDomainID string) *apierror.APIError
	Delete(ctx context.Context, accountID, portalDomainID string) (bool, *apierror.APIError)
	// ResolveVerifiedHost returns the public account whose verified portal domain matches the given host, or a not-found error.
	ResolveVerifiedHost(ctx context.Context, domainName string) (*PublicAccountBySlug, *apierror.APIError)
}

type PortalDomainSvc

type PortalDomainSvc interface {
	CreatePortalDomain(ctx context.Context, domainName string) (*PortalDomain, *apierror.APIError)
	GetPortalDomain(ctx context.Context, portalDomainID string) (*PortalDomain, *apierror.APIError)
	ListPortalDomains(ctx context.Context) ([]*PortalDomain, *apierror.APIError)
	VerifyPortalDomain(ctx context.Context, portalDomainID string) (*PortalDomain, *apierror.APIError)
	DeletePortalDomain(ctx context.Context, portalDomainID string) *apierror.APIError
	ResolvePortalHost(ctx context.Context, domainName string) (*PublicAccountBySlug, *apierror.APIError)
	BatchGetPortalDomainsByIDs(ctx context.Context, ids []string) ([]*PortalDomain, *apierror.APIError)
}

type PortalProfile

type PortalProfile struct {
	ID           string
	Name         string
	Slug         string
	LogoURL      *string
	FaviconURL   *string
	SupportEmail *string
	Address      *Address
}

PortalProfile is the authenticated seller portal profile: identity plus the seller's public letterhead address. Served to logged-in customer-portal pages, unlike the minimal, unauthenticated PublicAccountBySlug.

type PortalRegistrationSession

type PortalRegistrationSession struct {
	ID                 string
	UserID             string
	SellerAccountID    string
	SellerSlug         string
	IsExistingCustomer *bool
	Step               constants.PortalRegistrationStep
	CustomerID         *string
	SessionData        PortalRegistrationSessionData
	CompletedAt        *time.Time
	AbandonedAt        *time.Time
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

PortalRegistrationSession is a buyer's in-progress (or completed/abandoned) registration into a specific seller's customer portal.

func (*PortalRegistrationSession) DeriveStatus

DeriveStatus computes the session's lifecycle status as of now: completed/abandoned take precedence over the derived in-progress-vs-expired split (an incomplete session past its resume TTL reads as expired). now is passed in so callers control the clock (testability).

type PortalRegistrationSessionData

type PortalRegistrationSessionData struct {
	CustomerName      string `json:"customer_name,omitempty"`
	CustomerNumber    string `json:"customer_number,omitempty"`
	CustomerGroupID   string `json:"customer_group_id,omitempty"`
	PaymentTermID     string `json:"payment_term_id,omitempty"`
	ShippingTermID    string `json:"shipping_term_id,omitempty"`
	Phone             string `json:"phone,omitempty"`
	AddressName       string `json:"address_name,omitempty"`
	AddressStreet1    string `json:"address_street_1,omitempty"`
	AddressStreet2    string `json:"address_street_2,omitempty"`
	AddressLocality   string `json:"address_locality,omitempty"`
	AddressState      string `json:"address_state,omitempty"`
	AddressPostalCode string `json:"address_postal_code,omitempty"`
	AddressCountry    string `json:"address_country,omitempty"`
}

PortalRegistrationSessionData is the scratch form data accumulated across the buyer registration steps, persisted as JSON on the session so a resumed session restores exactly where the buyer left off.

type PortalRegistrationSessionRepo

type PortalRegistrationSessionRepo interface {
	Create(ctx context.Context, typeID string, params CreatePortalRegistrationSessionParams) (*PortalRegistrationSession, *apierror.APIError)
	GetByTypeID(ctx context.Context, typeID string) (*PortalRegistrationSession, *apierror.APIError)
	// GetIncomplete returns the newest non-completed, non-abandoned session for the (user, seller) pair, or nil.
	GetIncomplete(ctx context.Context, userID, sellerAccountID string) (*PortalRegistrationSession, *apierror.APIError)
	Update(ctx context.Context, params UpdatePortalRegistrationSessionParams) (*PortalRegistrationSession, *apierror.APIError)
	Complete(ctx context.Context, typeID, customerID string) (*PortalRegistrationSession, *apierror.APIError)
	Abandon(ctx context.Context, typeID string) *apierror.APIError
	// ListSessions returns a seller's registration sessions (keyset-paginated), for customer-service follow-up.
	ListSessions(ctx context.Context, params ListPortalRegistrationSessionsParams) (*ListPortalRegistrationSessionsResult, *apierror.APIError)
}

persists customer portal custom domains. The single-row getters return (nil, nil) when no matching row exists so callers can distinguish absence from failure. persists a buyer's customer-portal registration session.

type PortalRegistrationSessionSvc

type PortalRegistrationSessionSvc interface {
	// CreateOrResumeSession returns the buyer's active session for the seller (resuming a non-expired incomplete one), or starts a new one.
	CreateOrResumeSession(ctx context.Context, sellerSlug string) (*PortalRegistrationSession, *apierror.APIError)
	GetSession(ctx context.Context, typeID string) (*PortalRegistrationSession, *apierror.APIError)
	UpdateSession(ctx context.Context, params UpdatePortalRegistrationSessionParams) (*PortalRegistrationSession, *apierror.APIError)
	CompleteSession(ctx context.Context, typeID string) (*PortalRegistrationSession, *apierror.APIError)
	AbandonSession(ctx context.Context, typeID string) (*PortalRegistrationSession, *apierror.APIError)
	// ListSessions returns the seller account's registration sessions for the customer-service follow-up view (seller-facing; scoped to the caller's account).
	ListSessions(ctx context.Context, params ListPortalRegistrationSessionsParams) (*ListPortalRegistrationSessionsResult, *apierror.APIError)
}

PortalRegistrationSessionSvc drives a buyer's session-based registration into a seller's customer portal.

type PreviewProductionScheduleParams

type PreviewProductionScheduleParams struct {
	AccountID    string
	PlanningAsOf time.Time
	// HorizonWeeks and DemandBasis override the saved settings for this preview only.
	HorizonWeeks int
	DemandBasis  string
}

PreviewProductionScheduleParams drives the internal solve-only endpoint.

type PricingAccountPrice

type PricingAccountPrice struct {
	ID            string
	ProductLineID string
	UnitValue     string
	// Numerator/Denominator unit ids of the override rate.
	NumeratorUnitID   string
	DenominatorUnitID string
	AttributeIDs      []string
	CreatedAt         time.Time
}

PricingAccountPrice is an absolute price override for a product line and recipient. The recipient is either the buyer or its parent account.

type PricingBundle

type PricingBundle struct {
	// Products keyed by product id (only products that exist for the account).
	Products map[string]*PricingProduct
	// Units keyed by unit id.
	Units map[string]*PricingUnit
	// UnitGroupUnits keyed by unitGroupID -> unitID.
	UnitGroupUnits map[string]map[string]*PricingUnitGroupUnit
	// AccountPrices in created_at ASC order (last match wins, so callers iterate and keep the last applicable).
	AccountPrices []*PricingAccountPrice
	// VolumeDiscounts applicable to the buyer.
	VolumeDiscounts []*PricingVolumeDiscount
}

PricingBundle is everything the engine needs for a single computation, keyed for O(1) lookup. Loaded in one repository call.

type PricingProduct

type PricingProduct struct {
	ProductID string
	// ItemID, SKU, Description are item-derived fields used to tie the line to inventory and default the line's recorded SKU/description.
	ItemID      string
	SKU         string
	Description *string
	// UnitCost is the item's cost rate (pulled server-side, never a caller input).
	UnitCost                  string
	UnitCostNumeratorUnitID   string
	UnitCostDenominatorUnitID string
	// ProductLineID is nil when the product has no product line. Such products never match an account price and use the item category's unit group.
	ProductLineID *string
	// UnitValue is the item's list-price rate value (currency numerator per item-category base-unit denominator).
	UnitValue                  string
	UnitValueNumeratorUnitID   string
	UnitValueDenominatorUnitID string
	// ProductLineUnitGroupID is set when the product has a product line.
	ProductLineUnitGroupID *string
	// CategoryUnitGroupID is the item category's unit group (fallback group).
	CategoryUnitGroupID string
	// ItemCategoryID is the item's category id, used for volume-discount category scoping.
	ItemCategoryID string
	// AttributeIDs are the product's (item's) attribute ids.
	AttributeIDs []string
}

PricingProduct is the list-price data the engine needs for one product.

type PricingRepo

type PricingRepo interface {
	// LoadPricingBundle fetches, in a small number of queries, all product list prices, unit conversion data, unit-group discounts, account-price overrides (for the buyer and its parent account), and applicable volume discounts.
	LoadPricingBundle(ctx context.Context, params LoadPricingBundleParams) (*PricingBundle, *apierror.APIError)
	// ProductQuantityUnits returns, per product, the set of unit IDs its unit group allows a quantity to be expressed in. Products the account does not own are absent, which the caller reports as an unknown product rather than as an unusable unit.
	ProductQuantityUnits(ctx context.Context, accountID string, productIDs []string) (map[string]map[string]struct{}, *apierror.APIError)
}

PricingRepo loads the data the sales-order-line pricing engine needs.

type PricingUnit

type PricingUnit struct {
	ID                string
	RatioNumerator    string
	RatioDenominator  string
	OffsetNumerator   string
	OffsetDenominator string
	IsBaseUnit        bool
}

PricingUnit carries the raw unit-conversion data for normalizeQuantity.

type PricingUnitGroupUnit

type PricingUnitGroupUnit struct {
	UnitGroupID        string
	UnitID             string
	DiscountPercentage string
	DiscountFixed      string
}

PricingUnitGroupUnit is a unit's conversion discount within a unit group.

type PricingVolumeDiscount

type PricingVolumeDiscount struct {
	ID                   string
	MatchesCustomerGroup bool
	Tiers                []PricingVolumeDiscountTier
	AcceptableUnitIDs    []string
	// Scoping: a product matches the discount only if it satisfies every non-empty dimension (product line AND item category AND attributes). An empty dimension is a wildcard. Customer-group scoping is already applied when the discount is loaded.
	ProductLineIDs []string
	CategoryIDs    []string
	AttributeIDs   []string
}

PricingVolumeDiscount is a quantity discount applicable to the buyer, with its tiers and the set of units a line quantity may be normalized into.

type PricingVolumeDiscountTier

type PricingVolumeDiscountTier struct {
	Threshold          string
	DiscountPercentage string
}

PricingVolumeDiscountTier is one threshold/percentage tier of a discount.

type Priority

type Priority struct {
	ID        string
	Name      string
	Code      constants.PriorityCode
	CreatedAt time.Time
	UpdatedAt time.Time
}

type PriorityRepo

type PriorityRepo interface {
	List(ctx context.Context, params ListPrioritiesParams) (*ListPrioritiesResult, *apierror.APIError)
	Get(ctx context.Context, identifier string) (*Priority, *apierror.APIError)
	GetByIDs(ctx context.Context, ids []string) ([]*Priority, *apierror.APIError)
}

type PrioritySvc

type PrioritySvc interface {
	// ListPriorities returns a paginated list of priorities.
	ListPriorities(ctx context.Context, params ListPrioritiesParams) (*ListPrioritiesResult, *apierror.APIError)

	// GetPriority returns a single priority by ID or code.
	GetPriority(ctx context.Context, identifier string) (*Priority, *apierror.APIError)

	// BatchGetPrioritiesByIDs returns priorities by ID for the api-gateway include resolver. Priorities are system-wide, no per-caller scoping.
	BatchGetPrioritiesByIDs(ctx context.Context, ids []string) ([]*Priority, *apierror.APIError)
}

type ProductFull

type ProductFull struct {
	ID              string
	ProductTypeCode string  `audit:"product_type_code"`
	IsPortalReady   bool    `audit:"is_portal_ready"`
	ProductLineID   *string `audit:"product_line_id"`
	ItemID          string
	CreatedAt       time.Time
	UpdatedAt       time.Time

	// Joined data
	Item        *Item
	ProductLine *ProductLineFull
	ProductType *ProductType
}

ProductFull represents a product entity, which extends an Item with product-specific fields.

type ProductInfo

type ProductInfo struct {
	ProductID   string
	ItemID      string
	SKU         string
	Description string
	UnitPrice   string
}

type ProductLineFull

type ProductLineFull struct {
	ID               string
	Name             string                     `audit:"name"`
	Description      *string                    `audit:"description"`
	Notes            *string                    `audit:"notes"`
	CommissionPolicy constants.CommissionPolicy `audit:"commission_policy"`
	FreightPolicy    constants.FreightPolicy    `audit:"freight_policy"`
	UnitGroupID      string                     `audit:"unit_group_id"`
	// The lot products in this line are made in, carried as a quantity so the number and its unit stay one value: 60 pairs and 60 eaches are different lots, and a size on its own cannot say which. Flattened here the way credit_limit is on a customer.
	DefaultLotID     *string `audit:"default_lot_id"`
	DefaultLotValue  *string `audit:"default_lot_value"`
	DefaultLotUnitID *string `audit:"default_lot_unit_id"`
	// How products in this line are produced when they do not say for themselves; nil falls through to the account default.
	FulfillmentPolicyCode *string `audit:"fulfillment_policy_code"`
	AccountID             *string
	CreatedAt             time.Time
	UpdatedAt             time.Time

	// Expandable sub-resources (populated via includes)
	UnitGroup *ProductLineUnitGroup
}

ProductLineFull represents a full product line with optional joined data.

type ProductLineInfo

type ProductLineInfo struct {
	ID   string
	Name string
}

type ProductLineInfoRow

type ProductLineInfoRow struct {
	ID   string
	Name string
}

ProductLineInfoRow is a product line's identifier and display name.

type ProductLineItemRow

type ProductLineItemRow struct {
	ProductLineID string
	ItemID        string
}

ProductLineItemRow maps one product line to one item sold under it.

type ProductLineLotDefault

type ProductLineLotDefault struct {
	ProductLineID string
	Quantity      float64
	UnitID        string
}

ProductLineLotDefault is one line's configured lot convention.

type ProductLineRepo

type ProductLineRepo interface {
	List(ctx context.Context, params ListProductLinesParams) (*ListProductLinesResult, *apierror.APIError)
	Export(ctx context.Context, params ExportProductLinesParams) ([]*ProductLineFull, *apierror.APIError)
	Get(ctx context.Context, params GetProductLineParams) (*ProductLineFull, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateProductLineParams) (*ProductLineFull, *apierror.APIError)
	Update(ctx context.Context, params UpdateProductLineParams) (*ProductLineFull, *apierror.APIError)
	Delete(ctx context.Context, params DeleteProductLineParams) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	FindByNames(ctx context.Context, accountID string, names []string) ([]*ProductLineFull, *apierror.APIError)
	GetUnitGroup(ctx context.Context, accountID, unitGroupID string, includes []string) (*ProductLineUnitGroup, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*ProductLineFull, *apierror.APIError)
	// IsUnitInGroup reports whether a unit can be used by a line on this unit group. A lot counted in a unit the line cannot express is not a lot anybody can act on.
	IsUnitInGroup(ctx context.Context, unitGroupID, unitID string) (bool, *apierror.APIError)

	// Lot conventions. These back both the solver's resolution and the one-item lookup a person gets when adding a batch by hand.
	GetItemLotOverride(ctx context.Context, accountID, itemID string) (float64, *apierror.APIError)
	// GetProductLineLotForItem returns the convention of the line an item sells under, or nil for an intermediate item that is not itself sold.
	GetProductLineLotForItem(ctx context.Context, accountID, itemID string) (*ProductLineLotDefault, *apierror.APIError)
	// GetDownstreamProductLineLot returns the convention an intermediate item inherits from what it becomes, highest-demand line first.
	GetDownstreamProductLineLot(ctx context.Context, accountID, itemID string) (*ProductLineLotDefault, *apierror.APIError)
	// GetFlowProductLineLot walks the production flow from an intermediate item to the first thing it becomes that has a lot convention. It answers for an item that has never been produced, which the demand-weighted lookup cannot.
	GetFlowProductLineLot(ctx context.Context, accountID, itemID string, maxDepth int) (*ProductLineLotDefault, *apierror.APIError)
}

type ProductLineSvc

type ProductLineSvc interface {
	// ListProductLines returns a paginated list of product lines visible to the caller's account.
	ListProductLines(ctx context.Context, params ListProductLinesParams) (*ListProductLinesResult, *apierror.APIError)

	ExportProductLines(ctx context.Context, params ExportProductLinesParams) (*Job, *apierror.APIError)
	// BuildExportProductLines renders the file an accepted export recorded.
	BuildExportProductLines(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// GetProductLine returns a single product line by ID.
	GetProductLine(ctx context.Context, params GetProductLineParams) (*ProductLineFull, *apierror.APIError)

	// CreateProductLine creates a new product line.
	CreateProductLine(ctx context.Context, params CreateProductLineParams) (*ProductLineFull, *apierror.APIError)

	// UpdateProductLine partially updates a product line. Default product lines cannot be updated.
	UpdateProductLine(ctx context.Context, params UpdateProductLineParams) (*ProductLineFull, *apierror.APIError)

	// DeleteProductLine deletes a product line. Default product lines cannot be deleted.
	DeleteProductLine(ctx context.Context, productLineID string) *apierror.APIError

	// BatchGetProductLinesByIDs returns product lines by ID for the api-gateway include resolver.
	BatchGetProductLinesByIDs(ctx context.Context, ids []string) ([]*ProductLineFull, *apierror.APIError)

	// accepts a bulk upsert of product lines and returns the job to poll.
	BulkUpsertProductLines(ctx context.Context, params BulkUpsertProductLinesParams) (*Job, *apierror.APIError)

	// performs the writes for an enqueued bulk upsert.
	ExecuteBulkUpsertProductLines(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError
}

type ProductLineUnitGroup

type ProductLineUnitGroup struct {
	ID         string
	Name       string
	BaseUnitID string
	Type       string
	CreatedAt  time.Time
	UpdatedAt  time.Time

	// Populated when product_line.unit_group.base_unit is included.
	BaseUnit *LightUnit
	// Populated when product_line.unit_group.associated_units is included.
	AssociatedUnits []*UnitGroupUnit
}

ProductLineUnitGroup represents the unit group associated with a product line.

type ProductRepo

type ProductRepo interface {
	SearchBySKU(ctx context.Context, accountID, query string) ([]ProductInfo, *apierror.APIError)
	ListByAccount(ctx context.Context, accountID string) ([]ProductInfo, *apierror.APIError)
	// GetSystemProduct fetches the account's built-in product matching the given product_type_code (e.g. "credit", "shipping") along with the base unit of its item category. Returns nil if no such product exists.
	GetSystemProduct(ctx context.Context, accountID, productTypeCode string) (*SystemProductInfo, *apierror.APIError)

	List(ctx context.Context, params ListProductsFullParams) (*ListProductsFullResult, *apierror.APIError)
	Export(ctx context.Context, params ExportProductsParams) ([]*ProductFull, *apierror.APIError)
	Get(ctx context.Context, params GetProductFullParams) (*ProductFull, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*ProductFull, *apierror.APIError)
	Create(ctx context.Context, productID, itemID string, params CreateProductParams) (*ProductFull, *apierror.APIError)
	Update(ctx context.Context, params UpdateProductParams) (*ProductFull, *apierror.APIError)
	SoftDelete(ctx context.Context, params DeleteProductParams) *apierror.APIError
	ChangeProductLine(ctx context.Context, params ChangeProductProductLineParams) (*ProductFull, *apierror.APIError)
	ValidateProducts(ctx context.Context, params ValidateProductsParams) (*ValidateProductsResult, *apierror.APIError)
	ExistsBySKU(ctx context.Context, accountID, sku string, excludeItemID *string) (bool, *apierror.APIError)
	// FindBySKUs batch-resolves existing products by SKU within the account, returning the
	// product/item IDs and unit_value/unit_cost rate IDs needed to update them.
	FindBySKUs(ctx context.Context, accountID string, skus []string) ([]*ProductSKUMatch, *apierror.APIError)
	InsertRate(ctx context.Context, id, value, numeratorUnitID, denominatorUnitID string) *apierror.APIError
	InsertItem(ctx context.Context, params InsertProductItemParams) *apierror.APIError
}

type ProductSKUMatch

type ProductSKUMatch struct {
	ProductID       string
	ItemID          string
	SKU             string
	CategoryID      string
	UnitValueRateID string
	UnitCostRateID  string
}

ProductSKUMatch is an existing product keyed by SKU, with the IDs needed to update it.

type ProductSvc

type ProductSvc interface {
	SearchProducts(ctx context.Context, accountID, query string) ([]ProductInfo, *apierror.APIError)
	ListProducts(ctx context.Context, accountID string) ([]ProductInfo, *apierror.APIError)
	GetCustomerByEmail(ctx context.Context, ownerAccountID, email string) (*CustomerByEmail, *apierror.APIError)
	FindContactsByEmail(ctx context.Context, email string) ([]ContactMatch, *apierror.APIError)

	// ListProductsFull returns a paginated list of products for the caller's account.
	ListProductsFull(ctx context.Context, params ListProductsFullParams) (*ListProductsFullResult, *apierror.APIError)

	// ExportProducts accepts an export and returns the job that tracks it.
	ExportProducts(ctx context.Context, params ExportProductsParams) (*Job, *apierror.APIError)
	// BuildExportProducts renders the file an accepted export recorded.
	BuildExportProducts(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// GetProduct returns a single product by item ID.
	GetProduct(ctx context.Context, params GetProductFullParams) (*ProductFull, *apierror.APIError)

	// CreateProduct creates a new product with its associated item and rates.
	CreateProduct(ctx context.Context, params CreateProductParams) (*ProductFull, *apierror.APIError)

	// UpdateProduct partially updates an existing product.
	UpdateProduct(ctx context.Context, params UpdateProductParams) (*ProductFull, *apierror.APIError)

	// BulkUpsertProducts creates or updates multiple products in a single atomic
	// operation, matched by SKU within the account.
	BulkUpsertProducts(ctx context.Context, params BulkUpsertProductsParams) (*Job, *apierror.APIError)

	// performs the writes for an enqueued bulk product upsert.
	ExecuteBulkUpsertProducts(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// DeleteProduct soft-deletes a product by its item ID.
	DeleteProduct(ctx context.Context, params DeleteProductParams) (*ProductFull, *apierror.APIError)

	// ChangeProductProductLine changes the product line assigned to a product.
	ChangeProductProductLine(ctx context.Context, params ChangeProductProductLineParams) (*ProductFull, *apierror.APIError)

	// ValidateProducts validates a map of SKUs and returns matching products.
	ValidateProducts(ctx context.Context, params ValidateProductsParams) (*ValidateProductsResult, *apierror.APIError)

	// BatchGetProductsByIDs returns products by their IDs for include resolution.
	BatchGetProductsByIDs(ctx context.Context, ids []string) ([]*ProductFull, *apierror.APIError)
}

type ProductType

type ProductType struct {
	ID        string
	Name      string `audit:"name"`
	Code      string `audit:"code"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type ProductTypeLine

type ProductTypeLine struct {
	ProductID       string
	ProductTypeCode string
	ProductLineID   *string
}

ProductTypeLine carries a product's type code and product line ID, used by shipping-rate estimation (parcel weight + product-line freight exemption) on create.

type ProductTypeRepo

type ProductTypeRepo interface {
	List(ctx context.Context, params ListProductTypesParams) (*ListProductTypesResult, *apierror.APIError)
	Get(ctx context.Context, identifier string) (*ProductType, *apierror.APIError)
	GetByIDs(ctx context.Context, ids []string) ([]*ProductType, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateProductTypeParams) (*ProductType, *apierror.APIError)
	Update(ctx context.Context, params UpdateProductTypeParams) (*ProductType, *apierror.APIError)
	Delete(ctx context.Context, id string) *apierror.APIError
	ExistsByName(ctx context.Context, name string, excludeID *string) (bool, *apierror.APIError)
	ExistsByCode(ctx context.Context, code string, excludeID *string) (bool, *apierror.APIError)
	ExistsByID(ctx context.Context, id string) (bool, *apierror.APIError)
}

type ProductTypeSvc

type ProductTypeSvc interface {
	// ListProductTypes returns a paginated list of product types. Product types are global (not account-scoped).
	ListProductTypes(ctx context.Context, params ListProductTypesParams) (*ListProductTypesResult, *apierror.APIError)

	// GetProductType returns a single product type by ID or code.
	GetProductType(ctx context.Context, identifier string) (*ProductType, *apierror.APIError)

	// CreateProductType creates a new product type.
	CreateProductType(ctx context.Context, params CreateProductTypeParams) (*ProductType, *apierror.APIError)

	// UpdateProductType partially updates a product type.
	UpdateProductType(ctx context.Context, params UpdateProductTypeParams) (*ProductType, *apierror.APIError)

	// DeleteProductType deletes a product type by ID.
	DeleteProductType(ctx context.Context, id string) *apierror.APIError

	// BatchGetProductTypesByIDs returns product types matching the input IDs. Used by the api-gateway resourcekit include resolver.
	BatchGetProductTypesByIDs(ctx context.Context, ids []string) ([]*ProductType, *apierror.APIError)
}

type Production

type Production struct {
	ID               string
	ItemID           string   `audit:"item_id"`
	ItemSKU          string   `audit:"item_sku"`
	ItemDescription  *string  `audit:"item_description"`
	ItemTypeCode     string   `audit:"item_type_code"`
	Quantity         Quantity `audit:"quantity"`
	ProductionStepID string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

Production represents the output of a production step.

type ProductionBatchItem

type ProductionBatchItem struct {
	ItemID  string
	Measure decimal.Decimal
	UnitID  string
}

ProductionBatchItem is a computed production batch: a material-only-block item and the quantity to produce, expressed in UnitID.

type ProductionBatchLineInput

type ProductionBatchLineInput struct {
	ProducedItemID string
	OrderedMeasure decimal.Decimal
	OrderedUnitID  string
}

ProductionBatchLineInput identifies one order line's produced item and ordered quantity, the input to the production-run batch computation.

type ProductionCostEntry

type ProductionCostEntry struct {
	ItemID             string
	ProductSku         string
	ProductDescription *string
	ProductLine        *string
	TotalQuantity      float64
	TotalCost          float64
	CostPerUnit        float64
	Unit               string
}

type ProductionFlowMed

type ProductionFlowMed interface {
	// LinkFlow recomputes all parent-child production step connections for a step based on its current consumptions and productions.
	//
	//  1. Delegate to the production flow repository to rebuild the step's connections.
	LinkFlow(ctx context.Context, productionStepID, accountID string) *apierror.APIError

	// DisconnectSteps removes a specific parent-child connection between two steps.
	//
	//  1. Delegate to the production flow repository to remove the connection.
	DisconnectSteps(ctx context.Context, sourceID, targetID string) *apierror.APIError

	// FindSourceStepsByConsumption returns IDs of parent steps that should be disconnected when a consumption is deleted.
	//
	//  1. Delegate to the production flow repository to find the matching parent step IDs.
	FindSourceStepsByConsumption(ctx context.Context, productionStepID, consumptionID, accountID string) ([]string, *apierror.APIError)

	// FindDownstreamStepByItem returns the ID of a downstream step connected via a specific consumed item, if one exists.
	//
	//  1. Delegate to the production flow repository to find the connected downstream step.
	FindDownstreamStepByItem(ctx context.Context, productionStepID, itemID, accountID string) (*string, *apierror.APIError)
}

type ProductionFlowRepo

type ProductionFlowRepo interface {
	LinkFlow(ctx context.Context, productionStepID, accountID string) *apierror.APIError
	DisconnectSteps(ctx context.Context, sourceID, targetID string) *apierror.APIError
	FindSourceStepsByConsumption(ctx context.Context, productionStepID, consumptionID, accountID string) ([]string, *apierror.APIError)
	FindDownstreamStepByItem(ctx context.Context, productionStepID, itemID, accountID string) (*string, *apierror.APIError)
	GetAllStepEdgesForAccount(ctx context.Context, accountID string) ([]StepEdge, *apierror.APIError)
	ConnectStepsIdempotent(ctx context.Context, sourceID, targetID string) *apierror.APIError
	GetFlowStep(ctx context.Context, accountID, stepID string) (*ProductionFlowStep, *apierror.APIError)
	FindStepsByProducedItem(ctx context.Context, accountID, itemID string) ([]string, *apierror.APIError)
}

type ProductionFlowStep

type ProductionFlowStep struct {
	ID                string
	Name              string
	Notes             *string
	Production        StepProduction
	Consumptions      []StepConsumption
	InStepIDs         []string
	OutStepIDs        []string
	ScanningStationID *string
	DepartmentID      *string
	MachineIDs        []string
	LevelingFactor    string
	Allowances        string
	LaborRate         *FlowRate
	LaborTime         *FlowRate
	OverheadRate      *FlowRate
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

ProductionFlowStep represents a single step in the production flow with all associated data needed for flow display.

type ProductionFlowSvc

type ProductionFlowSvc interface {
	// GetProductionFlow returns the production flow graph for a given item.
	GetProductionFlow(ctx context.Context, itemID string) ([]*ProductionFlowStep, *apierror.APIError)

	// ConnectSteps links two production steps in the flow DAG.
	ConnectSteps(ctx context.Context, sourceStepID, targetStepID string) *apierror.APIError
}

type ProductionRepo

type ProductionRepo interface {
	Get(ctx context.Context, accountID, productionStepID, productionID string) (*Production, *apierror.APIError)
	UpdateItem(ctx context.Context, productionID, itemID string) *apierror.APIError
	UpdateQuantity(ctx context.Context, productionID, value, unitID string) *apierror.APIError
	GetQuantityID(ctx context.Context, productionID string) (string, *apierror.APIError)
}

ProductionRepo provides CRUD access to production (output) data.

type ProductionRun

type ProductionRun struct {
	ID                string
	Number            string `audit:"number"`
	ResponsibleUserID string `audit:"responsible_user_id"`
	AccountID         string
	BatchCount        int32      `audit:"batch_count"`
	StartedAt         *time.Time `audit:"started_at"`
	CompletedAt       *time.Time `audit:"completed_at"`
	CreatedAt         time.Time
	UpdatedAt         time.Time

	// Joined fields for reads
	ResponsibleUserName       *string
	ResponsibleUserStatusCode *string
	ResponsibleUserCreatedAt  *time.Time
	ResponsibleUserUpdatedAt  *time.Time
}

type ProductionRunExport

type ProductionRunExport struct {
	ID                  string
	Number              string
	ResponsibleUserName string
	StartedAt           *time.Time
	CompletedAt         *time.Time
	OrderID             *string
	Batches             []ProductionRunExportBatch
}

carries one run and its batches as the export sheet lays them out. The read model has neither batches nor a sales order, so the export reads its own shape.

type ProductionRunExportBatch

type ProductionRunExportBatch struct {
	ID             string
	ItemSKU        string
	QuantityValue  string
	QuantityUnit   string
	DepartmentName *string
	MachineNames   []string
	ScannedAt      *time.Time
}

carries one batch of an exported run, one sheet row each

type ProductionRunQueryRepo

type ProductionRunQueryRepo interface {
	Start(ctx context.Context, accountID, id string) *apierror.APIError
	CloseIfAllBatchesScannedOrDeleted(ctx context.Context, accountID, id string) *apierror.APIError
	// Reopen undoes a completion after one of the run's batches goes back to unscanned, clearing started_at as well when nothing in the run is scanned any more.
	Reopen(ctx context.Context, accountID, id string) *apierror.APIError
	Create(ctx context.Context, id, responsibleUserID, number, accountID string) *apierror.APIError
	GetNextNumber(ctx context.Context, accountID string) (string, *apierror.APIError)
}

ProductionRunQueryRepo provides limited write access for starting and closing production runs.

type ProductionRunRepo

type ProductionRunRepo interface {
	List(ctx context.Context, params ListProductionRunsParams) (*ListProductionRunsResult, *apierror.APIError)
	Export(ctx context.Context, params ExportProductionRunsParams) ([]*ProductionRunExport, *apierror.APIError)
	Get(ctx context.Context, params GetProductionRunParams) (*ProductionRun, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateProductionRunParams, number string) (*ProductionRun, *apierror.APIError)
	Update(ctx context.Context, params UpdateProductionRunParams) (*ProductionRun, *apierror.APIError)
	Delete(ctx context.Context, params DeleteProductionRunParams) *apierror.APIError
	ExistsByNumber(ctx context.Context, accountID, number string, excludeID *string) (bool, *apierror.APIError)
	GetNextNumber(ctx context.Context, accountID string) (string, *apierror.APIError)
	// reserves count sequential numbers from a single locked read, for batch writes
	GetNextNumbers(ctx context.Context, accountID string, count int) ([]string, *apierror.APIError)
	IsCompleted(ctx context.Context, accountID, id string) (bool, *apierror.APIError)
	DeleteBatchesByRun(ctx context.Context, accountID, productionRunID string) *apierror.APIError
	FindOrderIDsByRun(ctx context.Context, accountID, productionRunID string) ([]string, *apierror.APIError)
	UnlinkOrdersFromRun(ctx context.Context, accountID, productionRunID string) *apierror.APIError
	DeleteReservedInventoryIssuesByOrder(ctx context.Context, accountID, orderID string) *apierror.APIError
	ListBatchesByRun(ctx context.Context, params ListBatchesByProductionRunParams) (*ListBatchesByProductionRunResult, *apierror.APIError)
	SetBatchProductionRunID(ctx context.Context, accountID, batchID, productionRunID string) *apierror.APIError
}

ProductionRunRepo provides full CRUD access for production run management.

type ProductionRunSummary

type ProductionRunSummary struct {
	ID                string
	Number            string
	ResponsibleUserID string
	BatchCount        int32
	StartedAt         *time.Time
	CompletedAt       *time.Time
	CreatedAt         time.Time
	UpdatedAt         time.Time

	// Joined fields
	ResponsibleUserName       *string
	ResponsibleUserStatusCode *string
	ResponsibleUserCreatedAt  *time.Time
	ResponsibleUserUpdatedAt  *time.Time
}

ProductionRunSummary represents a production run for list views.

type ProductionRunSvc

type ProductionRunSvc interface {
	ListProductionRuns(ctx context.Context, params ListProductionRunsParams) (*ListProductionRunsResult, *apierror.APIError)
	ExportProductionRuns(ctx context.Context, params ExportProductionRunsParams) (*Job, *apierror.APIError)
	// BuildExportProductionRuns renders the file an accepted export recorded.
	BuildExportProductionRuns(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)
	GetProductionRun(ctx context.Context, params GetProductionRunParams) (*ProductionRun, *apierror.APIError)
	CreateProductionRun(ctx context.Context, params CreateProductionRunParams) (*ProductionRun, *apierror.APIError)
	UpdateProductionRun(ctx context.Context, params UpdateProductionRunParams) (*ProductionRun, *apierror.APIError)
	DeleteProductionRun(ctx context.Context, params DeleteProductionRunParams) *apierror.APIError
	AddBatchesToProductionRun(ctx context.Context, params AddBatchesToProductionRunParams) ([]*BaseBatch, *apierror.APIError)
	ListBatchesByProductionRun(ctx context.Context, params ListBatchesByProductionRunParams) (*ListBatchesByProductionRunResult, *apierror.APIError)
	// BulkCreateProductionRuns validates a bulk create request, resolves every
	// reference, pre-generates the run and batch IDs, records the resolved payload
	// and those IDs on a job row, and enqueues that job's ID via the message outbox.
	// It returns the raised Job (already carrying the pre-generated IDs in its results);
	// the runs themselves are created asynchronously by ExecuteBulkCreateProductionRuns.
	BulkCreateProductionRuns(ctx context.Context, params BulkCreateProductionRunsParams) (*Job, *apierror.APIError)
	// ExecuteBulkCreateProductionRuns loads the job named by the event, performs its
	// writes in a single atomic transaction, and records the outcome on the job.
	// Called by the bulk create consumer — exactly-once delivery is provided by the
	// message inbox, so there is no idempotency envelope here.
	ExecuteBulkCreateProductionRuns(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError
}

type ProductionSchedule

type ProductionSchedule struct {
	ID        string
	AccountID string
	Version   int32

	StatusCode string  `audit:"status_code"`
	Name       *string `audit:"name"`

	PlanningAsOf      time.Time
	HorizonStartDate  time.Time
	HorizonEndDate    time.Time
	HorizonWeeks      int32
	FrozenWeeks       int32
	FrozenThroughDate *time.Time

	DemandBasisCode      string
	GenerationSourceCode string
	SolverVersion        string

	SettingsSnapshot json.RawMessage
	Diagnostics      json.RawMessage
	ErrorMessage     *string

	FrozenLineCount       int32
	FrozenPlannedQuantity float64

	GeneratedByID  *string
	PublishedByID  *string
	PublishedAt    *time.Time
	SupersededByID *string

	CreatedAt time.Time
	UpdatedAt time.Time
}

ProductionSchedule is one generated version of the plan.

type ProductionScheduleDerivedLine

type ProductionScheduleDerivedLine struct {
	ID                   string
	ProductionScheduleID string
	SourceLineID         string

	ProductionStepID string
	DepartmentID     *string
	ItemID           string

	WeekIndex     int32
	WeekStartDate time.Time

	Quantity      float64
	PlannedUnitID *string

	ExplosionDepth int32
	OffsetWeeks    int32
	StatusCode     string

	CreatedAt time.Time
	UpdatedAt time.Time
}

ProductionScheduleDerivedLine is downstream department work implied by a constraint campaign.

type ProductionScheduleDeviation

type ProductionScheduleDeviation struct {
	ID                   string
	AccountID            string
	ProductionScheduleID string
	// Nil for a removed line, whose row no longer exists, and for an added one at the moment the deviation is written.
	ProductionScheduleLineID *string

	DeviationTypeCode string

	// IsFrozenWeek is materialized at write time from the schedule's frozen_through_date as it stood at that moment. Deriving it on read would let a later publish retroactively reclassify past edits and the adherence KPI would drift.
	IsFrozenWeek bool

	WeekIndex *int32
	MachineID *string
	ItemID    *string

	BeforeJSON []byte
	AfterJSON  []byte

	DeltaQuantity float64
	DeltaRunHours float64

	ReasonCode *string
	ReasonNote *string

	ActorID   string
	CreatedAt time.Time
}

type ProductionScheduleEnqueuer

type ProductionScheduleEnqueuer interface {
	// EnqueueGeneration writes a generate-production-schedule command to the outbox for the given placeholder schedule.
	EnqueueGeneration(ctx context.Context, params EnqueueGenerationParams) *apierror.APIError
}

ProductionScheduleEnqueuer publishes a generate command. The cadence tick uses it so the solve happens out of band rather than inside the scheduler lease.

type ProductionScheduleFinishedPolicy

type ProductionScheduleFinishedPolicy struct {
	ID                   string
	AccountID            string
	ProductionScheduleID string

	ItemID        string
	SKU           string
	GreigeItemID  string
	GreigeSKU     string
	ProductLineID *string

	AnnualDemand float64
	WeeklyDemand float64
	SigmaWeekly  float64

	SafetyStock  float64
	ReorderPoint float64
	OnHand       float64
	WeeksOfCover float64

	CreatedAt time.Time
	UpdatedAt time.Time
}

type ProductionScheduleFinishingLine

type ProductionScheduleFinishingLine struct {
	ID                   string
	AccountID            string
	ProductionScheduleID string

	WeekIndex     int32
	WeekStartDate time.Time

	ItemID       string
	SKU          string
	GreigeItemID string
	GreigeSKU    string
	// DepartmentID and ProductionStepID are denormalized from the finishing step so a department rollup needs no join.
	DepartmentID     *string
	ProductionStepID *string

	PlannedQuantity float64
	PlannedUnitID   *string
	// PlannedUnitAbbreviation is joined on read. "240" is not an instruction until it says 240 of what.
	PlannedUnitAbbreviation *string
	PlannedLots             int32
	PlannedLotUnits         float64
	PlannedRunHours         float64

	// GreigeConsumed is what the line takes out of the stage-one buffer. Stored rather than derived, because a finishing yield loss makes it differ from PlannedQuantity and the two stages reconciling is the whole point.
	GreigeConsumed float64
	// FirmUnits is how much of the week's draw is an order rather than a forecast.
	FirmUnits float64

	ProjectedOnHandBefore float64
	ProjectedOnHandAfter  float64

	StatusCode string
	SourceCode string
	IsFrozen   bool

	CreatedAt time.Time
	UpdatedAt time.Time
}

ProductionScheduleFinishedPolicy is one finished SKU's own inventory target, snapshotted per version.

The greige policy pools every finished good a constraint item feeds into one echelon figure, which is the right basis for deciding whether to build. These rows are what that pooling hides: per-SKU demand, per-SKU variability, and a buffer sized against the finishing lead time rather than the constraint's. ProductionScheduleFinishingLine is one finished good's build in one week: stage two of the plan.

Stage one plans the constraint and pools a family's demand into one greige campaign; this is where that pooling is undone, against each finished SKU's own position, its own orders and the hours the rest of the factory has. Which is to say: this is the row that answers "how many of which finished good do we make from what was knitted".

type ProductionScheduleInputRepo

type ProductionScheduleInputRepo interface {
	// GetConstraintMachines returns every planned machine in the constraint department, in name order.
	GetConstraintMachines(ctx context.Context, accountID, departmentID string) ([]scheduling.Machine, *apierror.APIError)

	// CountConstraintMachinesWithoutStep reports how many constraint machines cannot carry a plan downstream because they have no production step.
	CountConstraintMachinesWithoutStep(ctx context.Context, accountID, departmentID string) (int, *apierror.APIError)

	// GetConstraintDepartmentLaborRate returns the hourly labor rate configured on the constraint department, or nil when it has none.
	GetConstraintDepartmentLaborRate(ctx context.Context, accountID, departmentID string) (*float64, *apierror.APIError)

	// GetConstraintBatchMeasurements returns one row per historical batch produced on the given machines inside the window.
	GetConstraintBatchMeasurements(ctx context.Context, params GetConstraintBatchMeasurementsParams) ([]ConstraintBatchRow, *apierror.APIError)
	// GetItemRunRateHistory returns the run-rate samples behind an item's most recent scans, newest first, ignoring any measurement window. Only scans whose step carries a labor time come back.
	GetItemRunRateHistory(ctx context.Context, accountID, itemID string, limit int32) ([]ItemRunRateSample, *apierror.APIError)
	// GetFinishingMachines returns every machine outside the constraint department — the second stage, selected as the complement of the constraint rather than as a list of its own.
	GetFinishingMachines(ctx context.Context, accountID, constraintDepartmentID string) ([]scheduling.Machine, *apierror.APIError)
	// GetFinishingBatchMeasurements returns the second stage's production history for the given finished goods, which is what its run rates are measured from.
	GetFinishingBatchMeasurements(ctx context.Context, params GetFinishingBatchMeasurementsParams) ([]FinishingBatchRow, *apierror.APIError)

	// GetStepConsumptionItems returns the input items each production step consumes.
	GetStepConsumptionItems(ctx context.Context, stepIDs []string) ([]StepConsumptionRow, *apierror.APIError)

	// GetSeedBatchesForItems returns every scanned batch for the given items inside the demand window, to start the genealogy walk from.
	GetSeedBatchesForItems(ctx context.Context, params GetSeedBatchesParams) ([]SeedBatchRow, *apierror.APIError)

	// GetBatchFlowChildren returns the immediate downstream batches of the given parent batches.
	GetBatchFlowChildren(ctx context.Context, accountID string, parentBatchIDs []string) ([]BatchFlowChildRow, *apierror.APIError)

	// GetEchelonOnHand returns available inventory per item, net of allocations, normalized through the unit ratio.
	GetEchelonOnHand(ctx context.Context, accountID string, itemIDs []string) (map[string]float64, *apierror.APIError)

	// GetProductsForItems returns the sellable products carried by the given items.
	GetProductsForItems(ctx context.Context, accountID string, itemIDs []string) ([]SellableProductRow, *apierror.APIError)

	// GetPooledOrderDemandByProduct returns monthly sold quantity per product inside the window.
	GetPooledOrderDemandByProduct(ctx context.Context, params GetPooledOrderDemandParams) ([]PooledMonthlyDemandRow, *apierror.APIError)

	// ListDeliveryOutcomes returns every order whose commitment came due inside the window, with what happened to it, narrowed by the given filters.
	ListDeliveryOutcomes(ctx context.Context, accountID string, start, end time.Time, filters DeliveryFilters) ([]scheduling.DeliveryOutcome, *apierror.APIError)

	// CountUncommittedOrders counts issued orders in the window carrying no ship-by date, under the same filters, so the excluded count describes the same slice the rates do.
	CountUncommittedOrders(ctx context.Context, accountID string, start, end time.Time, filters DeliveryFilters) (int, *apierror.APIError)

	// GetOpenOrderRequirements returns the outstanding quantity on every issued, unshipped line for the given products.
	GetOpenOrderRequirements(ctx context.Context, accountID string, productIDs []string) ([]OpenOrderRequirementRow, *apierror.APIError)

	// GetProductDemandByCustomer returns monthly sold quantity per product and buyer, for measuring customer concentration.
	GetProductDemandByCustomer(ctx context.Context, params GetPooledOrderDemandParams) ([]CustomerDemandRow, *apierror.APIError)

	// GetCustomerFulfillmentProfiles returns every customer's resolved lead time and stated policy.
	GetCustomerFulfillmentProfiles(ctx context.Context, accountID string, accountDefaultLeadTimeDays int) ([]CustomerFulfillmentProfile, *apierror.APIError)

	// GetActiveDemandOverrides returns the demand overrides in force at the planning date.
	GetActiveDemandOverrides(ctx context.Context, accountID string, asOf time.Time) ([]scheduling.DemandOverride, *apierror.APIError)

	// GetItemsForProductLines maps product lines to the items sold under them.
	GetItemsForProductLines(ctx context.Context, accountID string, productLineIDs []string) ([]ProductLineItemRow, *apierror.APIError)

	// ListProductLineLotDefaults returns every product line in the account that has a lot convention.
	ListProductLineLotDefaults(ctx context.Context, accountID string) ([]scheduling.ProductLineLot, *apierror.APIError)

	// ListProductLineFulfillmentPolicies returns every product line in the account that sets a fulfillment policy, keyed by line id.
	ListProductLineFulfillmentPolicies(ctx context.Context, accountID string) (map[string]string, *apierror.APIError)

	// GetAllSellableProducts returns every product in the account, which is the candidate set for a fulfillment recommendation.
	GetAllSellableProducts(ctx context.Context, accountID string) ([]SellableProductRow, *apierror.APIError)

	// GetItemUnitCosts returns each item's unit cost, keyed by item id.
	GetItemUnitCosts(ctx context.Context, accountID string, itemIDs []string) (map[string]float64, *apierror.APIError)

	// ListItemProductLines maps items to the product line they sell under.
	ListItemProductLines(ctx context.Context, accountID string, itemIDs []string) ([]ItemProductLineRow, *apierror.APIError)

	// GetAccountScheduleSettings returns the account's stored planning assumptions as one raw row, or nil when the account has never configured scheduling.
	GetAccountScheduleSettings(ctx context.Context, accountID string) (*ProductionScheduleSettingsRow, *apierror.APIError)

	// ListScheduleItemSettings returns the account's per-item planning overrides.
	ListScheduleItemSettings(ctx context.Context, accountID string) ([]ProductionScheduleItemSetting, *apierror.APIError)
}

ProductionScheduleInputRepo is the thin read surface behind solver-input assembly. Each method is one query mapped to domain or scheduling types; the assembly itself — genealogy attribution, demand pooling, settings defaulting — lives in the production schedule service.

type ProductionScheduleItemPlanningSetting

type ProductionScheduleItemPlanningSetting struct {
	ID        string
	AccountID string
	ItemID    string
	SKU       string

	IsExcluded bool
	// LotMultipleUnits overrides the lot this item is made in; nil leaves the lot chain alone.
	LotMultipleUnits *float64
	// FulfillmentPolicyCode overrides how this item is produced; nil falls through to its product line, then the account default.
	FulfillmentPolicyCode *string

	CreatedAt time.Time
	UpdatedAt time.Time
}

ProductionScheduleItemPlanningSetting is one item's planning override as the API serves it.

Distinct from ProductionScheduleItemSetting, which is the solver's narrower view of the same row: the solve needs the values, the API needs the identity and timestamps too.

type ProductionScheduleItemPolicy

type ProductionScheduleItemPolicy struct {
	ID                   string
	ProductionScheduleID string
	ItemID               string
	SKU                  string

	ProductionStepID *string
	PrimaryMachineID *string
	// UnitID is what every quantity in this policy is counted in; the abbreviation is joined for display.
	UnitID           *string
	UnitAbbreviation *string

	AnnualDemand   float64
	WeeklyDemand   float64
	SecondsPerUnit float64
	UnitCost       float64

	SetupCost   float64
	HoldingCost float64
	EOQUnits    float64

	ConstraintLeadTimeWeeks float64
	FinishLeadTimeWeeks     float64

	SigmaWeeklyPooled     float64
	SigmaDownstreamSum    float64
	SafetyStockPrimary    float64
	SafetyStockDownstream float64

	ReorderPoint  float64
	OrderUpTo     float64
	OnHandEchelon float64
	// The greige stage on its own, and how much the stage holds on average and at peak. The echelon figure above drives the build decision; these describe the store.
	OnHandGreige           float64
	AverageGreigeInventory float64
	MaxGreigeInventory     float64
	// ProjectedOnHand is the echelon position at the end of each horizon week. Weeks with no campaign are the ones this explains: stock draining toward the trigger.
	ProjectedOnHand []float64
	// ProjectedGreigeOnHand is the physical greige store at the end of each horizon week — the constraint stage on its own, which the echelon curve cannot be decomposed back into. It is what the greige buffer is measured against, so a week where it dips to the floor is the week knitting is meant to replenish. Nil for a schedule generated before the buffer existed.
	ProjectedGreigeOnHand []float64
	WeeksOfCover          float64
	AnnualRunHours        float64

	ABCClass           *string
	WasEOQCapped       bool
	WasCapacityStarved bool

	// The policy this SKU was solved under, the rule that decided it, and the split between what the order book already owed and what the forecast projected.
	FulfillmentPolicyCode string
	PolicySourceCode      string
	FirmDemandUnits       float64
	ForecastDemandUnits   float64

	CreatedAt time.Time
	UpdatedAt time.Time
}

ProductionScheduleItemPolicy is the per-item "why" behind the lines, snapshotted so a historical plan stays explainable after costs and demand move.

type ProductionScheduleItemSetting

type ProductionScheduleItemSetting struct {
	ItemID           string
	IsExcluded       bool
	LotMultipleUnits float64
	// FulfillmentPolicyCode is an explicit per-item override; empty means the item inherits from its product line, then the account default.
	FulfillmentPolicyCode string
}

ProductionScheduleItemSetting is a merchant override for one item's planning.

type ProductionScheduleLine

type ProductionScheduleLine struct {
	ID                   string
	ProductionScheduleID string

	WeekIndex     int32     `audit:"week_index"`
	WeekStartDate time.Time `audit:"week_start_date"`

	MachineID        string `audit:"machine_id"`
	ProductionStepID *string
	DepartmentID     *string
	ItemID           string `audit:"item_id"`
	// ItemSKU is joined for display: a plan row is read by SKU, and a line whose item the version holds no policy for — every hand-added campaign — has nowhere else to get one.
	ItemSKU string

	PlannedQuantity float64 `audit:"planned_quantity"`
	PlannedUnitID   *string `audit:"planned_unit_id"`
	// PlannedUnitAbbreviation is joined for display: every quantity on this line is counted in it, and a bare 360 on a plan grid cannot say whether it means pairs or eaches.
	PlannedUnitAbbreviation  *string
	PlannedLots              int32 `audit:"planned_lots"`
	PlannedLotUnits          float64
	PlannedRunHours          float64 `audit:"planned_run_hours"`
	PlannedChangeoverMinutes float64
	SequenceIndex            int32 `audit:"sequence_index"`

	ProjectedOnHandBefore float64
	ProjectedOnHandAfter  float64

	StatusCode      string  `audit:"status_code"`
	SourceCode      string  `audit:"source_code"`
	ReasonCode      *string `audit:"reason_code"`
	IsFrozen        bool    `audit:"is_frozen"`
	ProductionRunID *string
	// Progress, measured from the run this campaign was released as. Zero until the week is released; a released campaign is complete when every batch it issued has been scanned.
	ReleasedBatchCount int64
	ScannedBatchCount  int64
	ScannedQuantity    float64

	CreatedAt time.Time
	UpdatedAt time.Time
}

ProductionScheduleLine is one planned campaign.

type ProductionScheduleLineOrder

type ProductionScheduleLineOrder struct {
	ID                       string
	ProductionScheduleLineID string
	SalesOrderID             string
	SalesOrderNumber         string
	SalesOrderLineID         string
	AllocatedQuantity        float64

	// Denormalized from the line so a caller can read what is being built without a second round trip.
	ItemID     string
	SKU        string
	WeekIndex  int32
	MachineID  string
	ShipByDate *time.Time
}

ProductionScheduleLineOrder is one campaign's contribution to one order.

type ProductionScheduleRepo

type ProductionScheduleRepo interface {
	NextVersion(ctx context.Context, accountID string) (int32, *apierror.APIError)
	Create(ctx context.Context, schedule *ProductionSchedule) *apierror.APIError
	CreateLines(ctx context.Context, accountID, scheduleID string, lines []*ProductionScheduleLine) *apierror.APIError
	CreateItemPolicies(ctx context.Context, accountID, scheduleID string, policies []*ProductionScheduleItemPolicy) *apierror.APIError
	// ReplaceFinishedPolicies rewrites a version's finished-goods targets — the per-SKU decomposition of the pooled greige buffers.
	ReplaceFinishedPolicies(ctx context.Context, accountID, scheduleID string, policies []*ProductionScheduleFinishedPolicy) *apierror.APIError
	ListFinishedPolicies(ctx context.Context, accountID, scheduleID string) ([]*ProductionScheduleFinishedPolicy, *apierror.APIError)
	// ReplaceFinishingLines rewrites a version's stage-two plan. Wholesale rather than patched: the finished mix is a pure function of the knit plan, the order book and each SKU's position, so a partial update could leave a week holding lines for a campaign the re-solve no longer produces.
	ReplaceFinishingLines(ctx context.Context, accountID, scheduleID string, lines []*ProductionScheduleFinishingLine) *apierror.APIError
	ListFinishingLines(ctx context.Context, params ListProductionScheduleFinishingLinesParams) ([]*ProductionScheduleFinishingLine, *apierror.APIError)
	DeleteFinishingLines(ctx context.Context, accountID, scheduleID string) *apierror.APIError
	// DeleteItemPolicies clears a version's policy snapshot. A regenerate re-solves the same version, and the snapshot describes one solve rather than an accumulation.
	DeleteItemPolicies(ctx context.Context, accountID, scheduleID string) *apierror.APIError
	Get(ctx context.Context, params GetProductionScheduleParams) (*ProductionSchedule, *apierror.APIError)
	// GetCurrent returns the published version covering the date, or nil when none does — an account with no live plan is a normal state, not an error.
	GetCurrent(ctx context.Context, accountID string, asOf time.Time) (*ProductionSchedule, *apierror.APIError)
	List(ctx context.Context, params ListProductionSchedulesParams) (*ListProductionSchedulesResult, *apierror.APIError)
	ListLines(ctx context.Context, params ListProductionScheduleLinesParams) ([]*ProductionScheduleLine, *apierror.APIError)
	ListItemPolicies(ctx context.Context, accountID, scheduleID string) ([]*ProductionScheduleItemPolicy, *apierror.APIError)
	Delete(ctx context.Context, accountID, scheduleID string) *apierror.APIError

	// Lifecycle: hand edits, the deviation log, and publish.
	ListScheduleDeviationTypes(ctx context.Context) ([]*ScheduleDeviationType, *apierror.APIError)
	GetLine(ctx context.Context, accountID, lineID string) (*ProductionScheduleLine, *apierror.APIError)
	UpdateLine(ctx context.Context, params UpdateLineRepoParams) (*ProductionScheduleLine, *apierror.APIError)
	DeleteLine(ctx context.Context, accountID, lineID string) *apierror.APIError
	NextSequenceIndex(ctx context.Context, accountID, scheduleID string, weekIndex int32) (int32, *apierror.APIError)
	CreateDeviation(ctx context.Context, id string, deviation *ProductionScheduleDeviation) *apierror.APIError
	ListDeviations(ctx context.Context, params ListProductionScheduleDeviationsParams) (*ListProductionScheduleDeviationsResult, *apierror.APIError)
	// SumFrozenLines returns the counts captured onto the version at publish. They are snapshotted rather than recomputed, so adherence keeps its original denominator.
	SumFrozenLines(ctx context.Context, accountID, scheduleID string, frozenThrough time.Time) (*FrozenLineTotals, *apierror.APIError)
	FreezeLines(ctx context.Context, accountID, scheduleID string, frozenThrough time.Time) *apierror.APIError
	Publish(ctx context.Context, accountID, scheduleID string, frozenThrough time.Time, totals *FrozenLineTotals, publishedByID *string) *apierror.APIError
	ListPublishedOverlapping(ctx context.Context, accountID, excludeID string, start, end time.Time) ([]string, *apierror.APIError)
	Supersede(ctx context.Context, accountID, scheduleID, supersededByID string) *apierror.APIError
	SetStatus(ctx context.Context, accountID, scheduleID, statusCode string) *apierror.APIError

	// Releasing a week to the floor.
	CountReleasedLinesForWeek(ctx context.Context, accountID, scheduleID string, weekIndex int32) (*WeekReleaseState, *apierror.APIError)
	// UnreleaseLinesForRun returns a week to planned when the run holding its work is deleted, so it can be released again.
	UnreleaseLinesForRun(ctx context.Context, accountID, productionRunID string) *apierror.APIError
	// MarkLineReleased links a campaign to the run now carrying it. It is a no-op on a line that is already released, so a racing double release cannot re-point work.
	MarkLineReleased(ctx context.Context, accountID, lineID, productionRunID string) *apierror.APIError
	// ListCarryForwardBatches returns an item's unworked tickets from weeks that have already begun, oldest first, so a release can move them rather than print their replacements.
	ListCarryForwardBatches(ctx context.Context, params ListCarryForwardBatchesParams) ([]*CarryForwardBatch, *apierror.APIError)

	// Generation cadence.
	ListGenerationCadences(ctx context.Context) ([]GenerationCadence, *apierror.APIError)
	StampGenerationRun(ctx context.Context, accountID string, at time.Time) *apierror.APIError
	ReapStalledGenerations(ctx context.Context, before time.Time) *apierror.APIError
	CreateGeneratingSchedule(ctx context.Context, params CreateGeneratingScheduleParams) *apierror.APIError
	FillGeneratedSchedule(ctx context.Context, schedule *ProductionSchedule) *apierror.APIError
	// RefreshRegenerated re-stamps a draft with the metadata of the solve that just replaced its lines.
	RefreshRegenerated(ctx context.Context, schedule *ProductionSchedule) *apierror.APIError
	FailGeneration(ctx context.Context, accountID, scheduleID, reason string) *apierror.APIError

	// Merchant-editable planning assumptions.
	GetSettings(ctx context.Context, accountID string) (*ProductionScheduleSettings, *apierror.APIError)

	// ReplaceLineOrders rewrites which campaigns are building which orders for one version.
	ReplaceLineOrders(ctx context.Context, accountID, scheduleID string, links []CreateLineOrderParams) *apierror.APIError
	// ListLineOrders returns which campaigns are building which orders for one version.
	ListLineOrders(ctx context.Context, accountID, scheduleID string) ([]*ProductionScheduleLineOrder, *apierror.APIError)

	// ListItemSettings returns every per-item planning override in the account.
	ListItemSettings(ctx context.Context, accountID string) ([]*ProductionScheduleItemPlanningSetting, *apierror.APIError)
	// GetItemSetting returns one item's override, or nil when it has none.
	GetItemSetting(ctx context.Context, accountID, itemID string) (*ProductionScheduleItemPlanningSetting, *apierror.APIError)
	// UpsertItemSetting writes one item's override.
	UpsertItemSetting(ctx context.Context, params UpsertItemSettingParams) *apierror.APIError
	// DeleteItemSetting removes one item's override; false when there was none.
	DeleteItemSetting(ctx context.Context, accountID, itemID string) (bool, *apierror.APIError)
	UpsertSettings(ctx context.Context, settings *ProductionScheduleSettings) *apierror.APIError
	ListResourceSettings(ctx context.Context, accountID string) ([]*ProductionScheduleResourceSetting, *apierror.APIError)
	UpsertResourceSetting(ctx context.Context, id string, params UpsertResourceSettingParams) *apierror.APIError
	DeleteResourceSetting(ctx context.Context, accountID, settingID string) *apierror.APIError

	// Derived department work.
	LoadStepGraph(ctx context.Context, accountID string) (*StepGraph, *apierror.APIError)
	ReplaceDerivedLines(ctx context.Context, accountID, scheduleID string, lines []*ProductionScheduleDerivedLine) *apierror.APIError
	ListDerivedLines(ctx context.Context, params ListDerivedLinesParams) ([]*ProductionScheduleDerivedLine, *apierror.APIError)
}

type ProductionScheduleResourceSetting

type ProductionScheduleResourceSetting struct {
	ID                  string
	AccountID           string
	ScopeCode           string
	ScopeRefID          string
	IsExcluded          bool
	LeadTimeWeeks       *float64
	LeadTimeOffsetWeeks float64
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

ProductionScheduleResourceSetting overrides planning behaviour for one machine, department or production step.

type ProductionScheduleSettings

type ProductionScheduleSettings struct {
	AccountID string

	ConstraintDepartmentID *string `audit:"constraint_department_id"`

	PlanningHorizonWeeks int32 `audit:"planning_horizon_weeks"`
	FrozenWeeks          int32 `audit:"frozen_weeks"`
	WeekStartDay         int32 `audit:"week_start_day"`

	DemandWindowMonths    int32   `audit:"demand_window_months"`
	ForecastHistoryMonths int32   `audit:"forecast_history_months"`
	ForecastMonths        int32   `audit:"forecast_months"`
	DemandBasisCode       string  `audit:"demand_basis_code"`
	ForecastZ             float64 `audit:"forecast_z"`

	ChangeoverAvgMinutes float64 `audit:"changeover_avg_minutes"`
	ChangeoverMinMinutes float64 `audit:"changeover_min_minutes"`
	ChangeoverMaxMinutes float64 `audit:"changeover_max_minutes"`
	ChangeoverLaborRate  float64 `audit:"changeover_labor_rate"`

	HoldingRatePct                 float64 `audit:"holding_rate_pct"`
	ServiceLevelZ                  float64 `audit:"service_level_z"`
	FinishLeadTimeWeeks            float64 `audit:"finish_lead_time_weeks"`
	DefaultConstraintLeadTimeWeeks float64 `audit:"default_constraint_lead_time_weeks"`
	MaxWeeksSupply                 float64 `audit:"max_weeks_supply"`
	MaxFlowDepth                   int32   `audit:"max_flow_depth"`

	ShiftsPerDay        int32   `audit:"shifts_per_day"`
	HoursPerShift       float64 `audit:"hours_per_shift"`
	WorkDaysPerWeek     int32   `audit:"work_days_per_week"`
	WeeksPerYear        int32   `audit:"weeks_per_year"`
	CapacityHeadroomPct float64 `audit:"capacity_headroom_pct"`
	DefaultLotUnits     float64 `audit:"default_lot_units"`

	// DefaultCustomerLeadTimeDays is the last fallback in an order's ship-by chain, behind the customer and its account group.
	DefaultCustomerLeadTimeDays int32 `audit:"default_customer_lead_time_days"`
	// ShipCalendarID and ReceiveCalendarID are the account-wide fallbacks behind the per-customer and per-address links, and the last stop before Monday to Friday. They sit with the planning assumptions because they answer the same question the lead time does — when can this order actually leave.
	ShipCalendarID    *string `audit:"ship_calendar_id"`
	ReceiveCalendarID *string `audit:"receive_calendar_id"`

	// DefaultFulfillmentPolicyCode is how a SKU is produced when neither it nor its product line says.
	DefaultFulfillmentPolicyCode string `audit:"default_fulfillment_policy_code"`

	IsEnabled          bool    `audit:"is_enabled"`
	GenerationCron     *string `audit:"generation_cron"`
	GenerationTimezone string  `audit:"generation_timezone"`
	AutoPublish        bool    `audit:"auto_publish"`
	LastGeneratedAt    *time.Time

	// HasStoredSettings is false when the values are code defaults rather than something the merchant chose.
	HasStoredSettings bool

	CreatedAt time.Time
	UpdatedAt time.Time
}

ProductionScheduleSettings are the merchant-editable planning assumptions.

Every value here was a hardcoded constant in the original knit-scheduling script. The resource is always returned fully populated: an account that has never saved settings gets code defaults rather than nulls, so a caller never has to know which defaults the solver would have applied.

type ProductionScheduleSettingsRow

type ProductionScheduleSettingsRow struct {
	PlanningHorizonWeeks           int
	FrozenWeeks                    int
	WeekStartDay                   int
	ShiftsPerDay                   int
	HoursPerShift                  float64
	WorkDaysPerWeek                int
	WeeksPerYear                   int
	CapacityHeadroomPct            float64
	DefaultLotUnits                float64
	ChangeoverAvgMinutes           float64
	ChangeoverMinMinutes           float64
	ChangeoverMaxMinutes           float64
	ChangeoverLaborRate            float64
	HoldingRatePct                 float64
	ServiceLevelZ                  float64
	FinishLeadTimeWeeks            float64
	DefaultConstraintLeadTimeWeeks float64
	MaxWeeksSupply                 float64
	MaxFlowDepth                   int

	DefaultCustomerLeadTimeDays  int
	DefaultFulfillmentPolicyCode string
	RecommendationThresholds     scheduling.RecommendationThresholds

	DemandWindowMonths    int
	ForecastHistoryMonths int
	ForecastMonths        int
	DemandBasisCode       string
	ForecastZ             float64
	// ConstraintDepartmentID is empty when no constraint department is configured.
	ConstraintDepartmentID string
}

ProductionScheduleSettingsRow is the merchant's stored planning assumptions as one raw row, before code defaults are merged in by the service.

type ProductionScheduleSvc

type ProductionScheduleSvc interface {
	// PreviewRegenerateProductionSchedule says what a re-solve would change about a draft, without changing it.
	PreviewRegenerateProductionSchedule(ctx context.Context, params RegenerateProductionScheduleParams) (*ScheduleRegeneratePreview, *apierror.APIError)
	// RegenerateProductionSchedule re-solves a draft in place, keeping its version number.
	RegenerateProductionSchedule(ctx context.Context, params RegenerateProductionScheduleParams) (*ProductionSchedule, *apierror.APIError)
	// PreviewProductionSchedule runs the solver and returns the plan without persisting it.
	PreviewProductionSchedule(ctx context.Context, params PreviewProductionScheduleParams) (*scheduling.SolverOutput, *apierror.APIError)

	// GenerateProductionSchedule solves and persists a new draft version.
	GenerateProductionSchedule(ctx context.Context, params GenerateProductionScheduleParams) (*ProductionSchedule, *apierror.APIError)

	// GetProductionSchedule returns one version by ID.
	GetProductionSchedule(ctx context.Context, scheduleID string) (*ProductionSchedule, *apierror.APIError)

	// GetCurrentProductionSchedule returns the published version covering today, or nil when there is none.
	GetCurrentProductionSchedule(ctx context.Context) (*ProductionSchedule, *apierror.APIError)

	// ListProductionSchedules returns a paginated list of versions.
	ListProductionSchedules(ctx context.Context, params ListProductionSchedulesParams) (*ListProductionSchedulesResult, *apierror.APIError)

	// ListProductionScheduleLines returns the planned campaigns for a version.
	ListProductionScheduleLines(ctx context.Context, params ListProductionScheduleLinesParams) ([]*ProductionScheduleLine, *apierror.APIError)

	// ListProductionScheduleItemPolicies returns the per-item policy snapshot behind a version.
	ListProductionScheduleItemPolicies(ctx context.Context, scheduleID string) ([]*ProductionScheduleItemPolicy, *apierror.APIError)
	// ListProductionScheduleFinishedPolicies returns the per-finished-SKU decomposition of a version's pooled constraint buffers.
	ListProductionScheduleFinishedPolicies(ctx context.Context, scheduleID string) ([]*ProductionScheduleFinishedPolicy, *apierror.APIError)
	// ListProductionScheduleFinishingLines returns stage two: how many of which finished good to make from the knitted parts.
	ListProductionScheduleFinishingLines(ctx context.Context, params ListProductionScheduleFinishingLinesParams) ([]*ProductionScheduleFinishingLine, *apierror.APIError)

	// GetProductionScheduleSettings returns the merchant's planning assumptions, falling back to code defaults when nothing has been saved.
	GetProductionScheduleSettings(ctx context.Context) (*ProductionScheduleSettings, *apierror.APIError)

	// UpdateProductionScheduleSettings replaces the merchant's planning assumptions.
	UpdateProductionScheduleSettings(ctx context.Context, params UpdateProductionScheduleSettingsParams) (*ProductionScheduleSettings, *apierror.APIError)

	// ListAtRiskOrders returns the commitments a version does not meet.
	ListAtRiskOrders(ctx context.Context, scheduleID string) ([]*ScheduleOrderCoverage, *apierror.APIError)

	// ListFulfillmentRecommendations works out which SKUs should be built to order and which to stock.
	ListFulfillmentRecommendations(ctx context.Context) ([]*FulfillmentRecommendation, *apierror.APIError)

	// ApplyFulfillmentRecommendations writes the recommended policy onto the named items.
	ApplyFulfillmentRecommendations(ctx context.Context, itemIDs []string) ([]*FulfillmentRecommendation, *apierror.APIError)

	// ListItemSettings returns every per-item planning override in the account.
	ListItemSettings(ctx context.Context) ([]*ProductionScheduleItemPlanningSetting, *apierror.APIError)

	// GetItemSetting returns one item's planning override.
	GetItemSetting(ctx context.Context, itemID string) (*ProductionScheduleItemPlanningSetting, *apierror.APIError)

	// UpsertItemSetting writes one item's planning override.
	UpsertItemSetting(ctx context.Context, params UpsertItemSettingParams) (*ProductionScheduleItemPlanningSetting, *apierror.APIError)

	// DeleteItemSetting removes one item's planning override.
	DeleteItemSetting(ctx context.Context, itemID string) *apierror.APIError

	// ListResourceSettings returns per-machine, per-department and per-step overrides.
	ListResourceSettings(ctx context.Context) ([]*ProductionScheduleResourceSetting, *apierror.APIError)

	// UpsertResourceSetting writes one per-resource override.
	UpsertResourceSetting(ctx context.Context, params UpsertResourceSettingParams) (*ProductionScheduleResourceSetting, *apierror.APIError)

	// DeleteResourceSetting removes one per-resource override.
	DeleteResourceSetting(ctx context.Context, settingID string) *apierror.APIError

	// EnqueueScheduledGeneration reserves a version and queues its solve, in one transaction. Used by the generation cadence.
	EnqueueScheduledGeneration(ctx context.Context, params EnqueueGenerationParams) *apierror.APIError

	// RunScheduledGeneration solves into a row already created in `generating`. Used by the generate-command consumer.
	RunScheduledGeneration(ctx context.Context, params RunScheduledGenerationParams) *apierror.APIError

	// ListProductionScheduleDerivedLines returns derived downstream department work.
	ListProductionScheduleDerivedLines(ctx context.Context, params ListDerivedLinesParams) ([]*ProductionScheduleDerivedLine, *apierror.APIError)

	// ListScheduleDeviationTypes returns the global taxonomy of what a hand change can be.
	ListScheduleDeviationTypes(ctx context.Context) ([]*ScheduleDeviationType, *apierror.APIError)

	// ListProductionScheduleDeviations returns the append-only log of hand changes.
	ListProductionScheduleDeviations(ctx context.Context, params ListProductionScheduleDeviationsParams) (*ListProductionScheduleDeviationsResult, *apierror.APIError)

	// CreateProductionScheduleLine adds a campaign by hand and logs a deviation.
	CreateProductionScheduleLine(ctx context.Context, params CreateProductionScheduleLineParams) (*ProductionScheduleLine, *apierror.APIError)

	// UpdateProductionScheduleLine edits a campaign and logs a deviation.
	UpdateProductionScheduleLine(ctx context.Context, params UpdateProductionScheduleLineParams) (*ProductionScheduleLine, *apierror.APIError)

	// DeleteProductionScheduleLine removes a campaign and logs a deviation.
	DeleteProductionScheduleLine(ctx context.Context, params DeleteProductionScheduleLineParams) *apierror.APIError

	// PublishProductionSchedule freezes the first weeks, snapshots the frozen counts, and supersedes whatever it replaces.
	PublishProductionSchedule(ctx context.Context, scheduleID string) (*ProductionSchedule, *apierror.APIError)

	// ReleaseProductionScheduleWeek turns one planned week into a production run, with one batch per planned lot.
	ReleaseProductionScheduleWeek(ctx context.Context, params ReleaseScheduleWeekParams) (*ReleaseScheduleWeekResult, *apierror.APIError)

	// PreviewReleaseProductionScheduleWeek says what releasing a week would create, without creating it.
	PreviewReleaseProductionScheduleWeek(ctx context.Context, scheduleID string, weekIndex int32, skipCarryForward bool) (*ReleaseScheduleWeekPreview, *apierror.APIError)

	// ArchiveProductionSchedule retires a version without deleting its history.
	ArchiveProductionSchedule(ctx context.Context, scheduleID string) (*ProductionSchedule, *apierror.APIError)

	// DeleteProductionSchedule removes a draft. Published versions must be archived.
	DeleteProductionSchedule(ctx context.Context, scheduleID string) *apierror.APIError
}

type ProductionStep

type ProductionStep struct {
	ID              string
	Name            string                `audit:"name"`
	Notes           *string               `audit:"notes"`
	LevelingFactor  string                `audit:"leveling_factor"`
	Allowances      string                `audit:"allowances"`
	LaborRate       *ProductionStepRate   `audit:"labor_rate"`
	LaborTime       *ProductionStepRate   `audit:"labor_time"`
	OverheadRate    *ProductionStepRate   `audit:"overhead_rate"`
	Production      *Production           `audit:"production"`
	Consumptions    []Consumption         `audit:"consumptions"`
	Machines        []LightMachine        `audit:"machines"`
	ScanningStation *LightScanningStation `audit:"scanning_station"`
	InSteps         []LightProductionStep `audit:"in_steps"`
	OutSteps        []LightProductionStep `audit:"out_steps"`
	DepartmentID    *string               `audit:"department_id"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

ProductionStep is the full production step domain model with all associated data.

type ProductionStepBulkRow

type ProductionStepBulkRow struct {
	ID                string
	Name              string
	Notes             *string
	LevelingFactor    string
	Allowances        string
	ScanningStationID *string
	DepartmentID      *string
	LaborRateID       string
	LaborTimeID       string
	OverheadRateID    string
}

ProductionStepBulkRow is the slim row shape used to match bulk upsert rows against existing production steps.

type ProductionStepDetail

type ProductionStepDetail struct {
	ID           string
	Name         string
	Production   StepProduction
	Consumptions []StepConsumption
}

type ProductionStepExport

type ProductionStepExport struct {
	ID                       string
	Name                     string
	DepartmentName           *string
	ScanningStationName      *string
	LaborRate                *string
	LaborRateCurrencyUnit    *string
	LaborRateTimeUnit        *string
	LaborTime                *string
	LaborTimeUnit            *string
	LaborTimePerUnit         *string
	OverheadRate             *string
	OverheadRateCurrencyUnit *string
	OverheadRateTimeUnit     *string
	Allowances               string
	LevelingFactor           string
	Notes                    *string
	ProducedItemSKU          string
	ProducedQuantity         string
	ProducedUnit             string
	Consumptions             []ProductionStepExportConsumption
}

carries one step and its consumptions as the export sheet lays them out. The read model nests rates and quantities; the sheet wants them flat.

type ProductionStepExportConsumption

type ProductionStepExportConsumption struct {
	ItemSKU       string
	Quantity      string
	Unit          string
	WasteQuantity *string
	WasteUnit     *string
	Instructions  *string
}

carries one consumption of an exported step, one sheet row each

type ProductionStepQueryRepo

type ProductionStepQueryRepo interface {
	Find(ctx context.Context, accountID, id string) (*ProductionStepDetail, *apierror.APIError)
	Export(ctx context.Context, params ExportProductionStepsParams) ([]*ProductionStepExport, *apierror.APIError)
	IsInAccount(ctx context.Context, accountID, id string) (bool, *apierror.APIError)
	IsMultiPart(ctx context.Context, accountID, id string) (bool, *apierror.APIError)
	IsLastStep(ctx context.Context, accountID, id string) (bool, *apierror.APIError)
	IsInputOfStep(ctx context.Context, accountID, currentStepID, inputStepID string) (bool, *apierror.APIError)
	FindProducedItemID(ctx context.Context, accountID, id string) (string, *apierror.APIError)
	FindProducedUnit(ctx context.Context, accountID, id string) (*LightUnit, *apierror.APIError)
	FindIDByScanningStationAndProducedBlock(ctx context.Context, accountID, scanningStationID, itemID string) (string, *apierror.APIError)
	FindOneByScanningStationAndProducedBlock(ctx context.Context, accountID, scanningStationID, itemID string) (*ProductionStepDetail, *apierror.APIError)
	CalculateNextStepQuantities(ctx context.Context, accountID, itemID string, batchQuantity BatchQuantity, stepID string) (*NextStepQuantitiesResult, *apierror.APIError)
}

ProductionStepQueryRepo provides read-only methods the batch service needs from production steps.

type ProductionStepRate

type ProductionStepRate struct {
	ID              string
	Value           string
	NumeratorUnit   LightUnit
	DenominatorUnit LightUnit
}

ProductionStepRate represents a rate associated with a production step (labor, overhead, etc).

type ProductionStepRef

type ProductionStepRef struct {
	ID             string
	Name           string
	LevelingFactor string
	Allowances     string
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

ProductionStepRef is a reference to a production step with the minimal required fields.

type ProductionStepRepo

type ProductionStepRepo interface {
	List(ctx context.Context, params ListProductionStepsParams) (*ListProductionStepsResult, *apierror.APIError)
	Get(ctx context.Context, accountID, id string) (*ProductionStep, *apierror.APIError)
	InsertStep(ctx context.Context, id, name string, notes *string, levelingFactor, allowances, laborRateID, laborTimeID, overheadRateID string, scanningStationID, departmentID *string, accountID string) *apierror.APIError
	Update(ctx context.Context, params UpdateProductionStepParams) *apierror.APIError
	Delete(ctx context.Context, accountID, id string) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	FindIDByName(ctx context.Context, accountID, name string) (*string, *apierror.APIError)
	DeleteParentChildLinks(ctx context.Context, id string) *apierror.APIError
	GetInputSteps(ctx context.Context, id string) ([]LightProductionStep, *apierror.APIError)
	GetOutputSteps(ctx context.Context, id string) ([]LightProductionStep, *apierror.APIError)
	GetMachines(ctx context.Context, id string) ([]LightMachine, *apierror.APIError)
	InsertRate(ctx context.Context, id string, params CreateRateParams) *apierror.APIError
	InsertQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	InsertProduction(ctx context.Context, id, itemID, quantityID, productionStepID string) *apierror.APIError
	DeleteConsumptionsByStepID(ctx context.Context, stepID string) *apierror.APIError
	DeleteProductionsByStepID(ctx context.Context, stepID string) *apierror.APIError
	UpdateStepFull(ctx context.Context, id, accountID, levelingFactor, allowances string, scanningStationID *string) *apierror.APIError
	// FindByNames resolves existing production steps by name (case-insensitive) in
	// one query. Names must be pre-lowercased by the caller.
	FindByNames(ctx context.Context, accountID string, names []string) ([]*ProductionStepBulkRow, *apierror.APIError)
	// UpdateForBulkUpsert writes the full step row for a bulk upsert update; the rate
	// IDs point at freshly inserted rate rows.
	UpdateForBulkUpsert(ctx context.Context, params UpdateProductionStepForBulkUpsertParams) *apierror.APIError
}

ProductionStepRepo provides CRUD access to production step data.

type ProductionStepSvc

type ProductionStepSvc interface {
	// ListProductionSteps returns a paginated list of production steps.
	ListProductionSteps(ctx context.Context, params ListProductionStepsParams) (*ListProductionStepsResult, *apierror.APIError)

	ExportProductionSteps(ctx context.Context, params ExportProductionStepsParams) (*Job, *apierror.APIError)
	// BuildExportProductionSteps renders the file an accepted export recorded.
	BuildExportProductionSteps(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// GetProductionStep returns a single production step by ID.
	GetProductionStep(ctx context.Context, id string) (*ProductionStep, *apierror.APIError)

	// CreateProductionStep creates a new production step with rates, production, and consumptions.
	CreateProductionStep(ctx context.Context, params CreateProductionStepParams) (*ProductionStep, *apierror.APIError)

	// UpdateProductionStep partially updates a production step.
	UpdateProductionStep(ctx context.Context, params UpdateProductionStepParams) (*ProductionStep, *apierror.APIError)

	// DeleteProductionStep deletes a production step and its associated data.
	DeleteProductionStep(ctx context.Context, id string) *apierror.APIError

	// BulkCreateProductionSteps creates multiple production steps in a single operation.
	BulkCreateProductionSteps(ctx context.Context, params BulkCreateProductionStepsParams) ([]BulkCreateProductionStepResult, *apierror.APIError)

	// BulkUpsertProductionSteps validates and resolves synchronously, records the
	// resolved rows on a job, and returns the raised Job to poll. The steps are created
	// or updated asynchronously by ExecuteBulkUpsertProductionSteps.
	BulkUpsertProductionSteps(ctx context.Context, params BulkUpsertProductionStepsParams) (*Job, *apierror.APIError)
	ExecuteBulkUpsertProductionSteps(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError
}

type ProductionSvc

type ProductionSvc interface {
	// GetProduction returns a single production output by ID within a production step.
	GetProduction(ctx context.Context, productionStepID, productionID string) (*Production, *apierror.APIError)

	// UpdateProduction partially updates a production output.
	UpdateProduction(ctx context.Context, params UpdateProductionParams) (*Production, *apierror.APIError)
}

type Property

type Property struct {
	ID         string
	Name       string `audit:"name"`
	AccountID  string
	IsPublic   bool `audit:"is_public"`
	Attributes []*Attribute
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

Property represents a user-defined property that groups attributes.

type PropertyRepo

type PropertyRepo interface {
	List(ctx context.Context, params ListPropertiesParams) (*ListPropertiesResult, *apierror.APIError)
	Get(ctx context.Context, params GetPropertyParams) (*Property, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Property, *apierror.APIError)
	Create(ctx context.Context, id string, params CreatePropertyParams) (*Property, *apierror.APIError)
	Update(ctx context.Context, params UpdatePropertyParams) (*Property, *apierror.APIError)
	Delete(ctx context.Context, params DeletePropertyParams) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	FindByNames(ctx context.Context, accountID string, names []string) ([]*Property, *apierror.APIError)
	IsInAccount(ctx context.Context, accountID, propertyID string) (bool, *apierror.APIError)
	DeleteAttributesByPropertyID(ctx context.Context, propertyID, accountID string) *apierror.APIError
	Export(ctx context.Context, params ExportPropertiesParams) ([]*Property, *apierror.APIError)
}

type PropertySvc

type PropertySvc interface {
	// ListProperties returns a paginated list of properties for the caller's account.
	ListProperties(ctx context.Context, params ListPropertiesParams, includes []string) (*ListPropertiesResult, *apierror.APIError)

	// GetProperty returns a single property by ID.
	GetProperty(ctx context.Context, propertyID string, includes []string) (*Property, *apierror.APIError)

	// CreateProperty creates a new property.
	CreateProperty(ctx context.Context, params CreatePropertyParams, includes []string) (*Property, *apierror.APIError)

	// UpdateProperty partially updates a property.
	UpdateProperty(ctx context.Context, params UpdatePropertyParams, includes []string) (*Property, *apierror.APIError)

	// DeleteProperty deletes a property and cascades to its attributes.
	DeleteProperty(ctx context.Context, propertyID string) *apierror.APIError

	// BatchGetPropertiesByIDs returns properties matching the input IDs that belong to the caller's account. Always populates attributes.
	BatchGetPropertiesByIDs(ctx context.Context, ids []string) ([]*Property, *apierror.APIError)

	// BulkUpsertProperties accepts a bulk upsert and returns the job that tracks it.
	// Properties are matched by name within the account.
	BulkUpsertProperties(ctx context.Context, params BulkUpsertPropertiesParams) (*Job, *apierror.APIError)

	// performs the writes for an enqueued bulk property upsert.
	ExecuteBulkUpsertProperties(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// ExportProperties accepts an export and returns the job that tracks it.
	ExportProperties(ctx context.Context, params ExportPropertiesParams) (*Job, *apierror.APIError)

	// BuildExportProperties renders the file an accepted export recorded.
	BuildExportProperties(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)
}

type PublicAccountBySlug

type PublicAccountBySlug struct {
	ID                      string
	Name                    string
	Slug                    string
	DefaultBillingAddressID *string
	SupportEmail            *string
	LogoURL                 *string
	FaviconURL              *string
	// PortalDomain is the account's verified custom portal domain (e.g. shop.acme.com), when one exists.
	PortalDomain *string
}

PublicAccountBySlug is a minimal account representation returned for unauthenticated slug lookups.

type PublishProductionScheduleParams

type PublishProductionScheduleParams struct {
	AccountID  string
	ScheduleID string
}

type PurchaseOrder

type PurchaseOrder struct {
	ID                    string
	Number                string                 `audit:"number"`
	Note                  *string                `audit:"note"`
	IsAcknowledgmentSent  bool                   `audit:"is_acknowledgment_sent"`
	BillingAddressID      string                 `audit:"billing_address_id"`
	ShippingAddressID     string                 `audit:"shipping_address_id"`
	CarrierID             *string                `audit:"carrier_id"`
	ServiceLevelID        *string                `audit:"service_level_id"`
	CarrierBillingType    *string                `audit:"carrier_billing_type"`
	CarrierBillingAccount *string                `audit:"carrier_billing_account"`
	PriorityCode          constants.PriorityCode `audit:"priority_code"`
	ShippingTermID        *string                `audit:"shipping_term_id"`
	SalesOrderStatusCode  string                 `audit:"sales_order_status_code"`
	SalesOrderTypeCode    string                 `audit:"sales_order_type_code"`
	PaymentTermID         *string                `audit:"payment_term_id"`
	BuyerAccountID        string                 `audit:"buyer_account_id"`
	SellerAccountID       string                 `audit:"seller_account_id"`
	OwnerAccountID        string
	IssuedAt              *time.Time `audit:"issued_at"`
	CompletedAt           *time.Time `audit:"completed_at"`
	PromisedAt            *time.Time `audit:"promised_at"`
	CreatedAt             time.Time
	UpdatedAt             time.Time

	// Joined fields for reads
	SupplierName   string
	SupplierNumber string
	StatusName     string
	TypeName       string
	PriorityName   string

	// Joined address details (same as sales order)
	BillToName        *string
	BillToIsDropShip  *bool
	BillToStreetLine1 *string
	BillToStreetLine2 *string
	BillToLocality    *string
	BillToState       *string
	BillToPostalCode  *string
	BillToCountry     *string
	BillToPhone       *string
	BillToEmail       *string
	BillToCreatedAt   *time.Time
	BillToUpdatedAt   *time.Time
	ShipToName        *string
	ShipToIsDropShip  *bool
	ShipToStreetLine1 *string
	ShipToStreetLine2 *string
	ShipToLocality    *string
	ShipToState       *string
	ShipToPostalCode  *string
	ShipToCountry     *string
	ShipToPhone       *string
	ShipToEmail       *string
	ShipToCreatedAt   *time.Time
	ShipToUpdatedAt   *time.Time

	// Joined carrier details
	CarrierName                 *string
	CarrierIsPortalEnabled      *bool
	CarrierCreatedAt            *time.Time
	CarrierUpdatedAt            *time.Time
	ServiceLevelName            *string
	ServiceLevelToken           *string
	ServiceLevelIsPortalEnabled *bool
	ServiceLevelCreatedAt       *time.Time
	ServiceLevelUpdatedAt       *time.Time

	// Joined payment/shipping term
	PaymentTermName             *string
	PaymentTermIsActive         *bool
	PaymentTermCreatedAt        *time.Time
	PaymentTermUpdatedAt        *time.Time
	ShippingTermName            *string
	ShippingTermIsFreightExempt *bool
	ShippingTermIsCarrierRate   *bool
	ShippingTermCreatedAt       *time.Time
	ShippingTermUpdatedAt       *time.Time

	// Joined priority
	PriorityID *string

	// Joined receiving order
	ReceivingOrderID *string

	// Lines (populated when included)
	Lines []*PurchaseOrderLine

	// Contacts (populated when fetched)
	Contacts []*PurchaseOrderEmailContact

	// ReceivingOrder (populated when included)
	ReceivingOrder *ReceivingOrder
}

PurchaseOrder represents a full purchase order domain model.

type PurchaseOrderEmailContact

type PurchaseOrderEmailContact struct {
	ID            string
	AccountUserID string
}

PurchaseOrderEmailContact represents an email contact on a purchase order.

type PurchaseOrderLine

type PurchaseOrderLine struct {
	ID                 string
	LineItemNumber     int32   `audit:"line_item_number"`
	ProductSKU         string  `audit:"product_sku"`
	ProductDescription *string `audit:"product_description"`
	ProductID          *string `audit:"product_id"`
	ItemID             *string `audit:"item_id"`
	ItemSKU            *string `audit:"item_sku"`
	SalesOrderID       string

	// Quantity ordered
	QuantityID               string
	QuantityValue            string `audit:"quantity_value"`
	QuantityUnitID           string `audit:"quantity_unit_id"`
	QuantityUnitName         string `audit:"quantity_unit_name"`
	QuantityUnitAbbreviation string `audit:"quantity_unit_abbreviation"`
	QuantityUnitType         string `audit:"quantity_unit_type"`

	// Quantity received
	QuantityReceivedValue *string `audit:"quantity_received_value"`

	// Unit price
	UnitPriceID                  string
	UnitPriceValue               string `audit:"unit_price_value"`
	UnitPriceNumeratorUnitID     string `audit:"unit_price_numerator_unit_id"`
	UnitPriceNumeratorUnitAbbr   string `audit:"unit_price_numerator_unit_abbr"`
	UnitPriceDenominatorUnitID   string `audit:"unit_price_denominator_unit_id"`
	UnitPriceDenominatorUnitAbbr string `audit:"unit_price_denominator_unit_abbr"`

	// Unit cost (nullable)
	UnitCostID                  *string
	UnitCostValue               *string `audit:"unit_cost_value"`
	UnitCostNumeratorUnitID     *string `audit:"unit_cost_numerator_unit_id"`
	UnitCostNumeratorUnitAbbr   *string `audit:"unit_cost_numerator_unit_abbr"`
	UnitCostDenominatorUnitID   *string `audit:"unit_cost_denominator_unit_id"`
	UnitCostDenominatorUnitAbbr *string `audit:"unit_cost_denominator_unit_abbr"`

	CreatedAt time.Time
	UpdatedAt time.Time
}

PurchaseOrderLine represents a purchase order line domain model.

type PurchaseOrderLineRepo

type PurchaseOrderLineRepo interface {
	Get(ctx context.Context, salesOrderLineID, salesOrderID string) (*PurchaseOrderLine, *apierror.APIError)
	Create(ctx context.Context, id string, params CreatePurchaseOrderLineParams) (*PurchaseOrderLine, *apierror.APIError)
	Update(ctx context.Context, params UpdatePurchaseOrderLineParams) (*PurchaseOrderLine, *apierror.APIError)
	Delete(ctx context.Context, salesOrderLineID, salesOrderID string) *apierror.APIError
	IsInOrder(ctx context.Context, salesOrderLineID, salesOrderID string) (bool, *apierror.APIError)
	GetNextLineItemNumber(ctx context.Context, salesOrderID string) (int32, *apierror.APIError)
	DeleteCascade(ctx context.Context, salesOrderLineID string) *apierror.APIError
	CreateQuantity(ctx context.Context, quantityID, value, unitID string) *apierror.APIError
	CreateRate(ctx context.Context, rateID, value, numeratorUnitID, denominatorUnitID string) *apierror.APIError
	UpdateQuantityValue(ctx context.Context, quantityID, value string) *apierror.APIError
	UpdateRateValue(ctx context.Context, rateID, value string, numeratorUnitID, denominatorUnitID *string) *apierror.APIError
}

type PurchaseOrderLineSvc

type PurchaseOrderLineSvc interface {
	CreatePurchaseOrderLine(ctx context.Context, params CreatePurchaseOrderLineParams) (*PurchaseOrderLine, *apierror.APIError)
	UpdatePurchaseOrderLine(ctx context.Context, params UpdatePurchaseOrderLineParams) (*PurchaseOrderLine, *apierror.APIError)
	DeletePurchaseOrderLine(ctx context.Context, params DeletePurchaseOrderLineParams) *apierror.APIError
}

type PurchaseOrderRepo

type PurchaseOrderRepo interface {
	List(ctx context.Context, params ListPurchaseOrdersParams) (*ListPurchaseOrdersResult, *apierror.APIError)
	Get(ctx context.Context, accountID, purchaseOrderID string) (*PurchaseOrder, *apierror.APIError)
	GetLines(ctx context.Context, salesOrderID string) ([]*PurchaseOrderLine, *apierror.APIError)
	Create(ctx context.Context, id string, params CreatePurchaseOrderParams) (*PurchaseOrder, *apierror.APIError)
	Update(ctx context.Context, params UpdatePurchaseOrderParams) (*PurchaseOrder, *apierror.APIError)
	Delete(ctx context.Context, accountID, purchaseOrderID string) *apierror.APIError
	UpdateStatus(ctx context.Context, accountID, purchaseOrderID, statusCode string, issuedAt, completedAt *time.Time) *apierror.APIError
	IsDuplicateOrderNumber(ctx context.Context, accountID, number string, excludeID *string) (bool, *apierror.APIError)
	GetNextOrderNumber(ctx context.Context, accountID string) (string, *apierror.APIError)
	DeleteCascade(ctx context.Context, accountID, purchaseOrderID string) *apierror.APIError
	GetSupplierID(ctx context.Context, accountID, purchaseOrderID string) (string, *apierror.APIError)
	UpdateAcknowledgmentSent(ctx context.Context, accountID, purchaseOrderID string) *apierror.APIError
	CreateEmailContact(ctx context.Context, id, salesOrderID, accountUserID, notificationTypeCode string) *apierror.APIError
	DeleteEmailContactsByOrder(ctx context.Context, salesOrderID string) *apierror.APIError
	GetEmailContacts(ctx context.Context, salesOrderID string) ([]*PurchaseOrderEmailContact, *apierror.APIError)
	GetSubmissionRecipients(ctx context.Context, purchaseOrderID string) ([]string, *apierror.APIError)
	MarkSubmissionSent(ctx context.Context, accountID, purchaseOrderID string) *apierror.APIError
}

type PurchaseOrderSummary

type PurchaseOrderSummary struct {
	ID                   string
	Number               string
	StatusCode           string
	StatusName           string
	TypeCode             string
	TypeName             string
	SupplierID           string
	SupplierName         string
	SupplierNumber       string
	LineCount            int32
	IsAcknowledgmentSent bool
	PriorityCode         constants.PriorityCode
	PriorityName         string
	PriorityID           *string
	IssuedAt             *time.Time
	CompletedAt          *time.Time
	CreatedAt            time.Time
	UpdatedAt            time.Time
	// Lines (populated only when the list request includes "lines").
	Lines []*PurchaseOrderLine
}

PurchaseOrderSummary represents a purchase order for list views.

type PurchaseOrderSvc

type PurchaseOrderSvc interface {
	ListPurchaseOrders(ctx context.Context, params ListPurchaseOrdersParams) (*ListPurchaseOrdersResult, *apierror.APIError)
	GetPurchaseOrder(ctx context.Context, params GetPurchaseOrderParams) (*PurchaseOrder, *apierror.APIError)
	CreatePurchaseOrder(ctx context.Context, params CreatePurchaseOrderParams) (*PurchaseOrder, *apierror.APIError)
	UpdatePurchaseOrder(ctx context.Context, params UpdatePurchaseOrderParams) (*PurchaseOrder, *apierror.APIError)
	DeletePurchaseOrder(ctx context.Context, params DeletePurchaseOrderParams) *apierror.APIError
	BulkDeletePurchaseOrders(ctx context.Context, params BulkDeletePurchaseOrdersParams) *apierror.APIError
	ChangePurchaseOrderStatus(ctx context.Context, params ChangePurchaseOrderStatusParams) (*PurchaseOrder, *apierror.APIError)
}

type Quantity

type Quantity struct {
	ID               string
	Value            string `audit:"value"`
	UnitID           string `audit:"unit_id"`
	UnitName         string `audit:"unit_name"`
	UnitAbbreviation string `audit:"unit_abbreviation"`
	UnitType         string `audit:"unit_type"`
	CreatedAt        time.Time
	UpdatedAt        time.Time
	EmbeddedUnit     *Unit `audit:"-"`
}

type QuantityInput

type QuantityInput struct {
	Value  string
	UnitID string
}

type QuantityRepo

type QuantityRepo interface {
	Get(ctx context.Context, id string) (*Quantity, *apierror.APIError)
	Update(ctx context.Context, params UpdateQuantityParams) (*Quantity, *apierror.APIError)
}

type QuarterlyData

type QuarterlyData struct {
	Q1    float64
	Q2    float64
	Q3    float64
	Q4    float64
	Total float64
}

type QuoteCommitmentParams

type QuoteCommitmentParams struct {
	AccountID    string
	SalesOrderID *string

	BuyerAccountID  *string
	ShipToAddressID *string
	CarrierID       *string
	ServiceLevelID  *string
	IssuedAt        *time.Time

	PromisedAt           *time.Time
	LeadTimeOverrideDays *int32
	ShipByOverrideDate   *time.Time
}

QuoteCommitmentParams previews what a set of inputs would commit to, without writing anything.

SalesOrderID and the loose fields are alternatives: an existing order supplies its own customer, address and carrier, while the order-entry form has none of that saved yet and passes them directly. The bases apply either way, so a form can preview a change to an order it has not saved.

type QuoteSalesOrderFreightParams

type QuoteSalesOrderFreightParams struct {
	AccountID    string
	SalesOrderID string
}

QuoteSalesOrderFreightParams identifies the existing order whose freight is re-estimated.

type QuoteSalesOrderLinePricesParams

type QuoteSalesOrderLinePricesParams struct {
	AccountID      string
	BuyerAccountID string
	Lines          []SalesOrderPriceLineInput
}

QuoteSalesOrderLinePricesParams holds the parameters for a price quote.

type Rate

type Rate struct {
	ID                               string
	Value                            string `audit:"value"`
	NumeratorUnitID                  string `audit:"numerator_unit_id"`
	NumeratorUnitName                string `audit:"numerator_unit_name"`
	NumeratorUnitAbbreviation        string `audit:"numerator_unit_abbreviation"`
	NumeratorUnitType                string `audit:"numerator_unit_type"`
	NumeratorUnitRatioNumerator      string
	NumeratorUnitRatioDenominator    string
	NumeratorUnitOffsetNumerator     string
	NumeratorUnitOffsetDenominator   string
	NumeratorUnitCreatedAt           time.Time
	NumeratorUnitUpdatedAt           time.Time
	DenominatorUnitID                string `audit:"denominator_unit_id"`
	DenominatorUnitName              string `audit:"denominator_unit_name"`
	DenominatorUnitAbbreviation      string `audit:"denominator_unit_abbreviation"`
	DenominatorUnitType              string `audit:"denominator_unit_type"`
	DenominatorUnitRatioNumerator    string
	DenominatorUnitRatioDenominator  string
	DenominatorUnitOffsetNumerator   string
	DenominatorUnitOffsetDenominator string
	DenominatorUnitCreatedAt         time.Time
	DenominatorUnitUpdatedAt         time.Time
	CreatedAt                        time.Time
	UpdatedAt                        time.Time
}

Rate represents a rate value (unit_value, unit_cost, or burn_rate).

type RateRepo

type RateRepo interface {
	Get(ctx context.Context, id string) (*Rate, *apierror.APIError)
	Update(ctx context.Context, params UpdateRateParams) (*Rate, *apierror.APIError)
}

type RateShopOption

type RateShopOption struct {
	CarrierID        string
	CarrierName      string
	ServiceLevelID   string
	ServiceLevelName string
	Rate             float64
	EstimatedDays    *int32
}

RateShopOption represents a single carrier option with its rate.

type RateShopParams

type RateShopParams struct {
	AccountID      string
	ProductLineIDs []string
	CustomerID     *string
	FromAddress    ShippingAddress
	ToAddress      ShippingAddress
	Parcels        []Parcel
	OrderTotal     *float64
}

RateShopParams holds the parameters for rate shopping.

type RateShopResult

type RateShopResult struct {
	Options       []*RateShopOption
	ExemptionType *string
	FlatRate      *float64
}

RateShopResult holds the result of rate shopping.

type RateValue

type RateValue struct {
	Value             string
	NumeratorUnitID   string
	DenominatorUnitID string
}

RateValue is a minimal currency-per-unit rate: a value with numerator and denominator unit ids. Used as the override input and as the engine output.

type ReadAccessMed

type ReadAccessMed interface {
	// CheckReadAccess verifies that the actor account has owner-side read access to the target account. Same-account access is always allowed. Cross-account access requires an account_relation row in the actor→target direction (the actor is the owner of the relation). Use this for endpoints that expose the owner's view of a counterparty account (e.g. a merchant reading data scoped to one of their customers).
	//
	//  1. Allow access when the actor and target accounts are the same.
	//  2. Require an actor→target account relation; otherwise return an authorization error.
	CheckReadAccess(ctx context.Context, actorAccountID, targetAccountID string) *apierror.APIError

	// CheckCounterpartyReadAccess verifies access in either direction. It is intended for customer/supplier portal endpoints where the counterparty (e.g. a customer) reads data on the owner's account (e.g. a vendor), and the account_relation row is stored owner→counterparty. Only use this on endpoints that explicitly scope returned data to the counterparty — otherwise it leaks cross-tenant data.
	//
	//  1. Allow access when the actor and target accounts are the same.
	//  2. Check for an account relation in the actor→target direction.
	//  3. Fall back to checking the target→actor direction.
	//  4. Return an authorization error when no relation exists in either direction.
	CheckCounterpartyReadAccess(ctx context.Context, actorAccountID, targetAccountID string) *apierror.APIError
}

type RealizedMarginAnalysis

type RealizedMarginAnalysis struct {
	Findings               []RealizedMarginFinding
	LinesAnalyzed          int
	RelationshipsAnalyzed  int
	BelowPeerMedianCount   int
	BelowTargetMarginCount int
	MarginNotAssessedCount int
}

RealizedMarginAnalysis is the rolled-up result: one row per flagged customer and SKU, plus what the sweep covered.

type RealizedMarginFinding

type RealizedMarginFinding struct {
	CustomerID              string
	CustomerGroupID         string
	ItemID                  string
	ProductLineID           string
	UnitAbbreviation        string
	QuantityInvoiced        string
	Revenue                 string
	Cost                    string
	AverageUnitPrice        string
	PeerMedianPrice         *string
	BelowPeerMedianFraction *string
	GrossMargin             *string
	LineCount               int
	Reason                  string
}

RealizedMarginFinding is one customer/SKU trading relationship flagged by the audit.

type RecalcItemBurnRateEvent added in v1.1.8

type RecalcItemBurnRateEvent struct {
	AccountID string `json:"account_id"`
	ItemID    string `json:"item_id"`
}

RecalcItemBurnRateEvent is the outbox command payload asking a consumer to recompute an item's burn rate from history. It carries only the item's identity; the rate is recomputed from current state, so repeated commands coalesce and a redelivery recomputes the same absolute value.

type ReceivableEntry

type ReceivableEntry struct {
	InvoiceID        string
	InvoiceNumber    string
	PONumber         *string
	InvoicedAt       time.Time
	CustomerID       string
	CustomerNumber   string
	CustomerName     string
	RemainingBalance string
	IsPaidInFull     bool
}

ReceivableEntry represents a single receivable invoice entry with its remaining balance.

type ReceivableRepo

type ReceivableRepo interface {
	List(ctx context.Context, params ListReceivablesParams) (*ListReceivablesResult, *apierror.APIError)
	ListByCustomer(ctx context.Context, params ListReceivablesByCustomerParams) (*ListReceivablesByCustomerResult, *apierror.APIError)
	ListAllByCustomer(ctx context.Context, accountID, customerAccountID string, cutoffDate *time.Time) ([]ReceivableEntry, *apierror.APIError)
	ListOpenCreditsByCustomer(ctx context.Context, accountID, customerAccountID string) ([]OpenCredit, *apierror.APIError)
}

type ReceivableSvc

type ReceivableSvc interface {
	// ListReceivables returns a paginated list of receivable entries for the caller's account.
	ListReceivables(ctx context.Context, params ListReceivablesParams) (*ListReceivablesResult, *apierror.APIError)

	// ListReceivablesByCustomer returns a paginated list of receivable entries for a specific customer.
	ListReceivablesByCustomer(ctx context.Context, params ListReceivablesByCustomerParams) (*ListReceivablesByCustomerResult, *apierror.APIError)

	// ExportReceivablesByCustomer returns all receivable entries for a specific customer (no pagination).
	ExportReceivablesByCustomer(ctx context.Context, params ListReceivablesByCustomerParams) ([]ReceivableEntry, *apierror.APIError)

	// EmailReceivablesForCustomer sends a receivables statement to the specified email addresses.
	EmailReceivablesForCustomer(ctx context.Context, params EmailReceivablesParams) *apierror.APIError
}

type ReceiveCalendarQuery

type ReceiveCalendarQuery struct {
	AccountID      string
	BuyerAccountID *string
	AddressID      *string
}

ReceiveCalendarQuery is the destination whose receiving days are wanted. Every field but the account is optional: an order with no customer relation and no address still resolves to the account default.

type ReceivingOrder

type ReceivingOrder struct {
	ID                  string
	Number              string `audit:"number"`
	PurchaseOrderID     string
	PurchaseOrderNumber string  `audit:"purchase_order_number"`
	SupplierID          *string `audit:"supplier_id"`
	SupplierName        *string `audit:"supplier_name"`
	SupplierNumber      *string `audit:"supplier_number"`
	Note                *string `audit:"note"`
	Lines               []*ReceivingOrderLine
	CompletedAt         *time.Time `audit:"completed_at"`
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

ReceivingOrder represents a full receiving order with its lines.

type ReceivingOrderLine

type ReceivingOrderLine struct {
	ID                        string
	QuantityID                string
	QuantityValue             string `audit:"quantity_value"`
	QuantityUnitID            string
	QuantityUnitAbbreviation  string  `audit:"quantity_unit_abbreviation"`
	RejectedQuantityValue     *string `audit:"rejected_quantity_value"`
	OrderLineID               string
	OrderLineProductID        *string
	OrderLineItemID           *string `audit:"order_line_item_id"`
	OrderLineItemSKU          *string `audit:"order_line_item_sku"`
	OrderLineItemDescription  *string `audit:"order_line_item_description"`
	OrderLineQuantityOrdered  string  `audit:"order_line_quantity_ordered"`
	OrderLineUnitID           string
	OrderLineUnitAbbreviation string     `audit:"order_line_unit_abbreviation"`
	StockedAt                 *time.Time `audit:"stocked_at"`
	CreatedAt                 time.Time
	UpdatedAt                 time.Time
}

ReceivingOrderLine represents a line item in a receiving order.

type ReceivingOrderLineSvc

type ReceivingOrderLineSvc interface {
	// UpdateReceivingOrderLine updates a receiving order line's quantity.
	UpdateReceivingOrderLine(ctx context.Context, params UpdateReceivingOrderLineParams) (*ReceivingOrderLine, *apierror.APIError)

	// VoidReceivingOrderLine voids a single receiving order line.
	VoidReceivingOrderLine(ctx context.Context, receivingOrderID, lineID string) (*ReceivingOrderLine, *apierror.APIError)

	// ReceiveReceivingOrderLine receives a single line, setting its quantity to remaining.
	ReceiveReceivingOrderLine(ctx context.Context, receivingOrderID, lineID string) (*ReceivingOrderLine, *apierror.APIError)
}

type ReceivingOrderLineUnitPrice

type ReceivingOrderLineUnitPrice struct {
	ReceivingOrderLineID       string
	ItemID                     string
	UnitPriceValue             string
	UnitPriceNumeratorUnitID   string
	UnitPriceDenominatorUnitID string
	QuantityUnitID             string
}

ReceivingOrderLineUnitPrice holds unit price information for a receiving order line.

type ReceivingOrderRepo

type ReceivingOrderRepo interface {
	// Existing methods
	Create(ctx context.Context, id, number, orderID, accountID string) *apierror.APIError
	CreateLine(ctx context.Context, id, receivingOrderID, quantityID, salesOrderLineID string) *apierror.APIError
	GetByOrderID(ctx context.Context, orderID string) (*string, *apierror.APIError)
	DeleteLinesByOrderID(ctx context.Context, orderID string) *apierror.APIError
	DeleteByOrderID(ctx context.Context, orderID string) *apierror.APIError
	MarkComplete(ctx context.Context, orderID string) *apierror.APIError
	MarkIncomplete(ctx context.Context, orderID string) *apierror.APIError
	DeleteLinesByOrderLineID(ctx context.Context, salesOrderLineID string) *apierror.APIError

	// New methods for the receiving order endpoints
	List(ctx context.Context, params ListReceivingOrdersParams) (*ListReceivingOrdersResult, *apierror.APIError)
	Get(ctx context.Context, accountID, receivingOrderID string) (*ReceivingOrder, *apierror.APIError)
	ListLines(ctx context.Context, receivingOrderID string) ([]*ReceivingOrderLine, *apierror.APIError)
	FindUnstockedLineIDs(ctx context.Context, receivingOrderID, accountID string, enforceNonZero bool) ([]UnstockedLine, *apierror.APIError)
	StockLines(ctx context.Context, lineIDs []string, accountID string) *apierror.APIError
	MarkCompleteIfAllStocked(ctx context.Context, id, accountID string) (bool, *apierror.APIError)
	MarkIncompleteByID(ctx context.Context, id, accountID string) *apierror.APIError
	BulkCreateForRemainingQuantities(ctx context.Context, receivingOrderID string, orderLineIDs []string, accountID string) *apierror.APIError
	BulkReceiveRemainingQuantities(ctx context.Context, receivingOrderID string, orderLineIDs []string, accountID string) *apierror.APIError
	VoidAllLines(ctx context.Context, receivingOrderID, accountID string) *apierror.APIError
	DeleteDuplicateLines(ctx context.Context, receivingOrderID, accountID string) *apierror.APIError
	UpdateLineQuantity(ctx context.Context, lineID string, quantityValue string) *apierror.APIError
	VoidLine(ctx context.Context, lineID, accountID string) *apierror.APIError
	GetLine(ctx context.Context, lineID string) (*ReceivingOrderLine, *apierror.APIError)
	IsLineInReceivingOrder(ctx context.Context, lineID, receivingOrderID string) (bool, *apierror.APIError)
	CalculateQuantityYetToBeReceived(ctx context.Context, lineID, accountID string) (string, string, *apierror.APIError)
	IsInAccount(ctx context.Context, accountID, receivingOrderID string) (bool, *apierror.APIError)
	GetLineUnitPrices(ctx context.Context, receivingOrderID string) ([]ReceivingOrderLineUnitPrice, *apierror.APIError)
	GetPurchaseOrderID(ctx context.Context, receivingOrderID, accountID string) (string, *apierror.APIError)
	UpsertLot(ctx context.Context, lotID, accountID, itemID, lotNumber string) (string, *apierror.APIError)
	InsertInventoryReceiptForDelivery(ctx context.Context, receiptID, accountID, itemID, quantityID, unitCostID string, storageLocationID, lotID, orderID *string) *apierror.APIError
	MarkPurchaseOrderFulfilled(ctx context.Context, purchaseOrderID, accountID string) *apierror.APIError
	FindOpenIssuesForItem(ctx context.Context, accountID, itemID string) ([]OpenInventoryIssue, *apierror.APIError)
	GetAllocationSumForIssue(ctx context.Context, issueID string) (string, *apierror.APIError)
	HasUnstockedLineForOrderLine(ctx context.Context, salesOrderLineID string) (bool, *apierror.APIError)
	CreateLineForRemainingQuantity(ctx context.Context, receivingOrderID, salesOrderLineID, accountID string) *apierror.APIError
}

type ReceivingOrderSummary

type ReceivingOrderSummary struct {
	ID                   string
	Number               string
	PurchaseOrderID      string
	PurchaseOrderNumber  string
	SupplierID           *string
	SupplierName         *string
	SupplierNumber       *string
	LineCount            int32
	CompletionPercentage float64
	CompletedAt          *time.Time
	CreatedAt            time.Time
	UpdatedAt            time.Time
	// Lines (populated only when the list request includes "lines").
	Lines []*ReceivingOrderLine
}

ReceivingOrderSummary represents a receiving order in list views.

type ReceivingOrderSvc

type ReceivingOrderSvc interface {
	// ListReceivingOrders returns a paginated list of receiving orders.
	ListReceivingOrders(ctx context.Context, params ListReceivingOrdersParams) (*ListReceivingOrdersResult, *apierror.APIError)

	// GetReceivingOrder returns a single receiving order by ID with lines.
	GetReceivingOrder(ctx context.Context, params GetReceivingOrderParams) (*ReceivingOrder, *apierror.APIError)

	// StockReceivingOrder stocks a receiving order, creating deliveries and inventory records.
	StockReceivingOrder(ctx context.Context, params StockReceivingOrderParams) (*ReceivingOrder, *apierror.APIError)

	// ReceiveReceivingOrder receives all unstocked lines, setting their quantities to remaining.
	ReceiveReceivingOrder(ctx context.Context, receivingOrderID string) (*ReceivingOrder, *apierror.APIError)

	// VoidReceivingOrder voids all lines in a receiving order.
	VoidReceivingOrder(ctx context.Context, receivingOrderID string) (*ReceivingOrder, *apierror.APIError)
}

type ReconcileError

type ReconcileError struct {
	SKU   string
	Error string
}

ReconcileError represents an error that occurred during reconciliation.

type ReconciledItem

type ReconciledItem struct {
	ItemID          string
	SKU             string
	PreviousMeasure decimal.Decimal
	NewMeasure      decimal.Decimal
}

ReconciledItem represents a successfully reconciled item.

type RecoveryPoint

type RecoveryPoint string
const (
	InvoiceRecoveryPointStarted  RecoveryPoint = "started"
	InvoiceRecoveryPointFinished RecoveryPoint = "finished"
)

RecoveryPoint constants for invoice operations.

const (
	RecoveryPointStarted  RecoveryPoint = "core:started"
	RecoveryPointFinished RecoveryPoint = "core:finished"
)

Flows that only perform local atomic mutations within a single transaction (for example CreateSupplier and UpdateSupplier) reuse these generic points; multi-phase flows declare their own in domain-specific *_recovery_points.go files.

const (
	SettlementRecoveryPointStarted  RecoveryPoint = "started"
	SettlementRecoveryPointFinished RecoveryPoint = "finished"
)

RecoveryPoint constants for settlement operations.

const (
	RecoveryPointShipLabelsCreated  RecoveryPoint = "core:ship_labels_created"
	RecoveryPointVoidLabelsRefunded RecoveryPoint = "core:void_labels_refunded"
)

Recovery points for multi-phase shipping operations.

const (
	PortalDomainRecoveryPointProviderRegistered RecoveryPoint = "core:portal_domain_provider_registered"
)

RecoveryPoint constants for portal domain operations. The provider registration is a foreign mutation (Vercel API), so it gets its own atomic phase: a request that crashes after registering with the provider but before persisting the DNS records resumes here and safely repeats the idempotent provider calls.

func (RecoveryPoint) IsValid

func (r RecoveryPoint) IsValid() bool

func (RecoveryPoint) String

func (r RecoveryPoint) String() string

type RegenerateProductionScheduleParams

type RegenerateProductionScheduleParams struct {
	ScheduleID string
	// MergeMode decides what happens to hand-edited campaigns. Empty defaults to preserving them: silently discarding a planner's work is never the safe default.
	MergeMode string
	// PlanningAsOf, HorizonWeeks and DemandBasis override the stored version's own values. Empty or zero reuses what the version was generated with, so a plain regenerate answers "what would the solver say now" rather than "what would it say about a different question".
	PlanningAsOf *time.Time
	HorizonWeeks int
	DemandBasis  string
}

RegenerateProductionScheduleParams drives a re-solve of an existing draft.

type RegisterCustomerParams

type RegisterCustomerParams struct {
	AccountSlug        string
	IsExistingCustomer bool
	CustomerData       CustomerRegistrationData
}

type RegistrationAccountData

type RegistrationAccountData struct {
	AccountName string
}

RegistrationAccountData holds the business profile information collected during onboarding.

type RegistrationAddress

type RegistrationAddress struct {
	Line1      string
	Line2      string
	City       string
	State      string
	PostalCode string
	Country    string
}

RegistrationAddress is a structured postal address collected during registration.

type RegistrationFlow

type RegistrationFlow struct {
	ID                   string
	Name                 string `audit:"name"`
	AccountID            string
	CustomerGroupOptions []*RegistrationFlowOption `audit:"customer_group_options"`
	PaymentTermOptions   []*RegistrationFlowOption `audit:"payment_term_options"`
	ShippingTermOptions  []*RegistrationFlowOption `audit:"shipping_term_options"`
	CreatedAt            time.Time
	UpdatedAt            time.Time
}

type RegistrationFlowOption

type RegistrationFlowOption struct {
	ID   string
	Name string
}

type RegistrationFlowSvc

type RegistrationFlowSvc interface {
	ListRegistrationFlows(ctx context.Context, params ListRegistrationFlowsParams) (*ListRegistrationFlowsResult, *apierror.APIError)
	GetRegistrationFlow(ctx context.Context, flowID string) (*RegistrationFlow, *apierror.APIError)
	GetRegistrationFlowBySlug(ctx context.Context, slug string) (*RegistrationFlow, *apierror.APIError)
	CreateRegistrationFlow(ctx context.Context, params CreateRegistrationFlowParams) (*RegistrationFlow, *apierror.APIError)
	UpdateRegistrationFlow(ctx context.Context, params UpdateRegistrationFlowParams) (*RegistrationFlow, *apierror.APIError)
	DeleteRegistrationFlow(ctx context.Context, flowID string) *apierror.APIError
	RegisterCustomer(ctx context.Context, params RegisterCustomerParams) *apierror.APIError
}

type RegistrationRepo

type RegistrationRepo interface {
	// CreateAccountForRegistration creates a production account with Stripe billing fields populated.
	CreateAccountForRegistration(ctx context.Context, params CreateAccountParams) *apierror.APIError

	// CreateAccountUser creates an account-user join record linking the user to the account with the given role.
	CreateAccountUser(ctx context.Context, accountID, userID, roleID string) *apierror.APIError

	// CreateBusinessAddress creates a geolocation, address, and account-address chain and sets the address as the account's default billing and shipping address.
	CreateBusinessAddress(ctx context.Context, accountID, accountName string, address RegistrationAddress) *apierror.APIError

	// CreateAccountPortal creates a portal record with a slug derived from the account ID.
	CreateAccountPortal(ctx context.Context, accountID string) *apierror.APIError

	// CreateSystemProducts creates the shipping and credit system products required by every account. This includes units, unit groups, item categories, product lines, rates, items, and product records.
	CreateSystemProducts(ctx context.Context, accountID string) *apierror.APIError

	// CreateAccountBranding creates a default (empty) branding record for the account so portal and notification templates can reference it.
	CreateAccountBranding(ctx context.Context, accountID string) *apierror.APIError
}

RegistrationRepo handles the multi-step account creation during registration: account record, owner role with all permissions, account-user join, business address, and account portal.

type RelationPriceGroup

type RelationPriceGroup struct {
	ID             string
	AccountGroupID string
}

RelationPriceGroup is a lightweight reference to an account relation price group.

type RelationProductLine

type RelationProductLine struct {
	ID            string
	ProductLineID string
}

RelationProductLine is a lightweight reference to an account relation product line.

type ReleaseBatch

type ReleaseBatch struct {
	ItemID   string
	SKU      string
	Quantity float64
	// BatchID is empty on a preview of a batch that would be created; a carried-forward batch already exists and names itself even in a preview.
	BatchID string
	// CarriedForwardFrom is the number of the run this ticket came off when the batch already existed. Empty means the release creates it new.
	//
	// This is what the confirmation is really telling a planner: these doffs are already printed and on the floor, so nobody needs to print them again.
	CarriedForwardFrom string
}

ReleaseBatch is one batch a release puts into the run: a single lot off one campaign.

type ReleaseScheduleWeekParams

type ReleaseScheduleWeekParams struct {
	AccountID            string
	ProductionScheduleID string
	WeekIndex            int32
	ResponsibleUserID    string
	ScanningStationID    *string
	// SkipCarryForward issues the whole week as new tickets, leaving an earlier week's unworked doffs where they are. Off by default: reprinting a ticket the floor is already holding is the failure this exists to prevent, and a planner has to ask for it deliberately.
	SkipCarryForward bool
}

ReleaseScheduleWeekParams asks for one planned week to become a production run.

type ReleaseScheduleWeekPreview

type ReleaseScheduleWeekPreview struct {
	WeekIndex     int32
	WeekStartDate time.Time
	LineCount     int32
	BatchCount    int32
	// CarriedForwardBatchCount is how many of BatchCount would be moved off an earlier run rather than created new.
	CarriedForwardBatchCount int32
	TotalQuantity            float64
	Lines                    []ReleasedScheduleLine
	IsReleasable             bool
	BlockedReason            *string
	ExistingProductionRunID  *string
}

ReleaseScheduleWeekPreview is what a release would do, with nothing written.

A preview is not just a courtesy here: a release creates a numbered run and dozens of batch rows, and undoing that by hand is real work. IsReleasable is false when the week is empty or already released, and BlockedReason says which.

type ReleaseScheduleWeekResult

type ReleaseScheduleWeekResult struct {
	ProductionRun     *ProductionRun
	WeekIndex         int32
	WeekStartDate     time.Time
	ReleasedLineCount int32
	BatchCount        int32
	// CarriedForwardBatchCount is how many of BatchCount were moved off an earlier run rather than created. Tickets for these are already printed.
	CarriedForwardBatchCount int32
	TotalQuantity            float64
	Lines                    []ReleasedScheduleLine
}

ReleaseScheduleWeekResult is the run a release produced, and what went into it.

type ReleasedScheduleLine

type ReleasedScheduleLine struct {
	ProductionScheduleLineID string
	ItemID                   string
	SKU                      string
	MachineID                string
	MachineName              *string
	PlannedQuantity          float64
	LotUnits                 float64
	// Unit is what the quantity and the lot are counted in. "6 × 60" on a release confirmation is not an instruction until it says 6 × 60 of what.
	Unit string
	// CarriedForwardQuantity is how much of PlannedQuantity is covered by tickets an earlier week already issued.
	CarriedForwardQuantity float64
	Batches                []ReleaseBatch
}

ReleasedScheduleLine is one campaign and the lots it broke into.

type RemoveItemAttributeParams

type RemoveItemAttributeParams struct {
	AccountID   string
	ItemID      string
	AttributeID string
}

RemoveItemAttributeParams holds parameters for removing an attribute from an item.

type RemoveItemCategoryPropertyParams

type RemoveItemCategoryPropertyParams struct {
	AccountID      string
	ItemCategoryID string
	PropertyID     string
}

type ReorderSalesOrderLinesParams

type ReorderSalesOrderLinesParams struct {
	SalesOrderID string
	AccountID    string
	// LineIDs are the order's product-line IDs in the desired display order. Credit/freight lines are kept at the bottom and must not appear here.
	LineIDs []string
}

ReorderSalesOrderLinesParams holds the parameters for re-sequencing a sales order's lines.

type RepoFactory

type RepoFactory interface {
	NewAccountRepo() AccountRepo
	NewAccountUserRepo() AccountUserRepo
	NewAccountRelationRepo() AccountRelationRepo
	NewRolePermissionRepo() RolePermissionRepo
	NewRoleRepo() RoleRepo
	NewSandboxAccountRepo() SandboxAccountRepo
	NewRegistrationRepo() RegistrationRepo
	NewIdempotencyKeyRepo() IdempotencyKeyRepo
	NewUnitRepo() UnitRepo
	NewPaymentTermRepo() PaymentTermRepo
	NewShippingTermRepo() ShippingTermRepo
	NewProductRepo() ProductRepo
	NewAccountGroupRepo() AccountGroupRepo
	NewDeletedRecordRepo() DeletedRecordRepo
	NewAccountGroupProductLineAccessRepo() AccountGroupProductLineAccessRepo
	NewCustomerProductLineAccessRepo() CustomerProductLineAccessRepo
	NewAddressRepo() AddressRepo
	NewAccountStatusRepo() AccountStatusRepo
	NewUserRepo() UserRepo
	NewAccountPriceRepo() AccountPriceRepo
	NewAccountIntegrationRepo() AccountIntegrationRepo
	NewHubspotSyncRepo() HubspotSyncRepo
	NewSalesTargetRepo() SalesTargetRepo
	NewAdjustmentTypeRepo() AdjustmentTypeRepo
	NewPropertyRepo() PropertyRepo
	NewAttributeRepo() AttributeRepo
	NewCarrierRepo() CarrierRepo
	NewCarrierTransitEstimateRepo() CarrierTransitEstimateRepo
	NewOperatingCalendarRepo() OperatingCalendarRepo
	NewServiceLevelRepo() ServiceLevelRepo
	NewItemRepo() ItemRepo
	NewItemCategoryRepo() ItemCategoryRepo
	NewProductLineRepo() ProductLineRepo
	NewOutboxRepo() messaging.OutboxRepo
	NewBatchRepo() BatchRepo
	NewProductionStepQueryRepo() ProductionStepQueryRepo
	NewScanningStationQueryRepo() ScanningStationQueryRepo
	NewProductionRunQueryRepo() ProductionRunQueryRepo
	NewProductionRunRepo() ProductionRunRepo
	NewUnitGroupQueryRepo() UnitGroupQueryRepo
	NewUnitGroupRepo() UnitGroupRepo
	NewUnitQueryRepo() UnitQueryRepo
	NewInventoryQueryRepo() InventoryQueryRepo
	NewConsumptionRepo() ConsumptionRepo
	NewProductionFlowRepo() ProductionFlowRepo
	NewInventoryMutationRepo() InventoryMutationRepo
	NewOrderQueryRepo() OrderQueryRepo
	NewInventoryReservationRepo() InventoryReservationRepo
	NewMaterialDemandRepo() MaterialDemandRepo
	NewUnitConversionRepo() UnitConversionRepo
	NewCustomerRepo() CustomerRepo
	NewMachineRepo() MachineRepo
	NewMachineStatusRepo() MachineStatusRepo
	NewMachineDowntimeRepo() MachineDowntimeRepo
	NewDemandOverrideRepo() DemandOverrideRepo
	NewScheduleAttainmentRepo() ScheduleAttainmentRepo
	NewProductionScheduleInputRepo() ProductionScheduleInputRepo
	NewProductionScheduleRepo() ProductionScheduleRepo
	NewDepartmentRepo() DepartmentRepo
	NewDeliveryRepo() DeliveryRepo
	NewEmailLogRepo() EmailLogRepo
	NewInventoryChangeLogRepo() InventoryChangeLogRepo
	NewInvoiceRepo() InvoiceRepo
	NewReceivableRepo() ReceivableRepo
	NewSalesOrderRepo() SalesOrderRepo
	NewSalesOrderLineRepo() SalesOrderLineRepo
	NewSalesOrderStatusRepo() SalesOrderStatusRepo
	NewPurchaseOrderRepo() PurchaseOrderRepo
	NewPurchaseOrderLineRepo() PurchaseOrderLineRepo
	NewReceivingOrderRepo() ReceivingOrderRepo
	NewOrderDiscountRepo() OrderDiscountRepo
	NewVolumeDiscountRepo() VolumeDiscountRepo
	NewMaterialRepo() MaterialRepo
	NewSupplierMaterialRepo() SupplierMaterialRepo
	NewPartRepo() PartRepo
	NewPermissionGroupRepo() PermissionGroupRepo
	NewPickRepo() PickRepo
	NewPickLineRepo() PickLineRepo
	NewPriorityRepo() PriorityRepo
	NewProductTypeRepo() ProductTypeRepo
	NewProductionStepRepo() ProductionStepRepo
	NewProductionRepo() ProductionRepo
	NewQuantityRepo() QuantityRepo
	NewRateRepo() RateRepo
	NewSettlementRepo() SettlementRepo
	NewTransactionRepo() TransactionRepo
	NewTransactionAllocationRepo() TransactionAllocationRepo
	NewAnalyticsRepo() AnalyticsRepo
	NewCatalogRepo() CatalogRepo
	NewEDIRepo() EDIRepo
	NewRegistrationFlowRepo() RegistrationFlowRepo
	NewShippingCaseRepo() ShippingCaseRepo
	NewSysPropertyRepo() SysPropertyRepo
	NewStripeEventLogRepo() StripeEventLogRepo
	NewOrderPaymentIntentRepo() OrderPaymentIntentRepo
	NewCustomerRegistrationRepo() CustomerRegistrationRepo
	NewShipmentRepo() ShipmentRepo
	NewShipmentLineRepo() ShipmentLineRepo
	NewTerritoryRepo() TerritoryRepo
	NewSupplierRepo() SupplierRepo
	NewLocationRepo() LocationRepo
	NewScanningStationRepo() ScanningStationRepo
	NewPricingRepo() PricingRepo
	NewJobRepo() JobRepo
	NewPortalDomainRepo() PortalDomainRepo
	NewPortalRegistrationSessionRepo() PortalRegistrationSessionRepo
}

type RequestDemoParams

type RequestDemoParams struct {
	Name        string
	Email       string
	Company     string
	PhoneNumber *string
	Message     *string
}

RequestDemoParams holds parameters for submitting a demo request.

type ResolveHubspotCompanyReviewParams

type ResolveHubspotCompanyReviewParams struct {
	ID                string
	AccountID         string
	Status            string
	Resolution        *string
	ResolvedHubspotID *string
}

type ResolveHubspotReviewParams

type ResolveHubspotReviewParams struct {
	ReviewID          string
	Action            string
	ResolvedHubspotID *string
}

ResolveHubspotReviewParams resolves one ambiguous company review. Action is "link" (requires ResolvedHubspotID), "create_new", or "skip".

type ResolvedBulkHubspotReviewRow

type ResolvedBulkHubspotReviewRow struct {
	ReviewID          string
	Status            string
	Resolution        *string
	ResolvedHubspotID *string
}

ResolvedBulkHubspotReviewRow is one decision after the accept phase has confirmed the review exists on the job. Stored on the job, so it carries only settled values.

type ResolvedSalesOrderLine

type ResolvedSalesOrderLine struct {
	ProductID          string
	ItemID             string
	ProductSKU         string
	ProductDescription *string
	QuantityValue      string
	QuantityUnitID     string
	UnitPrice          RateValue
	UnitCost           RateValue
}

ResolvedSalesOrderLine is a fully resolved create-line: the caller's product + quantity, with the SKU/description defaulted from the product, the item derived from the product, the unit cost pulled from the item, and the unit price computed server-side (or taken from an internal override). Produced by resolving the create line inputs against the pricing bundle in one pass.

type ResolvedUnitGroupConversion

type ResolvedUnitGroupConversion struct {
	UnitID             string
	DimensionCode      string
	DiscountPercentage string
}

ResolvedUnitGroupConversion is one conversion after resolution.

type ResolvedUpsertConsumption

type ResolvedUpsertConsumption struct {
	ItemID              string
	QuantityValue       string
	QuantityUnitID      string
	WasteQuantityValue  *string
	WasteQuantityUnitID *string
	Instructions        *string
}

ResolvedUpsertConsumption is a consumption with its item and units resolved. A nil WasteQuantityUnitID means waste defaults to the consumption's own quantity unit.

type ResolvedUpsertDepartmentRow

type ResolvedUpsertDepartmentRow struct {
	Name       string
	Notes      *string
	LocationID *string
}

ResolvedUpsertDepartmentRow is a department upsert row with its location reference resolved to an id. No JSON tags: the engine round-trips job_items against this type, an internal column.

type ResolvedUpsertItemCategoryRow

type ResolvedUpsertItemCategoryRow struct {
	Name                 string
	Notes                *string
	ItemCategoryTypeCode string
	UnitGroupID          string
	PropertyNames        []string
}

mirrors an upsert row with its unit group reference resolved to an id. Property names stay as written: they are found-or-created when the job runs, so nothing to resolve.

type ResolvedUpsertLocationRow

type ResolvedUpsertLocationRow struct {
	Name     string
	TypeCode string
	Parent   *LocationRef
	Children []LocationRef
}

ResolvedUpsertLocationRow is a location upsert row after resolution: its parent and child references resolved to either an existing location id or a same-batch row name. No JSON tags: the engine round-trips job_items against this type and it is an internal column.

type ResolvedUpsertMachineRow

type ResolvedUpsertMachineRow struct {
	Name         string
	SerialNumber string
	Notes        *string
	DepartmentID string
}

ResolvedUpsertMachineRow is a machine upsert row with its department reference resolved to an id. No JSON tags: the engine round-trips job_items against this type, an internal column.

type ResolvedUpsertMaterialRow

type ResolvedUpsertMaterialRow struct {
	SKU         string
	Description *string
	Notes       *string
	CategoryID  string
	OrderPoint  *QuantityInput
	LeadTime    *QuantityInput
	UnitPrice   *CreateRateParams
	UnitCost    *CreateRateParams
	Properties  []UpsertItemPropertyParams
}

mirrors an upsert row with its category reference resolved to an id. Property names/values stay as written: they are found-or-created when the job runs.

type ResolvedUpsertPartRow

type ResolvedUpsertPartRow struct {
	SKU         string
	Description *string
	Notes       *string
	CategoryID  string
	UnitPrice   *CreateRateParams
	UnitCost    *CreateRateParams
	Properties  []UpsertItemPropertyParams
}

mirrors an upsert row with its category reference resolved to an id. Property names/values stay as written: they are found-or-created when the job runs.

type ResolvedUpsertProductLineRow

type ResolvedUpsertProductLineRow struct {
	Name             string
	UnitGroupID      string
	CommissionPolicy constants.CommissionPolicy
	FreightPolicy    constants.FreightPolicy
}

ResolvedUpsertProductLineRow is a product line upsert row with its unit group reference resolved to an id. No JSON tags: the engine round-trips job_items against this type, an internal column.

type ResolvedUpsertProductRow

type ResolvedUpsertProductRow struct {
	SKU             string
	ProductTypeCode string
	Description     *string
	Notes           *string
	CategoryID      string
	ProductLineID   *string
	IsPortalReady   *bool
	UnitPrice       *CreateRateParams
	UnitCost        *CreateRateParams
	Properties      []UpsertItemPropertyParams
}

mirrors an upsert row with its category and product line resolved to ids. Property names/values stay as written: they are found-or-created when the job runs.

type ResolvedUpsertProduction

type ResolvedUpsertProduction struct {
	ItemID         string
	QuantityValue  string
	QuantityUnitID string
}

ResolvedUpsertProduction is a production output with its item and unit resolved.

type ResolvedUpsertPropertyAttribute

type ResolvedUpsertPropertyAttribute struct {
	Value     string
	ColorCode string
}

carries one selectable value, swatch settled

type ResolvedUpsertPropertyRow

type ResolvedUpsertPropertyRow struct {
	Name       string
	Attributes []ResolvedUpsertPropertyAttribute
}

carries a bulk upsert row once normalized, so the job records a fully determined write

type ResolvedUpsertRate

type ResolvedUpsertRate struct {
	Value             string
	NumeratorUnitID   string
	DenominatorUnitID string
}

ResolvedUpsertRate is a rate with its units resolved.

type ResolvedUpsertScanningStationRow

type ResolvedUpsertScanningStationRow struct {
	Name                string
	Notes               *string
	Type                constants.ScanningStationType
	LabelSizeCode       field.Clearable[string] `json:",omitzero"`
	LabelTypeCode       field.Clearable[string] `json:",omitzero"`
	OperatorRequirement constants.OperatorRequirement
	DepartmentID        string
}

ResolvedUpsertScanningStationRow is a scanning station upsert row with its department reference resolved to an id. The engine round-trips job_items against this type, so it carries no JSON tags — except the Clearable label fields, whose MarshalJSON errors on an unset value and so require `omitzero` to be skipped.

type ResolvedUpsertStepRow

type ResolvedUpsertStepRow struct {
	Name              string
	Notes             *string
	LevelingFactor    *string
	Allowances        *string
	ScanningStationID *string
	DepartmentID      *string
	LaborRate         ResolvedUpsertRate
	LaborTime         ResolvedUpsertRate
	OverheadRate      ResolvedUpsertRate
	Production        ResolvedUpsertProduction
	Consumptions      []ResolvedUpsertConsumption
}

ResolvedUpsertStepRow is a production step upsert row after fuzzy resolution. A nil DepartmentID or ScanningStationID means the row did not name one.

type ResolvedUpsertUnitGroupRow

type ResolvedUpsertUnitGroupRow struct {
	Name       string
	Notes      *string
	Type       string
	BaseUnitID string
	// BaseUnitDimensionCode is the resolved base unit's dimension, carried so Write can
	// check it against the group's (stored, immutable) type without a further lookup —
	// exactly as the conversions do.
	BaseUnitDimensionCode string
	Conversions           []ResolvedUnitGroupConversion
}

ResolvedUpsertUnitGroupRow is a unit-group upsert row after resolution.

type RevenueForecastPoint

type RevenueForecastPoint struct {
	Date       time.Time
	Forecast   float64
	LowerBound float64
	UpperBound float64
}

type RevenueHistoryPoint

type RevenueHistoryPoint struct {
	Date    time.Time
	Revenue float64
}

type ReverseInventoryForBatchParams

type ReverseInventoryForBatchParams struct {
	AccountID string
	BatchID   string
	// ScanningStationID and ResponsibleUserID are recorded on the change-log entries the reversal writes, so the correction is attributable to the same station and person as the scan.
	ScanningStationID string
	ResponsibleUserID string
}

ReverseInventoryForBatchParams describes the undo of everything a scan wrote against one batch.

type Role

type Role struct {
	ID        string
	Name      string `audit:"name"`
	RoleType  string `audit:"role_type_code"`
	AccountID *string
	CreatedAt time.Time
	UpdatedAt time.Time
}

Role represents a role record from the database.

type RoleInfo

type RoleInfo struct {
	ID       string
	Name     string
	RoleType string
}

type RolePermission

type RolePermission struct {
	ID             string
	PermissionCode string
	Create         bool
	Read           bool
	Update         bool
	Delete         bool
	RoleID         string
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

RolePermission represents a structured role_permission record.

type RolePermissionRepo

type RolePermissionRepo interface {
	FindByRoleID(ctx context.Context, roleID string) (map[string]bool, *apierror.APIError)
	ListByRoleID(ctx context.Context, roleID string) ([]*RolePermission, *apierror.APIError)
	ListByRoleIDs(ctx context.Context, roleIDs []string) (map[string][]*RolePermission, *apierror.APIError)
	Create(ctx context.Context, permID, roleID string, input CreateRolePermissionInput) *apierror.APIError
	DeleteByRoleID(ctx context.Context, roleID string) *apierror.APIError
}

type RoleRepo

type RoleRepo interface {
	GetByID(ctx context.Context, roleID string) (*RoleInfo, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Role, *apierror.APIError)
	FindByTypeCode(ctx context.Context, typeCode string, accountID string) (*RoleInfo, *apierror.APIError)
	List(ctx context.Context, params ListRolesParams) (*ListRolesPage, *apierror.APIError)
	Get(ctx context.Context, roleID, accountID string) (*Role, *apierror.APIError)
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	Create(ctx context.Context, roleID string, params CreateRoleParams) *apierror.APIError
	UpdateName(ctx context.Context, roleID, accountID, name string) *apierror.APIError
	Delete(ctx context.Context, roleID, accountID string) *apierror.APIError
}

type RoleSvc

type RoleSvc interface {
	ListRoles(ctx context.Context, params ListRolesParams) (*ListRolesResult, *apierror.APIError)
	GetRole(ctx context.Context, roleID string, incs []string) (*RoleWithPermissions, *apierror.APIError)
	CreateRole(ctx context.Context, params CreateRoleParams) (*RoleWithPermissions, *apierror.APIError)
	UpdateRole(ctx context.Context, params UpdateRoleParams) (*RoleWithPermissions, *apierror.APIError)
	DeleteRole(ctx context.Context, roleID string) *apierror.APIError
	BatchGetRolesByIDs(ctx context.Context, ids []string) ([]*RoleWithPermissions, *apierror.APIError)
}

type RoleWithPermissions

type RoleWithPermissions struct {
	Role
	Permissions []*RolePermission
}

RoleWithPermissions combines a role with its structured permissions.

type RowResult

type RowResult struct {
	Index        int
	Status       constants.JobResultStatus
	ResourceType constants.ObjectType
	ID           string
	// The resource's human-readable reference — a shipment number, say. Set only where the
	// operation has one to hand, so a client can name what it wrote without a second read.
	Name         *string
	SubResources []SubResourceRef
	Error        *apierror.ResponseError
}

names what became of one row of a bulk request: the resource it produced, or the error it was rejected with. Exactly one of ID/Error is set, per Status.

func (RowResult) Failed

func (r RowResult) Failed() bool

Failed reports whether the row was rejected rather than written.

type RunScheduledGenerationParams

type RunScheduledGenerationParams struct {
	AccountID    string
	ScheduleID   string
	PlanningAsOf time.Time
	AutoPublish  bool
}

RunScheduledGenerationParams drives a queued solve.

type SaleProductItemRow

type SaleProductItemRow struct {
	ItemID        string
	ProductLineID *string
}

SaleProductItemRow links a sale-type product's item to its product line.

type SalesEntry

type SalesEntry struct {
	ID                  string
	IssuedAt            *time.Time
	CompletedAt         *time.Time
	FirstShipAt         *time.Time
	PromisedAt          *time.Time
	InvoiceDate         time.Time
	InvoiceID           string
	InvoiceNumber       string
	CustomerPO          *string
	SalesOrderNumber    string
	SalesOrderID        string
	SalesRepID          *string
	SalesRepUsername    *string
	CustomerID          string
	ParentCustomerID    *string
	CustomerName        string
	CustomerNumber      string
	CustomerCreatedAt   time.Time
	CustomerTypeGroupID *string
	CustomerGroupName   *string
	ProductLineID       *string
	ProductTypeCode     string
	ItemID              string
	ProductSku          string
	ProductDescription  *string
	CategoryName        string
	ProductLine         *string
	Unit                string
	QuantityInvoiced    float64
	TotalInvoiced       float64
	TotalCost           float64
	TotalProfit         float64
	UnitPrice           float64
	UnitCost            float64
	UnitProfit          float64
	ShipToState         *string
	ShipToCity          *string
	ShipToPostalCode    *string
	ShipToCountry       *string
	OrderDiscountCode   *string
}

type SalesOrder

type SalesOrder struct {
	ID                    string
	Number                string                 `audit:"number"`
	CustomerPONumber      *string                `audit:"customer_po_number"`
	Note                  *string                `audit:"note"`
	IsAcknowledgmentSent  bool                   `audit:"is_acknowledgment_sent"`
	BillingAddressID      string                 `audit:"billing_address_id"`
	ShippingAddressID     string                 `audit:"shipping_address_id"`
	CarrierID             *string                `audit:"carrier_id"`
	ServiceLevelID        *string                `audit:"service_level_id"`
	CarrierBillingType    *string                `audit:"carrier_billing_type"`
	CarrierBillingAccount *string                `audit:"carrier_billing_account"`
	PriorityCode          constants.PriorityCode `audit:"priority_code"`
	SalesRepID            *string                `audit:"sales_rep_id"`
	ShippingTermID        *string                `audit:"shipping_term_id"`
	SalesOrderStatusCode  string                 `audit:"sales_order_status_code"`
	SalesOrderTypeCode    string                 `audit:"sales_order_type_code"`
	PaymentTermID         *string                `audit:"payment_term_id"`
	ProductionRunID       *string                `audit:"production_run_id"`
	OrderDiscountID       *string                `audit:"order_discount_id"`
	BuyerAccountID        string                 `audit:"buyer_account_id"`
	SellerAccountID       string                 `audit:"seller_account_id"`
	OwnerAccountID        string                 `audit:"owner_account_id"`
	IssuedAt              *time.Time             `audit:"issued_at"`
	CompletedAt           *time.Time             `audit:"completed_at"`
	FirstShipAt           *time.Time             `audit:"first_ship_at"`
	ExpiredAt             *time.Time             `audit:"expired_at"`
	PromisedAt            *time.Time             `audit:"promised_at"`
	ShipByDate            *time.Time             `audit:"ship_by_date"`
	LeadTimeDays          *int32                 `audit:"lead_time_days"`
	LeadTimeSourceCode    *string                `audit:"lead_time_source_code"`
	TransitDays           *int32                 `audit:"transit_days"`
	TransitSourceCode     *string                `audit:"transit_source_code"`
	// LeadTimeOverrideDays and ShipByOverrideDate are the two per-order commitment bases beside PromisedAt. At most one of the three is ever set; the write path rejects more.
	LeadTimeOverrideDays *int       `audit:"lead_time_override_days"`
	ShipByOverrideDate   *time.Time `audit:"ship_by_override_date"`
	// ShipByCutoffAt is ShipByDate at the plant's pickup cutoff, and CalendarAdjustmentDays how many days the receiving and shipping calendars pulled the date back beyond transit. Both stamped with the commitment so an edited calendar cannot rewrite the explanation of a promise already made.
	ShipByCutoffAt         *time.Time `audit:"ship_by_cutoff_at"`
	CalendarAdjustmentDays *int32     `audit:"calendar_adjustment_days"`
	CreatedAt              time.Time
	UpdatedAt              time.Time

	// Joined customer details
	CustomerName             string
	CustomerNumber           string
	CustomerStatusCode       *string
	CustomerCommissionPolicy *string
	CustomerCreatedAt        *time.Time
	CustomerUpdatedAt        *time.Time
	StatusName               string
	TypeName                 string
	PriorityName             string

	// Joined address details
	BillToName          *string
	BillToIsDropShip    *bool
	BillToGeolocationID *string
	BillToStreetLine1   *string
	BillToStreetLine2   *string
	BillToLocality      *string
	BillToState         *string
	BillToPostalCode    *string
	BillToCountry       *string
	BillToPhone         *string
	BillToEmail         *string
	BillToCreatedAt     *time.Time
	BillToUpdatedAt     *time.Time
	ShipToName          *string
	ShipToIsDropShip    *bool
	ShipToGeolocationID *string
	ShipToStreetLine1   *string
	ShipToStreetLine2   *string
	ShipToLocality      *string
	ShipToState         *string
	ShipToPostalCode    *string
	ShipToCountry       *string
	ShipToPhone         *string
	ShipToEmail         *string
	ShipToCreatedAt     *time.Time
	ShipToUpdatedAt     *time.Time

	// Joined carrier details
	CarrierName                 *string
	CarrierIsPortalEnabled      *bool
	CarrierCreatedAt            *time.Time
	CarrierUpdatedAt            *time.Time
	ServiceLevelName            *string
	ServiceLevelToken           *string
	ServiceLevelIsPortalEnabled *bool
	ServiceLevelCreatedAt       *time.Time
	ServiceLevelUpdatedAt       *time.Time

	// Joined sales rep
	SalesRepName *string

	// Joined payment/shipping term
	PaymentTermName             *string
	PaymentTermIsActive         *bool
	PaymentTermCreatedAt        *time.Time
	PaymentTermUpdatedAt        *time.Time
	ShippingTermName            *string
	ShippingTermIsFreightExempt *bool
	ShippingTermIsCarrierRate   *bool
	ShippingTermCreatedAt       *time.Time
	ShippingTermUpdatedAt       *time.Time

	// Joined order discount
	OrderDiscountName         *string
	OrderDiscountCode         *string
	OrderDiscountPercentage   *string
	OrderDiscountAmount       *string
	OrderDiscountDiscountType *string
	OrderDiscountOrderCount   *int32
	OrderDiscountCreatedAt    *time.Time
	OrderDiscountUpdatedAt    *time.Time

	// Joined priority
	PriorityID *string

	// Joined pick
	PickID *string

	// Count of order lines (always populated, independent of the lines include).
	LineCount int32

	// Derived payment state (always populated): computed from settlement allocations vs. invoiced amounts plus any Stripe payment intent.
	PaymentStatus constants.SalesOrderPaymentStatus

	// Stripe payment intent IDs recorded against this order (always populated).
	PaymentIntentIDs []string

	// Lines (populated when included)
	Lines []*SalesOrderLine

	// IDs of shipments linked to this order (populated when related.shipments is included).
	ShipmentIDs []string

	InvoiceIDs []string

	// Invoice email recipients (populated when contacts is included).
	InvoiceEmails []string

	// Order acknowledgement email recipients (populated when contacts is included).
	AcknowledgementEmails []string

	// Fulfillment progress as fractions between 0 and 1 aggregated over the order's sale-type lines (always populated, independent of the lines include).
	PickedCompletion   float64
	PackedCompletion   float64
	InvoicedCompletion float64
}

SalesOrder represents a full sales order domain model.

type SalesOrderContacts

type SalesOrderContacts struct {
	InvoiceEmails         []string
	AcknowledgementEmails []string
}

SalesOrderContacts holds a sales order's email recipients grouped by notification type.

type SalesOrderEmailContactInput

type SalesOrderEmailContactInput struct {
	AccountUserID string
}

SalesOrderEmailContactInput represents a single recipient to wire to a sales order.

type SalesOrderEventPublisher

type SalesOrderEventPublisher interface {
	// PublishSalesOrderCreated writes a sales-order-created event to the outbox so out-of-band consumers (e.g. CRM sync) can react without blocking the create.
	PublishSalesOrderCreated(ctx context.Context, data messaging.SalesOrderCreatedData) *apierror.APIError
	// PublishSalesOrderShippingUpdated writes a sales-order shipping-changed event to the outbox so the shipment records are re-synced out-of-band from the update.
	PublishSalesOrderShippingUpdated(ctx context.Context, data messaging.SalesOrderShippingUpdatedData) *apierror.APIError
}

SalesOrderEventPublisher publishes sales-order domain events via the outbox pattern.

type SalesOrderFreightQuote

type SalesOrderFreightQuote struct {
	UnitPrice RateValue
}

SalesOrderFreightQuote is the freshly estimated freight (shipping) charge for an order, expressed as currency (numerator) per shipping unit (denominator). No order is mutated.

type SalesOrderFulfillmentProgress

type SalesOrderFulfillmentProgress struct {
	PickedCompletion   float64
	PackedCompletion   float64
	InvoicedCompletion float64
}

SalesOrderFulfillmentProgress holds an order's picked/packed/invoiced completion fractions (0..1), aggregated over its sale-type lines.

type SalesOrderLine

type SalesOrderLine struct {
	ID                 string
	LineItemNumber     int32   `audit:"line_item_number"`
	ProductSKU         string  `audit:"product_sku"`
	ProductDescription *string `audit:"product_description"`
	ProductID          *string `audit:"product_id"`
	ProductTypeCode    *string `audit:"product_type_code"`
	ItemID             *string `audit:"item_id"`
	ItemSKU            *string `audit:"item_sku"`
	SalesOrderID       string
	EdiLineItemID      *string `audit:"edi_line_item_id"`

	// Quantity ordered
	QuantityID               string
	QuantityValue            string `audit:"quantity_value"`
	QuantityUnitID           string `audit:"quantity_unit_id"`
	QuantityUnitName         string `audit:"quantity_unit_name"`
	QuantityUnitAbbreviation string `audit:"quantity_unit_abbreviation"`
	QuantityUnitType         string `audit:"quantity_unit_type"`

	// Aggregated quantity values
	QuantityPickedValue   *string `audit:"quantity_picked_value"`
	QuantityPackedValue   *string `audit:"quantity_packed_value"`
	QuantityInvoicedValue *string `audit:"quantity_invoiced_value"`

	// Unit price
	UnitPriceID                  string
	UnitPriceValue               string `audit:"unit_price_value"`
	UnitPriceNumeratorUnitID     string `audit:"unit_price_numerator_unit_id"`
	UnitPriceNumeratorUnitAbbr   string `audit:"unit_price_numerator_unit_abbr"`
	UnitPriceDenominatorUnitID   string `audit:"unit_price_denominator_unit_id"`
	UnitPriceDenominatorUnitAbbr string `audit:"unit_price_denominator_unit_abbr"`

	// Unit cost (nullable)
	UnitCostID                  *string
	UnitCostValue               *string `audit:"unit_cost_value"`
	UnitCostNumeratorUnitID     *string `audit:"unit_cost_numerator_unit_id"`
	UnitCostNumeratorUnitAbbr   *string `audit:"unit_cost_numerator_unit_abbr"`
	UnitCostDenominatorUnitID   *string `audit:"unit_cost_denominator_unit_id"`
	UnitCostDenominatorUnitAbbr *string `audit:"unit_cost_denominator_unit_abbr"`

	CreatedAt time.Time
	UpdatedAt time.Time
}

SalesOrderLine represents a sales order line domain model.

type SalesOrderLineForBOM

type SalesOrderLineForBOM struct {
	ID             string
	ItemID         string
	QuantityValue  decimal.Decimal
	QuantityUnitID string
}

SalesOrderLineForBOM represents a sales order line with BOM-relevant fields.

type SalesOrderLinePosition

type SalesOrderLinePosition struct {
	ID             string
	LineItemNumber int32
	IsSystem       bool
}

SalesOrderLinePosition is a line's current position and whether it is a credit/freight (system) line, used when re-sequencing.

type SalesOrderLinePrice

type SalesOrderLinePrice struct {
	Value             string
	NumeratorUnitID   string
	DenominatorUnitID string
}

SalesOrderLinePrice is the computed unit price for a single line, expressed as currency (numerator) per ordered unit (denominator).

type SalesOrderLineQuote

type SalesOrderLineQuote struct {
	ProductID string
	UnitPrice RateValue
}

SalesOrderLineQuote is one priced line returned by a quote (no order is created).

type SalesOrderLineRepo

type SalesOrderLineRepo interface {
	List(ctx context.Context, salesOrderID string) ([]*SalesOrderLine, *apierror.APIError)
	Get(ctx context.Context, salesOrderLineID string) (*SalesOrderLine, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateSalesOrderLineParams) (*SalesOrderLine, *apierror.APIError)
	Update(ctx context.Context, params UpdateSalesOrderLineParams) (*SalesOrderLine, *apierror.APIError)
	Delete(ctx context.Context, salesOrderLineID string) *apierror.APIError
	IsInOrder(ctx context.Context, salesOrderLineID, salesOrderID, accountID string) (bool, *apierror.APIError)
	GetNextLineItemNumber(ctx context.Context, salesOrderID string) (int32, *apierror.APIError)
	// HasShipmentAgainstOrderLine reports whether the order line is part of any shipment (packed or shipped).
	HasShipmentAgainstOrderLine(ctx context.Context, salesOrderLineID string) (bool, *apierror.APIError)
	// SyncInvoiceLineQuantities keeps the invoice lines referencing the order line in sync
	// with a quantity edit: their unit always follows the order line's unit (a unit edit is
	// a correction, and rollups sum these values without conversion), while their value
	// follows only when it still mirrors the pre-update ordered quantity — partial-shipment
	// snapshots keep the amount that was actually billed.
	SyncInvoiceLineQuantities(ctx context.Context, salesOrderLineID, previousQuantityValue, quantityValue, quantityUnitID string) *apierror.APIError
	// SyncShipmentLineQuantities applies the same sync rule as SyncInvoiceLineQuantities to
	// the shipment lines referencing the order line.
	SyncShipmentLineQuantities(ctx context.Context, salesOrderLineID, previousQuantityValue, quantityValue, quantityUnitID string) *apierror.APIError
	// SyncPickLineQuantityUnits relabels the pick line quantities referencing the order line
	// to the given unit. Pick line values are picking progress and are reconciled separately,
	// so only the unit follows a unit edit on the order line.
	SyncPickLineQuantityUnits(ctx context.Context, salesOrderLineID, quantityUnitID string) *apierror.APIError
	DeleteCascade(ctx context.Context, salesOrderLineID string) *apierror.APIError
	CreateQuantity(ctx context.Context, quantityID, value, unitID string) *apierror.APIError
	// GetLineOrder returns the order's lines in current display order, flagging credit/freight (system) lines.
	GetLineOrder(ctx context.Context, salesOrderID string) ([]*SalesOrderLinePosition, *apierror.APIError)
	// SetLineItemNumber sets a single line's line_item_number.
	SetLineItemNumber(ctx context.Context, salesOrderLineID string, lineItemNumber int32) *apierror.APIError
}

type SalesOrderLineShipmentCapacity

type SalesOrderLineShipmentCapacity struct {
	SalesOrderID string
	Ordered      decimal.Decimal
	Shipped      decimal.Decimal
}

Reports how much of a sales order line remains unshipped.

func (SalesOrderLineShipmentCapacity) Remaining

Reports the quantity still available to ship, never negative.

type SalesOrderLineSvc

type SalesOrderLineSvc interface {
	// CreateSalesOrderLine creates a new line on a sales order.
	CreateSalesOrderLine(ctx context.Context, params CreateSalesOrderLineParams) (*SalesOrderLine, *apierror.APIError)

	// UpdateSalesOrderLine partially updates a sales order line.
	UpdateSalesOrderLine(ctx context.Context, params UpdateSalesOrderLineParams) (*SalesOrderLine, *apierror.APIError)

	// DeleteSalesOrderLine deletes a sales order line and cascades to pick/shipment/invoice lines.
	DeleteSalesOrderLine(ctx context.Context, params DeleteSalesOrderLineParams) *apierror.APIError

	// ReorderSalesOrderLines re-sequences the order's product lines to match the given order, keeping credit/freight lines at the bottom. Returns the order's lines in their new order.
	ReorderSalesOrderLines(ctx context.Context, params ReorderSalesOrderLinesParams) ([]*SalesOrderLine, *apierror.APIError)
}

type SalesOrderPriceLineInput

type SalesOrderPriceLineInput struct {
	ProductID         string
	QuantityValue     string
	QuantityUnitID    string
	OverrideUnitPrice *RateValue
}

SalesOrderPriceLineInput is one line to price. The volume-discount stage sums quantities across all lines that share a chosen discount, so the engine takes every line at once.

type SalesOrderRepo

type SalesOrderRepo interface {
	List(ctx context.Context, params ListSalesOrdersParams) (*ListSalesOrdersResult, *apierror.APIError)
	Get(ctx context.Context, accountID, salesOrderID string) (*SalesOrder, *apierror.APIError)
	GetForCustomer(ctx context.Context, accountID, buyerAccountID, salesOrderID string) (*SalesOrder, *apierror.APIError)
	GetLines(ctx context.Context, salesOrderID string) ([]*SalesOrderLine, *apierror.APIError)
	GetShipmentIDs(ctx context.Context, salesOrderID string) ([]string, *apierror.APIError)
	GetInvoiceIDs(ctx context.Context, salesOrderID string) ([]string, *apierror.APIError)
	GetContactsByOrders(ctx context.Context, salesOrderIDs []string) (map[string]*SalesOrderContacts, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateSalesOrderParams) (*SalesOrder, *apierror.APIError)
	Update(ctx context.Context, params UpdateSalesOrderParams) (*SalesOrder, *apierror.APIError)
	Delete(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	UpdateStatus(ctx context.Context, accountID, salesOrderID, statusCode string, issuedAt, completedAt *time.Time) *apierror.APIError
	GetCustomerLeadTimeChain(ctx context.Context, accountID, buyerAccountID string) (*CustomerLeadTimeChain, *apierror.APIError)
	SetShipByCommitment(ctx context.Context, accountID, salesOrderID string, commitment *ShipByCommitment) *apierror.APIError
	IsOrderForCustomer(ctx context.Context, salesOrderID, buyerAccountID string) (bool, *apierror.APIError)
	AreAllLineProductLinesCommissionExempt(ctx context.Context, productIDs []string) (bool, *apierror.APIError)
	GetAccountOriginAddress(ctx context.Context, accountID string) (*ShippingAddress, *apierror.APIError)
	GetProductTypesAndLines(ctx context.Context, productIDs []string) ([]ProductTypeLine, *apierror.APIError)
	IsDuplicateOrderNumber(ctx context.Context, accountID, number string, excludeID *string) (bool, *apierror.APIError)
	IsDuplicateCustomerPO(ctx context.Context, accountID, buyerAccountID, customerPO string, excludeID *string) (bool, *apierror.APIError)
	CountSalesOrdersForBuyerAccounts(ctx context.Context, ownerAccountID string, buyerAccountIDs []string) (int64, *apierror.APIError)
	GetNextOrderNumber(ctx context.Context, accountID string) (string, *apierror.APIError)
	GetPickID(ctx context.Context, salesOrderID string) (*string, *apierror.APIError)
	DeleteCascade(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	CreatePick(ctx context.Context, pickID, number, salesOrderID, accountID string) *apierror.APIError
	CreatePickLine(ctx context.Context, pickLineID, pickID, quantityID, salesOrderLineID string) *apierror.APIError
	DeleteQuantitiesByPickLines(ctx context.Context, salesOrderID string) *apierror.APIError
	DeletePickLinesBySalesOrder(ctx context.Context, salesOrderID string) *apierror.APIError
	DeletePickBySalesOrder(ctx context.Context, salesOrderID string) *apierror.APIError
	CheckPaymentStatus(ctx context.Context, salesOrderID string) (bool, *apierror.APIError)
	GetPaymentStatuses(ctx context.Context, accountID string, salesOrderIDs []string) (map[string]constants.SalesOrderPaymentStatus, *apierror.APIError)
	// GetPaymentIntentIDs returns the Stripe payment intent IDs linked to each of the given orders (scoped to the owning account), keyed by sales order ID. Orders with no payments are absent from the map.
	GetPaymentIntentIDs(ctx context.Context, accountID string, salesOrderIDs []string) (map[string][]string, *apierror.APIError)
	// GetFulfillmentProgress returns each order's picked/packed/invoiced completion fractions (0..1), aggregated over its sale-type lines, keyed by sales order ID. Orders with no sale lines are absent from the map.
	GetFulfillmentProgress(ctx context.Context, salesOrderIDs []string) (map[string]SalesOrderFulfillmentProgress, *apierror.APIError)
	GetLinesForBOM(ctx context.Context, salesOrderID string) ([]SalesOrderLineForBOM, *apierror.APIError)
	SetProductionRunID(ctx context.Context, accountID, salesOrderID, productionRunID string) *apierror.APIError
	GetSaleLinesForIssue(ctx context.Context, salesOrderID string) ([]SalesOrderSaleLineForIssue, *apierror.APIError)
	CreateReservedInventoryIssue(ctx context.Context, id, accountID, itemID, quantityID, orderID string) *apierror.APIError
	DeleteInventoryAllocationsByReservedIssues(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	DeleteReservedInventoryIssues(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	GetAcknowledgementRecipients(ctx context.Context, salesOrderID string) ([]string, *apierror.APIError)
	MarkAcknowledgementSent(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	CreateEmailContact(ctx context.Context, id, salesOrderID, accountUserID, notificationTypeCode string) *apierror.APIError
	DeleteEmailContactsByOrderAndType(ctx context.Context, salesOrderID, notificationTypeCode string) *apierror.APIError
	NoteFirstShipAt(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	// MarkFulfilled sets the order status to fulfilled and stamps completed_at (idempotent).
	MarkFulfilled(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	// GetSalesRepEmail returns the order's sales rep email, or nil if it has no rep or no email.
	GetSalesRepEmail(ctx context.Context, accountID, salesOrderID string) (*string, *apierror.APIError)
	MarkUnfulfilled(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
	HasShippedShipment(ctx context.Context, salesOrderID string) (bool, *apierror.APIError)
}

type SalesOrderSaleLineForIssue

type SalesOrderSaleLineForIssue struct {
	ID             string
	ItemID         *string
	QuantityValue  string
	QuantityUnitID string
}

SalesOrderSaleLineForIssue represents a sale-type order line used during issue operations.

type SalesOrderStatus

type SalesOrderStatus struct {
	ID        string
	Code      string
	Name      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type SalesOrderStatusRepo

type SalesOrderStatusRepo interface {
	List(ctx context.Context, params ListSalesOrderStatusesParams) (*ListSalesOrderStatusesResult, *apierror.APIError)
	GetByIDs(ctx context.Context, ids []string) ([]*SalesOrderStatus, *apierror.APIError)
}

type SalesOrderStatusSvc

type SalesOrderStatusSvc interface {
	// ListSalesOrderStatuses returns a paginated list of sales order statuses. These are global lookup values.
	ListSalesOrderStatuses(ctx context.Context, params ListSalesOrderStatusesParams) (*ListSalesOrderStatusesResult, *apierror.APIError)

	// BatchGetSalesOrderStatusesByIDs returns statuses by ID for the api-gateway include resolver.
	BatchGetSalesOrderStatusesByIDs(ctx context.Context, ids []string) ([]*SalesOrderStatus, *apierror.APIError)
}

type SalesOrderSvc

type SalesOrderSvc interface {
	// TransitWarmer is embedded so the order-event consumers can drive lane warming through the same service that reads the cache back when a commitment is stamped.
	TransitWarmer

	// ListSalesOrders returns a paginated list of sales orders for the caller's account. Supports customer actor access via BuyerAccountID filter.
	ListSalesOrders(ctx context.Context, params ListSalesOrdersParams) (*ListSalesOrdersResult, *apierror.APIError)

	// GetSalesOrder returns a single sales order by ID. Lines are fetched conditionally based on the includes parameter.
	GetSalesOrder(ctx context.Context, params GetSalesOrderParams) (*SalesOrder, *apierror.APIError)

	// CreateSalesOrder creates a new sales order with lines, addresses, and optional discount.
	CreateSalesOrder(ctx context.Context, params CreateSalesOrderParams) (*SalesOrder, *apierror.APIError)

	// UpdateSalesOrder partially updates a sales order.
	UpdateSalesOrder(ctx context.Context, params UpdateSalesOrderParams) (*SalesOrder, *apierror.APIError)

	// DeleteSalesOrder deletes a sales order and cascades to related records.
	DeleteSalesOrder(ctx context.Context, params DeleteSalesOrderParams) *apierror.APIError

	// BulkDeleteSalesOrders deletes multiple sales orders.
	BulkDeleteSalesOrders(ctx context.Context, params BulkDeleteSalesOrdersParams) *apierror.APIError

	// ChangeSalesOrderStatus changes the status of a sales order.
	ChangeSalesOrderStatus(ctx context.Context, params ChangeSalesOrderStatusParams) (*SalesOrder, *apierror.APIError)

	// CheckoutSalesOrder initiates a Stripe checkout for a sales order.
	CheckoutSalesOrder(ctx context.Context, params CheckoutSalesOrderParams) (*CheckoutSalesOrderResult, *apierror.APIError)
	QuoteSalesOrderLinePrices(ctx context.Context, params QuoteSalesOrderLinePricesParams) ([]SalesOrderLineQuote, *apierror.APIError)

	// QuoteSalesOrderFreight re-estimates an existing order's freight charge from its current ship-to, carrier, service level, and lines, without mutating the order.
	QuoteSalesOrderFreight(ctx context.Context, params QuoteSalesOrderFreightParams) (*SalesOrderFreightQuote, *apierror.APIError)

	// QuoteSalesOrderCommitment previews the ship-by date a set of commitment inputs would produce, running the same resolution the issue path runs so the two cannot disagree. Returns nil when no rule produces a date.
	QuoteSalesOrderCommitment(ctx context.Context, params QuoteCommitmentParams) (*ShipByCommitment, *apierror.APIError)

	// CreateSalesOrderProductionRun creates a production run from a sales order.
	CreateSalesOrderProductionRun(ctx context.Context, params CreateSalesOrderProductionRunParams) (*CreateSalesOrderProductionRunResult, *apierror.APIError)

	// CreateCustomerCheckoutSession creates an embedded Stripe checkout session for a customer actor.
	CreateCustomerCheckoutSession(ctx context.Context, params CreateCustomerCheckoutSessionParams) (*CreateCustomerCheckoutSessionResult, *apierror.APIError)

	// RecordOrderPayment links a succeeded Stripe payment intent to a sales order (called from ProcessAccountStripeWebhook and from the billing-service's platform webhook consumer). Idempotent: a payment intent already linked is a no-op.
	RecordOrderPayment(ctx context.Context, salesOrderID, paymentIntentID string) *apierror.APIError

	// ProcessAccountStripeWebhook verifies a webhook event from an account's connected Stripe account against the account's stored webhook secret, then links succeeded payment intents to their sales orders via RecordOrderPayment. Events that are not order payments are acknowledged and ignored so Stripe does not retry them.
	ProcessAccountStripeWebhook(ctx context.Context, accountID string, rawPayload []byte, signature string) *apierror.APIError
}

type SalesTarget

type SalesTarget struct {
	ID           string
	StartDate    time.Time `audit:"starts_at"`
	EndDate      time.Time `audit:"ends_at"`
	SalesRepID   string    `audit:"sales_rep_id"`
	AccountID    string
	AmountID     string
	AmountValue  string `audit:"amount_value"`
	AmountUnitID string `audit:"amount_unit_id"`
	// The amount's unit, carried alongside the id so the API can render a quantity without a second lookup.
	AmountUnitName              string
	AmountUnitAbbreviation      string
	AmountUnitType              string
	AmountUnitRatioNumerator    string
	AmountUnitRatioDenominator  string
	AmountUnitOffsetNumerator   string
	AmountUnitOffsetDenominator string
	AmountUnitCreatedAt         time.Time
	AmountUnitUpdatedAt         time.Time
	CreatedAt                   time.Time
	UpdatedAt                   time.Time
}

SalesTarget represents a sales target for a user.

type SalesTargetRepo

type SalesTargetRepo interface {
	List(ctx context.Context, params ListSalesTargetsParams) (*ListSalesTargetsResult, *apierror.APIError)
	Get(ctx context.Context, targetID string) (*SalesTarget, *apierror.APIError)
	Exists(ctx context.Context, targetID string) (bool, *apierror.APIError)
	IsInAccount(ctx context.Context, targetID, accountID string) (bool, *apierror.APIError)
	SalesRepExistsInAccount(ctx context.Context, salesRepID, accountID string) (bool, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateSalesTargetParams, amountID string) *apierror.APIError
	Update(ctx context.Context, params UpsertSalesTargetParams) *apierror.APIError
	InsertQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	UpdateQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
}

type SalesTargetSvc

type SalesTargetSvc interface {
	// ListSalesTargets returns a paginated list of sales targets for an account user.
	ListSalesTargets(ctx context.Context, params ListSalesTargetsParams) (*ListSalesTargetsResult, *apierror.APIError)

	// CreateSalesTarget creates a new sales target.
	CreateSalesTarget(ctx context.Context, params CreateSalesTargetParams) (*SalesTarget, *apierror.APIError)

	// UpsertSalesTarget creates or updates a sales target by ID.
	UpsertSalesTarget(ctx context.Context, params UpsertSalesTargetParams) (*SalesTarget, *apierror.APIError)
}

type SandboxAccount

type SandboxAccount struct {
	ID                    int64
	TypeID                string
	OwnerAccountID        string
	AccountID             string
	Name                  string `audit:"name"`
	OwnerAccountName      *string
	OwnerAccountCreatedAt *time.Time
	OwnerAccountUpdatedAt *time.Time
	CreatedAt             time.Time
	UpdatedAt             time.Time
}

type SandboxAccountRepo

type SandboxAccountRepo interface {
	FindFirstByOwnerAccountID(ctx context.Context, ownerAccountID string) (string, *apierror.APIError)
	FindByTypeID(ctx context.Context, typeID string, includes []string) (*SandboxAccount, *apierror.APIError)
	GetByTypeIDs(ctx context.Context, ownerAccountID string, typeIDs []string) ([]*SandboxAccount, *apierror.APIError)
	List(ctx context.Context, ownerAccountID string, cursor *string, limit int32, query *string, includes []string) (*ListSandboxAccountsResult, *apierror.APIError)
	Create(ctx context.Context, typeID, ownerAccountID, accountID string) *apierror.APIError
	CountByOwnerAccountID(ctx context.Context, ownerAccountID string) (int64, *apierror.APIError)
	DeleteByID(ctx context.Context, id int64) *apierror.APIError
}

type SandboxMed

type SandboxMed interface {
	// Create provisions a new sandbox account under the given owner account.
	//
	// 1. Verify the owner is a production account (not already a sandbox).
	// 2. Fetch the owner's plan code and sandbox limit.
	// 3. Check the current sandbox count against the plan limit; reject if at capacity.
	// 4. Generate unique IDs for the new account and sandbox type.
	// 5. Create the account record with sandbox type and the owner's plan code.
	// 6. Create supporting records: business address, account-user link, portal, system products, and branding.
	// 7. Insert the sandbox account record linking it to the owner.
	// 8. Re-fetch and return the created sandbox with populated owner metadata.
	Create(ctx context.Context, ownerAccountID, userID, name string) (*SandboxAccount, *apierror.APIError)

	// Delete removes a sandbox account and its underlying account record.
	//
	// 1. Find the sandbox by type ID and verify it belongs to the requesting owner account.
	// 2. Confirm the underlying account is actually a sandbox account.
	// 3. Delete the sandbox account record from the sandbox table.
	// 4. Delete the underlying account record.
	// 5. Return the deleted account ID for downstream purge processing.
	Delete(ctx context.Context, ownerAccountID, sandboxTypeID string) (accountID string, apiErr *apierror.APIError)
}

type SandboxSvc

type SandboxSvc interface {
	// CreateSandbox creates a sandbox account with the given name.
	//
	// Preconditions:
	//   - The caller must be authorized to create sandbox accounts.
	//
	// Side effects:
	//   - Persists a new owner account and its associated sandbox account.
	CreateSandbox(ctx context.Context, name string, mode constants.SandboxMode) (*SandboxAccount, *apierror.APIError)

	// GetSandboxAccountByOwner returns the sandbox account ID associated with the given owner account.
	GetSandboxAccountByOwner(ctx context.Context, ownerAccountID string) (string, *apierror.APIError)

	// ListSandboxAccounts returns a paginated list of sandbox accounts visible to the caller.
	//
	// Pagination:
	//   - If cursor is non-nil, results begin after the provided cursor.
	//   - limit controls the maximum number of results returned.
	ListSandboxAccounts(ctx context.Context, cursor *string, limit int32, query *string, includes []string) (*ListSandboxAccountsResult, *apierror.APIError)

	// GetSandbox returns a single sandbox account by its type ID. The caller must have read permission on the sandbox domain and the sandbox must belong to the caller's target account.
	GetSandbox(ctx context.Context, sandboxTypeID string, includes []string) (*SandboxAccount, *apierror.APIError)

	// DeleteSandbox deletes a sandbox account and its underlying account record. Account-scoped data is purged asynchronously via an outbox message.
	DeleteSandbox(ctx context.Context, sandboxTypeID string) *apierror.APIError

	// BatchGetSandboxesByIDs returns sandbox accounts matching the input type IDs that the caller's account is authorized to read. Used by the api-gateway resourcekit include resolver.
	BatchGetSandboxesByIDs(ctx context.Context, typeIDs []string) ([]*SandboxAccount, *apierror.APIError)
}

type ScanningConsumption

type ScanningConsumption struct {
	SKU              string
	DemandMeasure    string
	DemandUnit       string
	InventoryMeasure string
	InventoryUnit    string
	Instructions     *string
}

ScanningConsumption represents a single consumption demand entry for a scanning station.

type ScanningProductionStepInfo

type ScanningProductionStepInfo struct {
	ID          string
	Name        string
	IsMultiPart bool
}

ScanningProductionStepInfo holds information about a production step available at a scanning station.

type ScanningStation

type ScanningStation struct {
	ID                  string
	Name                string                        `audit:"name"`
	Notes               *string                       `audit:"notes"`
	Type                constants.ScanningStationType `audit:"type"`
	LabelSizeCode       *string                       `audit:"label_size_code"`
	LabelTypeCode       *string                       `audit:"label_type_code"`
	OperatorRequirement constants.OperatorRequirement `audit:"operator_requirement"`
	DepartmentID        string                        `audit:"department_id"`
	DepartmentName      string
	DepartmentCreatedAt *time.Time
	DepartmentUpdatedAt *time.Time
	ProductionSteps     []ProductionStepRef
	AccountID           string
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

type ScanningStationQueryRepo

type ScanningStationQueryRepo interface {
	IsInAccount(ctx context.Context, accountID, id string) (bool, *apierror.APIError)
	FindType(ctx context.Context, accountID, id string) (string, *apierror.APIError)
}

ScanningStationQueryRepo provides read-only access to scanning station data.

type ScanningStationRepo

type ScanningStationRepo interface {
	List(ctx context.Context, params ListScanningStationsParams) (*ListScanningStationsResult, *apierror.APIError)
	Get(ctx context.Context, params GetScanningStationParams) (*ScanningStation, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*ScanningStation, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateScanningStationParams) (*ScanningStation, *apierror.APIError)
	Update(ctx context.Context, params UpdateScanningStationParams) (*ScanningStation, *apierror.APIError)
	Delete(ctx context.Context, params DeleteScanningStationParams) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	FindIDByName(ctx context.Context, accountID, name string) (*string, *apierror.APIError)
	// FindByNames resolves existing scanning stations by name (case-insensitive) in
	// one query. Names must be pre-lowercased by the caller.
	FindByNames(ctx context.Context, accountID string, names []string) ([]*ScanningStation, *apierror.APIError)
	ConnectProductionStepsByName(ctx context.Context, accountID, scanningStationID, name string) *apierror.APIError
	IsInAccount(ctx context.Context, accountID, id string) (bool, *apierror.APIError)
	FindType(ctx context.Context, accountID, id string) (string, *apierror.APIError)
	// Export returns every matching station up to params.Limit, unpaginated.
	Export(ctx context.Context, params ExportScanningStationsParams) ([]*ScanningStation, *apierror.APIError)
}

type ScanningStationSvc

type ScanningStationSvc interface {
	ListScanningStations(ctx context.Context, params ListScanningStationsParams) (*ListScanningStationsResult, *apierror.APIError)
	ExportScanningStations(ctx context.Context, params ExportScanningStationsParams) (*Job, *apierror.APIError)
	// BuildExportScanningStations renders the file an accepted export recorded.
	BuildExportScanningStations(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)
	GetScanningStation(ctx context.Context, params GetScanningStationParams) (*ScanningStation, *apierror.APIError)
	BatchGetScanningStationsByIDs(ctx context.Context, ids []string) ([]*ScanningStation, *apierror.APIError)
	CreateScanningStation(ctx context.Context, params CreateScanningStationParams) (*ScanningStation, *apierror.APIError)
	UpdateScanningStation(ctx context.Context, params UpdateScanningStationParams) (*ScanningStation, *apierror.APIError)
	BulkUpsertScanningStations(ctx context.Context, params BulkUpsertScanningStationsParams) (*Job, *apierror.APIError)
	ExecuteBulkUpsertScanningStations(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError
	DeleteScanningStation(ctx context.Context, scanningStationID string) *apierror.APIError
	ConnectProductionStepsByName(ctx context.Context, params ConnectProductionStepsByNameParams) *apierror.APIError
}

type ScheduleAttainmentRepo

type ScheduleAttainmentRepo interface {
	// SelectAttainmentBaselines returns every published version whose horizon overlaps the window, newest publish first.
	SelectAttainmentBaselines(ctx context.Context, params SelectAttainmentBaselinesParams) ([]AttainmentBaselineRow, *apierror.APIError)

	// SumPlannedByWeek returns planned quantity and run hours per (week, machine, item) for one baseline version.
	SumPlannedByWeek(ctx context.Context, params SumPlannedByWeekParams) ([]AttainmentPlannedRow, *apierror.APIError)

	// SumActualsByWeek returns what was actually produced, bucketed to the Monday of the scan week so it lines up with a schedule line's week_start_date. An unscanned batch was never produced, so it is excluded.
	SumActualsByWeek(ctx context.Context, params SumActualsByWeekParams) ([]AttainmentActualRow, *apierror.APIError)

	// CountDeviationsForBaselines counts frozen-week changes per baseline version, which is the numerator of frozen adherence.
	CountDeviationsForBaselines(ctx context.Context, accountID string, scheduleIDs []string) ([]AttainmentDeviationRow, *apierror.APIError)

	// GetMachineLabels returns machine names for the given ids.
	GetMachineLabels(ctx context.Context, accountID string, ids []string) ([]AttainmentLabelRow, *apierror.APIError)

	// GetDepartmentLabels returns department names for the given ids.
	GetDepartmentLabels(ctx context.Context, accountID string, ids []string) ([]AttainmentLabelRow, *apierror.APIError)

	// GetItemLabels returns item SKUs for the given ids.
	GetItemLabels(ctx context.Context, accountID string, ids []string) ([]AttainmentLabelRow, *apierror.APIError)
}

ScheduleAttainmentRepo is the thin read surface behind schedule attainment. Each method is one query mapped to domain rows; choosing the baseline that was live for a week — and every ratio built on that choice — lives in the analytics service.

type ScheduleAttainmentResult

type ScheduleAttainmentResult struct {
	StartDate time.Time
	EndDate   time.Time
	GroupBy   string

	// Baselines names the published versions the measurement was taken against, so a number can always be traced back to the plan that produced it.
	BaselineScheduleIDs []string

	Buckets []AttainmentBucket
	Totals  AttainmentBucket

	// ScheduledMachineCount is how many machines the plan asked for over the window. Every figure above covers those machines only, so this is what says how wide the measurement was.
	ScheduledMachineCount int64

	FrozenAdherence []FrozenAdherence
	// HasBaseline is false when nothing was ever published over the window. Every ratio is nil in that case, and the caller should say "no plan" rather than "0%".
	HasBaseline bool
}

type ScheduleDeviationType

type ScheduleDeviationType struct {
	ID        string
	Code      string
	Name      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type ScheduleDiffLine

type ScheduleDiffLine struct {
	ChangeCode string
	ItemID     string
	SKU        string
	MachineID  string
	WeekIndex  int32
	// CurrentQuantity and ProposedQuantity are zero on the side that does not have the campaign at all; ChangeCode says which side that is.
	CurrentQuantity  float64
	ProposedQuantity float64
	// CurrentIsManual marks a campaign a person created or edited. These are what preserve_manual keeps and what replace_all destroys.
	CurrentIsManual bool
}

ScheduleDiffLine is one campaign as the current plan and a fresh solve each see it.

type ScheduleLineForStatusRow

type ScheduleLineForStatusRow struct {
	ID              string
	MachineID       string
	ItemID          string
	WeekIndex       int32
	WeekStartDate   time.Time
	PlannedQuantity float64
	PlannedRunHours float64
	StatusCode      string
	ProductionRunID *string
	// PlannedUnitAbbreviation is nil when the line's unit row is missing.
	PlannedUnitAbbreviation *string
	// SKU is nil when the item has no policy row on the schedule.
	SKU                *string
	ReleasedBatchCount int64
	ScannedBatchCount  int64
	ScannedQuantity    float64
}

ScheduleLineForStatusRow is one schedule line with its scan progress, as stored.

type ScheduleOrderCoverage

type ScheduleOrderCoverage struct {
	SalesOrderID     string
	SalesOrderNumber string
	ItemID           string
	SKU              string
	UnitsAtRisk      float64
	DueWeek          int
	ReasonCode       string
	ShipByDate       *time.Time
	CoveringLines    []ScheduleOrderCoverageLine
}

ScheduleOrderCoverage is one order a version does not fully build in time, with the campaigns earmarked for the part it does.

type ScheduleOrderCoverageLine

type ScheduleOrderCoverageLine struct {
	ProductionScheduleLineID string
	WeekIndex                int32
	MachineID                string
	AllocatedQuantity        float64
}

ScheduleOrderCoverageLine is one campaign earmarked for an order.

type ScheduleRegeneratePreview

type ScheduleRegeneratePreview struct {
	ScheduleID    string
	SolverVersion string
	PlanningAsOf  time.Time
	Lines         []ScheduleDiffLine
	AddedCount    int32
	RemovedCount  int32
	ChangedCount  int32
	// ManualLineCount is how many hand-edited campaigns the version currently holds, and DiscardedManualCount how many of them replace_all would destroy. The two are shown together so the cost of the destructive mode is a number rather than a warning.
	ManualLineCount      int32
	DiscardedManualCount int32
}

ScheduleRegeneratePreview is what a regenerate would do, without doing it.

type SeedBatchRow

type SeedBatchRow struct {
	BatchID string
	ItemID  string
}

SeedBatchRow is one scanned batch a genealogy walk can start from.

type SelectAttainmentBaselinesParams

type SelectAttainmentBaselinesParams struct {
	AccountID   string
	WindowStart time.Time
	WindowEnd   time.Time
}

SelectAttainmentBaselinesParams scopes the baseline read to an account and analysis window.

type SellableProductRow

type SellableProductRow struct {
	ProductID string
	ItemID    string
	SKU       string
	// Description is nil when the item was never given one, which a SKU-only row still reads fine without.
	Description *string
	// ProductLineID is nil when the product sells under no line.
	ProductLineID *string
}

SellableProductRow is one sellable product carried by an item.

type ServiceLevel

type ServiceLevel struct {
	ID                string
	Name              string  `audit:"name"`
	Code              string  `audit:"code"`
	ServiceLevelToken *string `audit:"service_level_token"`
	IsPortalEnabled   bool    `audit:"is_portal_enabled"`
	IsDefault         bool    `audit:"is_default"`
	// DefaultTransitDays is the fallback transit for this service when no lane estimate has been cached, and the only source for carriers that cannot be rated.
	DefaultTransitDays *int32 `audit:"default_transit_days"`
	CarrierID          string
	AccountID          *string
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

type ServiceLevelRepo

type ServiceLevelRepo interface {
	List(ctx context.Context, params ListServiceLevelsParams) (*ListServiceLevelsResult, *apierror.APIError)
	Get(ctx context.Context, accountID, serviceLevelID string) (*ServiceLevel, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateServiceLevelParams) (*ServiceLevel, *apierror.APIError)
	Update(ctx context.Context, params UpdateServiceLevelParams) (*ServiceLevel, *apierror.APIError)
	Delete(ctx context.Context, accountID, serviceLevelID string) *apierror.APIError
	IsInCarrier(ctx context.Context, serviceLevelID, carrierID string) (bool, *apierror.APIError)
	ExistsByCodeInCarrier(ctx context.Context, carrierID, code string, excludeID *string) (bool, *apierror.APIError)
	ClearDefaultsForCarrier(ctx context.Context, accountID, carrierID string) *apierror.APIError
}

type ServiceLevelSvc

type ServiceLevelSvc interface {
	// ListServiceLevels returns a paginated list of service levels for a carrier.
	ListServiceLevels(ctx context.Context, params ListServiceLevelsParams) (*ListServiceLevelsResult, *apierror.APIError)

	// GetServiceLevel returns a single service level by ID.
	GetServiceLevel(ctx context.Context, carrierID, serviceLevelID string) (*ServiceLevel, *apierror.APIError)

	// CreateServiceLevel creates a new service level.
	CreateServiceLevel(ctx context.Context, params CreateServiceLevelParams) (*ServiceLevel, *apierror.APIError)

	// UpdateServiceLevel partially updates a service level.
	UpdateServiceLevel(ctx context.Context, params UpdateServiceLevelParams) (*ServiceLevel, *apierror.APIError)

	// DeleteServiceLevel deletes a service level.
	DeleteServiceLevel(ctx context.Context, carrierID, serviceLevelID string) *apierror.APIError
}

type Settlement

type Settlement struct {
	ID                  string
	Number              string  `audit:"number"`
	Note                *string `audit:"note"`
	ResponsibleUserID   *string
	ResponsibleUserName *string `audit:"responsible_user_name"`
	Allocations         []*TransactionAllocation
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

Settlement represents a full settlement with expandable allocations.

type SettlementRepo

type SettlementRepo interface {
	List(ctx context.Context, params ListSettlementsParams) (*ListSettlementsResult, *apierror.APIError)
	Get(ctx context.Context, accountID, settlementID string) (*Settlement, *apierror.APIError)
	GetAllocations(ctx context.Context, settlementID string) ([]*TransactionAllocation, *apierror.APIError)
	InsertSettlement(ctx context.Context, id, number string, params CreateSettlementParams) *apierror.APIError
	Update(ctx context.Context, params UpdateSettlementParams) (*Settlement, *apierror.APIError)
	Delete(ctx context.Context, accountID, settlementID string) *apierror.APIError
	IsDuplicateNumber(ctx context.Context, accountID, number string, excludeID *string) (bool, *apierror.APIError)
	CreateAllocation(ctx context.Context, allocationID, quantityID, settlementID, dollarUnitID string, params CreateSettlementAllocationParams) *apierror.APIError
	DeleteAllocations(ctx context.Context, settlementID string) ([]*TransactionAllocation, *apierror.APIError)
	GetAllocationTransactionIDs(ctx context.Context, settlementID string) ([]string, *apierror.APIError)
	GetAllocationInvoiceIDs(ctx context.Context, settlementID string) ([]string, *apierror.APIError)
	// AllocateNextSettlementNumber reserves the account's next settlement number in one locked statement.
	AllocateNextSettlementNumber(ctx context.Context, sysPropertyID, accountID string) (int64, *apierror.APIError)
	GetDollarUnitID(ctx context.Context) (string, *apierror.APIError)
	DeleteOrphanedAdjustmentTransactions(ctx context.Context, settlementID string) *apierror.APIError
	UpdateTransactionsFullyAllocated(ctx context.Context, transactionIDs []string, isFullyAllocated bool) *apierror.APIError
	UpdateInvoicePaymentStatus(ctx context.Context, invoiceID string, isPaidInFull, isOverPaid bool) *apierror.APIError
	GetInvoicePaymentFlags(ctx context.Context, invoiceIDs []string) ([]InvoicePaymentFlags, *apierror.APIError)
}

type SettlementSummary

type SettlementSummary struct {
	ID               string
	Number           string
	AllocationCount  int32
	TotalPayments    *string
	TotalRebates     *string
	TotalAdjustments *string
	TotalCredits     *string
	InvoiceNumbers   []string
	CustomerNames    []string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

SettlementSummary represents a lightweight settlement for list views.

type SettlementSvc

type SettlementSvc interface {
	// ListSettlements returns a paginated list of settlements for the caller's account.
	ListSettlements(ctx context.Context, params ListSettlementsParams) (*ListSettlementsResult, *apierror.APIError)

	// GetSettlement returns a single settlement by ID within the caller's account.
	GetSettlement(ctx context.Context, params GetSettlementParams) (*Settlement, *apierror.APIError)

	// CreateSettlement creates a new settlement with transaction allocations and idempotency support.
	CreateSettlement(ctx context.Context, params CreateSettlementParams) (*Settlement, *apierror.APIError)

	// UpdateSettlement partially updates a settlement with idempotency support.
	UpdateSettlement(ctx context.Context, params UpdateSettlementParams) (*Settlement, *apierror.APIError)

	// DeleteSettlement deletes a settlement and cascades cleanup to allocations, orphaned transactions, and payment statuses.
	DeleteSettlement(ctx context.Context, params DeleteSettlementParams) (*Settlement, *apierror.APIError)
}

type ShipByCommitment

type ShipByCommitment struct {
	ShipByDate   time.Time
	LeadTimeDays int
	SourceCode   string
	// TransitDays is the carrier transit subtracted from a promised delivery date to get ShipByDate, nil when transit was unknown or the commitment came from a lead time.
	TransitDays *int
	// TransitSourceCode names where TransitDays came from, empty when TransitDays is nil.
	TransitSourceCode string
	// ShipByCutoffAt is ShipByDate at the plant's pickup cutoff, nil when the ship calendar carries no cutoff.
	ShipByCutoffAt *time.Time
	// CalendarAdjustmentDays is how many days the receiving and shipping calendars pulled ShipByDate back beyond transit.
	CalendarAdjustmentDays int
	EstimatedDeliveryDate  *time.Time
	// Steps is the ordered derivation, one entry per rule that touched the date. Computed rather than stored: it explains a commitment to whoever is looking at it now, where the stamped scalars are what the commitment itself is made of.
	Steps []CommitmentStep
}

ShipByCommitment is the resolved promise stamped onto an order at issue.

type ShipShipmentParams

type ShipShipmentParams struct {
	AccountID     string
	ShipmentID    string
	EmailCustomer bool
	Includes      []string
}

ShipShipmentParams holds the parameters for shipping a shipment.

type Shipment

type Shipment struct {
	ID                           string
	Number                       string     `audit:"number"`
	Note                         *string    `audit:"note"`
	BillOfLading                 *string    `audit:"bill_of_lading"`
	MasterTrackingNumber         *string    `audit:"master_tracking_number"`
	StatusCode                   string     `audit:"status_code"`
	StatusName                   string     `audit:"status_name"`
	ShippedAt                    *time.Time `audit:"shipped_at"`
	SalesOrderID                 string
	SalesOrderNumber             string
	CustomerPONumber             *string
	CarrierBillingType           *string `audit:"carrier_billing_type"`
	CarrierBillingAccount        *string `audit:"carrier_billing_account"`
	CustomerID                   string
	CustomerName                 string
	CustomerNumber               string
	CustomerStatusCode           *string
	CustomerCommissionPolicy     *string
	CustomerCreatedAt            time.Time
	CustomerUpdatedAt            time.Time
	CarrierID                    string `audit:"carrier_id"`
	CarrierName                  string `audit:"carrier_name"`
	CarrierCode                  *string
	CarrierIsPortalEnabled       *bool
	CarrierCreatedAt             *time.Time
	CarrierUpdatedAt             *time.Time
	ServiceLevelID               *string `audit:"service_level_id"`
	ServiceLevelName             *string `audit:"service_level_name"`
	ServiceLevelToken            *string
	ServiceLevelIsPortalEnabled  *bool
	ServiceLevelCreatedAt        *time.Time
	ServiceLevelUpdatedAt        *time.Time
	ShippingAddressID            string
	ShippingAddressName          *string
	ShippingAddressPhone         *string
	ShippingAddressEmail         *string
	ShippingAddressIsDropShip    *bool
	ShippingAddressGeolocationID *string
	ShippingAddressStreetLine1   *string
	ShippingAddressStreetLine2   *string
	ShippingAddressLocality      *string
	ShippingAddressState         *string
	ShippingAddressPostalCode    *string
	ShippingAddressCountry       *string
	ShippingAddressCreatedAt     *time.Time
	ShippingAddressUpdatedAt     *time.Time
	ShippedByID                  *string `audit:"shipped_by_id"`
	ShippedByName                *string `audit:"shipped_by_name"`
	ShippedByStatusCode          *string
	ShippedByCreatedAt           *time.Time
	ShippedByUpdatedAt           *time.Time
	InvoiceID                    *string
	InvoiceNumber                *string
	InvoiceCreatedAt             *time.Time
	InvoiceUpdatedAt             *time.Time
	PickID                       *string
	PickNumber                   *string
	PickCreatedAt                *time.Time
	PickUpdatedAt                *time.Time
	SalesOrderCreatedAt          time.Time
	SalesOrderUpdatedAt          time.Time
	BillingAddressCountry        *string
	BillingAddressZip            *string
	PriorityCode                 string
	CaseCount                    int64
	// Reports whether the shipment can be shipped now: unshipped, cased, every case weighed.
	IsReadyToShip bool
	AccountID     string
	CreatedAt     time.Time
	UpdatedAt     time.Time

	// Expandable collections
	Lines         []*ShipmentLine
	ShippingCases []*ShippingCase
}

Shipment represents the full detail of a shipment domain model.

type ShipmentLine

type ShipmentLine struct {
	ID                 string
	ShipmentID         string
	SalesOrderLineID   string  `audit:"sales_order_line_id"`
	OrderLineSKU       string  `audit:"order_line_sku"`
	OrderLineDesc      *string `audit:"order_line_desc"`
	OrderLineItemID    *string
	OrderLineProductID *string
	// Position of the sales order line the shipment line fulfills.
	OrderLineItemNumber int32

	// Quantity
	QuantityID               string
	QuantityValue            string `audit:"quantity_value"`
	QuantityUnitID           string `audit:"quantity_unit_id"`
	QuantityUnitName         string `audit:"quantity_unit_name"`
	QuantityUnitAbbreviation string `audit:"quantity_unit_abbreviation"`
	QuantityUnitType         string `audit:"quantity_unit_type"`

	CreatedAt time.Time
	UpdatedAt time.Time
}

ShipmentLine represents a shipment line domain model.

type ShipmentLineRepo

type ShipmentLineRepo interface {
	List(ctx context.Context, params ListShipmentLinesParams) (*ListShipmentLinesResult, *apierror.APIError)
	Get(ctx context.Context, shipmentLineID string) (*ShipmentLine, *apierror.APIError)
	Create(ctx context.Context, id, quantityID string, params CreateShipmentLineEndpointParams) (*ShipmentLine, *apierror.APIError)
	Update(ctx context.Context, params UpdateShipmentLineEndpointParams) (*ShipmentLine, *apierror.APIError)
	Delete(ctx context.Context, shipmentLineID string) *apierror.APIError
	IsInShipment(ctx context.Context, shipmentLineID, shipmentID string) (bool, *apierror.APIError)
	ListByShipment(ctx context.Context, shipmentID string) ([]*ShipmentLine, *apierror.APIError)
	DeleteByShipment(ctx context.Context, shipmentID string) *apierror.APIError
	// GetSalesOrderLineCapacity reports which order a sales order line belongs to and how much of
	// it is still unshipped. excludeShipmentLineID omits the line an update is replacing.
	GetSalesOrderLineCapacity(ctx context.Context, salesOrderLineID string, excludeShipmentLineID *string) (*SalesOrderLineShipmentCapacity, *apierror.APIError)
}

type ShipmentLineSvc

type ShipmentLineSvc interface {
	ListShipmentLines(ctx context.Context, params ListShipmentLinesParams) (*ListShipmentLinesResult, *apierror.APIError)
	GetShipmentLine(ctx context.Context, accountID, shipmentID, shipmentLineID string) (*ShipmentLine, *apierror.APIError)
	CreateShipmentLine(ctx context.Context, params CreateShipmentLineEndpointParams) (*ShipmentLine, *apierror.APIError)
	UpdateShipmentLine(ctx context.Context, params UpdateShipmentLineEndpointParams) (*ShipmentLine, *apierror.APIError)
	DeleteShipmentLine(ctx context.Context, params DeleteShipmentLineEndpointParams) *apierror.APIError
}

type ShipmentRepo

type ShipmentRepo interface {
	List(ctx context.Context, params ListShipmentsParams) (*ListShipmentsResult, *apierror.APIError)
	Get(ctx context.Context, params GetShipmentParams) (*Shipment, *apierror.APIError)
	Update(ctx context.Context, params UpdateShipmentParams) (*Shipment, *apierror.APIError)
	SyncShippingForOrder(ctx context.Context, params SyncShipmentShippingParams) *apierror.APIError
	// SyncShipToForOrder re-points every shipment on an order to the given ship-to address, independently of the carrier.
	SyncShipToForOrder(ctx context.Context, accountID, salesOrderID, shippingAddressID string) *apierror.APIError
	Delete(ctx context.Context, accountID, shipmentID string) *apierror.APIError
	MarkShipped(ctx context.Context, accountID, shipmentID, shippedByID string) *apierror.APIError
	MarkVoided(ctx context.Context, accountID, shipmentID string) *apierror.APIError
	FindInvoiceIDByShipment(ctx context.Context, accountID, shipmentID string) (*string, *apierror.APIError)
	// LinkInvoice points the shipment at the invoice created for it, so void can find it later.
	LinkInvoice(ctx context.Context, accountID, shipmentID, invoiceID string) *apierror.APIError
	// SetMasterTracking stamps the shipment's carrier master tracking number.
	SetMasterTracking(ctx context.Context, accountID, shipmentID, trackingNumber string) *apierror.APIError
	IsInAccount(ctx context.Context, accountID, shipmentID string) (bool, *apierror.APIError)
}

type ShipmentSvc

type ShipmentSvc interface {
	ListShipments(ctx context.Context, params ListShipmentsParams) (*ListShipmentsResult, *apierror.APIError)
	GetShipment(ctx context.Context, params GetShipmentParams) (*Shipment, *apierror.APIError)
	UpdateShipment(ctx context.Context, params UpdateShipmentParams) (*Shipment, *apierror.APIError)
	// AdminUpdateShipmentTracking corrects the tracking and routing of a shipment that has already shipped.
	AdminUpdateShipmentTracking(ctx context.Context, params AdminUpdateShipmentTrackingParams) (*Shipment, *apierror.APIError)
	DeleteShipment(ctx context.Context, params DeleteShipmentParams) *apierror.APIError
	ShipShipment(ctx context.Context, params ShipShipmentParams) (*Shipment, *apierror.APIError)
	VoidShipment(ctx context.Context, params VoidShipmentParams) (*Shipment, *apierror.APIError)
	EstimateRate(ctx context.Context, params EstimateRateParams) (float64, *apierror.APIError)
	RateShop(ctx context.Context, params RateShopParams) (*RateShopResult, *apierror.APIError)
}

type ShippingAddress

type ShippingAddress struct {
	Name    string
	Company *string
	Street1 string
	Street2 *string
	City    string
	State   string
	Zip     string
	Country string
	Phone   *string
	Email   *string
	// Timezone is the stored IANA zone for this address, nil when it has not been resolved. Carried so a commitment can read a promised delivery instant as a local date rather than a UTC one.
	Timezone *string
}

ShippingAddress is a simplified address for rate estimation.

func (ShippingAddress) IsEmpty

func (a ShippingAddress) IsEmpty() bool

IsEmpty reports whether no meaningful address was provided, so callers can fall back to a resolved origin.

type ShippingBilling

type ShippingBilling struct {
	// Type is the Shippo billing type, e.g. "THIRD_PARTY".
	Type    string
	Account string
	Country string
	Zip     string
}

ShippingBilling carries third-party freight-billing details passed through to the carrier (Shippo) when the order is billed to a third party.

type ShippingCase

type ShippingCase struct {
	ID                  string
	Number              string  `audit:"number"`
	SSCC                *string `audit:"sscc"`
	TrackingNumber      *string `audit:"tracking_number"`
	ShippoTransactionID *string
	ShippingLabelURL    *string
	ShippedAt           *time.Time `audit:"shipped_at"`
	// Freight amount quantity
	FreightAmountID                    string
	FreightAmountValue                 string `audit:"freight_amount_value"`
	FreightAmountUnitID                string `audit:"freight_amount_unit_id"`
	FreightAmountUnitName              string
	FreightAmountUnitAbbreviation      string
	FreightAmountUnitType              string
	FreightAmountUnitRatioNumerator    string
	FreightAmountUnitRatioDenominator  string
	FreightAmountUnitOffsetNumerator   string
	FreightAmountUnitOffsetDenominator string
	FreightAmountUnitCreatedAt         time.Time
	FreightAmountUnitUpdatedAt         time.Time
	// Freight weight quantity
	FreightWeightID                    string
	FreightWeightValue                 string `audit:"freight_weight_value"`
	FreightWeightUnitID                string `audit:"freight_weight_unit_id"`
	FreightWeightUnitName              string
	FreightWeightUnitAbbreviation      string
	FreightWeightUnitType              string
	FreightWeightUnitRatioNumerator    string
	FreightWeightUnitRatioDenominator  string
	FreightWeightUnitOffsetNumerator   string
	FreightWeightUnitOffsetDenominator string
	FreightWeightUnitCreatedAt         time.Time
	FreightWeightUnitUpdatedAt         time.Time
	// Relations
	ShipmentID             string
	ShipmentNumber         string
	ShipmentStatusCode     string
	ShipmentStatusName     string
	ShipmentCreatedAt      time.Time
	ShipmentUpdatedAt      time.Time
	CarrierID              string `audit:"carrier_id"`
	CarrierName            string
	CarrierIsPortalEnabled bool
	CarrierCreatedAt       time.Time
	CarrierUpdatedAt       time.Time
	AccountID              string
	CreatedAt              time.Time
	UpdatedAt              time.Time
}

ShippingCase represents a shipping case domain model with joined fields for reads.

type ShippingCaseLabelURL

type ShippingCaseLabelURL struct {
	URL *string
}

ShippingCaseLabelURL represents a label URL response for a shipping case.

type ShippingCaseRepo

type ShippingCaseRepo interface {
	Get(ctx context.Context, accountID, shippingCaseID string) (*ShippingCase, *apierror.APIError)
	Update(ctx context.Context, params UpdateShippingCaseParams) *apierror.APIError
	// RepointToCarrier moves every case on a shipment onto the given carrier, so per-case tracking deep-links keep resolving against the carrier that actually carries them.
	RepointToCarrier(ctx context.Context, accountID, shipmentID, carrierID string) *apierror.APIError
	Delete(ctx context.Context, accountID, shippingCaseID string) *apierror.APIError
	IsInAccount(ctx context.Context, accountID, shippingCaseID string) (bool, *apierror.APIError)
	GetNumber(ctx context.Context, accountID, shippingCaseID string) (string, *apierror.APIError)
	// GetSalesOrderID walks the case to its order, so audit events can stamp that order as their root.
	GetSalesOrderID(ctx context.Context, accountID, shippingCaseID string) (string, *apierror.APIError)
	ListByShipment(ctx context.Context, shipmentID string) ([]*ShippingCase, *apierror.APIError)
	MarkShippedByShipment(ctx context.Context, shipmentID string) *apierror.APIError
	VoidByShipment(ctx context.Context, shipmentID string) *apierror.APIError
	UpdateWithShipmentInfo(ctx context.Context, shippingCaseID, trackingNumber, shippoTransactionID, shippingLabelURL string) *apierror.APIError
	AddSscc(ctx context.Context, shippingCaseID, sscc string) *apierror.APIError
	FindAndIncrementSsccCounter(ctx context.Context, accountID string) (int64, *apierror.APIError)
	DeleteByShipment(ctx context.Context, shipmentID string) *apierror.APIError
}

type ShippingCaseSvc

type ShippingCaseSvc interface {
	GetShippingCase(ctx context.Context, accountID, shippingCaseID string) (*ShippingCase, *apierror.APIError)
	UpdateShippingCase(ctx context.Context, params UpdateShippingCaseParams) (*ShippingCase, *apierror.APIError)
	// AdminUpdateShippingCaseTracking corrects the tracking number of a case that has already shipped.
	AdminUpdateShippingCaseTracking(ctx context.Context, params AdminUpdateShippingCaseTrackingParams) (*ShippingCase, *apierror.APIError)
	DeleteShippingCase(ctx context.Context, accountID, shippingCaseID string) *apierror.APIError
	GetShippingCaseLabel(ctx context.Context, accountID, shippingCaseID string) (*string, *apierror.APIError)
}

type ShippingTerm

type ShippingTerm struct {
	ID                          string
	Name                        string                     `audit:"name"`
	Type                        constants.ShippingTermType `audit:"type"`
	FlatRate                    *Quantity                  `audit:"flat_rate"`
	MinimumOrderValue           *Quantity                  `audit:"minimum_order_value"`
	FreeShippingServiceLevelIDs []string                   `audit:"free_shipping_service_level_ids"`
	FreeShippingServiceLevels   []*ServiceLevel            `audit:"-"`
	AccountID                   *string
	CreatedAt                   time.Time
	UpdatedAt                   time.Time
}

type ShippingTermRepo

type ShippingTermRepo interface {
	List(ctx context.Context, params ListShippingTermsParams) (*ListShippingTermsResult, *apierror.APIError)
	Get(ctx context.Context, params GetShippingTermParams) (*ShippingTerm, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*ShippingTerm, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateShippingTermParams) (*ShippingTerm, *apierror.APIError)
	Update(ctx context.Context, params UpdateShippingTermParams) (*ShippingTerm, *apierror.APIError)
	Delete(ctx context.Context, params DeleteShippingTermParams) *apierror.APIError
	InsertQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	UpdateQuantity(ctx context.Context, id, value, unitID string) *apierror.APIError
	DeleteQuantity(ctx context.Context, id string) *apierror.APIError
	InsertFreeShippingRule(ctx context.Context, id, shippingTermID, serviceLevelID string) *apierror.APIError
	DeleteFreeShippingRulesByShippingTermID(ctx context.Context, shippingTermID string) *apierror.APIError
}

type ShippingTermSvc

type ShippingTermSvc interface {
	// ListShippingTerms returns a paginated list of shipping terms visible to the caller's account. Includes both account-specific and default (system) shipping terms.
	ListShippingTerms(ctx context.Context, params ListShippingTermsParams) (*ListShippingTermsResult, *apierror.APIError)

	// GetShippingTerm returns a single shipping term by ID. The shipping term must belong to the caller's account or be a default (global) shipping term.
	GetShippingTerm(ctx context.Context, params GetShippingTermParams) (*ShippingTerm, *apierror.APIError)

	// CreateShippingTerm creates a new account-owned shipping term.
	CreateShippingTerm(ctx context.Context, params CreateShippingTermParams) (*ShippingTerm, *apierror.APIError)

	// UpdateShippingTerm partially updates an account-owned shipping term. Default shipping terms cannot be updated.
	UpdateShippingTerm(ctx context.Context, params UpdateShippingTermParams) (*ShippingTerm, *apierror.APIError)

	// DeleteShippingTerm deletes an account-owned shipping term. Default shipping terms cannot be deleted.
	DeleteShippingTerm(ctx context.Context, shippingTermID string) *apierror.APIError

	// BatchGetShippingTermsByIDs returns shipping terms matching the given IDs that the caller's account is authorized to read.
	BatchGetShippingTermsByIDs(ctx context.Context, ids []string) ([]*ShippingTerm, *apierror.APIError)
}

type ShippoCarrierAccount

type ShippoCarrierAccount struct {
	ObjectID        string
	Carrier         string
	AccountID       string
	Active          bool
	IsShippoAccount bool
}

ShippoCarrierAccount represents a carrier account registered with Shippo.

type ShippoClient

type ShippoClient interface {
	FindOrRegisterCarrierAccount(ctx context.Context, carrier string) (*ShippoCarrierAccount, *apierror.APIError)
	ConnectCarrierAccount(ctx context.Context, carrier, accountID string, params map[string]string) (*ShippoCarrierAccount, *apierror.APIError)
	GetCarrierAccount(ctx context.Context, objectID string) (*ShippoCarrierAccount, *apierror.APIError)
	DeactivateCarrierAccount(ctx context.Context, objectID string) *apierror.APIError
	GetCarrierServiceLevels(ctx context.Context, objectID string) ([]ShippoServiceLevel, *apierror.APIError)
	InitiateOAuth(ctx context.Context, objectID, redirectURI string, state *string) (string, *apierror.APIError)
	FetchShippingRate(ctx context.Context, params FetchShippingRateParams) (float64, *apierror.APIError)
	FetchAllShippingRates(ctx context.Context, params FetchAllShippingRatesParams) ([]ShippoRateOption, *apierror.APIError)
	// CreateTransactionInstantLabel buys carrier labels for a shipment's cases and returns the
	// master tracking number, negotiated rate, and per-case tracking/label details.
	CreateTransactionInstantLabel(ctx context.Context, params CreateLabelParams) (*LabelResult, *apierror.APIError)
	// RefundTransaction refunds a purchased Shippo label transaction (best-effort; used on void).
	RefundTransaction(ctx context.Context, transactionID string) *apierror.APIError
}

ShippoClient defines the interface for interacting with the Shippo API.

type ShippoClientFactory

type ShippoClientFactory interface {
	Build(apiKey string) ShippoClient
}

Builds ShippoClient instances from API keys.

type ShippoCredentials

type ShippoCredentials struct {
	APIKey string `json:"api_key"` // #nosec G117 -- field carries encrypted credentials, not a hardcoded secret
}

ShippoCredentials holds the parsed Shippo credential fields used for validation.

func (*ShippoCredentials) UnmarshalJSON

func (c *ShippoCredentials) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts both the canonical snake_case key and the legacy camelCase key (apiKey) so legacy and v2 stored credentials can be read interchangeably.

type ShippoRateOption

type ShippoRateOption struct {
	ServiceLevelName  string
	ServiceLevelToken string
	Amount            float64
	EstimatedDays     *int32
}

ShippoRateOption represents a rate from a Shippo rate response.

type ShippoServiceLevel

type ShippoServiceLevel struct {
	Name  string
	Token string
}

ShippoServiceLevel represents a service level returned by Shippo.

type SkippedItem

type SkippedItem struct {
	SKU    string
	Reason string
}

SkippedItem represents an item that was skipped during reconciliation.

type SplitBatchParams

type SplitBatchParams struct {
	BatchIDs          []string
	ScanningStationID string
	ProductionStepID  string
	Firsts            BatchQuantity
	Seconds           *BatchQuantity
	Waste             *BatchQuantity
	CloseBatch        bool
}

SplitBatchParams holds the parameters for splitting a batch.

type StartHubspotBackfillParams

type StartHubspotBackfillParams struct {
	GoLiveCutoffAt *time.Time
}

StartHubspotBackfillParams starts a backfill. GoLiveCutoffAt bounds which historical orders become deals (nil = no deal backfill).

type StartJobParams

type StartJobParams struct {
	JobID string
}

type StepConsumption

type StepConsumption struct {
	ID            string
	ConsumedItem  LightItem
	Quantity      BatchQuantity
	WasteQuantity BatchQuantity
	Instructions  *string
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

StepConsumption represents a single consumption of a production step.

type StepConsumptionRow

type StepConsumptionRow struct {
	ProductionStepID string
	ItemID           string
}

StepConsumptionRow is one input item a production step consumes.

type StepEdge

type StepEdge struct {
	ParentStepID string `audit:"parent_step_id"`
	ChildStepID  string `audit:"child_step_id"`
}

StepEdge represents a parent→child edge in the production step graph.

type StepGraph

type StepGraph struct {
	Edges []scheduling.StepEdge
	Steps map[string]scheduling.StepInfo
}

StepGraph is the production-step DAG plus the metadata the explosion needs.

type StepProduction

type StepProduction struct {
	ID           string
	ProducedItem LightItem
	Quantity     BatchQuantity
}

StepProduction represents the output of a production step.

type StockReceivingOrderParams

type StockReceivingOrderParams struct {
	AccountID        string
	ReceivingOrderID string
	Data             StockingData
}

StockReceivingOrderParams holds parameters for stocking a receiving order.

type StockingData

type StockingData struct {
	LineItems []StockingLineItem
}

StockingData contains the stocking data sent in the request body.

type StockingLineItem

type StockingLineItem struct {
	ReceivingOrderLineID string
	LotNumber            *string
	RejectedQuantity     *decimal.Decimal
	Allocations          []StorageAllocation
}

StockingLineItem represents a single line item in a stocking request.

type StorageAllocation

type StorageAllocation struct {
	LocationID *string
	Quantity   decimal.Decimal
}

StorageAllocation represents a storage allocation for a stocking line item.

type StripeCheckoutClient

type StripeCheckoutClient interface {
	CreateOneTimeCheckoutSession(ctx context.Context, params CreateCheckoutSessionParams) (*StripeCheckoutSession, *apierror.APIError)
	CreateEmbeddedCheckoutSession(ctx context.Context, params CreateEmbeddedCheckoutSessionParams) (*StripeEmbeddedCheckoutSession, *apierror.APIError)
	CreateStripeCustomer(ctx context.Context, params CreateStripeCustomerParams) (*StripeCustomer, *apierror.APIError)
	// UpdateStripeCustomer pushes changed customer details onto an existing Stripe customer. Nil fields are left untouched.
	UpdateStripeCustomer(ctx context.Context, params UpdateStripeCustomerParams) *apierror.APIError
	ConstructWebhookEvent(payload []byte, signature, webhookSecret string) (*StripeWebhookEvent, *StripePaymentIntent, *apierror.APIError)
	// ListPayoutPaymentIntentIDs resolves the payment intent IDs whose charges fund the given payout, by walking the payout's balance transactions (called on payout.paid to stamp funds_received_at).
	ListPayoutPaymentIntentIDs(ctx context.Context, payoutID string) ([]string, *apierror.APIError)
}

StripeCheckoutClient provides Stripe checkout session creation for per-account Stripe integrations.

type StripeCheckoutClientFactory

type StripeCheckoutClientFactory interface {
	Build(apiKey string) StripeCheckoutClient
}

StripeCheckoutClientFactory builds StripeCheckoutClient instances from API keys.

type StripeCheckoutSession

type StripeCheckoutSession struct {
	URL string
}

StripeCheckoutSession represents the result of creating a Stripe checkout session.

type StripeCredentials

type StripeCredentials struct {
	PrivateKey     string `json:"private_key"` // #nosec G117 -- field carries encrypted credentials, not a hardcoded secret
	PublishableKey string `json:"publishable_key"`
	WebhookSecret  string `json:"webhook_secret"`
}

StripeCredentials holds the parsed Stripe credential fields used for validation.

func (*StripeCredentials) UnmarshalJSON

func (c *StripeCredentials) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts both the canonical snake_case keys and the legacy camelCase keys (privateKey/publishableKey/webhookSecret) so credentials stored by the legacy dashboard and the v2 Go service can be read interchangeably while both write paths coexist.

type StripeCustomer

type StripeCustomer struct {
	ID string
}

StripeCustomer represents a Stripe customer.

type StripeEmbeddedCheckoutSession

type StripeEmbeddedCheckoutSession struct {
	ClientSecret string // #nosec G117 -- Stripe ephemeral client secret
}

StripeEmbeddedCheckoutSession represents an embedded Stripe checkout session result.

type StripeEventLog

type StripeEventLog struct {
	ID        string
	EventID   string
	ObjectID  string
	EventType string
}

StripeEventLog represents a deduplicated record of a processed Stripe event.

type StripeEventLogRepo

type StripeEventLogRepo interface {
	Exists(ctx context.Context, eventID, objectID string) (bool, *apierror.APIError)
	Create(ctx context.Context, id, eventID, objectID, eventType string) *apierror.APIError
}

type StripePaymentIntent

type StripePaymentIntent struct {
	ID                 string
	Amount             int64
	PaymentMethodTypes []string
	Metadata           map[string]string
}

StripePaymentIntent represents a Stripe payment intent extracted from a webhook event.

type StripeWebhookEvent

type StripeWebhookEvent struct {
	ID      string
	Type    string
	RawJSON []byte
}

StripeWebhookEvent represents a parsed Stripe webhook event.

type StripeWebhookSvc

type StripeWebhookSvc interface {
	HandleAccountStripeWebhook(ctx context.Context, params HandleStripeWebhookParams) *apierror.APIError
}

type SubResourceRef

type SubResourceRef struct {
	ResourceType constants.ObjectType
	ID           string
	Name         *string
}

references one resource produced alongside a result row's own — a production run's batches, say.

func NewSubResourceRefs

func NewSubResourceRefs(resourceType constants.ObjectType, ids []string) []SubResourceRef

NewSubResourceRefs tags a run of ids produced by one row with the object type they all share, which is every case that has come up: a row's sub-resources are siblings.

type SubmitFeedbackParams

type SubmitFeedbackParams struct {
	Question string
	Answer   string
	PageURL  *string
}

SubmitFeedbackParams holds parameters for submitting user feedback.

type SumActualsByWeekParams

type SumActualsByWeekParams struct {
	AccountID   string
	WindowStart time.Time
	WindowEnd   time.Time
}

SumActualsByWeekParams scopes the actuals read to an account and scan window.

type SumPlannedByWeekParams

type SumPlannedByWeekParams struct {
	AccountID            string
	ProductionScheduleID string
	WindowStart          time.Time
	WindowEnd            time.Time
}

SumPlannedByWeekParams scopes the planned read to one baseline version within the window.

type Supplier

type Supplier struct {
	ID            string
	Name          string           `audit:"name"`
	Number        string           `audit:"number"`
	Note          *string          `audit:"note"`
	BillToAddress *CustomerAddress `audit:"bill_to_address"`
	ShipToAddress *CustomerAddress `audit:"ship_to_address"`
	MaterialCount int64
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

Supplier represents a full supplier record.

type SupplierMaterial

type SupplierMaterial struct {
	ID                  string
	MaterialID          string
	SupplierAccountID   string
	SupplierPartNumber  string  `audit:"supplier_part_number"`
	SupplierDescription *string `audit:"supplier_description"`
	IsActive            bool    `audit:"is_active"`
	OwnerAccountID      string
	CreatedAt           time.Time
	UpdatedAt           time.Time

	// Joined
	Material *Material
}

SupplierMaterial represents a link between a supplier and a material.

type SupplierMaterialRepo

type SupplierMaterialRepo interface {
	List(ctx context.Context, params ListSupplierMaterialsParams) (*ListSupplierMaterialsResult, *apierror.APIError)
	GetBySupplierAndMaterialID(ctx context.Context, ownerAccountID, supplierAccountID, materialID string) (*SupplierMaterial, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateSupplierMaterialParams) (*SupplierMaterial, *apierror.APIError)
	Update(ctx context.Context, params UpdateSupplierMaterialParams) (*SupplierMaterial, *apierror.APIError)
	Delete(ctx context.Context, params DeleteSupplierMaterialParams) (*SupplierMaterial, *apierror.APIError)
	ExistsByMaterialAndSupplier(ctx context.Context, ownerAccountID, materialID, supplierAccountID string) (bool, *apierror.APIError)
}

type SupplierMaterialSvc

type SupplierMaterialSvc interface {
	// ListSupplierMaterials returns a paginated list of supplier materials.
	ListSupplierMaterials(ctx context.Context, params ListSupplierMaterialsParams) (*ListSupplierMaterialsResult, *apierror.APIError)

	// GetSupplierMaterial returns a single supplier material by supplier and material ID.
	GetSupplierMaterial(ctx context.Context, supplierAccountID, materialID string) (*SupplierMaterial, *apierror.APIError)

	// CreateSupplierMaterial creates a new supplier material association.
	CreateSupplierMaterial(ctx context.Context, params CreateSupplierMaterialParams) (*SupplierMaterial, *apierror.APIError)

	// UpdateSupplierMaterial partially updates a supplier material.
	UpdateSupplierMaterial(ctx context.Context, params UpdateSupplierMaterialParams) (*SupplierMaterial, *apierror.APIError)

	// DeleteSupplierMaterial deletes a supplier material association.
	DeleteSupplierMaterial(ctx context.Context, params DeleteSupplierMaterialParams) (*SupplierMaterial, *apierror.APIError)
}

type SupplierNameMatch

type SupplierNameMatch struct {
	AccountID string
	Name      string
}

SupplierNameMatch maps a supplier's display name to its account ID within the owner account. Used by bulk upsert to resolve supplier names.

type SupplierRepo

type SupplierRepo interface {
	List(ctx context.Context, params ListSuppliersParams) (*ListSuppliersResult, *apierror.APIError)
	Get(ctx context.Context, params GetSupplierParams) (*Supplier, *apierror.APIError)
	Create(ctx context.Context, accountID, relationID string, params CreateSupplierParams, billToAddressID, shipToAddressID *string) (*Supplier, *apierror.APIError)
	Update(ctx context.Context, params UpdateSupplierParams) (*Supplier, *apierror.APIError)
	Delete(ctx context.Context, ownerAccountID, supplierAccountID string) (*Supplier, *apierror.APIError)
	BulkDelete(ctx context.Context, ownerAccountID string, supplierAccountIDs []string) *apierror.APIError
	ExistsByNumber(ctx context.Context, ownerAccountID, number string, excludeID *string) (bool, *apierror.APIError)
	// FindByNames resolves supplier display names to supplier account IDs within the
	// owner account (case-insensitive). Used by bulk upsert to attach existing suppliers.
	FindByNames(ctx context.Context, ownerAccountID string, names []string) ([]*SupplierNameMatch, *apierror.APIError)
}

type SupplierSummary

type SupplierSummary struct {
	ID            string
	Name          string
	Number        string
	MaterialCount int64
	CreatedAt     time.Time
}

SupplierSummary is a lightweight supplier record for list results.

type SupplierSvc

type SupplierSvc interface {
	ListSuppliers(ctx context.Context, params ListSuppliersParams) (*ListSuppliersResult, *apierror.APIError)
	GetSupplier(ctx context.Context, params GetSupplierParams) (*Supplier, *apierror.APIError)
	CreateSupplier(ctx context.Context, params CreateSupplierParams) (*Supplier, *apierror.APIError)
	UpdateSupplier(ctx context.Context, params UpdateSupplierParams) (*Supplier, *apierror.APIError)
	DeleteSupplier(ctx context.Context, params DeleteSupplierParams) (*Supplier, *apierror.APIError)
	BulkDeleteSuppliers(ctx context.Context, params BulkDeleteSuppliersParams) *apierror.APIError
}

type SyncShipmentShippingParams

type SyncShipmentShippingParams struct {
	AccountID         string
	SalesOrderID      string
	CarrierID         string
	ServiceLevelID    *string
	ShippingAddressID string
}

SyncShipmentShippingParams re-points every shipment on an order to the order's current carrier, service level, and ship-to. Used by the out-of-band shipping-updated consumer.

type SyncStripeCustomerEvent

type SyncStripeCustomerEvent struct {
	// OwnerAccountID is the merchant account whose Stripe integration is written to.
	OwnerAccountID string `json:"owner_account_id"`
	// CustomerAccountID is the counterparty account being synced.
	CustomerAccountID string `json:"customer_account_id"`
}

SyncStripeCustomerEvent is the outbox command payload for reconciling one customer with the account's connected Stripe integration.

It carries identifiers only, never the field values that triggered it: the consumer re-reads the customer at handling time, so a burst of edits collapses into the same final state instead of racing stale snapshots onto Stripe in arbitrary delivery order.

type SysProperty

type SysProperty struct {
	ID        string
	TypeID    string
	TypeCode  constants.SysPropertyTypeCode `audit:"type_code"`
	TypeName  string                        `audit:"type_name"`
	Value     int32                         `audit:"value"`
	AccountID string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type SysPropertyRepo

type SysPropertyRepo interface {
	List(ctx context.Context, params ListSysPropertiesParams) (*ListSysPropertiesResult, *apierror.APIError)
	Get(ctx context.Context, accountID, id string) (*SysProperty, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*SysProperty, *apierror.APIError)
	GetByTypeCode(ctx context.Context, accountID string, typeCode constants.SysPropertyTypeCode) (*SysProperty, *apierror.APIError)
	Create(ctx context.Context, id, accountID string, typeCode constants.SysPropertyTypeCode, value int32) (*SysProperty, *apierror.APIError)
	UpdateValue(ctx context.Context, accountID, id string, value int32) (*SysProperty, *apierror.APIError)
	IncrementValue(ctx context.Context, accountID, id string) (*SysProperty, *apierror.APIError)
	IsDuplicate(ctx context.Context, accountID string, typeCode constants.SysPropertyTypeCode, value string) (bool, *apierror.APIError)
}

type SysPropertySvc

type SysPropertySvc interface {
	ListSysProperties(ctx context.Context, params ListSysPropertiesParams) (*ListSysPropertiesResult, *apierror.APIError)
	GetSysProperty(ctx context.Context, sysPropertyID string) (*SysProperty, *apierror.APIError)
	GetSysPropertyValue(ctx context.Context, code string) (*SysPropertyValue, *apierror.APIError)
	GetLatestSysPropertyValue(ctx context.Context, typeCode constants.SysPropertyTypeCode) (string, *apierror.APIError)
	UpdateSysProperty(ctx context.Context, params UpdateSysPropertyParams) (*SysProperty, *apierror.APIError)

	// BatchGetSysPropertiesByIDs returns sys properties matching the input IDs. Used by the api-gateway resourcekit include resolver.
	BatchGetSysPropertiesByIDs(ctx context.Context, ids []string) ([]*SysProperty, *apierror.APIError)
}

type SysPropertyValue

type SysPropertyValue struct {
	Value string
}

SysPropertyValue represents a serialized sys property value response.

type SystemProductInfo

type SystemProductInfo struct {
	ProductID          string
	ProductSKU         string
	ProductDescription *string
	QuantityUnitID     string
}

SystemProductInfo holds the minimal info needed to synthesize an order line using one of the account's built-in system products (credit, shipping).

type Tenancy

type Tenancy struct {
	HasTenancy          bool
	CurrentAccount      *TenancyCurrentAccount
	Sandboxes           []TenancySandbox
	OwnerAccount        *TenancyOwnerAccount
	OtherAccounts       []TenancyOtherAccount
	PendingRegistration *TenancyPendingRegistration
}

Tenancy is the resolved multi-tenant context for a user.

type TenancyAccount

type TenancyAccount struct {
	AccountID                string
	AccountName              string
	AccountTypeCode          string
	OnboardingStatusCode     string
	PlanCode                 string
	RoleID                   *string
	RoleName                 *string
	RoleType                 *string
	RoleCreatedAt            *time.Time
	RoleUpdatedAt            *time.Time
	AccountUserID            string
	AccountUserStatusCode    string
	LastUsedAt               *time.Time
	OwnerAccountID           *string
	InternalStripeCustomerID *string
	Plan                     *TenancyAccountPlanSummary
}

TenancyAccount represents an enriched account row from the tenancy query, containing all fields needed for tenancy resolution.

type TenancyAccountPlan

type TenancyAccountPlan struct {
	TypeID        string
	Name          string
	PlanTypeCode  string
	Version       int32
	PricePerSeat  float64
	PricePerMonth *float64
	SeatMinimum   *int32
	// Keys are limit codes, values are the limit int (nil = unlimited).
	Limits map[string]*int32
	// Keys are feature codes, values indicate whether the feature is enabled.
	Features map[string]bool
}

TenancyAccountPlan is the fully-resolved plan for the current account, including its limits and features.

type TenancyAccountPlanSummary

type TenancyAccountPlanSummary struct {
	TypeID        string
	Name          string
	PlanTypeCode  string
	Version       int32
	PricePerSeat  float64
	PricePerMonth *float64
	SeatMinimum   *int32
}

TenancyAccountPlanSummary is the inline plan data returned by the tenancy query, before limits/features have been joined in.

type TenancyCurrentAccount

type TenancyCurrentAccount struct {
	ID                       string
	Name                     string
	Type                     string
	OnboardingStatus         string
	PlanCode                 string
	Slug                     *string
	Role                     *TenancyRole
	InternalStripeCustomerID *string
	AccountPlan              *TenancyAccountPlan
	AccountUserID            string
}

TenancyCurrentAccount represents the user's active account.

type TenancyOtherAccount

type TenancyOtherAccount struct {
	ID   string
	Name string
	Type string
}

TenancyOtherAccount represents another accessible account.

type TenancyOwnerAccount

type TenancyOwnerAccount struct {
	ID   string
	Name string
}

TenancyOwnerAccount represents the owner (production) account summary.

type TenancyPendingRegistration

type TenancyPendingRegistration struct {
	SessionID string
	PlanCode  string
	Step      string
	CreatedAt time.Time
}

TenancyPendingRegistration represents an in-progress registration session for the authenticated user.

type TenancyRole

type TenancyRole struct {
	ID          string
	Name        string
	RoleType    string
	Permissions []string
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

TenancyRole represents the user's role on the current account.

type TenancySandbox

type TenancySandbox struct {
	ID   string
	Name string
}

TenancySandbox represents a sandbox account summary.

type TenancySvc

type TenancySvc interface {
	GetTenancy(ctx context.Context, userID string, targetAccountID *string) (*Tenancy, *apierror.APIError)
	SwitchAccount(ctx context.Context, userID, accountID string) (*Tenancy, *apierror.APIError)
	GetCurrentUser(ctx context.Context, userID string, targetAccountID *string) (*UserRecord, *apierror.APIError)
	ListCustomerAccountsForUser(ctx context.Context, userID, vendorAccountID string) ([]CustomerAccountSummary, *apierror.APIError)
}

type Territory

type Territory struct {
	ID           string
	State        string `audit:"state"`
	StartZipcode *int32 `audit:"start_zipcode"`
	EndZipcode   *int32 `audit:"end_zipcode"`
	SalesRepID   string
	SalesRep     *TerritorySalesRep    `audit:"sales_rep"`
	ProductLine  *TerritoryProductLine `audit:"product_line"`
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

Territory represents a sales rep territory assignment.

type TerritoryProductLine

type TerritoryProductLine struct {
	ID               string
	Name             string
	CommissionPolicy *constants.CommissionPolicy
	FreightPolicy    *constants.FreightPolicy
	CreatedAt        *time.Time
	UpdatedAt        *time.Time
}

TerritoryProductLine represents the product line sub-resource within a territory.

type TerritoryRepo

type TerritoryRepo interface {
	List(ctx context.Context, params ListTerritoriesParams) (*ListTerritoriesResult, *apierror.APIError)
	Get(ctx context.Context, params GetTerritoryParams) (*Territory, *apierror.APIError)
	Create(ctx context.Context, territoryID string, params CreateTerritoryParams) (*Territory, *apierror.APIError)
	Update(ctx context.Context, params UpdateTerritoryParams) (*Territory, *apierror.APIError)
	Delete(ctx context.Context, params DeleteTerritoryParams) *apierror.APIError
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Territory, *apierror.APIError)
	IsInAccount(ctx context.Context, accountID, territoryID string) (bool, *apierror.APIError)
	// FindSalesRepByZipcode returns the sales_rep (account_user) ID for the territory whose zipcode range includes the given zipcode, if any.
	FindSalesRepByZipcode(ctx context.Context, accountID string, zipcode int32) (*string, *apierror.APIError)
	// FindSalesRepByState returns the sales_rep (account_user) ID for the state-only territory matching the given state, if any.
	FindSalesRepByState(ctx context.Context, accountID, state string) (*string, *apierror.APIError)
}

type TerritorySalesRep

type TerritorySalesRep struct {
	ID        string
	Name      *string
	Email     *string
	Status    *constants.AccountUserStatus
	CreatedAt *time.Time
	UpdatedAt *time.Time
}

TerritorySalesRep represents the sales rep sub-resource within a territory.

type TerritorySvc

type TerritorySvc interface {
	ListTerritories(ctx context.Context, params ListTerritoriesParams) (*ListTerritoriesResult, *apierror.APIError)
	GetTerritory(ctx context.Context, params GetTerritoryParams) (*Territory, *apierror.APIError)
	CreateTerritory(ctx context.Context, params CreateTerritoryParams) (*Territory, *apierror.APIError)
	UpdateTerritory(ctx context.Context, params UpdateTerritoryParams) (*Territory, *apierror.APIError)
	DeleteTerritory(ctx context.Context, params DeleteTerritoryParams) *apierror.APIError
	BatchGetTerritoriesByIDs(ctx context.Context, ids []string) ([]*Territory, *apierror.APIError)
}

type Transaction

type Transaction struct {
	ID                        string
	Number                    string `audit:"number"`
	AmountID                  string
	AmountValue               string `audit:"amount_value"`
	AmountUnitID              string
	AmountUnitAbbr            string
	CustomerID                *string `audit:"customer_id"`
	CustomerName              *string
	CustomerNumber            *string
	CustomerStatusCode        *string
	CustomerCommissionPolicy  *string
	CustomerCreatedAt         *time.Time
	CustomerUpdatedAt         *time.Time
	ResponsibleUserID         *string `audit:"responsible_user_id"`
	ResponsibleUserName       *string
	ResponsibleUserStatusCode *string
	ResponsibleUserCreatedAt  *time.Time
	ResponsibleUserUpdatedAt  *time.Time
	Note                      *string `audit:"note"`
	TransactionTypeCode       string  `audit:"transaction_type_code"`
	TransactionTypeName       string
	TransactionTypeID         string
	TransactionMethodCode     *string `audit:"transaction_method_code"`
	TransactionMethodName     *string
	TransactionMethodID       *string
	AdjustmentTypeCode        *string `audit:"adjustment_type_code"`
	AdjustmentTypeName        *string
	AdjustmentTypeID          *string
	IsFullyAllocated          bool    `audit:"is_fully_allocated"`
	StripePaymentID           *string `audit:"stripe_payment_id"`
	AllocationCount           int32
	Allocations               []*TransactionAllocation
	CreatedAt                 time.Time
	UpdatedAt                 time.Time
}

Transaction represents a full transaction with all related data.

type TransactionAllocation

type TransactionAllocation struct {
	ID                string
	AmountID          string
	AmountValue       string `audit:"amount_value"`
	AmountUnitID      string
	AmountUnitAbbr    string  `audit:"amount_unit_abbr"`
	Note              *string `audit:"note"`
	TransactionID     string
	TransactionNumber string `audit:"transaction_number"`
	TransactionType   string `audit:"transaction_type"`
	InvoiceID         string
	InvoiceNumber     string `audit:"invoice_number"`
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

TransactionAllocation represents an allocation of a transaction against an invoice within a settlement.

type TransactionAllocationRepo

type TransactionAllocationRepo interface {
	ListEntries(ctx context.Context, params ListAllocationEntriesParams) (*ListAllocationEntriesResult, *apierror.APIError)
	GetByID(ctx context.Context, accountID, allocationID string) (*TransactionAllocation, *apierror.APIError)
	UpdateAmount(ctx context.Context, amountID, newValue string) *apierror.APIError
	Delete(ctx context.Context, accountID, allocationID string) *apierror.APIError
	ListOpenCredits(ctx context.Context, params ListOpenCreditsParams) (*ListOpenCreditsResult, *apierror.APIError)
	GetDollarUnitID(ctx context.Context) (string, *apierror.APIError)
}

type TransactionAllocationSvc

type TransactionAllocationSvc interface {
	// ListAllocationEntries returns a paginated list of allocation entries for the caller's account.
	ListAllocationEntries(ctx context.Context, params ListAllocationEntriesParams) (*ListAllocationEntriesResult, *apierror.APIError)

	// UpdateTransactionAllocation updates a transaction allocation's amount and/or created_at with idempotency support.
	UpdateTransactionAllocation(ctx context.Context, params UpdateTransactionAllocationParams) (*TransactionAllocation, *apierror.APIError)

	// DeleteTransactionAllocation deletes a transaction allocation.
	DeleteTransactionAllocation(ctx context.Context, params DeleteTransactionAllocationParams) *apierror.APIError

	// ListOpenCredits returns a list of open (not fully allocated) credit transactions.
	ListOpenCredits(ctx context.Context, params ListOpenCreditsParams) (*ListOpenCreditsResult, *apierror.APIError)
}

type TransactionMethodCode

type TransactionMethodCode string

TransactionMethodCode maps Stripe payment method types to internal codes.

const (
	TransactionMethodCreditCard TransactionMethodCode = "credit_card"
	TransactionMethodACH        TransactionMethodCode = "ach"
)

type TransactionRecord

type TransactionRecord struct {
	ID       string
	Number   string
	AmountID string
}

TransactionRecord represents a payment transaction.

type TransactionRepo

type TransactionRepo interface {
	Create(ctx context.Context, txID, number, typeCode, accountID, customerAccountID string, stripePaymentID *string, methodCode *string, adjustmentTypeCode *string, responsibleUserID *string, note *string, amountValue string, amountUnitID string) *apierror.APIError
	// FindByStripePaymentID returns the transaction linked to the given Stripe payment intent, or nil when none exists.
	FindByStripePaymentID(ctx context.Context, stripePaymentID string) (*TransactionRecord, *apierror.APIError)
	// UpdateFundsReceivedByStripePaymentIDs stamps funds_received_at on every transaction of the account whose stripe_payment_id is in the given set (called when a Stripe payout lands).
	UpdateFundsReceivedByStripePaymentIDs(ctx context.Context, accountID string, stripePaymentIDs []string, fundsReceivedAt time.Time) *apierror.APIError
	UpdateNote(ctx context.Context, txID, note string) *apierror.APIError
	Delete(ctx context.Context, txID string) *apierror.APIError
	DeleteAllocations(ctx context.Context, transactionID string) *apierror.APIError
	DeleteQuantity(ctx context.Context, quantityID string) *apierror.APIError
	FetchAndIncrementTransactionNumber(ctx context.Context, accountID string) (string, *apierror.APIError)
	List(ctx context.Context, params ListTransactionsParams) (*ListTransactionsResult, *apierror.APIError)
	Get(ctx context.Context, accountID, transactionID string) (*Transaction, *apierror.APIError)
	GetAllocations(ctx context.Context, transactionID string) ([]*TransactionAllocation, *apierror.APIError)
	Update(ctx context.Context, params UpdateTransactionParams) (*Transaction, *apierror.APIError)
	ExistsByNumber(ctx context.Context, accountID, number string, excludeID *string) (bool, *apierror.APIError)
	ResolveResponsibleUserID(ctx context.Context, accountID, userOrAccountUserID string) (string, *apierror.APIError)
	ListByCustomer(ctx context.Context, params ListAccountTransactionsParams) (*ListAccountTransactionsResult, *apierror.APIError)
	GetDollarUnitID(ctx context.Context) (string, *apierror.APIError)
}

type TransactionSummary

type TransactionSummary struct {
	ID                       string
	Number                   string
	AmountID                 string
	AmountValue              string
	AmountUnitID             string
	AmountUnitAbbr           string
	CustomerID               *string
	CustomerName             *string
	CustomerNumber           *string
	CustomerStatusCode       *string
	CustomerCommissionPolicy *string
	CustomerCreatedAt        *time.Time
	CustomerUpdatedAt        *time.Time
	TransactionTypeCode      string
	TransactionTypeName      string
	TransactionTypeID        string
	TransactionMethodCode    *string
	TransactionMethodName    *string
	TransactionMethodID      *string
	AdjustmentTypeCode       *string
	AdjustmentTypeName       *string
	AdjustmentTypeID         *string
	IsFullyAllocated         bool
	AllocationCount          int32
	CreatedAt                time.Time
	UpdatedAt                time.Time
}

TransactionSummary represents a lightweight transaction for list views.

type TransactionSvc

type TransactionSvc interface {
	ListTransactions(ctx context.Context, params ListTransactionsParams) (*ListTransactionsResult, *apierror.APIError)
	GetTransaction(ctx context.Context, params GetTransactionParams) (*Transaction, *apierror.APIError)
	CreateTransaction(ctx context.Context, params CreateTransactionParams) (*Transaction, *apierror.APIError)
	UpdateTransaction(ctx context.Context, params UpdateTransactionParams) (*Transaction, *apierror.APIError)
	DeleteTransaction(ctx context.Context, params DeleteTransactionParams) (*Transaction, *apierror.APIError)
	ListAccountTransactions(ctx context.Context, params ListAccountTransactionsParams) (*ListAccountTransactionsResult, *apierror.APIError)
}

type TransitLane

type TransitLane struct {
	CarrierOptionID string
	OriginCountry   string
	OriginPostal    string
	DestCountry     string
	DestPostal      string
}

TransitLane identifies the journey a transit estimate describes: one service level between two postal codes. Postal codes are compared as stored, so callers normalize before building one.

func (TransitLane) IsComplete

func (l TransitLane) IsComplete() bool

IsComplete reports whether the lane has every part needed to look up or warm an estimate. An incomplete lane is the normal state for an order that has no carrier chosen yet, not an error.

type TransitWarmer

type TransitWarmer interface {
	// WarmForOrder quotes an order's lane with its carrier and records the transit for every service level the carrier returns. It is best-effort by contract: an order with no carrier, no Shippo integration, or an unratable lane is a no-op, not an error.
	WarmForOrder(ctx context.Context, accountID, salesOrderID string) *apierror.APIError
}

TransitWarmer fills the lane cache out of band, so the estimate is already there by the time an order is issued.

It is an interface in domain because the consumers that drive it live in the event package, which must not depend on the service package that implements it.

type UndoBatchScanEvent

type UndoBatchScanEvent struct {
	BatchID           string `json:"batch_id"`
	ScanningStationID string `json:"scanning_station_id,omitempty"`
	ResponsibleUserID string `json:"responsible_user_id,omitempty"`
	OrderID           string `json:"order_id,omitempty"`
	ProducedItemID    string `json:"produced_item_id,omitempty"`
	ShortfallMeasure  string `json:"shortfall_measure,omitempty"`
	ShortfallUnitID   string `json:"shortfall_unit_id,omitempty"`
}

UndoBatchScanEvent is the outbox event payload for reversing the inventory a scan recorded against a batch that has just been deleted.

The reversal itself is keyed off the batch: every row a scan writes carries it on `batch_id`, and those columns have no foreign key, so the tags outlive the batch row. What does not outlive it is the lineage — the flow edges go with the batch — so the seconds and waste the scan released reservations for are snapshotted here at delete time.

type Unit

type Unit struct {
	ID                string
	Name              string `audit:"name"`
	Abbreviation      string `audit:"abbreviation"`
	UnitDimensionCode string `audit:"unit_dimension_code"`
	RatioNumerator    string `audit:"ratio_numerator"`
	RatioDenominator  string `audit:"ratio_denominator"`
	OffsetNumerator   string `audit:"offset_numerator"`
	OffsetDenominator string `audit:"offset_denominator"`
	IsBaseUnit        bool   `audit:"is_base_unit"`
	AccountID         *string
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

type UnitConversionRepo

type UnitConversionRepo interface {
	// ConvertValue converts a measure from one unit to another within the same unit group. Returns the converted measure.
	ConvertValue(ctx context.Context, measure decimal.Decimal, fromUnitID, toUnitID string) (decimal.Decimal, *apierror.APIError)
	// GetUnitFactors returns the base-conversion factors for each requested unit ID. Unknown IDs are omitted.
	GetUnitFactors(ctx context.Context, accountID string, unitIDs []string) (map[string]UnitFactors, *apierror.APIError)
}

UnitConversionRepo provides unit conversion capabilities.

type UnitFactors

type UnitFactors struct {
	RatioNum   decimal.Decimal
	RatioDen   decimal.Decimal
	OffsetNum  decimal.Decimal
	OffsetDen  decimal.Decimal
	IsBaseUnit bool
	// DimensionCode is what the unit measures, so a caller that needs a duration can reject a unit that measures socks.
	DimensionCode string
}

UnitFactors carries a unit's linear conversion to/from its dimension's base unit: base = (value * ratioNum / ratioDen) + (offsetNum / offsetDen).

func (UnitFactors) FromBase

func (f UnitFactors) FromBase(base decimal.Decimal) decimal.Decimal

FromBase converts a base measure to a measure in this unit.

func (UnitFactors) ToBase

ToBase converts a measure in this unit to its dimension's base measure.

type UnitGroup

type UnitGroup struct {
	ID       string
	BaseUnit LightUnit
}

UnitGroup represents a unit group with its base unit.

type UnitGroupExistsParams

type UnitGroupExistsParams struct {
	AccountID   string
	UnitGroupID string
}

type UnitGroupFull

type UnitGroupFull struct {
	ID              string
	Name            string           `audit:"name"`
	Notes           *string          `audit:"notes"`
	Type            string           `audit:"type"`
	BaseUnit        LightUnit        `audit:"base_unit"`
	UnitConversions []*UnitGroupUnit `audit:"associated_units"`
	AccountID       *string
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

type UnitGroupQueryRepo

type UnitGroupQueryRepo interface {
	FindByItem(ctx context.Context, accountID, itemID string) (*UnitGroup, *apierror.APIError)
}

UnitGroupQueryRepo provides read-only access to unit group data.

type UnitGroupRepo

type UnitGroupRepo interface {
	List(ctx context.Context, params ListUnitGroupsParams) (*ListUnitGroupsResult, *apierror.APIError)
	Export(ctx context.Context, params ExportUnitGroupsParams) ([]*UnitGroupFull, *apierror.APIError)
	Get(ctx context.Context, params GetUnitGroupParams) (*UnitGroupFull, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateUnitGroupParams) (*UnitGroupFull, *apierror.APIError)
	Update(ctx context.Context, params UpdateUnitGroupParams) (*UnitGroupFull, *apierror.APIError)
	Delete(ctx context.Context, params DeleteUnitGroupParams) *apierror.APIError
	Exists(ctx context.Context, params UnitGroupExistsParams) (bool, *apierror.APIError)
	GetTypesByIDs(ctx context.Context, accountID string, ids []string) (map[string]string, *apierror.APIError)
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	FindByNames(ctx context.Context, accountID string, names []string) ([]*UnitGroupFull, *apierror.APIError)
	FindUnitsByGroupIDs(ctx context.Context, unitGroupIDs []string) ([]*UnitGroupUnit, *apierror.APIError)
	UpsertUnitGroupUnit(ctx context.Context, id string, params UpsertUnitGroupUnitParams) (*UnitGroupUnit, *apierror.APIError)
	DeleteUnitGroupUnit(ctx context.Context, params DeleteUnitGroupUnitParams) *apierror.APIError
	DeleteAllUnitGroupUnits(ctx context.Context, accountID, unitGroupID string) *apierror.APIError
	ListUnits(ctx context.Context, unitGroupID string, includes []string) ([]*UnitGroupUnit, *apierror.APIError)
	GetUnit(ctx context.Context, params GetUnitGroupUnitParams) (*UnitGroupUnit, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*UnitGroupFull, *apierror.APIError)
	GetUnitGroupUnitsByIDs(ctx context.Context, accountID string, ids []string) ([]*UnitGroupUnit, *apierror.APIError)
}

type UnitGroupSvc

type UnitGroupSvc interface {
	// ListUnitGroups returns a paginated list of unit groups visible to the caller's account. Includes both account-specific and system unit groups.
	ListUnitGroups(ctx context.Context, params ListUnitGroupsParams) (*ListUnitGroupsResult, *apierror.APIError)

	ExportUnitGroups(ctx context.Context, params ExportUnitGroupsParams) (*Job, *apierror.APIError)
	// renders the file an accepted export recorded.
	BuildExportUnitGroups(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// returns a single unit group by ID with its unit conversions. Supports both internal and customer (cross-account) access.
	GetUnitGroup(ctx context.Context, params GetUnitGroupParams) (*UnitGroupFull, *apierror.APIError)

	// CreateUnitGroup creates a new account-owned unit group with optional unit conversions. Idempotent via idempotency keys.
	CreateUnitGroup(ctx context.Context, params CreateUnitGroupParams) (*UnitGroupFull, *apierror.APIError)

	// UpdateUnitGroup partially updates an account-owned unit group. System unit groups cannot be modified. Idempotent via idempotency keys.
	UpdateUnitGroup(ctx context.Context, params UpdateUnitGroupParams) (*UnitGroupFull, *apierror.APIError)

	// DeleteUnitGroup deletes an account-owned unit group and cascades to all unit_group_unit records. System unit groups cannot be deleted.
	DeleteUnitGroup(ctx context.Context, unitGroupID string) *apierror.APIError

	// UpsertUnitGroupUnit creates or updates a unit conversion within a unit group. The parent unit group must be account-owned.
	UpsertUnitGroupUnit(ctx context.Context, params UpsertUnitGroupUnitParams) (*UnitGroupUnit, *apierror.APIError)

	// validates and resolves synchronously, records the rows on a job, and returns the raised Job to poll
	BulkUpsertUnitGroups(ctx context.Context, params BulkUpsertUnitGroupsParams) (*Job, *apierror.APIError)
	// performs the writes for an enqueued bulk upsert; the message inbox makes delivery effectively-once
	ExecuteBulkUpsertUnitGroups(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// removes a unit conversion from a unit group. The parent unit group must be account-owned.
	DeleteUnitGroupUnit(ctx context.Context, params DeleteUnitGroupUnitParams) *apierror.APIError

	// ListUnitGroupUnits returns all unit conversions for a unit group.
	ListUnitGroupUnits(ctx context.Context, unitGroupID string, includes []string) ([]*UnitGroupUnit, *apierror.APIError)

	// GetUnitGroupUnit returns a single unit conversion by ID.
	GetUnitGroupUnit(ctx context.Context, params GetUnitGroupUnitParams) (*UnitGroupUnit, *apierror.APIError)

	// BatchGetUnitGroupsByIDs returns unit groups by ID for the api-gateway include resolver.
	BatchGetUnitGroupsByIDs(ctx context.Context, ids []string) ([]*UnitGroupFull, *apierror.APIError)

	// BatchGetUnitGroupUnitsByIDs returns unit group units by ID for the api-gateway include resolver.
	BatchGetUnitGroupUnitsByIDs(ctx context.Context, ids []string) ([]*UnitGroupUnit, *apierror.APIError)
}

type UnitGroupUnit

type UnitGroupUnit struct {
	ID                 string
	UnitID             string `audit:"unit_id"`
	UnitGroupID        string
	DiscountPercentage string `audit:"discount_percentage"`
	DiscountFixed      string `audit:"discount_fixed"`
	IsVisible          bool   `audit:"is_visible"`
	Unit               LightUnit
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

UnitGroupUnit represents a unit conversion within a unit group.

type UnitIdentifier

type UnitIdentifier struct {
	ID           string
	Name         string
	Abbreviation string
}

UnitIdentifier identifies a unit by its ID, name, or abbreviation. Precedence: ID, then name, then abbreviation. The zero value means no unit was provided.

type UnitQueryRepo

type UnitQueryRepo interface {
	Find(ctx context.Context, accountID, id string) (*LightUnit, *apierror.APIError)
	GetDimensionCodes(ctx context.Context, ids []string) (map[string]string, *apierror.APIError)
}

UnitQueryRepo provides read-only access to unit data.

type UnitRepo

type UnitRepo interface {
	List(ctx context.Context, params ListUnitsParams) (*ListUnitsResult, *apierror.APIError)
	Export(ctx context.Context, params ExportUnitsParams) ([]*Unit, *apierror.APIError)
	Get(ctx context.Context, params GetUnitParams) (*Unit, *apierror.APIError)
	// GetCurrencyBaseUnitID returns the global currency base unit ID used as the numerator unit when building monetary price rates.
	GetCurrencyBaseUnitID(ctx context.Context) (string, *apierror.APIError)
	// GetFreightWeightUnitID returns the global unit shipping-case freight weights are recorded in (pounds), which is what carriers are quoted and billed on.
	GetFreightWeightUnitID(ctx context.Context) (string, *apierror.APIError)
	// GetDimensionCodes returns a unit-id → unit_dimension_code map for the given IDs. Used to enforce unit-type constraints (e.g., currency-only numerator on cost rates) before persisting rate rows.
	GetDimensionCodes(ctx context.Context, ids []string) (map[string]string, *apierror.APIError)
	Create(ctx context.Context, id string, params CreateUnitParams) (*Unit, *apierror.APIError)
	Update(ctx context.Context, params UpdateUnitParams) (*Unit, *apierror.APIError)
	Delete(ctx context.Context, params DeleteUnitParams) *apierror.APIError
	ExistsByName(ctx context.Context, accountID, name string, excludeID *string) (bool, *apierror.APIError)
	ExistsByAbbreviation(ctx context.Context, accountID, abbreviation string, excludeID *string) (bool, *apierror.APIError)
	FindByAbbreviations(ctx context.Context, accountID string, abbreviations []string) ([]*Unit, *apierror.APIError)
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*Unit, *apierror.APIError)
	FindByAbbreviationsOrNames(ctx context.Context, accountID string, abbreviations, names []string) ([]*Unit, *apierror.APIError)
}

type UnitSvc

type UnitSvc interface {
	// ListUnits returns a paginated list of units visible to the caller's account. Includes both account-specific and global (system) units.
	ListUnits(ctx context.Context, params ListUnitsParams) (*ListUnitsResult, *apierror.APIError)

	ExportUnits(ctx context.Context, params ExportUnitsParams) (*Job, *apierror.APIError)
	// renders the file an accepted export recorded.
	BuildExportUnits(ctx context.Context, accountID string, filters json.RawMessage) (*Export, *apierror.APIError)

	// returns a single unit by ID. The unit must belong to the caller's account or be a system (global) unit.
	GetUnit(ctx context.Context, unitID string) (*Unit, *apierror.APIError)

	// CreateUnit creates a new account-owned unit.
	CreateUnit(ctx context.Context, params CreateUnitParams) (*Unit, *apierror.APIError)

	// UpdateUnit partially updates an account-owned unit. System units cannot be updated.
	UpdateUnit(ctx context.Context, params UpdateUnitParams) (*Unit, *apierror.APIError)

	// validates and resolves synchronously, records the rows on a job, and returns the raised Job to poll
	BulkUpsertUnits(ctx context.Context, params BulkUpsertUnitsParams) (*Job, *apierror.APIError)
	// performs the writes for an enqueued bulk upsert; the message inbox makes delivery effectively-once
	ExecuteBulkUpsertUnits(ctx context.Context, event BulkOperationJobEvent) *apierror.APIError

	// deletes an account-owned unit and cascades to unit_group_unit associations. System units cannot be deleted.
	DeleteUnit(ctx context.Context, unitID string) *apierror.APIError

	// ValidateUnits validates unit abbreviations and returns matching units. Performs case-insensitive matching against both account and system units.
	ValidateUnits(ctx context.Context, params ValidateUnitsParams) (*ValidateUnitsResult, *apierror.APIError)

	// BatchGetUnitsByIDs returns units by ID for the api-gateway include resolver.
	BatchGetUnitsByIDs(ctx context.Context, ids []string) ([]*Unit, *apierror.APIError)
}

type UnstockedLine

type UnstockedLine struct {
	ID          string
	OrderLineID string
}

UnstockedLine holds the ID and order line ID of an unstocked line.

type UpdateAccountGroupParams

type UpdateAccountGroupParams struct {
	AccountID            string
	AccountGroupID       string
	Name                 *string
	Description          field.Clearable[string]
	CommissionPolicyCode *string
	FreightPolicyCode    *string
	DefaultLeadTimeDays  field.Clearable[int32]
}

type UpdateAccountGroupProductLineAccessParams

type UpdateAccountGroupProductLineAccessParams struct {
	AccountID      string
	AccountGroupID string
	ProductLineIDs []string
}

type UpdateAccountIntegrationParams

type UpdateAccountIntegrationParams struct {
	AccountID string
	ID        string
	Name      *string
	IsActive  *bool
}

type UpdateAccountParams

type UpdateAccountParams struct {
	AccountID       string
	Name            *string
	SupportEmail    *string
	PhoneNumber     *string
	Slug            *string
	WebsiteURL      *string
	FacebookHandle  *string
	InstagramHandle *string
	LinkedInHandle  *string
	TwitterHandle   *string
}

UpdateAccountParams holds the optional fields for updating an account.

func (*UpdateAccountParams) HasBrandingUpdates

func (p *UpdateAccountParams) HasBrandingUpdates() bool

HasBrandingUpdates returns true if any branding fields are set.

type UpdateAccountPriceParams

type UpdateAccountPriceParams struct {
	AccountID             string
	AccountPriceID        string
	RecipientAccountID    *string
	ProductLineID         *string
	RateValue             *string
	RateNumeratorUnitID   *string
	RateDenominatorUnitID *string
	CategoryIDs           *[]string
	AttributeIDs          *[]string
}

type UpdateAccountUserParams

type UpdateAccountUserParams struct {
	AccountID               string
	AccountUserID           string
	Name                    *string
	Email                   *string
	Username                *string
	RoleID                  field.Clearable[string]
	DepartmentID            field.Clearable[string]
	IsCommissionEligible    field.Optional[bool]
	NotificationPreferences []NotificationPreferenceItem
}

UpdateAccountUserParams are the parameters for updating an account user. NotificationPreferences: nil means "do not touch"; a non-nil (possibly empty) slice applies the provided toggles.

type UpdateAddressParams

type UpdateAddressParams struct {
	AccountID         string
	AddressID         string
	Name              *string
	Phone             field.Clearable[string]
	Email             field.Clearable[string]
	IsDropShip        *bool
	ReceiveCalendarID *string
	StreetLine1       *string
	StreetLine2       field.Clearable[string]
	Locality          *string
	State             *string
	PostalCode        *string
	Country           *string
}

UpdateAddressParams contains the parameters for updating an address.

type UpdateAttributeParams

type UpdateAttributeParams struct {
	AttributeID string
	PropertyID  string
	AccountID   string
	Value       *string
	ColorCode   *string
	SortOrder   *int32
}

UpdateAttributeParams holds the parameters for updating an attribute.

type UpdateCarrierParams

type UpdateCarrierParams struct {
	AccountID       string
	CarrierID       string
	Name            *string
	IsPortalEnabled *bool
	Includes        []string
}

type UpdateConsumptionParams

type UpdateConsumptionParams struct {
	AccountID           string
	ProductionStepID    string
	ConsumptionID       string
	ItemID              *string
	QuantityValue       *string
	QuantityUnitID      *string
	WasteQuantityValue  *string
	WasteQuantityUnitID *string
	Instructions        *string
}

UpdateConsumptionParams holds the parameters for updating a consumption.

type UpdateCustomerNotificationRecipientsParams

type UpdateCustomerNotificationRecipientsParams struct {
	CustomerAccountID string
	Recipients        []NotificationRecipientInput
}

UpdateCustomerNotificationRecipientsParams are the parameters for replacing a customer relationship's default order-notification recipients.

type UpdateCustomerParams

type UpdateCustomerParams struct {
	OwnerAccountID           string
	CustomerAccountID        string
	Name                     *string
	Number                   *string
	Note                     field.Clearable[string]
	Email                    field.Clearable[string]
	Phone                    field.Clearable[string]
	URL                      field.Clearable[string]
	StatusCode               *string
	IsEdiEnabled             *bool
	CommissionPolicy         *constants.CommissionPolicy
	FreightPolicy            *constants.FreightPolicy
	DefaultLeadTimeDays      field.Clearable[int32]
	ReceiveCalendarID        field.Clearable[string]
	FulfillmentPolicy        field.Clearable[constants.FulfillmentPolicy]
	DefaultCarrierID         *string
	DefaultServiceLevelID    field.Clearable[string]
	DefaultPaymentTermID     *string
	DefaultShippingTermID    *string
	DefaultPriorityCode      *string
	DefaultSalesRepID        field.Clearable[string]
	BillToAddressID          field.Clearable[string]
	ShipToAddressID          field.Clearable[string]
	CustomerPriceGroupIDs    []string
	HasCustomerPriceGroupIDs bool
	CustomerTypeGroupID      *string
	CarrierBillingType       *string
	CarrierBillingAccount    field.Clearable[string]
	CreditLimit              field.Clearable[field.QuantityInput]
	CreditLimitID            *string
	Includes                 []string
}

UpdateCustomerParams holds the parameters for updating a customer.

type UpdateCustomerProductLineAccessParams

type UpdateCustomerProductLineAccessParams struct {
	AccountID      string
	CustomerID     string
	ProductLineIDs []string
}

type UpdateDCLocationParams

type UpdateDCLocationParams struct {
	OwnerAccountID string
	DCLocationID   string
	AccountID      *string
	Location       *string
}

type UpdateDemandOverrideParams

type UpdateDemandOverrideParams struct {
	AccountID        string
	OverrideID       string
	PeriodStartDate  *time.Time
	PeriodEndDate    *time.Time
	OverrideTypeCode *string
	Value            *float64
	// The nullable columns are Clearable: unset leaves the column unchanged, clear nulls it. Clearing ExpiresAt makes the override permanent again.
	UnitID     field.Clearable[string]
	ReasonCode field.Clearable[string]
	Note       field.Clearable[string]
	ExpiresAt  field.Clearable[time.Time]
	IsActive   *bool
}

type UpdateDepartmentParams

type UpdateDepartmentParams struct {
	AccountID    string
	DepartmentID string
	Name         *string
	Notes        *string
	LocationID   *string
	// LaborRate creates the department's rate when it has none, or rewrites the existing rate row in place.
	LaborRate *CreateRateParams
	// LaborRateID is the rate row the service created from LaborRate; the repo only links it.
	LaborRateID        *string
	ScanningStationIDs []string
	MachineIDs         []string
}

type UpdateHubspotSyncJobParams

type UpdateHubspotSyncJobParams struct {
	ID        string
	AccountID string
	Status    *string
	Cursors   json.RawMessage
	Counts    json.RawMessage
	// LastError is three-way: nil preserves the stored error, a non-empty string replaces it, and an empty string clears it.
	LastError   *string
	StartedAt   *time.Time
	CompletedAt *time.Time
}

UpdateHubspotSyncJobParams patches a job. Nil fields leave the existing value unchanged, so a partial write (a cursor checkpoint, say) cannot erase an unrelated column.

type UpdateInvoiceParams

type UpdateInvoiceParams struct {
	AccountID    string
	InvoiceID    string
	Note         field.Clearable[string]
	HasBeenSent  *bool
	IsEdiSent    *bool
	IsPaidInFull *bool
	Includes     []string
}

UpdateInvoiceParams holds parameters for updating an invoice.

type UpdateItemCategoryParams

type UpdateItemCategoryParams struct {
	AccountID      string
	ItemCategoryID string
	Name           *string
	Notes          *string
	Includes       []string
}

type UpdateItemCategoryWithUnitGroupParams

type UpdateItemCategoryWithUnitGroupParams struct {
	AccountID      string
	ItemCategoryID string
	Name           *string
	Notes          *string
	UnitGroupID    string
}

type UpdateItemInventoryParams

type UpdateItemInventoryParams struct {
	AccountID  string
	ItemID     string
	Measure    decimal.Decimal
	UnitID     string
	Reconcile  *bool
	CustomerID *string
	LocationID *string
	LotNumber  *string
}

UpdateItemInventoryParams holds parameters for updating item inventory.

type UpdateItemParams

type UpdateItemParams struct {
	AccountID         string
	ItemID            string
	SKU               *string
	Description       *string
	UpdateDescription bool // true if the caller explicitly set the description field (even to null)
	Notes             *string
	UpdateNotes       bool // true if the caller explicitly set the notes field (even to null)
}

UpdateItemParams holds parameters for partially updating an item.

type UpdateJobRepositoryParams

type UpdateJobRepositoryParams struct {
	JobID            string
	AccountID        string
	Results          []RowResult
	ResultsTruncated bool
	Error            *apierror.ResponseError
	StartedAt        *time.Time
	CompletedAt      *time.Time
	FailedAt         *time.Time
	CancelledAt      *time.Time
}

type UpdateJobServiceParams

type UpdateJobServiceParams struct {
	JobID   string
	Status  constants.JobStatus
	Results []RowResult
	Error   *apierror.ResponseError
}

type UpdateLineRepoParams

type UpdateLineRepoParams struct {
	AccountID       string
	LineID          string
	MachineID       *string
	WeekIndex       *int32
	WeekStartDate   *time.Time
	PlannedQuantity *float64
	PlannedLots     *int32
	PlannedRunHours *float64
	SequenceIndex   *int32
	StatusCode      *string
	ReasonCode      *string
	ClearReasonCode bool
}

type UpdateLocationParams

type UpdateLocationParams struct {
	AccountID  string
	LocationID string
	Name       *string
	TypeCode   *string
	ParentID   field.Clearable[string]
	ChildIDs   field.Clearable[[]string]
	Includes   []string
}

UpdateLocationParams contains the parameters for updating a location.

type UpdateMachineDowntimeEventParams

type UpdateMachineDowntimeEventParams struct {
	AccountID  string
	EventID    string
	ReasonCode *string
	StartedAt  *time.Time
	// MachineID moves the stoppage to another machine, re-resolving the department and step it is charged to. Correcting the machine is the one thing a mis-logged event most often needs, and deleting and re-logging would lose the record of who reported it and when.
	MachineID *string
	// The nullable columns are Clearable: unset leaves the column unchanged, clear nulls it. Clearing EndedAt reopens an event closed by mistake.
	EndedAt field.Clearable[time.Time]
	// Duration restates the end as a length of time from the start. Clearing it reopens the event, the same as clearing EndedAt.
	Duration        field.Clearable[DowntimeDurationInput]
	ItemID          field.Clearable[string]
	ProductionRunID field.Clearable[string]
	BatchID         field.Clearable[string]
	Note            field.Clearable[string]
}

type UpdateMachineParams

type UpdateMachineParams struct {
	AccountID    string
	MachineID    string
	Name         *string
	SerialNumber *string
	Notes        *string
}

type UpdateMaterialParams

type UpdateMaterialParams struct {
	AccountID         string
	MaterialID        string
	SKU               *string
	Description       *string
	UpdateDescription bool
	Notes             *string
	UpdateNotes       bool
	OrderPoint        *QuantityInput
	LeadTime          *QuantityInput
	UnitCost          *CreateRateParams
	Includes          []string
}

type UpdateOperatingCalendarParams

type UpdateOperatingCalendarParams struct {
	ID            string
	AccountID     string
	Name          *string
	DaysOfWeek    *string
	CutoffAt      *string
	ClearCutoffAt bool
	Timezone      *string
	ClearTimezone bool
	IsDefault     *bool
}

UpdateOperatingCalendarParams patches a calendar. A nil field is left alone; the Clear flags are how a cutoff or zone is removed, since nil already means "unchanged".

type UpdateOrderDiscountParams

type UpdateOrderDiscountParams struct {
	AccountID       string
	OrderDiscountID string
	Name            *string
	Code            *string
	Percentage      *string
	Amount          *string
	DiscountType    *string
}

type UpdatePartParams

type UpdatePartParams struct {
	AccountID   string
	PartID      string
	SKU         *string
	Description field.Clearable[string]
	Notes       field.Clearable[string]
	Includes    []string
}

type UpdatePaymentTermParams

type UpdatePaymentTermParams struct {
	AccountID     string
	PaymentTermID string
	Name          *string
}

type UpdatePickLineParams

type UpdatePickLineParams struct {
	AccountID     string
	PickID        string
	PickLineID    string
	QuantityValue *string
}

Carries the parameters for updating a pick line's picked quantity.

type UpdatePickParams

type UpdatePickParams struct {
	AccountID  string
	PickID     string
	Number     *string
	FinishedAt **time.Time // double pointer: nil = not provided, *nil = set to null
	Includes   []string
}

UpdatePickParams holds the parameters for updating a pick.

type UpdatePortalRegistrationSessionParams

type UpdatePortalRegistrationSessionParams struct {
	TypeID             string
	Step               constants.PortalRegistrationStep
	SessionData        PortalRegistrationSessionData
	IsExistingCustomer *bool
}

UpdatePortalRegistrationSessionParams holds the inputs to advance a session.

type UpdateProductLineParams

type UpdateProductLineParams struct {
	AccountID        string
	ProductLineID    string
	Name             *string
	CommissionPolicy *constants.CommissionPolicy
	FreightPolicy    *constants.FreightPolicy
	UnitGroupID      *string
	DefaultLot       *LotQuantityInput
	// ClearDefaultLot removes the line's lot convention entirely.
	ClearDefaultLot       bool
	Includes              []string
	FulfillmentPolicyCode field.Clearable[string]
}

type UpdateProductParams

type UpdateProductParams struct {
	AccountID     string
	ProductID     string
	SKU           *string
	Description   field.Clearable[string]
	Notes         field.Clearable[string]
	IsPortalReady *bool
	UnitPrice     *CreateRateParams
	Includes      []string
}

UpdateProductParams holds parameters for partially updating a product.

type UpdateProductTypeParams

type UpdateProductTypeParams struct {
	ProductTypeID string
	Name          *string
	Code          *string
}

type UpdateProductionParams

type UpdateProductionParams struct {
	AccountID        string
	ProductionStepID string
	ProductionID     string
	ItemID           *string
	QuantityValue    *string
	QuantityUnitID   *string
}

UpdateProductionParams holds the parameters for updating a production output.

type UpdateProductionRunParams

type UpdateProductionRunParams struct {
	ProductionRunID   string
	AccountID         string
	Number            *string
	ResponsibleUserID *string
}

UpdateProductionRunParams holds the parameters for updating a production run.

type UpdateProductionScheduleLineParams

type UpdateProductionScheduleLineParams struct {
	AccountID     string
	ScheduleID    string
	LineID        string
	WeekIndex     *int32
	MachineID     *string
	Quantity      *float64
	Lots          *int32
	RunHours      *float64
	SequenceIndex *int32
	StatusCode    *string
	// ReasonCode is Clearable: unset leaves the column unchanged, clear nulls it.
	ReasonCode field.Clearable[string]
	ReasonNote *string
}

type UpdateProductionScheduleSettingsParams

type UpdateProductionScheduleSettingsParams struct {
	AccountID string
	Settings  ProductionScheduleSettings
}

type UpdateProductionStepForBulkUpsertParams

type UpdateProductionStepForBulkUpsertParams struct {
	AccountID         string
	ProductionStepID  string
	Name              string
	Notes             *string
	LevelingFactor    string
	Allowances        string
	ScanningStationID *string
	LaborRateID       string
	LaborTimeID       string
	OverheadRateID    string
}

UpdateProductionStepForBulkUpsertParams holds the full-row write used by the bulk upsert update path. Rate IDs point at freshly inserted rate rows.

type UpdateProductionStepParams

type UpdateProductionStepParams struct {
	AccountID         string
	ProductionStepID  string
	Name              *string
	LevelingFactor    *string
	Allowances        *string
	ScanningStationID *string
}

UpdateProductionStepParams holds the parameters for updating a production step.

type UpdatePropertyParams

type UpdatePropertyParams struct {
	PropertyID string
	AccountID  string
	Name       *string
}

UpdatePropertyParams holds the parameters for updating a property.

type UpdatePurchaseOrderLineParams

type UpdatePurchaseOrderLineParams struct {
	PurchaseOrderLineID        string
	SalesOrderID               string
	AccountID                  string
	ProductID                  *string
	ItemID                     *string
	ProductSKU                 *string
	ProductDescription         *string
	QuantityValue              *string
	QuantityUnitID             *string
	UnitPriceValue             *string
	UnitPriceNumeratorUnitID   *string
	UnitPriceDenominatorUnitID *string
	UnitCostValue              *string
	UnitCostNumeratorUnitID    *string
	UnitCostDenominatorUnitID  *string
}

UpdatePurchaseOrderLineParams holds the parameters for updating a purchase order line.

type UpdatePurchaseOrderParams

type UpdatePurchaseOrderParams struct {
	PurchaseOrderID       string
	AccountID             string
	Includes              []string
	Note                  *string
	Number                *string
	PriorityCode          *string
	BillingAddressID      *string
	ShippingAddressID     *string
	PromisedAt            *string
	ContactAccountUserIDs []string
}

UpdatePurchaseOrderParams holds the parameters for updating a purchase order.

type UpdateQuantityParams

type UpdateQuantityParams struct {
	QuantityID string
	Value      *string
	UnitID     *string
	ObjectID   *string
	ObjectType *constants.ObjectType
}

type UpdateRateParams

type UpdateRateParams struct {
	RateID            string
	Value             *string
	NumeratorUnitID   *string
	DenominatorUnitID *string
	ObjectID          *string
	ObjectType        *constants.ObjectType
}

type UpdateReceivingOrderLineParams

type UpdateReceivingOrderLineParams struct {
	AccountID        string
	ReceivingOrderID string
	LineID           string
	QuantityValue    *string
}

UpdateReceivingOrderLineParams holds parameters for updating a receiving order line.

type UpdateRegistrationFlowParams

type UpdateRegistrationFlowParams struct {
	AccountID           string
	RegistrationFlowID  string
	Name                *string
	CustomerGroupIDs    []string
	PaymentTermIDs      []string
	ShippingTermIDs     []string
	HasCustomerGroupIDs bool
	HasPaymentTermIDs   bool
	HasShippingTermIDs  bool
}

type UpdateRoleParams

type UpdateRoleParams struct {
	RoleID      string
	AccountID   string
	Name        *string
	Permissions *[]CreateRolePermissionInput
}

UpdateRoleParams are the parameters for updating a role.

type UpdateSalesOrderLineParams

type UpdateSalesOrderLineParams struct {
	SalesOrderLineID string
	SalesOrderID     string
	AccountID        string
	ProductID        *string
	ItemID           *string
	ProductSKU       *string
	// Clearable: omitting it keeps the line's current description, an explicit clear removes it.
	ProductDescription         field.Clearable[string]
	QuantityValue              *string
	QuantityUnitID             *string
	UnitPriceValue             *string
	UnitPriceNumeratorUnitID   *string
	UnitPriceDenominatorUnitID *string
	UnitCostValue              *string
	UnitCostNumeratorUnitID    *string
	UnitCostDenominatorUnitID  *string
	EdiLineItemID              *string
}

UpdateSalesOrderLineParams holds the parameters for updating a sales order line.

type UpdateSalesOrderParams

type UpdateSalesOrderParams struct {
	SalesOrderID string
	AccountID    string
	Includes     []string
	// Optional (set-or-leave; non-nullable — cannot be cleared).
	Number               *string
	BillingAddressID     *string
	ShippingAddressID    *string
	CarrierID            *string
	PriorityCode         *string
	ShippingTermID       *string
	PaymentTermID        *string
	IsAcknowledgmentSent *bool
	BuyerAccountID       *string
	// Clearable (set / clear / leave). The service backfills unset from the existing
	// order, so a cleared field resolves to NULL and an unset field keeps its value.
	CustomerPONumber      field.Clearable[string]
	Note                  field.Clearable[string]
	ServiceLevelID        field.Clearable[string]
	CarrierBillingType    field.Clearable[string]
	CarrierBillingAccount field.Clearable[string]
	SalesRepID            field.Clearable[string]
	OrderDiscountID       field.Clearable[string]
	PromisedAt            field.Clearable[time.Time]
	// LeadTimeOverrideDays and ShipByOverrideDate are the alternatives to PromisedAt. Clearing one to set another in the same request is how a caller switches basis.
	LeadTimeOverrideDays field.Clearable[int32]
	ShipByOverrideDate   field.Clearable[time.Time]
	// When non-nil, replaces the acknowledgement email contacts on the order. Empty slice clears all contacts; nil leaves existing contacts untouched.
	AcknowledgementEmailContacts *[]SalesOrderEmailContactInput
	// When non-nil, replaces the invoice email contacts on the order. Empty slice clears all contacts; nil leaves existing contacts untouched.
	InvoiceEmailContacts *[]SalesOrderEmailContactInput
}

UpdateSalesOrderParams holds the parameters for updating a sales order.

type UpdateScanningStationParams

type UpdateScanningStationParams struct {
	AccountID           string
	ScanningStationID   string
	Name                *string
	Notes               field.Clearable[string]
	LabelSizeCode       field.Clearable[string]
	LabelTypeCode       field.Clearable[string]
	OperatorRequirement *constants.OperatorRequirement
	Includes            []string
}

type UpdateServiceLevelParams

type UpdateServiceLevelParams struct {
	AccountID       string
	ServiceLevelID  string
	CarrierID       string
	Name            *string
	Code            *string
	IsPortalEnabled *bool
	IsDefault       *bool
	// DefaultTransitDays is assigned rather than merged, so the service backfills the existing value when the caller leaves it unset.
	DefaultTransitDays field.Clearable[int32]
}

type UpdateSettlementParams

type UpdateSettlementParams struct {
	AccountID         string
	SettlementID      string
	Number            *string
	Note              *string
	ResponsibleUserID *string
}

UpdateSettlementParams holds parameters for updating a settlement.

type UpdateShipmentLineEndpointParams

type UpdateShipmentLineEndpointParams struct {
	AccountID      string
	ShipmentID     string
	ShipmentLineID string
	QuantityValue  *string
	QuantityUnitID *string
}

UpdateShipmentLineEndpointParams holds the parameters for updating a shipment line via the API.

type UpdateShipmentParams

type UpdateShipmentParams struct {
	AccountID            string
	ShipmentID           string
	Note                 *string
	Number               *string
	MasterTrackingNumber *string
	CarrierID            *string
	// Tri-state: unset keeps the current service level, null clears it.
	ServiceLevelID field.Clearable[string]
	Includes       []string
}

UpdateShipmentParams holds the parameters for updating a shipment.

type UpdateShippingCaseParams

type UpdateShippingCaseParams struct {
	AccountID           string
	ShippingCaseID      string
	TrackingNumber      *string
	FreightAmountValue  *string
	FreightAmountUnitID *string
	FreightWeightValue  *string
	FreightWeightUnitID *string
}

UpdateShippingCaseParams holds the parameters for updating a shipping case.

type UpdateShippingTermParams

type UpdateShippingTermParams struct {
	AccountID                   string
	ShippingTermID              string
	Name                        *string
	Type                        *constants.ShippingTermType
	FlatRate                    field.Clearable[QuantityInput]
	MinimumOrderValue           field.Clearable[QuantityInput]
	FreeShippingServiceLevelIDs field.Clearable[[]string]
	FlatRateID                  *string
	MinimumOrderID              *string
	Includes                    []string
}

type UpdateStripeCustomerParams

type UpdateStripeCustomerParams struct {
	StripeCustomerID string
	Email            *string
	Name             *string
	Number           *string
}

UpdateStripeCustomerParams holds the parameters for updating a Stripe customer.

type UpdateSupplierMaterialParams

type UpdateSupplierMaterialParams struct {
	OwnerAccountID      string
	SupplierAccountID   string
	MaterialID          string
	SupplierPartNumber  *string
	SupplierDescription *string
	UpdateDescription   bool
	IsActive            *bool
}

type UpdateSupplierParams

type UpdateSupplierParams struct {
	OwnerAccountID  string
	SupplierID      string
	Name            *string
	Number          *string
	Note            *string
	UpdateNote      bool
	BillToAddressID *string
	ShipToAddressID *string
	Includes        []string
}

UpdateSupplierParams holds the parameters for updating a supplier.

type UpdateSysPropertyParams

type UpdateSysPropertyParams struct {
	AccountID string
	ID        string
	Value     *int32
}

type UpdateTerritoryParams

type UpdateTerritoryParams struct {
	AccountID         string
	TerritoryID       string
	State             *string
	StartZipcode      *int32
	EndZipcode        *int32
	SalesRepID        *string
	ProductLineID     *string
	ClearProductLine  bool
	ClearStartZipcode bool
	ClearEndZipcode   bool
	Includes          []string
}

UpdateTerritoryParams contains the parameters for updating a territory.

type UpdateTransactionAllocationParams

type UpdateTransactionAllocationParams struct {
	AccountID    string
	AllocationID string
	Amount       *string
}

UpdateTransactionAllocationParams holds parameters for updating a transaction allocation.

type UpdateTransactionParams

type UpdateTransactionParams struct {
	AccountID              string
	TransactionID          string
	Number                 *string
	Note                   *string
	Amount                 *string
	TransactionMethodCode  *string
	AdjustmentTypeCode     *string
	ResponsibleUserID      *string
	ClearResponsibleUser   bool
	ClearTransactionMethod bool
	ClearAdjustmentType    bool
	IsFullyAllocated       *bool
}

UpdateTransactionParams holds parameters for updating a transaction.

type UpdateUnitGroupParams

type UpdateUnitGroupParams struct {
	AccountID       string
	UnitGroupID     string
	Name            *string
	Notes           field.Clearable[string]
	BaseUnitID      *string
	UnitConversions *[]CreateUnitGroupUnitParams
	Includes        []string
}

UpdateUnitGroupParams is the service-level params for updating a unit group and optionally upserting conversions.

type UpdateUnitParams

type UpdateUnitParams struct {
	AccountID         string
	UnitID            string
	Name              *string
	Abbreviation      *string
	RatioNumerator    *string
	RatioDenominator  *string
	OffsetNumerator   *string
	OffsetDenominator *string
}

type UpdateUserParams

type UpdateUserParams struct {
	Name          *string
	ImageURL      *string
	EmailVerified *time.Time
}

UpdateUserParams are the parameters for updating a user record.

type UpdateVolumeDiscountCustomerGroupParams

type UpdateVolumeDiscountCustomerGroupParams struct {
	ID             string
	AccountGroupID string
}

type UpdateVolumeDiscountParams

type UpdateVolumeDiscountParams struct {
	AccountID         string
	VolumeDiscountID  string
	Name              *string
	Tiers             []UpdateVolumeDiscountTierParams
	CustomerGroups    []UpdateVolumeDiscountCustomerGroupParams
	ProductLineIDs    []string
	CategoryIDs       []string
	AttributeIDs      []string
	UnitIDs           []string
	HasTiers          bool
	HasCustomerGroups bool
	HasProductLines   bool
	HasCategories     bool
	HasAttributes     bool
	HasUnits          bool
	Includes          []string
}

type UpdateVolumeDiscountTierParams

type UpdateVolumeDiscountTierParams struct {
	ID                 *string
	GeneratedID        string
	Name               *string
	DiscountPercentage *string
	Threshold          *string
	ParentTierID       *string
}

type UpsertClosureParams

type UpsertClosureParams struct {
	ID         string
	AccountID  string
	CalendarID string
	ClosedOn   time.Time
	Name       string
}

UpsertClosureParams is one closure to write. Re-seeding a year is idempotent and leaves an operator's own label intact.

type UpsertDepartmentParams

type UpsertDepartmentParams struct {
	Name     string
	Notes    *string
	Location *ObjectIdentifier
}

UpsertDepartmentParams is a single department in a bulk upsert, matched by name (case-insensitive) within the account. The location is referenced by name and resolved server-side. Machine / scanning-station attachment is not part of bulk upsert — machines and stations reference their department at creation.

type UpsertHubspotSyncRecordParams

type UpsertHubspotSyncRecordParams struct {
	AccountID   string
	AugnoType   string
	AugnoID     string
	HubspotType string
	HubspotID   string
	SyncHash    *string
}

type UpsertItemCategoryParams

type UpsertItemCategoryParams struct {
	Name                 string
	Notes                *string
	ItemCategoryTypeCode string
	UnitGroup            ObjectIdentifier
	// PropertyNames is an optional list of property names to attach to this category.
	// Properties are matched by name (case-insensitive) within the account; names not
	// found are created automatically. Relations are additive — existing relations are
	// not removed.
	PropertyNames []string
}

UpsertItemCategoryParams holds the fields for a single location in a bulk upsert.

type UpsertItemPropertyParams

type UpsertItemPropertyParams struct {
	Name  string
	Value string
}

UpsertItemPropertyParams is a (property name, value) pair resolved to an attribute.

type UpsertItemSettingParams

type UpsertItemSettingParams struct {
	AccountID             string
	ItemID                string
	IsExcluded            bool
	LotMultipleUnits      *float64
	FulfillmentPolicyCode *string
}

type UpsertLocationParams

type UpsertLocationParams struct {
	Name     string
	TypeCode string
	// Parent references this location's parent by id or name. The parent may be another
	// row in the same batch (referenced by name).
	Parent *ObjectIdentifier
	// Children references locations to re-parent under this one, by id or name. Each may be
	// another row in the same batch (referenced by name).
	Children []ObjectIdentifier
}

type UpsertMachineParams

type UpsertMachineParams struct {
	Name         string
	SerialNumber string
	Notes        *string
	Department   ObjectIdentifier
}

UpsertMachineParams is a single machine in a bulk upsert, matched by name OR serial number (case-insensitive) within the account. The department is referenced by name, resolved server-side, and confirms matching intent: updates must state the machine's current department, and a key matching a machine in a different department is rejected as a collision.

type UpsertMaterialParams

type UpsertMaterialParams struct {
	SKU         string
	Description *string
	Notes       *string
	Category    ObjectIdentifier // create-only
	OrderPoint  *QuantityInput
	LeadTime    *QuantityInput
	UnitPrice   *CreateRateParams
	UnitCost    *CreateRateParams
	// Properties are resolved to attributes (find-or-create by name + value) and attached.
	Properties []UpsertItemPropertyParams
}

UpsertMaterialParams is a single material to create or update in a bulk upsert. On create all fields apply; on update sku/description/notes/order_point/lead_time plus unit_price/unit_cost and properties are applied (category is create-only, matching the single update endpoint). Properties are additive.

type UpsertPartParams

type UpsertPartParams struct {
	SKU         string
	Description *string
	Notes       *string
	Category    ObjectIdentifier // create-only
	UnitPrice   *CreateRateParams
	UnitCost    *CreateRateParams
	// Properties are resolved to attributes (find-or-create by name + value) and attached.
	Properties []UpsertItemPropertyParams
}

UpsertPartParams is a single part to create or update in a bulk upsert. On create all fields apply; on update sku/description/notes/unit_price/unit_cost/properties are applied (properties are additive).

type UpsertProductLineParams

type UpsertProductLineParams struct {
	Name             string
	UnitGroup        ObjectIdentifier
	CommissionPolicy constants.CommissionPolicy
	FreightPolicy    constants.FreightPolicy
}

UpsertProductLineParams holds the fields for a single product line in a bulk upsert.

type UpsertProductParams

type UpsertProductParams struct {
	SKU             string
	ProductTypeCode string // create-only; defaults to "sale" when empty
	Description     *string
	Notes           *string
	Category        ObjectIdentifier  // create-only
	ProductLine     *ObjectIdentifier // create-only; optional
	IsPortalReady   *bool
	UnitPrice       *CreateRateParams
	UnitCost        *CreateRateParams
	// Properties are resolved to attributes (find-or-create by name + value) and attached.
	Properties []UpsertItemPropertyParams
}

UpsertProductParams is a single product to create or update in a bulk upsert. On create all fields apply; on update sku/description/notes/portal/unit_price/unit_cost and properties are applied (type, product line, and category are create-only, matching the single update endpoint). Properties are additive.

type UpsertProductionParams

type UpsertProductionParams struct {
	Item          ItemIdentifier
	QuantityValue string
	QuantityUnit  UnitIdentifier
}

UpsertProductionParams is a production output in a bulk upsert, with the item and unit referenced fuzzily.

type UpsertProductionStepParams

type UpsertProductionStepParams struct {
	Name            string
	Notes           *string
	LevelingFactor  *string
	Allowances      *string
	ScanningStation *ObjectIdentifier
	Department      *ObjectIdentifier
	LaborRate       UpsertRateParams
	LaborTime       UpsertRateParams
	OverheadRate    UpsertRateParams
	Production      UpsertProductionParams
	Consumptions    []UpsertStepConsumptionParams
}

UpsertProductionStepParams is a single production step in a bulk upsert, matched by name (case-insensitive) within the account. Items, units, the department, and the scanning station are referenced fuzzily and resolved server-side. The department is create-only: a matched row stating a different department is rejected. The production and the consumptions are replaced wholesale on update. Flow DAG edges are not part of the input — they are auto-derived from item flows after the batch commits, mirroring single create.

type UpsertPropertyAttributeParams

type UpsertPropertyAttributeParams struct {
	Value     string
	ColorCode *string
}

holds one selectable value in a bulk property upsert; an absent color is assigned

type UpsertPropertyParams

type UpsertPropertyParams struct {
	Name       string
	Attributes []UpsertPropertyAttributeParams
}

holds the fields for a single property in a bulk upsert

type UpsertRateParams

type UpsertRateParams struct {
	Value           string
	NumeratorUnit   UnitIdentifier
	DenominatorUnit UnitIdentifier
}

UpsertRateParams is a rate in a bulk upsert, with units referenced fuzzily (by id, name, or abbreviation) and resolved server-side. Rate rows are never mutated: updates insert fresh rate rows and re-point the step at them.

type UpsertResourceSettingParams

type UpsertResourceSettingParams struct {
	AccountID           string
	ScopeCode           string
	ScopeRefID          string
	IsExcluded          bool
	LeadTimeWeeks       *float64
	LeadTimeOffsetWeeks float64
}

type UpsertSalesTargetParams

type UpsertSalesTargetParams struct {
	TargetID     string
	AccountID    string
	SalesRepID   string
	StartDate    time.Time
	EndDate      time.Time
	AmountValue  string
	AmountUnitID string
}

UpsertSalesTargetParams are the parameters for upserting a sales target.

type UpsertScanningStationParams

type UpsertScanningStationParams struct {
	Name                string
	Notes               *string
	Type                constants.ScanningStationType
	LabelSizeCode       field.Clearable[string]
	LabelTypeCode       field.Clearable[string]
	OperatorRequirement constants.OperatorRequirement
	Department          ObjectIdentifier
}

type UpsertStepConsumptionParams

type UpsertStepConsumptionParams struct {
	Item               ItemIdentifier
	QuantityValue      string
	QuantityUnit       UnitIdentifier
	WasteQuantityValue *string
	WasteQuantityUnit  *UnitIdentifier
	Instructions       *string
}

UpsertStepConsumptionParams is a consumption in a bulk upsert, with the item and units referenced fuzzily. Waste defaults to zero in the quantity unit when omitted.

type UpsertTransitEstimateParams

type UpsertTransitEstimateParams struct {
	ID          string
	AccountID   string
	Lane        TransitLane
	TransitDays int
	SourceCode  string
}

UpsertTransitEstimateParams writes a harvested estimate for a lane. Operator-entered rows are never overwritten, so SourceCode decides whether the write lands.

type UpsertUnitConversionParams

type UpsertUnitConversionParams struct {
	Unit               UnitIdentifier
	DiscountPercentage string
}

type UpsertUnitGroupParams

type UpsertUnitGroupParams struct {
	Name            string
	Notes           *string
	Type            string
	BaseUnit        UnitIdentifier
	UnitConversions []UpsertUnitConversionParams
}

type UpsertUnitGroupUnitParams

type UpsertUnitGroupUnitParams struct {
	AccountID          string
	UnitGroupID        string
	UnitGroupUnitID    string
	UnitID             string
	DiscountPercentage string
	DiscountFixed      string
	IsVisible          bool
	// IsVisibleProvided reports whether the caller supplied is_visible. When false, the upsert preserves the stored value on update (or defaults to true on create) rather than clobbering it to false.
	IsVisibleProvided bool
	Includes          []string
}

type UpsertUnitParams

type UpsertUnitParams struct {
	Name              string
	Abbreviation      string
	UnitDimensionCode string
	RatioNumerator    string
	RatioDenominator  string
	OffsetNumerator   string
	OffsetDenominator string
	IsBaseUnit        bool
}

type UpsertUnitResult

type UpsertUnitResult struct {
	Unit *Unit
}

type UpsertUnitTxParams

type UpsertUnitTxParams struct {
	Unit    *UpsertUnitParams
	OldUnit *Unit
}

type UserRecord

type UserRecord struct {
	ID             string
	Email          *string `audit:"email"`
	Name           *string `audit:"name"`
	Username       *string `audit:"username"`
	HashedPassword *string
	EmailVerified  *time.Time `audit:"email_verified"`
	ImageURL       *string    `audit:"image_url"`
	StatusCode     string     `audit:"status_code"`
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

UserRecord represents a row from the user table.

type UserRepo

type UserRepo interface {
	FindByID(ctx context.Context, userID string) (*UserRecord, *apierror.APIError)
	// GetByIDs returns the users matching the given IDs that are affiliated with the given account.
	GetByIDs(ctx context.Context, accountID string, ids []string) ([]*UserRecord, *apierror.APIError)
	FindByEmail(ctx context.Context, email string) (*UserRecord, *apierror.APIError)
	FindByUsername(ctx context.Context, username string) (*UserRecord, *apierror.APIError)
	CreateUser(ctx context.Context, id string, params CreateUserRecordParams) *apierror.APIError
	UpdateProfile(ctx context.Context, userID string, name, email, username, imageURL *string, emailVerified *time.Time) *apierror.APIError
	UpdatePassword(ctx context.Context, userID, hashedPassword string) *apierror.APIError
	GetHashedPassword(ctx context.Context, userID string) (string, *apierror.APIError)
	UpdateImageURL(ctx context.Context, userID string, imageURL *string) *apierror.APIError
}

type UserSvc

type UserSvc interface {
	GetUser(ctx context.Context, userID string) (*UserRecord, *apierror.APIError)
	// BatchGetUsersByIDs returns users matching the given IDs that are affiliated with the target account.
	BatchGetUsersByIDs(ctx context.Context, ids []string) ([]*UserRecord, *apierror.APIError)
	UpdateUser(ctx context.Context, userID string, params UpdateUserParams) (*UserRecord, *apierror.APIError)
	UploadUserPhoto(ctx context.Context, userID string, file []byte, contentType string) *apierror.APIError
	GetUserPhotoURL(ctx context.Context, userID string) (*string, *apierror.APIError)
}

type UtilsSvc

type UtilsSvc interface {
	CheckDuplicate(ctx context.Context, params CheckDuplicateParams) (*CheckDuplicateResult, *apierror.APIError)
	EmailRecord(ctx context.Context, params EmailRecordParams) *apierror.APIError
	RequestDemo(ctx context.Context, params RequestDemoParams) *apierror.APIError
	SubmitFeedback(ctx context.Context, params SubmitFeedbackParams) *apierror.APIError
}

type ValidateProductsParams

type ValidateProductsParams struct {
	AccountID   string
	ProductsMap map[string]string // key -> SKU
	Includes    []string
}

ValidateProductsParams holds parameters for validating products by SKU.

type ValidateProductsResult

type ValidateProductsResult struct {
	Products map[string]*ProductFull
}

ValidateProductsResult contains matched products keyed by the original map key.

type ValidateUnitsParams

type ValidateUnitsParams struct {
	AccountID string
	UnitMap   map[string]string // key -> abbreviation
}

ValidateUnitsParams holds parameters for validating units by abbreviation.

type ValidateUnitsResult

type ValidateUnitsResult struct {
	Units map[string]*Unit
}

ValidateUnitsResult contains matched units keyed by the original map key.

type ValidatedAddress

type ValidatedAddress struct {
	IsValid            bool
	FormattedAddress   *string
	Components         *AddressComponents
	ValidationMessages []string
}

ValidatedAddress represents the result of address validation.

type VoidShipmentParams

type VoidShipmentParams struct {
	AccountID  string
	ShipmentID string
}

VoidShipmentParams holds the parameters for voiding a shipment.

type VolumeDiscount

type VolumeDiscount struct {
	ID              string
	Name            string `audit:"name"`
	AccountID       string
	Tiers           []*VolumeDiscountTier          `audit:"tiers"`
	CustomerGroups  []*VolumeDiscountCustomerGroup `audit:"customer_groups"`
	ProductLines    []*VolumeDiscountProductLine   `audit:"product_lines"`
	Categories      []*VolumeDiscountCategory      `audit:"categories"`
	Attributes      []*VolumeDiscountAttribute     `audit:"attributes"`
	AcceptableUnits []*VolumeDiscountUnit          `audit:"acceptable_units"`
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

type VolumeDiscountAttribute

type VolumeDiscountAttribute struct {
	ID         string
	Name       string
	ColorCode  string
	PropertyID string
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

type VolumeDiscountCategory

type VolumeDiscountCategory struct {
	ID        string
	Name      string
	Type      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type VolumeDiscountCustomerGroup

type VolumeDiscountCustomerGroup struct {
	ID               string
	AccountGroupID   string
	Name             string
	CommissionPolicy string
	FreightPolicy    string
	Type             string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

type VolumeDiscountProductLine

type VolumeDiscountProductLine struct {
	ID                 string
	Name               string
	IsCommissionExempt bool
	IsFreightExempt    bool
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

type VolumeDiscountSvc

type VolumeDiscountSvc interface {
	// ListVolumeDiscounts returns a paginated list of volume discounts. Supports both internal and customer actors.
	ListVolumeDiscounts(ctx context.Context, params ListVolumeDiscountsParams) (*ListVolumeDiscountsResult, *apierror.APIError)

	// GetVolumeDiscount returns a single volume discount by ID. Supports both internal and customer actors.
	GetVolumeDiscount(ctx context.Context, params GetVolumeDiscountParams) (*VolumeDiscount, *apierror.APIError)

	// CreateVolumeDiscount creates a new volume discount with tiers and relations.
	CreateVolumeDiscount(ctx context.Context, params CreateVolumeDiscountParams) (*VolumeDiscount, *apierror.APIError)

	// UpdateVolumeDiscount partially updates a volume discount.
	UpdateVolumeDiscount(ctx context.Context, params UpdateVolumeDiscountParams) (*VolumeDiscount, *apierror.APIError)

	// DeleteVolumeDiscount deletes a volume discount and its tiers and relations.
	DeleteVolumeDiscount(ctx context.Context, volumeDiscountID string) *apierror.APIError
}

type VolumeDiscountTier

type VolumeDiscountTier struct {
	ID                 string
	Name               string
	DiscountPercentage string
	Threshold          string
	ParentTierID       *string
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

type VolumeDiscountUnit

type VolumeDiscountUnit struct {
	ID                string
	Name              string
	Abbreviation      string
	Type              string
	RatioNumerator    string
	RatioDenominator  string
	OffsetNumerator   string
	OffsetDenominator string
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

type WeekReleaseState

type WeekReleaseState struct {
	TotalLines    int64
	ReleasedLines int64
	// ExistingProductionRunID names a run the week is already tied to, so a repeat release can point at it instead of failing with nothing to look at.
	ExistingProductionRunID *string
}

WeekReleaseState is how much of one planned week has already gone to the floor.

type WeeksOfSalesItem

type WeeksOfSalesItem struct {
	ProductLineID                        string
	ProductLineName                      string
	QuantityOnHand                       float64
	QuantityOnHandUnitAbbreviation       string
	QuantityOnHandUnitType               string
	AverageSalesQuantity                 float64
	AverageSalesQuantityUnitAbbreviation string
	AverageSalesQuantityUnitType         string
	WeeksOfSales                         float64
}

type WeeksOfSalesResult

type WeeksOfSalesResult struct {
	Items []WeeksOfSalesItem
	Count int64
}

type YearlyQuarterlyData

type YearlyQuarterlyData struct {
	Year int32
	Data QuarterlyData
}

Source Files

Directories

Path Synopsis
mock
client
Package clientmock is a generated GoMock package.
Package clientmock is a generated GoMock package.
factory
Package factorymock is a generated GoMock package.
Package factorymock is a generated GoMock package.
mediator
Package mediatormock is a generated GoMock package.
Package mediatormock is a generated GoMock package.
publisher
Package publishermock is a generated GoMock package.
Package publishermock is a generated GoMock package.
repository
Package repositorymock is a generated GoMock package.
Package repositorymock is a generated GoMock package.
service
Package servicemock is a generated GoMock package.
Package servicemock is a generated GoMock package.

Jump to

Keyboard shortcuts

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