metis-desk/modules/assets/src/api/application/workstation-input.mapper.ts
David 002781b56d feat: update asset status handling and improve UI labels
- Changed asset status label from "status" to "technicalStatus" in AssetForm component.
- Added help text for technical status in AssetForm.
- Updated test cases to reflect changes in asset status from "available" to "operational".
- Enhanced workstation form to utilize new asset status checks and display appropriate messages.
- Refactored asset context to replace "available" with "notRetired" across various application policies and repositories.
- Introduced new utility functions for asset status management, including technical status determination and assignment validation.
- Added integration tests for asset state verification and unlinking assets from workstations.
2026-10-13 11:35:31 +02:00

88 lines
2.6 KiB
TypeScript

import { Result } from "@repo/rdx-utils";
import { AssetCatalogError } from "../domain/asset-definition";
import { canAssignAsset } from "../domain/asset-state";
import { WorkstationValues } from "../domain/value-objects/workstation-values.vo";
import type { Workstation } from "../domain/workstation.aggregate";
import type { WorkstationInput } from "../domain/workstation-values";
import type { InventoryContext } from "./asset.repository";
export function mapWorkstationInput(
input: WorkstationInput,
context: InventoryContext,
previous?: Workstation
) {
const mapped = WorkstationValues.create(input);
if (!mapped.isSuccess) {
return mapped;
}
const values = mapped.data.toPrimitive();
if (values.siteId && !context.sites.some((id) => id.toPrimitive() === values.siteId)) {
return Result.fail(new AssetCatalogError("SITE_NOT_FOUND"));
}
const person = context.people.find((item) => item.id.toPrimitive() === values.personId);
if (
values.personId &&
(!person || (!person.active && previous?.values.toPrimitive().personId !== values.personId))
) {
return Result.fail(new AssetCatalogError("PERSON_UNAVAILABLE"));
}
for (const id of [...values.assetIds, ...values.sharedAssetIds]) {
const error = memberError(id, values, context, previous);
if (error) {
return Result.fail(new AssetCatalogError(error));
}
}
return mapped;
}
function memberError(
id: string,
values: WorkstationInput,
context: InventoryContext,
previous: Workstation | undefined
) {
const asset = context.assets.find((item) => item.id.toPrimitive() === id);
if (!asset) {
return "ASSET_NOT_FOUND";
}
if (!values.active) {
return undefined;
}
const exclusive = values.assetIds.includes(id);
const previousMembers = exclusive ? previous?.values.assetIds : previous?.values.sharedAssetIds;
const retained =
previous?.values.active && previousMembers?.some((item) => item.toPrimitive() === id);
if (
!(
retained ||
canAssignAsset(asset.values.technicalStatus, exclusive ? "exclusive" : "shared", false, false)
)
) {
return "ASSET_NOT_OPERATIONAL";
}
const others = context.workstations.filter(
(item) => item.values.active && item.id.toPrimitive() !== previous?.id.toPrimitive()
);
const exclusiveElsewhere = others.some((item) =>
item.values.assetIds.some((assetId) => assetId.toPrimitive() === id)
);
const sharedElsewhere = others.some((item) =>
item.values.sharedAssetIds.some((assetId) => assetId.toPrimitive() === id)
);
if (exclusiveElsewhere || (exclusive && sharedElsewhere)) {
return "ASSET_IN_WORKSTATION";
}
return undefined;
}