import { Amount } from '../../commonStateTypes/amount'; import { ID } from '../../commonStateTypes/common'; import { ZeniDate } from '../../zeniDayJS'; import { EntityType } from '../entityApprovalStatus/entityApprovalStatusState'; import { User } from '../user/userState'; import { ApprovalActionType, StepOperatorType } from './approvalStepTypes'; export declare const toActorApprovalType: (v: string) => "approved" | "rejected"; export type ActorApprovalType = ReturnType; export declare const toActorType: (v: string) => "user" | "attribute" | "role"; export type ActorType = ReturnType; declare const toAttributeType: (v: string) => "manager" | "vendor_owner" | "manager_of_manager"; export type AttributeType = ReturnType; export declare const toAttributeTypeStrict: (v: string | null) => AttributeType | undefined; declare const toRoleType: (v: string) => "admin"; export type RoleType = ReturnType; export declare const toRoleTypeStrict: (v: string | null) => RoleType | undefined; export declare const toAttributeOrRoleTypeStrict: (v: string | null) => AttributeType | RoleType | undefined; export interface Actor { isImplicitActor: boolean; type: ActorType; idType?: string; subType?: AttributeType | RoleType; userId?: ID; } /** * Approval rule criteria — discriminated union over the three condition * types the wire format supports: amount, vendor, and department. * * State-side, each rule carries a `Criteria[]` with at most one variant of * each kind (e.g. one AmountCriteria + one VendorCriteria + one DepartmentCriteria). * * Form-side, the rule create/edit form uses `ApprovalRuleFormCriteria` * (defined in commonState) — a structured object with named slots for * amount/vendor/department. Epics translate between the two. */ export type AmountComparator = 'greater_than' | 'less_than' | 'range'; export interface AmountCriteria { comparator: AmountComparator; type: 'amount'; /** Upper bound. Present for `less_than` and `range`. */ max?: Amount; /** Lower bound. Present for `greater_than` and `range`. */ min?: Amount; } export interface VendorCriteria { operator: 'is' | 'is_not'; type: 'vendor'; vendorIds: ID[]; } export interface DepartmentCriteria { departmentIds: ID[]; operator: 'is' | 'is_not'; type: 'department'; } export type Criteria = AmountCriteria | VendorCriteria | DepartmentCriteria; /** * Approval Rules 3.0 — canonical discriminator across the three * condition variants. Derived from the `Criteria` union's `type` * field so it can't drift from the underlying data model. * * Used by the unified `ConditionRow` UI component to switch which * variant body to render, and by chip-rendering helpers on the list * page to pick a label format. Consumers should import this type * rather than redeclaring the three string literals locally. */ export type ConditionType = Criteria['type']; export interface Step { actors: Actor[]; operator: StepOperatorType; action?: ApprovalActionType; } /** * Approval Rule State */ export interface ApprovalRuleState { approvalRuleById: Record; } export interface ApprovalRule { approvalRuleId: ID; createTime: ZeniDate; criteria: Criteria[]; entityType: EntityType; steps: Step[]; updateTime: ZeniDate; /** Backend bookkeeping: whether approval steps must run serialized. */ areApprovalsSerialized?: boolean; /** Free-text description shown beneath the rule name on the list page. */ description?: string; /** True when this rule is the tenant's default fallback rule. */ isFallback?: boolean; name?: string; /** Backend bookkeeping: number of entities currently pending against this rule. */ pendingApprovalsCount?: number; /** Backend bookkeeping: status of background updates against this rule. */ pendingEntityApprovalUpdateStatus?: string; /** Rule's position in the evaluation order; lower number = higher priority. */ priority?: number; /** * When on, the creator of a bill/reimbursement cannot auto-approve * their own request even if they are also an approver. Backend spec * is still pending — kept optional for now. */ separationOfDuties?: boolean; version?: number | string; } export interface Approvers { attributes: AttributeType[]; users: User[]; displayPendingApproverAsAdmin?: boolean; } export {};