import type { FdoDecimal } from '@feedmepos/core/entity'; export interface BindingSelector { type: FdoInventoryBinding['type']; id: string; amount?: FdoDecimal; measurementId?: string | null; rules?: Record | null; alternatives?: FdoInventoryBindingAlternative[]; } export type BindingChange = { type: 'replace-binding'; from: BindingSelector; to: FdoInventoryBinding; } | { type: 'remove-binding'; target: BindingSelector; } | { type: 'add-binding'; binding: FdoInventoryBinding; } | { type: 'update-binding-rule'; target: BindingSelector; rule: Record | null; } | { type: 'update-alternatives'; target: BindingSelector; alternatives: FdoInventoryBindingAlternative[]; }; export type RecipeChangeOutcome = 'applied' | 'ignored' | 'already-satisfied' | 'blocked'; export interface RecipeChangeResult { change: BindingChange; outcome: RecipeChangeOutcome; reason?: string; } export type RecipeBulkEditEntryStatus = 'will-update' | 'already-satisfied' | 'partially-ignored' | 'blocked' | 'no-applicable-changes'; export interface RecipeBulkEditEntry { recipeId: string; recipeName: string; original: FdoInventoryRecipe; projected: FdoInventoryRecipe | null; status: RecipeBulkEditEntryStatus; changes: RecipeChangeResult[]; counts: { applied: number; ignored: number; blocked: number; satisfied: number; }; } export type FlatBinding = FdoInventoryBinding & { recipeIds: string[]; isGroup?: boolean; }; export declare function flattenBindings(bindings: FdoInventoryBinding[], visitedIds: Set, recipeById: Record): FlatBinding[]; export declare function decimalsEqual(a: FdoDecimal, b: FdoDecimal): boolean; /** * Normalise a binding's `rules` for comparison. * * `FmCustomAttributeFilter` emits `{ $and: [] }` on mount for falsy values, * causing spurious diffs. null / {} / { $and: [] } / { $or: [] } are all * treated as "no rules" and normalised to `null`. */ export declare function normaliseRules(rules: Record | null | undefined): string | null; export declare function normaliseAlternatives(alts: FdoInventoryBindingAlternative[] | null | undefined): string; export declare function toBaseAmount(b: FdoInventoryBinding): FdoDecimal; export declare function bindingsExactlyEqual(a: FdoInventoryBinding, b: FdoInventoryBinding): boolean; export declare function bindingsSimilar(a: FdoInventoryBinding, b: FdoInventoryBinding): boolean; export declare function simulateChanges(original: FdoInventoryRecipe, changes: BindingChange[]): { projected: FdoInventoryRecipe; results: RecipeChangeResult[]; }; /** * Returns true if a BindingChange is fully specified (all required IDs are * non-empty). Stub/incomplete cards (e.g. a freshly-added blank tab) should be * filtered out before being passed to simulateChanges. */ export declare function isCompleteChange(change: BindingChange): boolean; export declare function deriveEntryStatus(results: RecipeChangeResult[]): RecipeBulkEditEntryStatus; export declare function deriveChangesFromDiff(original: FdoInventoryRecipe, draft: FdoInventoryRecipe): BindingChange[];