import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { Transaction, Updateable } from "../generated/kysely-tailordb"; import { StorageLocationNotFoundError, DuplicateLocationNameError } from "../lib/errors.generated"; export type UpdateStorageLocationInput = { id: string; name?: string; storageCondition?: string | null; capacity?: number | null; }; /** * Function: updateStorageLocation * * Modifies the mutable fields of a storage location, including name, * storageCondition, and capacity. siteId and code are immutable after creation. */ export async function run( db: Transaction, input: UpdateStorageLocationInput, _ctx: CommandContext, ) { const { name, storageCondition, capacity } = input; // 1. Check storage location exists const location = await db .selectFrom("StorageLocation") .selectAll() .where("id", "=", input.id) .forUpdate() .executeTakeFirst(); if (!location) { return err(new StorageLocationNotFoundError(input.id)); } // 2. If name changed, check uniqueness within site const nameChanged = name !== undefined && name !== location.name; if (nameChanged) { const checkName = name ?? location.name; const duplicate = await db .selectFrom("StorageLocation") .selectAll() .where("siteId", "=", location.siteId) .where("id", "!=", location.id) .where("name", "=", checkName) .forUpdate() .executeTakeFirst(); if (duplicate) { return err(new DuplicateLocationNameError(checkName)); } } // 3. Build update set const updates: Updateable<"StorageLocation"> = {}; if (name !== undefined) updates.name = name; if (storageCondition !== undefined) updates.storageCondition = storageCondition; if (capacity !== undefined) updates.capacity = capacity !== null ? String(capacity) : null; if (Object.keys(updates).length === 0) { return ok({ storageLocation: location }); } // 4. Update location const updatedLocation = await db .updateTable("StorageLocation") .set(updates) .where("id", "=", location.id) .returningAll() .executeTakeFirstOrThrow(); return ok({ storageLocation: updatedLocation }); }