import type { PurchaseRequestStatus } from "../api/purchaseRequests"; import type { AssetSensitivityLevel, AssetStatus, AssetType } from "../api/assets"; const PURCHASE_STATUS_VALUES = new Set([ "draft", "reviewing", "approved", "rejected", "cancelled", ]); const ASSET_STATUS_VALUES = new Set([ "in_stock", "in_use", "under_repair", "retired", "archived", ]); const ASSET_TYPE_VALUES = new Set([ "fixed_asset", "electronic_document", "electronic_system", "code_repository", "backup_media", ]); const ASSET_SENSITIVITY_VALUES = new Set([ "public_candidate", "internal", "confidential", "strictly_confidential", ]); export const ASSET_CREATE_PATH = "/assets/new"; function normalizedEntityId(value: string) { return value.trim(); } function optionalSearchValue(searchParams: URLSearchParams, key: string) { return (searchParams.get(key) ?? "").trim(); } function positivePage(value: string | null) { if (!value || !/^[1-9]\d*$/.test(value)) { return 1; } const parsed = Number(value); return Number.isSafeInteger(parsed) ? parsed : 1; } function appendOptional(target: URLSearchParams, key: string, value: string) { if (value) { target.set(key, value); } } export function buildPurchaseRequestDetailPath(purchaseRequestId: string) { const normalized = normalizedEntityId(purchaseRequestId); return normalized ? `/purchase-requests/${encodeURIComponent(normalized)}` : "/purchase-requests"; } export function buildAssetDetailPath(assetId: string) { const normalized = normalizedEntityId(assetId); return normalized ? `/assets/${encodeURIComponent(normalized)}` : "/assets"; } export function readPurchaseListFilters( searchParams: URLSearchParams, canViewAll: boolean, ): { status: PurchaseRequestStatus | ""; mine: boolean; supplierId: string; legalEntityId: string; costCenterId: string; page: number; } { const rawStatus = searchParams.get("status"); const status = rawStatus === "all" ? "" : rawStatus && PURCHASE_STATUS_VALUES.has(rawStatus as PurchaseRequestStatus) ? rawStatus as PurchaseRequestStatus : "draft"; const scope = searchParams.get("scope"); return { status, mine: !(canViewAll && scope === "all"), supplierId: optionalSearchValue(searchParams, "supplierId"), legalEntityId: optionalSearchValue(searchParams, "legalEntityId"), costCenterId: optionalSearchValue(searchParams, "costCenterId"), page: positivePage(searchParams.get("page")), }; } export function normalizePurchaseListSearchParams(searchParams: URLSearchParams) { const normalized = new URLSearchParams(); const rawStatus = searchParams.get("status"); if (rawStatus === "all" || (rawStatus && PURCHASE_STATUS_VALUES.has(rawStatus as PurchaseRequestStatus))) { normalized.set("status", rawStatus); } const rawScope = searchParams.get("scope"); if (rawScope === "own" || rawScope === "all") { normalized.set("scope", rawScope); } appendOptional(normalized, "supplierId", optionalSearchValue(searchParams, "supplierId")); appendOptional(normalized, "legalEntityId", optionalSearchValue(searchParams, "legalEntityId")); appendOptional(normalized, "costCenterId", optionalSearchValue(searchParams, "costCenterId")); const page = positivePage(searchParams.get("page")); if (page > 1) { normalized.set("page", String(page)); } return normalized; } export function readAssetListFilters( searchParams: URLSearchParams, canViewAll: boolean, ): { q: string; status: AssetStatus | ""; assetType: AssetType | ""; sensitivity: AssetSensitivityLevel | ""; categoryId: string; legalEntityId: string; costCenterId: string; assigneeId: string; mine: boolean; } { const rawStatus = searchParams.get("status"); const rawAssetType = searchParams.get("assetType"); const rawSensitivity = searchParams.get("sensitivity"); const scope = searchParams.get("scope"); return { q: searchParams.get("q") ?? "", status: rawStatus && ASSET_STATUS_VALUES.has(rawStatus as AssetStatus) ? rawStatus as AssetStatus : "", assetType: rawAssetType && ASSET_TYPE_VALUES.has(rawAssetType as AssetType) ? rawAssetType as AssetType : "", sensitivity: rawSensitivity && ASSET_SENSITIVITY_VALUES.has(rawSensitivity as AssetSensitivityLevel) ? rawSensitivity as AssetSensitivityLevel : "", categoryId: optionalSearchValue(searchParams, "categoryId"), legalEntityId: optionalSearchValue(searchParams, "legalEntityId"), costCenterId: optionalSearchValue(searchParams, "costCenterId"), assigneeId: optionalSearchValue(searchParams, "assigneeId"), mine: scope === "own" || !(canViewAll && (scope === "all" || scope == null)), }; } export function normalizeAssetListSearchParams(searchParams: URLSearchParams) { const normalized = new URLSearchParams(); appendOptional(normalized, "q", optionalSearchValue(searchParams, "q")); const rawStatus = searchParams.get("status"); if (rawStatus && ASSET_STATUS_VALUES.has(rawStatus as AssetStatus)) { normalized.set("status", rawStatus); } const rawAssetType = searchParams.get("assetType"); if (rawAssetType && ASSET_TYPE_VALUES.has(rawAssetType as AssetType)) { normalized.set("assetType", rawAssetType); } const rawSensitivity = searchParams.get("sensitivity"); if (rawSensitivity && ASSET_SENSITIVITY_VALUES.has(rawSensitivity as AssetSensitivityLevel)) { normalized.set("sensitivity", rawSensitivity); } appendOptional(normalized, "categoryId", optionalSearchValue(searchParams, "categoryId")); appendOptional(normalized, "legalEntityId", optionalSearchValue(searchParams, "legalEntityId")); appendOptional(normalized, "costCenterId", optionalSearchValue(searchParams, "costCenterId")); appendOptional(normalized, "assigneeId", optionalSearchValue(searchParams, "assigneeId")); const rawScope = searchParams.get("scope"); if (rawScope === "own" || rawScope === "all") { normalized.set("scope", rawScope); } return normalized; } function listSource(pathname: string, searchParams: URLSearchParams) { const search = searchParams.toString(); return search ? `${pathname}?${search}` : pathname; } export function resolvePurchaseRequestLegacyRedirect(searchParams: URLSearchParams) { const purchaseRequestId = normalizedEntityId(searchParams.get("id") ?? ""); if (!purchaseRequestId) { return null; } return { to: buildPurchaseRequestDetailPath(purchaseRequestId), from: listSource("/purchase-requests", normalizePurchaseListSearchParams(searchParams)), }; } export function resolveAssetLegacyRedirect(searchParams: URLSearchParams) { const assetId = normalizedEntityId(searchParams.get("id") ?? ""); if (!assetId) { return null; } return { to: buildAssetDetailPath(assetId), from: listSource("/assets", normalizeAssetListSearchParams(searchParams)), }; }