refactor: rename remaining recipient references to person/people
This commit is contained in:
@@ -134,7 +134,7 @@ model Assignment {
|
||||
assetId String? @unique
|
||||
asset Asset? @relation(fields: [assetId], references: [id], onDelete: SetNull, onUpdate: Cascade)
|
||||
recipientId String?
|
||||
recipient Person? @relation(fields: [recipientId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
person Person? @relation(fields: [recipientId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
assignmentDate DateTime @default(now())
|
||||
returnDate DateTime?
|
||||
createdBy String
|
||||
@@ -171,7 +171,7 @@ model Movement {
|
||||
previousStock Int?
|
||||
newStock Int?
|
||||
recipientId String?
|
||||
recipient Person? @relation(fields: [recipientId], references: [id], onDelete: SetNull, onUpdate: Cascade)
|
||||
person Person? @relation(fields: [recipientId], references: [id], onDelete: SetNull, onUpdate: Cascade)
|
||||
assignmentId String?
|
||||
assignment Assignment? @relation(fields: [assignmentId], references: [id], onDelete: SetNull, onUpdate: Cascade)
|
||||
userId String
|
||||
|
||||
@@ -308,7 +308,7 @@ export async function importItems(formData: ImportFormType) {
|
||||
notes: deliveryNote || "",
|
||||
itemId: newItem?.id || "",
|
||||
assetId: newAsset?.id || "",
|
||||
recipientId: newPerson?.id || "",
|
||||
personId: newPerson?.id || "",
|
||||
assignmentDate: new Date(),
|
||||
createdBy: userId,
|
||||
})
|
||||
@@ -319,7 +319,7 @@ export async function importItems(formData: ImportFormType) {
|
||||
quantity: stock || 1,
|
||||
type: assigned ? "ASSIGNMENT" : "IN",
|
||||
itemId: newItem?.id || undefined,
|
||||
recipientId: newPerson?.id || undefined,
|
||||
personId: newPerson?.id || undefined,
|
||||
}
|
||||
|
||||
if (newAssignment?.id) {
|
||||
@@ -327,7 +327,7 @@ export async function importItems(formData: ImportFormType) {
|
||||
}
|
||||
|
||||
if (newPerson?.id) {
|
||||
movementData.recipientId = newPerson.id
|
||||
movementData.personId = newPerson.id
|
||||
}
|
||||
|
||||
await MovementService.create({
|
||||
|
||||
@@ -77,7 +77,7 @@ export default async function Home() {
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
role="img"
|
||||
aria-label="total-recipients"
|
||||
aria-label="total-people"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { getI18n } from "@/i18n/server"
|
||||
import type { UpdateAssignmentFormType } from "@/schemas/assignment.schema"
|
||||
import { AssetService } from "@/services/asset.service"
|
||||
import { AssignmentService } from "@/services/assignment.service"
|
||||
import { ItemService } from "@/services/item.service"
|
||||
@@ -37,10 +36,19 @@ export default async function EditAssignmentPage({
|
||||
<h1 className="text-2xl font-bold">{copy.edit.title}</h1>
|
||||
</div>
|
||||
<AssignmentForm
|
||||
recipients={people}
|
||||
people={people}
|
||||
items={items}
|
||||
assets={assets}
|
||||
initialData={assignment as UpdateAssignmentFormType}
|
||||
initialData={{
|
||||
...assignment,
|
||||
id: assignment.id,
|
||||
personId: assignment.recipientId ?? "",
|
||||
itemId: assignment.itemId ?? undefined,
|
||||
assetId: assignment.assetId ?? undefined,
|
||||
quantity: assignment.quantity ?? undefined,
|
||||
notes: assignment.notes ?? undefined,
|
||||
assignmentDate: assignment.assignmentDate ?? undefined,
|
||||
}}
|
||||
formCopy={copy.form}
|
||||
schemaCopy={copy.schema}
|
||||
submitButtonCopy={dictionary.common.submitButton}
|
||||
|
||||
@@ -21,7 +21,7 @@ type AssignmentFormCopy = Dictionary["inventory"]["assignments"]["form"]
|
||||
type AssignmentSchemaCopy = Dictionary["inventory"]["assignments"]["schema"]
|
||||
|
||||
interface Props {
|
||||
recipients: Person[]
|
||||
people: Person[]
|
||||
items: Item[]
|
||||
assets: Asset[]
|
||||
initialData: UpdateAssignmentFormType
|
||||
@@ -31,7 +31,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function EditAssignmentForm({
|
||||
recipients,
|
||||
people,
|
||||
items,
|
||||
assets,
|
||||
initialData,
|
||||
@@ -84,24 +84,24 @@ export default function EditAssignmentForm({
|
||||
<form className="flex flex-col gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<input type="hidden" {...register("id")} />
|
||||
<div className="flex flex-col gap-2">
|
||||
<label htmlFor="recipientId" className="mb-2 block text-lg">
|
||||
{formCopy.recipientLabel}
|
||||
<label htmlFor="personId" className="mb-2 block text-lg">
|
||||
{formCopy.personLabel}
|
||||
</label>
|
||||
<select
|
||||
id="recipientId"
|
||||
{...register("recipientId")}
|
||||
id="personId"
|
||||
{...register("personId")}
|
||||
className={`w-full rounded-lg border px-4 py-2 ${
|
||||
errors.recipientId ? "border-error" : ""
|
||||
errors.personId ? "border-error" : ""
|
||||
}`}
|
||||
>
|
||||
{recipients.map((recipient) => (
|
||||
<option key={recipient.id} value={recipient.id}>
|
||||
{recipient.firstName} {recipient.lastName}
|
||||
{people.map((person) => (
|
||||
<option key={person.id} value={person.id}>
|
||||
{person.firstName} {person.lastName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{errors.recipientId && (
|
||||
<p className="text-error">{errors.recipientId.message}</p>
|
||||
{errors.personId && (
|
||||
<p className="text-error">{errors.personId.message}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
|
||||
@@ -21,7 +21,7 @@ type AssignmentFormCopy = Dictionary["inventory"]["assignments"]["form"]
|
||||
type AssignmentSchemaCopy = Dictionary["inventory"]["assignments"]["schema"]
|
||||
|
||||
interface Props {
|
||||
recipients: Person[]
|
||||
people: Person[]
|
||||
items: Item[]
|
||||
assets: Asset[]
|
||||
formCopy: AssignmentFormCopy
|
||||
@@ -30,7 +30,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function CreateAssignmentForm({
|
||||
recipients,
|
||||
people,
|
||||
items,
|
||||
assets,
|
||||
formCopy,
|
||||
@@ -81,25 +81,25 @@ export default function CreateAssignmentForm({
|
||||
return (
|
||||
<form className="flex flex-col gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="flex flex-col gap-2">
|
||||
<label htmlFor="recipientId" className="mb-2 block text-lg">
|
||||
{formCopy.recipientLabel}
|
||||
<label htmlFor="personId" className="mb-2 block text-lg">
|
||||
{formCopy.personLabel}
|
||||
</label>
|
||||
<select
|
||||
id="recipientId"
|
||||
{...register("recipientId")}
|
||||
id="personId"
|
||||
{...register("personId")}
|
||||
className={`w-full rounded-lg border px-4 py-2 ${
|
||||
errors.recipientId ? "border-error" : ""
|
||||
errors.personId ? "border-error" : ""
|
||||
}`}
|
||||
>
|
||||
<option value="">{formCopy.recipientPlaceholder}</option>
|
||||
{recipients.map((recipient) => (
|
||||
<option key={recipient.id} value={recipient.id}>
|
||||
{recipient.firstName} {recipient.lastName}
|
||||
<option value="">{formCopy.personPlaceholder}</option>
|
||||
{people.map((person) => (
|
||||
<option key={person.id} value={person.id}>
|
||||
{person.firstName} {person.lastName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{errors.recipientId && (
|
||||
<p className="text-error">{errors.recipientId.message}</p>
|
||||
{errors.personId && (
|
||||
<p className="text-error">{errors.personId.message}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
|
||||
@@ -18,7 +18,7 @@ export default async function NewAssignmentPage() {
|
||||
<h1 className="text-2xl font-bold">{copy.new.title}</h1>
|
||||
</div>
|
||||
<AssignmentForm
|
||||
recipients={people}
|
||||
people={people}
|
||||
items={items}
|
||||
assets={assets}
|
||||
formCopy={copy.form}
|
||||
|
||||
@@ -19,7 +19,7 @@ export default async function AssignmentsPage(props: {
|
||||
const currentPage = searchParams?.page ? parseInt(searchParams.page, 10) : 1
|
||||
const search = searchParams?.search || ""
|
||||
const { data: assignments, totalPages } =
|
||||
await AssignmentService.findAllWithRecipientPaginated({
|
||||
await AssignmentService.findAllWithPersonPaginated({
|
||||
page: currentPage,
|
||||
search,
|
||||
})
|
||||
@@ -42,7 +42,7 @@ export default async function AssignmentsPage(props: {
|
||||
<thead className="border-b">
|
||||
<tr>
|
||||
<th scope="col" className="p-4">
|
||||
{copy.list.columns.recipient}
|
||||
{copy.list.columns.person}
|
||||
</th>
|
||||
<th scope="col" className="p-4">
|
||||
{copy.list.columns.item}
|
||||
@@ -63,11 +63,11 @@ export default async function AssignmentsPage(props: {
|
||||
<tr key={assignment.id} className="border-b">
|
||||
<td className="p-4">
|
||||
<Link
|
||||
href={`/people/${assignment?.recipient?.id}`}
|
||||
href={`/people/${assignment?.person?.id}`}
|
||||
className="hover:underline"
|
||||
>
|
||||
{assignment?.recipient?.firstName}{" "}
|
||||
{assignment?.recipient?.lastName}
|
||||
{assignment?.person?.firstName}{" "}
|
||||
{assignment?.person?.lastName}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="p-4">
|
||||
|
||||
@@ -31,7 +31,7 @@ export default async function EditAssetPage({
|
||||
</div>
|
||||
<EditAssetForm
|
||||
items={items}
|
||||
recipients={people}
|
||||
people={people}
|
||||
asset={asset as unknown as AssetWithAssignment}
|
||||
formCopy={copy.form}
|
||||
schemaCopy={copy.schema}
|
||||
|
||||
@@ -31,7 +31,7 @@ import type {
|
||||
interface EditAssetFormProps {
|
||||
asset: AssetWithAssignment
|
||||
items: Item[]
|
||||
recipients: Person[]
|
||||
people: Person[]
|
||||
formCopy: AssetFormCopy
|
||||
schemaCopy: AssetSchemaCopy
|
||||
statusCopy: AssetStatusCopy
|
||||
@@ -41,7 +41,7 @@ interface EditAssetFormProps {
|
||||
export default function EditAssetForm({
|
||||
asset,
|
||||
items,
|
||||
recipients,
|
||||
people,
|
||||
formCopy,
|
||||
schemaCopy,
|
||||
statusCopy,
|
||||
@@ -64,7 +64,7 @@ export default function EditAssetForm({
|
||||
serialNumber: asset.serialNumber,
|
||||
deliveryNote: asset.deliveryNote ?? undefined,
|
||||
status: asset.status as UpdateAssetStatus,
|
||||
recipientId: asset.assignment?.recipientId ?? undefined,
|
||||
personId: asset.assignment?.recipientId ?? undefined,
|
||||
},
|
||||
shouldFocusError: true,
|
||||
mode: "onSubmit",
|
||||
@@ -168,23 +168,23 @@ export default function EditAssetForm({
|
||||
</div>
|
||||
{status === "ASSIGNED" && (
|
||||
<div>
|
||||
<label htmlFor="recipientId" className="mb-2 block text-lg">
|
||||
{formCopy.recipientLabel}
|
||||
<label htmlFor="personId" className="mb-2 block text-lg">
|
||||
{formCopy.personLabel}
|
||||
</label>
|
||||
<select
|
||||
id="recipientId"
|
||||
{...register("recipientId")}
|
||||
id="personId"
|
||||
{...register("personId")}
|
||||
className="w-full rounded-lg border px-4 py-2"
|
||||
>
|
||||
<option value="">{formCopy.recipientPlaceholder}</option>
|
||||
{recipients?.map((recipient) => (
|
||||
<option key={recipient.id} value={recipient.id}>
|
||||
{recipient.firstName} {recipient.lastName}
|
||||
<option value="">{formCopy.personPlaceholder}</option>
|
||||
{people?.map((person) => (
|
||||
<option key={person.id} value={person.id}>
|
||||
{person.firstName} {person.lastName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{errors?.recipientId && (
|
||||
<p className="text-error">{errors.recipientId.message}</p>
|
||||
{errors?.personId && (
|
||||
<p className="text-error">{errors.personId.message}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -25,7 +25,7 @@ import type {
|
||||
|
||||
interface NewAssetFormProps {
|
||||
items: ItemWithoutStock[]
|
||||
recipients: Person[]
|
||||
people: Person[]
|
||||
formCopy: AssetFormCopy
|
||||
schemaCopy: AssetSchemaCopy
|
||||
statusCopy: AssetStatusCopy
|
||||
@@ -34,7 +34,7 @@ interface NewAssetFormProps {
|
||||
|
||||
export default function NewAssetForm({
|
||||
items,
|
||||
recipients,
|
||||
people,
|
||||
formCopy,
|
||||
schemaCopy,
|
||||
statusCopy,
|
||||
@@ -156,23 +156,23 @@ export default function NewAssetForm({
|
||||
</div>
|
||||
{status === "ASSIGNED" && (
|
||||
<div>
|
||||
<label htmlFor="recipientId" className="mb-2 block text-lg">
|
||||
{formCopy.recipientLabel}
|
||||
<label htmlFor="personId" className="mb-2 block text-lg">
|
||||
{formCopy.personLabel}
|
||||
</label>
|
||||
<select
|
||||
id="recipientId"
|
||||
{...register("recipientId")}
|
||||
id="personId"
|
||||
{...register("personId")}
|
||||
className="w-full rounded-lg border px-4 py-2"
|
||||
>
|
||||
<option value="">{formCopy.recipientPlaceholder}</option>
|
||||
{recipients?.map((recipient) => (
|
||||
<option key={recipient.id} value={recipient.id}>
|
||||
{recipient.firstName} {recipient.lastName}
|
||||
<option value="">{formCopy.personPlaceholder}</option>
|
||||
{people?.map((person) => (
|
||||
<option key={person.id} value={person.id}>
|
||||
{person.firstName} {person.lastName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{errors?.recipientId && (
|
||||
<p className="text-error">{errors.recipientId.message}</p>
|
||||
{errors?.personId && (
|
||||
<p className="text-error">{errors.personId.message}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -19,7 +19,7 @@ export default async function NewAssetPage() {
|
||||
</div>
|
||||
<NewAssetForm
|
||||
items={items}
|
||||
recipients={people}
|
||||
people={people}
|
||||
formCopy={copy.form}
|
||||
schemaCopy={copy.schema}
|
||||
statusCopy={copy.status}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default async function MovementsPage(props: {
|
||||
{copy.list.columns.quantity}
|
||||
</th>
|
||||
<th scope="col" className="p-4">
|
||||
{copy.list.columns.recipient}
|
||||
{copy.list.columns.person}
|
||||
</th>
|
||||
<th scope="col" className="p-4">
|
||||
{copy.list.columns.date}
|
||||
@@ -69,8 +69,8 @@ export default async function MovementsPage(props: {
|
||||
</td>
|
||||
<td className="p-4">{movement.quantity}</td>
|
||||
<td className="p-4">
|
||||
{movement?.recipient
|
||||
? `${movement.recipient.firstName} ${movement.recipient.lastName}`
|
||||
{movement?.person
|
||||
? `${movement.person.firstName} ${movement.person.lastName}`
|
||||
: copy.fallback.missingValue}
|
||||
</td>
|
||||
<td className="p-4">{formatDate(movement.createdAt)}</td>
|
||||
|
||||
@@ -214,8 +214,8 @@ export const en = {
|
||||
deliveryNotePlaceholder: "Delivery note",
|
||||
statusLabel: "Status",
|
||||
statusPlaceholder: "Select a status",
|
||||
recipientLabel: "Recipient",
|
||||
recipientPlaceholder: "Select a recipient",
|
||||
personLabel: "Person",
|
||||
personPlaceholder: "Select a person",
|
||||
createSubmit: "Create Asset",
|
||||
updateSubmit: "Update Asset",
|
||||
},
|
||||
@@ -242,7 +242,7 @@ export const en = {
|
||||
assignmentAlreadyReturned: "Assignment already returned",
|
||||
previousItemNotFound: "Previous item not found for available asset",
|
||||
insufficientStock: "Item does not have enough stock",
|
||||
recipientRequired: "Recipient is required",
|
||||
personRequired: "Person is required",
|
||||
invalidStatus: "Invalid status",
|
||||
genericFailure: "Error processing asset",
|
||||
},
|
||||
@@ -261,7 +261,7 @@ export const en = {
|
||||
addLabel: "Add Assignment",
|
||||
empty: "No assignments found.",
|
||||
columns: {
|
||||
recipient: "Recipient",
|
||||
person: "Person",
|
||||
item: "Item",
|
||||
serialNumber: "Serial Number",
|
||||
quantity: "Quantity",
|
||||
@@ -280,8 +280,8 @@ export const en = {
|
||||
notFound: "Assignment not found",
|
||||
},
|
||||
form: {
|
||||
recipientLabel: "Recipient",
|
||||
recipientPlaceholder: "Select a recipient",
|
||||
personLabel: "Person",
|
||||
personPlaceholder: "Select a person",
|
||||
itemLabel: "Item",
|
||||
itemPlaceholder: "Select an item",
|
||||
assetLabel: "Asset",
|
||||
@@ -311,7 +311,7 @@ export const en = {
|
||||
genericFailure: "Error processing assignment",
|
||||
},
|
||||
schema: {
|
||||
recipientRequired: "Recipient is required",
|
||||
personRequired: "Person is required",
|
||||
itemIdRequired: "Item is required",
|
||||
quantityMinOne: "Quantity must be at least 1",
|
||||
assetIdRequired: "Asset ID is required when item ID is provided",
|
||||
@@ -402,7 +402,7 @@ export const en = {
|
||||
item: "Item",
|
||||
serialNumber: "Serial Number",
|
||||
quantity: "Quantity",
|
||||
recipient: "Recipient",
|
||||
person: "Person",
|
||||
date: "Date",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -217,8 +217,8 @@ export const es = {
|
||||
deliveryNotePlaceholder: "Remito",
|
||||
statusLabel: "Estado",
|
||||
statusPlaceholder: "Selecciona un estado",
|
||||
recipientLabel: "Destinatario",
|
||||
recipientPlaceholder: "Selecciona un destinatario",
|
||||
personLabel: "Persona",
|
||||
personPlaceholder: "Selecciona una persona",
|
||||
createSubmit: "Crear activo",
|
||||
updateSubmit: "Actualizar activo",
|
||||
},
|
||||
@@ -246,7 +246,7 @@ export const es = {
|
||||
previousItemNotFound:
|
||||
"Artículo anterior no encontrado para el activo disponible",
|
||||
insufficientStock: "El artículo no tiene stock suficiente",
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
personRequired: "La persona es obligatoria",
|
||||
invalidStatus: "Estado inválido",
|
||||
genericFailure: "Error al procesar el activo",
|
||||
},
|
||||
@@ -265,7 +265,7 @@ export const es = {
|
||||
addLabel: "Agregar asignación",
|
||||
empty: "No se encontraron asignaciones.",
|
||||
columns: {
|
||||
recipient: "Destinatario",
|
||||
person: "Persona",
|
||||
item: "Artículo",
|
||||
serialNumber: "Número de serie",
|
||||
quantity: "Cantidad",
|
||||
@@ -284,8 +284,8 @@ export const es = {
|
||||
notFound: "Asignación no encontrada",
|
||||
},
|
||||
form: {
|
||||
recipientLabel: "Destinatario",
|
||||
recipientPlaceholder: "Selecciona un destinatario",
|
||||
personLabel: "Persona",
|
||||
personPlaceholder: "Selecciona una persona",
|
||||
itemLabel: "Artículo",
|
||||
itemPlaceholder: "Selecciona un artículo",
|
||||
assetLabel: "Activo",
|
||||
@@ -315,7 +315,7 @@ export const es = {
|
||||
genericFailure: "Error al procesar la asignación",
|
||||
},
|
||||
schema: {
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
personRequired: "La persona es obligatoria",
|
||||
itemIdRequired: "El artículo es obligatorio",
|
||||
quantityMinOne: "La cantidad debe ser al menos 1",
|
||||
assetIdRequired:
|
||||
@@ -407,7 +407,7 @@ export const es = {
|
||||
item: "Artículo",
|
||||
serialNumber: "Número de serie",
|
||||
quantity: "Cantidad",
|
||||
recipient: "Destinatario",
|
||||
person: "Persona",
|
||||
date: "Fecha",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ function buildAssetBaseSchema(copy: AssetSchemaCopy) {
|
||||
}),
|
||||
deliveryNote: z.string().optional(),
|
||||
notes: z.string().optional(),
|
||||
recipientId: z.string().optional(),
|
||||
personId: z.string().optional(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ export type AssignmentSchemaCopy =
|
||||
Dictionary["inventory"]["assignments"]["schema"]
|
||||
|
||||
const defaultAssignmentSchemaCopy: AssignmentSchemaCopy = {
|
||||
recipientRequired: "Recipient is required",
|
||||
personRequired: "Person is required",
|
||||
itemIdRequired: "Item is required",
|
||||
quantityMinOne: "Quantity must be at least 1",
|
||||
assetIdRequired: "Asset ID is required when item ID is provided",
|
||||
@@ -27,8 +27,8 @@ function buildAssignmentBaseSchema(copy: AssignmentSchemaCopy) {
|
||||
})
|
||||
.optional(),
|
||||
assetId: z.string().optional(),
|
||||
recipientId: z.string().min(1, {
|
||||
error: copy.recipientRequired,
|
||||
personId: z.string().min(1, {
|
||||
error: copy.personRequired,
|
||||
}),
|
||||
assignmentDate: z.date().optional(),
|
||||
returnDate: z.date().optional(),
|
||||
|
||||
@@ -11,7 +11,7 @@ export const movementSchema = z.object({
|
||||
assetId: z.string().optional(),
|
||||
userId: z.string(),
|
||||
assignmentId: z.string().optional(),
|
||||
recipientId: z.string().optional(),
|
||||
personId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const createMovementSchema = movementSchema.omit({
|
||||
|
||||
@@ -2,12 +2,10 @@ import type { Prisma } from "@/generated/prisma/client"
|
||||
import { paginate } from "@/lib/paginate"
|
||||
import prisma from "@/lib/prisma"
|
||||
import type { CreateAssignmentData } from "@/schemas/assignment.schema"
|
||||
import type { Assignment, AssignmentWithRecipientItemAsset } from "@/types"
|
||||
import type { Assignment, AssignmentWithPersonItemAsset } from "@/types"
|
||||
|
||||
export const AssignmentService = {
|
||||
findAllWithRecipient: async (): Promise<
|
||||
AssignmentWithRecipientItemAsset[]
|
||||
> => {
|
||||
findAllWithPerson: async (): Promise<AssignmentWithPersonItemAsset[]> => {
|
||||
return prisma.assignment.findMany({
|
||||
where: {
|
||||
returnDate: {
|
||||
@@ -15,7 +13,7 @@ export const AssignmentService = {
|
||||
},
|
||||
},
|
||||
include: {
|
||||
recipient: true,
|
||||
person: true,
|
||||
item: true,
|
||||
asset: true,
|
||||
},
|
||||
@@ -24,7 +22,7 @@ export const AssignmentService = {
|
||||
},
|
||||
})
|
||||
},
|
||||
findAllWithRecipientPaginated: async ({
|
||||
findAllWithPersonPaginated: async ({
|
||||
page,
|
||||
pageSize,
|
||||
search,
|
||||
@@ -33,7 +31,7 @@ export const AssignmentService = {
|
||||
pageSize?: number
|
||||
search?: string
|
||||
}) => {
|
||||
return paginate<AssignmentWithRecipientItemAsset>({
|
||||
return paginate<AssignmentWithPersonItemAsset>({
|
||||
model: prisma.assignment,
|
||||
page,
|
||||
pageSize,
|
||||
@@ -45,12 +43,12 @@ export const AssignmentService = {
|
||||
? {
|
||||
OR: [
|
||||
{
|
||||
recipient: {
|
||||
person: {
|
||||
firstName: { contains: search, mode: "insensitive" },
|
||||
},
|
||||
},
|
||||
{
|
||||
recipient: {
|
||||
person: {
|
||||
lastName: { contains: search, mode: "insensitive" },
|
||||
},
|
||||
},
|
||||
@@ -59,7 +57,7 @@ export const AssignmentService = {
|
||||
: {}),
|
||||
},
|
||||
include: {
|
||||
recipient: true,
|
||||
person: true,
|
||||
item: true,
|
||||
asset: true,
|
||||
},
|
||||
@@ -71,23 +69,23 @@ export const AssignmentService = {
|
||||
findById: async (
|
||||
id: string,
|
||||
db: Prisma.TransactionClient | typeof prisma = prisma,
|
||||
): Promise<AssignmentWithRecipientItemAsset | null> => {
|
||||
): Promise<AssignmentWithPersonItemAsset | null> => {
|
||||
return db.assignment.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
recipient: true,
|
||||
person: true,
|
||||
item: true,
|
||||
asset: true,
|
||||
},
|
||||
})
|
||||
},
|
||||
findAllByPerson: async (
|
||||
recipientId: string,
|
||||
): Promise<AssignmentWithRecipientItemAsset[]> => {
|
||||
personId: string,
|
||||
): Promise<AssignmentWithPersonItemAsset[]> => {
|
||||
return prisma.assignment.findMany({
|
||||
where: { recipientId },
|
||||
where: { recipientId: personId },
|
||||
include: {
|
||||
recipient: true,
|
||||
person: true,
|
||||
item: true,
|
||||
asset: true,
|
||||
},
|
||||
@@ -97,8 +95,12 @@ export const AssignmentService = {
|
||||
data: CreateAssignmentData & { createdBy: string },
|
||||
db: Prisma.TransactionClient | typeof prisma = prisma,
|
||||
): Promise<Assignment> => {
|
||||
const { personId, ...rest } = data
|
||||
return db.assignment.create({
|
||||
data,
|
||||
data: {
|
||||
...rest,
|
||||
recipientId: personId,
|
||||
},
|
||||
})
|
||||
},
|
||||
delete: async (id: string): Promise<Assignment> => {
|
||||
|
||||
@@ -11,7 +11,7 @@ type MovementListResult = {
|
||||
createdAt: Date
|
||||
item: { name: string } | null
|
||||
asset: { serialNumber: string } | null
|
||||
recipient: { firstName: string; lastName: string } | null
|
||||
person: { firstName: string; lastName: string } | null
|
||||
}
|
||||
|
||||
export const MovementService = {
|
||||
@@ -38,7 +38,7 @@ export const MovementService = {
|
||||
serialNumber: true,
|
||||
},
|
||||
},
|
||||
recipient: {
|
||||
person: {
|
||||
select: {
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
@@ -51,8 +51,12 @@ export const MovementService = {
|
||||
data: CreateMovementFormType & { userId: string },
|
||||
db: Prisma.TransactionClient | typeof prisma = prisma,
|
||||
): Promise<Movement> => {
|
||||
const { personId, ...rest } = data
|
||||
return await db.movement.create({
|
||||
data,
|
||||
data: {
|
||||
...rest,
|
||||
recipientId: personId,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ export type Assignment = PrismaAssignment
|
||||
|
||||
export type AssignmentSummary = Pick<Assignment, "id" | "quantity">
|
||||
|
||||
export type AssignmentWithRecipientItemAsset = Assignment & {
|
||||
export type AssignmentWithPersonItemAsset = Assignment & {
|
||||
returnDate: Date | null
|
||||
recipient: Person | null
|
||||
person: Person | null
|
||||
item: Item | null
|
||||
asset: Asset | null
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ type AssetTransitionInput = {
|
||||
previousItemId: string | null
|
||||
nextItemId: string
|
||||
activeAssignment: Assignment | null
|
||||
nextRecipientId?: string
|
||||
nextPersonId?: string
|
||||
}
|
||||
|
||||
function getAssetTransition({
|
||||
@@ -77,7 +77,7 @@ function getAssetTransition({
|
||||
previousItemId,
|
||||
nextItemId,
|
||||
activeAssignment,
|
||||
nextRecipientId,
|
||||
nextPersonId,
|
||||
}: AssetTransitionInput) {
|
||||
return {
|
||||
previousStatus,
|
||||
@@ -87,13 +87,13 @@ function getAssetTransition({
|
||||
statusChanged: previousStatus !== nextStatus,
|
||||
itemChanged: previousItemId !== nextItemId,
|
||||
activeAssignment,
|
||||
nextRecipientId,
|
||||
hasRecipient: Boolean(nextRecipientId),
|
||||
nextPersonId,
|
||||
hasPerson: Boolean(nextPersonId),
|
||||
wasAssigned: previousStatus === "ASSIGNED",
|
||||
willBeAssigned: nextStatus === "ASSIGNED",
|
||||
wasAvailable: previousStatus === "AVAILABLE",
|
||||
willBeAvailable: nextStatus === "AVAILABLE",
|
||||
recipientChanged: activeAssignment?.recipientId !== nextRecipientId,
|
||||
personChanged: activeAssignment?.recipientId !== nextPersonId,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export async function createAssetUseCase(
|
||||
deliveryNote,
|
||||
status,
|
||||
notes,
|
||||
recipientId,
|
||||
personId,
|
||||
} = input
|
||||
|
||||
try {
|
||||
@@ -141,14 +141,14 @@ export async function createAssetUseCase(
|
||||
)
|
||||
|
||||
const createdAssignment =
|
||||
status === "ASSIGNED" && recipientId
|
||||
status === "ASSIGNED" && personId
|
||||
? await AssignmentService.create(
|
||||
{
|
||||
notes: "",
|
||||
itemId,
|
||||
assetId: newAsset.id,
|
||||
quantity: 1,
|
||||
recipientId,
|
||||
personId,
|
||||
assignmentDate: new Date(),
|
||||
createdBy: actorId,
|
||||
},
|
||||
@@ -162,7 +162,7 @@ export async function createAssetUseCase(
|
||||
assetId: newAsset.id,
|
||||
quantity: 1,
|
||||
type: status === "ASSIGNED" ? "ASSIGNMENT" : "IN",
|
||||
recipientId: createdAssignment?.recipientId || undefined,
|
||||
personId: createdAssignment?.recipientId || undefined,
|
||||
assignmentId: createdAssignment?.id,
|
||||
userId: actorId,
|
||||
},
|
||||
@@ -203,7 +203,7 @@ export async function updateAssetUseCase(
|
||||
deliveryNote,
|
||||
status,
|
||||
notes,
|
||||
recipientId,
|
||||
personId,
|
||||
} = input
|
||||
|
||||
try {
|
||||
@@ -226,7 +226,7 @@ export async function updateAssetUseCase(
|
||||
previousItemId: currentAsset.itemId,
|
||||
nextItemId: itemId,
|
||||
activeAssignment: currentAsset.assignment,
|
||||
nextRecipientId: recipientId,
|
||||
nextPersonId: personId,
|
||||
})
|
||||
|
||||
const existentAsset = await AssetService.findBySerialNumber(
|
||||
@@ -277,7 +277,7 @@ export async function updateAssetUseCase(
|
||||
? transition.nextItemId
|
||||
: activeAssignment.itemId || undefined,
|
||||
assetId: activeAssignment.assetId || undefined,
|
||||
recipientId: activeAssignment.recipientId || undefined,
|
||||
personId: activeAssignment.recipientId || undefined,
|
||||
assignmentId: activeAssignment.id,
|
||||
userId: actorId,
|
||||
},
|
||||
@@ -296,7 +296,7 @@ export async function updateAssetUseCase(
|
||||
|
||||
if (
|
||||
transition.statusChanged &&
|
||||
!transition.hasRecipient &&
|
||||
!transition.hasPerson &&
|
||||
!closedActiveAssignment
|
||||
) {
|
||||
const statusMovementItemId = transition.willBeAssigned
|
||||
@@ -408,18 +408,18 @@ export async function updateAssetUseCase(
|
||||
}
|
||||
}
|
||||
|
||||
if (transition.willBeAssigned && transition.nextRecipientId) {
|
||||
if (transition.willBeAssigned && transition.nextPersonId) {
|
||||
const activeAssignment = transition.activeAssignment
|
||||
|
||||
if (activeAssignment) {
|
||||
if (transition.recipientChanged) {
|
||||
if (transition.personChanged) {
|
||||
await MovementService.create(
|
||||
{
|
||||
type: "RETURN",
|
||||
quantity: activeAssignment.quantity || 1,
|
||||
itemId: activeAssignment.itemId || undefined,
|
||||
assetId: activeAssignment.assetId || undefined,
|
||||
recipientId: activeAssignment.recipientId || undefined,
|
||||
personId: activeAssignment.recipientId || undefined,
|
||||
assignmentId: activeAssignment.id,
|
||||
userId: actorId,
|
||||
},
|
||||
@@ -432,7 +432,7 @@ export async function updateAssetUseCase(
|
||||
quantity: 1,
|
||||
itemId,
|
||||
assetId: id,
|
||||
recipientId: transition.nextRecipientId,
|
||||
personId: transition.nextPersonId,
|
||||
assignmentId: activeAssignment.id,
|
||||
userId: actorId,
|
||||
},
|
||||
@@ -445,7 +445,7 @@ export async function updateAssetUseCase(
|
||||
createdBy: actorId,
|
||||
itemId,
|
||||
assetId: id,
|
||||
recipientId: transition.nextRecipientId,
|
||||
recipientId: transition.nextPersonId,
|
||||
quantity: 1,
|
||||
returnDate: null,
|
||||
},
|
||||
@@ -457,7 +457,7 @@ export async function updateAssetUseCase(
|
||||
{
|
||||
itemId,
|
||||
assetId: id,
|
||||
recipientId: transition.nextRecipientId,
|
||||
recipientId: transition.nextPersonId,
|
||||
quantity: 1,
|
||||
returnDate: null,
|
||||
},
|
||||
@@ -470,7 +470,7 @@ export async function updateAssetUseCase(
|
||||
itemId,
|
||||
assetId: id,
|
||||
quantity: 1,
|
||||
recipientId: transition.nextRecipientId,
|
||||
personId: transition.nextPersonId,
|
||||
assignmentDate: new Date(),
|
||||
createdBy: actorId,
|
||||
},
|
||||
@@ -483,7 +483,7 @@ export async function updateAssetUseCase(
|
||||
quantity: 1,
|
||||
itemId,
|
||||
assetId: id,
|
||||
recipientId: transition.nextRecipientId,
|
||||
personId: transition.nextPersonId,
|
||||
assignmentId: createdAssignment.id,
|
||||
userId: actorId,
|
||||
},
|
||||
|
||||
@@ -81,9 +81,9 @@ function updateAssignmentError(
|
||||
export async function createAssignmentUseCase(
|
||||
input: CreateAssignmentUseCaseInput,
|
||||
): Promise<CreateAssignmentUseCaseResult> {
|
||||
const { actorId, itemId, assetId, quantity, recipientId } = input
|
||||
const { actorId, itemId, assetId, quantity, personId } = input
|
||||
|
||||
if (!itemId || !recipientId || quantity <= 0) {
|
||||
if (!itemId || !personId || quantity <= 0) {
|
||||
return createAssignmentError({ error: ["Invalid assignment data"] })
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ export async function createAssignmentUseCase(
|
||||
itemId,
|
||||
assetId: assetId || undefined,
|
||||
quantity,
|
||||
recipientId,
|
||||
personId,
|
||||
notes: input.notes,
|
||||
assignmentDate: input.assignmentDate,
|
||||
createdBy: actorId,
|
||||
@@ -155,7 +155,7 @@ export async function createAssignmentUseCase(
|
||||
assetId: assetId || undefined,
|
||||
quantity,
|
||||
type: "ASSIGNMENT",
|
||||
recipientId,
|
||||
personId,
|
||||
assignmentId: createdAssignment.id,
|
||||
userId: actorId,
|
||||
},
|
||||
@@ -175,7 +175,7 @@ export async function updateAssignmentUseCase(
|
||||
const {
|
||||
actorId,
|
||||
id,
|
||||
recipientId,
|
||||
personId,
|
||||
itemId,
|
||||
assetId,
|
||||
quantity,
|
||||
@@ -216,14 +216,14 @@ export async function updateAssignmentUseCase(
|
||||
}
|
||||
}
|
||||
|
||||
if (assignment.recipientId !== recipientId) {
|
||||
if (assignment.recipientId !== personId) {
|
||||
await MovementService.create(
|
||||
{
|
||||
type: "RETURN",
|
||||
quantity: assignment.quantity || 1,
|
||||
itemId: assignment.itemId || undefined,
|
||||
assetId: assignment.assetId || undefined,
|
||||
recipientId: assignment.recipientId || undefined,
|
||||
personId: assignment.recipientId || undefined,
|
||||
assignmentId: id,
|
||||
userId: actorId,
|
||||
},
|
||||
@@ -236,7 +236,7 @@ export async function updateAssignmentUseCase(
|
||||
quantity,
|
||||
itemId,
|
||||
assetId: assetId || undefined,
|
||||
recipientId,
|
||||
personId,
|
||||
assignmentId: id,
|
||||
userId: actorId,
|
||||
},
|
||||
@@ -247,7 +247,7 @@ export async function updateAssignmentUseCase(
|
||||
id,
|
||||
{
|
||||
createdBy: actorId,
|
||||
recipientId,
|
||||
recipientId: personId,
|
||||
itemId,
|
||||
assetId,
|
||||
quantity,
|
||||
@@ -261,7 +261,7 @@ export async function updateAssignmentUseCase(
|
||||
await AssignmentService.update(
|
||||
id,
|
||||
{
|
||||
recipientId,
|
||||
recipientId: personId,
|
||||
itemId,
|
||||
assetId,
|
||||
quantity,
|
||||
|
||||
@@ -80,7 +80,7 @@ describe("asset use-cases", () => {
|
||||
|
||||
it("creates an assigned asset with assignment and ASSIGNMENT movement", async () => {
|
||||
const actor = await createTestUser(prisma)
|
||||
const recipient = await createTestPerson(prisma)
|
||||
const person = await createTestPerson(prisma)
|
||||
const item = await createTestItem(prisma, { stock: 0 })
|
||||
|
||||
const result = await createAssetUseCase({
|
||||
@@ -88,7 +88,7 @@ describe("asset use-cases", () => {
|
||||
itemId: item.id,
|
||||
serialNumber: "ASSET-ASSIGNED-001",
|
||||
status: "ASSIGNED",
|
||||
recipientId: recipient.id,
|
||||
personId: person.id,
|
||||
})
|
||||
|
||||
expect(result.success).toBe(true)
|
||||
@@ -114,7 +114,7 @@ describe("asset use-cases", () => {
|
||||
expect(assignment).toMatchObject({
|
||||
itemId: item.id,
|
||||
assetId: result.assetId,
|
||||
recipientId: recipient.id,
|
||||
recipientId: person.id,
|
||||
quantity: 1,
|
||||
createdBy: actor.id,
|
||||
returnDate: null,
|
||||
@@ -124,7 +124,7 @@ describe("asset use-cases", () => {
|
||||
type: "ASSIGNMENT",
|
||||
itemId: item.id,
|
||||
assetId: result.assetId,
|
||||
recipientId: recipient.id,
|
||||
recipientId: person.id,
|
||||
assignmentId: assignment.id,
|
||||
quantity: 1,
|
||||
userId: actor.id,
|
||||
@@ -133,7 +133,7 @@ describe("asset use-cases", () => {
|
||||
|
||||
it("moves an available asset to assigned and back to available", async () => {
|
||||
const actor = await createTestUser(prisma)
|
||||
const recipient = await createTestPerson(prisma)
|
||||
const person = await createTestPerson(prisma)
|
||||
const item = await createTestItem(prisma, { stock: 0 })
|
||||
|
||||
const created = await createAssetUseCase({
|
||||
@@ -153,7 +153,7 @@ describe("asset use-cases", () => {
|
||||
itemId: item.id,
|
||||
serialNumber: "ASSET-LIFECYCLE-001",
|
||||
status: "ASSIGNED",
|
||||
recipientId: recipient.id,
|
||||
personId: person.id,
|
||||
}),
|
||||
).resolves.toEqual({ success: true })
|
||||
|
||||
@@ -170,7 +170,7 @@ describe("asset use-cases", () => {
|
||||
expect(activeAssignment).toMatchObject({
|
||||
itemId: item.id,
|
||||
assetId: created.assetId,
|
||||
recipientId: recipient.id,
|
||||
recipientId: person.id,
|
||||
quantity: 1,
|
||||
})
|
||||
|
||||
@@ -214,7 +214,7 @@ describe("asset use-cases", () => {
|
||||
expect(movements[1]).toMatchObject({
|
||||
itemId: item.id,
|
||||
assetId: created.assetId,
|
||||
recipientId: recipient.id,
|
||||
recipientId: person.id,
|
||||
assignmentId: activeAssignment.id,
|
||||
quantity: 1,
|
||||
userId: actor.id,
|
||||
@@ -230,7 +230,7 @@ describe("asset use-cases", () => {
|
||||
|
||||
it("returns an active assignment without restoring stock when an assigned asset moves to a terminal status", async () => {
|
||||
const actor = await createTestUser(prisma)
|
||||
const recipient = await createTestPerson(prisma)
|
||||
const person = await createTestPerson(prisma)
|
||||
const item = await createTestItem(prisma, { stock: 0 })
|
||||
|
||||
const created = await createAssetUseCase({
|
||||
@@ -238,7 +238,7 @@ describe("asset use-cases", () => {
|
||||
itemId: item.id,
|
||||
serialNumber: "ASSET-BROKEN-001",
|
||||
status: "ASSIGNED",
|
||||
recipientId: recipient.id,
|
||||
personId: person.id,
|
||||
})
|
||||
|
||||
expect(created.success).toBe(true)
|
||||
@@ -282,7 +282,7 @@ describe("asset use-cases", () => {
|
||||
type: "RETURN",
|
||||
itemId: item.id,
|
||||
assetId: created.assetId,
|
||||
recipientId: recipient.id,
|
||||
recipientId: person.id,
|
||||
assignmentId: activeAssignment.id,
|
||||
quantity: 1,
|
||||
userId: actor.id,
|
||||
|
||||
@@ -38,7 +38,7 @@ afterAll(async () => {
|
||||
describe("assignment use-cases", () => {
|
||||
it("creates an assignment, decrements stock, and records an ASSIGNMENT movement", async () => {
|
||||
const actor = await createTestUser(prisma)
|
||||
const recipient = await createTestPerson(prisma)
|
||||
const person = await createTestPerson(prisma)
|
||||
const item = await createTestItem(prisma, { stock: 5 })
|
||||
|
||||
const assignmentDate = new Date("2026-01-01T00:00:00.000Z")
|
||||
@@ -46,7 +46,7 @@ describe("assignment use-cases", () => {
|
||||
const result = await createAssignmentUseCase({
|
||||
actorId: actor.id,
|
||||
itemId: item.id,
|
||||
recipientId: recipient.id,
|
||||
personId: person.id,
|
||||
quantity: 2,
|
||||
assignmentDate,
|
||||
notes: "Initial assignment",
|
||||
@@ -68,7 +68,7 @@ describe("assignment use-cases", () => {
|
||||
expect(updatedItem.stock).toBe(3)
|
||||
expect(assignment).toMatchObject({
|
||||
itemId: item.id,
|
||||
recipientId: recipient.id,
|
||||
recipientId: person.id,
|
||||
quantity: 2,
|
||||
notes: "Initial assignment",
|
||||
createdBy: actor.id,
|
||||
@@ -79,7 +79,7 @@ describe("assignment use-cases", () => {
|
||||
expect(movements[0]).toMatchObject({
|
||||
type: "ASSIGNMENT",
|
||||
itemId: item.id,
|
||||
recipientId: recipient.id,
|
||||
recipientId: person.id,
|
||||
assignmentId: result.assignmentId,
|
||||
quantity: 2,
|
||||
userId: actor.id,
|
||||
@@ -88,13 +88,13 @@ describe("assignment use-cases", () => {
|
||||
|
||||
it("rejects assignment creation when item stock is insufficient", async () => {
|
||||
const actor = await createTestUser(prisma)
|
||||
const recipient = await createTestPerson(prisma)
|
||||
const person = await createTestPerson(prisma)
|
||||
const item = await createTestItem(prisma, { stock: 1 })
|
||||
|
||||
const result = await createAssignmentUseCase({
|
||||
actorId: actor.id,
|
||||
itemId: item.id,
|
||||
recipientId: recipient.id,
|
||||
personId: person.id,
|
||||
quantity: 2,
|
||||
})
|
||||
|
||||
@@ -114,13 +114,13 @@ describe("assignment use-cases", () => {
|
||||
|
||||
it("returns an assignment, restores stock, closes it, and records a RETURN movement", async () => {
|
||||
const actor = await createTestUser(prisma)
|
||||
const recipient = await createTestPerson(prisma)
|
||||
const person = await createTestPerson(prisma)
|
||||
const item = await createTestItem(prisma, { stock: 4 })
|
||||
|
||||
const created = await createAssignmentUseCase({
|
||||
actorId: actor.id,
|
||||
itemId: item.id,
|
||||
recipientId: recipient.id,
|
||||
personId: person.id,
|
||||
quantity: 3,
|
||||
})
|
||||
|
||||
@@ -172,13 +172,13 @@ describe("assignment use-cases", () => {
|
||||
|
||||
it("rejects returning the same assignment twice", async () => {
|
||||
const actor = await createTestUser(prisma)
|
||||
const recipient = await createTestPerson(prisma)
|
||||
const person = await createTestPerson(prisma)
|
||||
const item = await createTestItem(prisma, { stock: 2 })
|
||||
|
||||
const created = await createAssignmentUseCase({
|
||||
actorId: actor.id,
|
||||
itemId: item.id,
|
||||
recipientId: recipient.id,
|
||||
personId: person.id,
|
||||
quantity: 1,
|
||||
})
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ const actionCopy = {
|
||||
assignmentAlreadyReturned: "La asignación ya fue devuelta",
|
||||
previousItemNotFound: "Artículo anterior no encontrado",
|
||||
insufficientStock: "El artículo no tiene stock suficiente",
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
personRequired: "La persona es obligatoria",
|
||||
invalidStatus: "Estado inválido",
|
||||
genericFailure: "Error al procesar el activo",
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { es } from "@/i18n/dictionaries/es"
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
getI18n: vi.fn(),
|
||||
findAllRecipients: vi.fn(),
|
||||
findAllPeople: vi.fn(),
|
||||
findAllItemsWithStock: vi.fn(),
|
||||
findAllAvailableAssets: vi.fn(),
|
||||
findAllItems: vi.fn(),
|
||||
@@ -25,7 +25,7 @@ vi.mock("@/i18n/server", () => ({
|
||||
|
||||
vi.mock("@/services/person.service", () => ({
|
||||
PersonService: {
|
||||
findAll: mocks.findAllRecipients,
|
||||
findAll: mocks.findAllPeople,
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -72,9 +72,9 @@ describe("assignment form pages localization", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mocks.getI18n.mockResolvedValue({ dictionary: es, locale: "es" })
|
||||
mocks.findAllRecipients.mockResolvedValue([
|
||||
mocks.findAllPeople.mockResolvedValue([
|
||||
{
|
||||
id: "recipient-1",
|
||||
id: "person-1",
|
||||
firstName: "Ada",
|
||||
lastName: "Lovelace",
|
||||
},
|
||||
@@ -122,10 +122,8 @@ describe("assignment form pages localization", () => {
|
||||
const html = renderToStaticMarkup(await NewAssignmentPage())
|
||||
|
||||
expect(html).toContain("Nueva asignación")
|
||||
expect(html).toContain("Destinatario")
|
||||
expect(html).toContain(
|
||||
'option value="">Selecciona un destinatario</option>',
|
||||
)
|
||||
expect(html).toContain("Persona")
|
||||
expect(html).toContain('option value="">Selecciona una persona</option>')
|
||||
expect(html).toContain("Artículo")
|
||||
expect(html).toContain('option value="">Selecciona un artículo</option>')
|
||||
expect(html).toContain("Cantidad")
|
||||
@@ -142,7 +140,7 @@ describe("assignment form pages localization", () => {
|
||||
|
||||
mocks.findAssignmentById.mockResolvedValue({
|
||||
id: "assignment-1",
|
||||
recipientId: "recipient-1",
|
||||
personId: "person-1",
|
||||
itemId: "item-1",
|
||||
assetId: "asset-1",
|
||||
quantity: 1,
|
||||
@@ -155,7 +153,7 @@ describe("assignment form pages localization", () => {
|
||||
)
|
||||
|
||||
expect(html).toContain("Editar asignación")
|
||||
expect(html).toContain("Destinatario")
|
||||
expect(html).toContain("Persona")
|
||||
expect(html).toContain("Artículo")
|
||||
expect(html).toContain("Activo")
|
||||
expect(html).toContain('option value="">Selecciona un activo</option>')
|
||||
|
||||
@@ -5,7 +5,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||
import { es } from "@/i18n/dictionaries/es"
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
findAllWithRecipientPaginated: vi.fn(),
|
||||
findAllWithPersonPaginated: vi.fn(),
|
||||
getI18n: vi.fn(),
|
||||
refresh: vi.fn(),
|
||||
returnAssignment: vi.fn(),
|
||||
@@ -19,7 +19,7 @@ vi.mock("@/i18n/server", () => ({
|
||||
|
||||
vi.mock("@/services/assignment.service", () => ({
|
||||
AssignmentService: {
|
||||
findAllWithRecipientPaginated: mocks.findAllWithRecipientPaginated,
|
||||
findAllWithPersonPaginated: mocks.findAllWithPersonPaginated,
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -65,13 +65,13 @@ describe("assignment pages localization", () => {
|
||||
"@/app/(dashboard)/assignments/page"
|
||||
)
|
||||
|
||||
mocks.findAllWithRecipientPaginated.mockResolvedValue({
|
||||
mocks.findAllWithPersonPaginated.mockResolvedValue({
|
||||
data: [
|
||||
{
|
||||
id: "assignment-1",
|
||||
quantity: 2,
|
||||
recipient: {
|
||||
id: "recipient-1",
|
||||
person: {
|
||||
id: "person-1",
|
||||
firstName: "Ada",
|
||||
lastName: "Lovelace",
|
||||
},
|
||||
@@ -93,7 +93,7 @@ describe("assignment pages localization", () => {
|
||||
|
||||
expect(html).toContain("Asignaciones")
|
||||
expect(html).toContain("Agregar asignación")
|
||||
expect(html).toContain("Destinatario")
|
||||
expect(html).toContain("Persona")
|
||||
expect(html).toContain("Artículo")
|
||||
expect(html).toContain("Número de serie")
|
||||
expect(html).toContain("Cantidad")
|
||||
@@ -110,7 +110,7 @@ describe("assignment pages localization", () => {
|
||||
"@/app/(dashboard)/assignments/page"
|
||||
)
|
||||
|
||||
mocks.findAllWithRecipientPaginated.mockResolvedValue({
|
||||
mocks.findAllWithPersonPaginated.mockResolvedValue({
|
||||
data: [],
|
||||
totalPages: 0,
|
||||
})
|
||||
|
||||
@@ -68,7 +68,7 @@ describe("movement pages localization", () => {
|
||||
createdAt: new Date("2026-06-13T00:00:00.000Z"),
|
||||
item: { name: "Laptop" },
|
||||
asset: { serialNumber: "SN-001" },
|
||||
recipient: { firstName: "Ada", lastName: "Lovelace" },
|
||||
person: { firstName: "Ada", lastName: "Lovelace" },
|
||||
},
|
||||
],
|
||||
totalPages: 1,
|
||||
@@ -83,7 +83,7 @@ describe("movement pages localization", () => {
|
||||
expect(html).toContain("Artículo")
|
||||
expect(html).toContain("Número de serie")
|
||||
expect(html).toContain("Cantidad")
|
||||
expect(html).toContain("Destinatario")
|
||||
expect(html).toContain("Persona")
|
||||
expect(html).toContain("Fecha")
|
||||
expect(html).toContain("Asignación")
|
||||
expect(html).toContain("Laptop")
|
||||
|
||||
@@ -415,7 +415,7 @@ describe("i18n dictionaries", () => {
|
||||
addLabel: "Add Assignment",
|
||||
empty: "No assignments found.",
|
||||
columns: {
|
||||
recipient: "Recipient",
|
||||
person: "Person",
|
||||
item: "Item",
|
||||
serialNumber: "Serial Number",
|
||||
quantity: "Quantity",
|
||||
@@ -434,8 +434,8 @@ describe("i18n dictionaries", () => {
|
||||
notFound: "Assignment not found",
|
||||
},
|
||||
form: {
|
||||
recipientLabel: "Recipient",
|
||||
recipientPlaceholder: "Select a recipient",
|
||||
personLabel: "Person",
|
||||
personPlaceholder: "Select a person",
|
||||
itemLabel: "Item",
|
||||
itemPlaceholder: "Select an item",
|
||||
assetLabel: "Asset",
|
||||
@@ -465,7 +465,7 @@ describe("i18n dictionaries", () => {
|
||||
genericFailure: "Error processing assignment",
|
||||
},
|
||||
schema: {
|
||||
recipientRequired: "Recipient is required",
|
||||
personRequired: "Person is required",
|
||||
itemIdRequired: "Item is required",
|
||||
quantityMinOne: "Quantity must be at least 1",
|
||||
assetIdRequired: "Asset ID is required when item ID is provided",
|
||||
@@ -479,7 +479,7 @@ describe("i18n dictionaries", () => {
|
||||
addLabel: "Agregar asignación",
|
||||
empty: "No se encontraron asignaciones.",
|
||||
columns: {
|
||||
recipient: "Destinatario",
|
||||
person: "Persona",
|
||||
item: "Artículo",
|
||||
serialNumber: "Número de serie",
|
||||
quantity: "Cantidad",
|
||||
@@ -498,8 +498,8 @@ describe("i18n dictionaries", () => {
|
||||
notFound: "Asignación no encontrada",
|
||||
},
|
||||
form: {
|
||||
recipientLabel: "Destinatario",
|
||||
recipientPlaceholder: "Selecciona un destinatario",
|
||||
personLabel: "Persona",
|
||||
personPlaceholder: "Selecciona una persona",
|
||||
itemLabel: "Artículo",
|
||||
itemPlaceholder: "Selecciona un artículo",
|
||||
assetLabel: "Activo",
|
||||
@@ -529,7 +529,7 @@ describe("i18n dictionaries", () => {
|
||||
genericFailure: "Error al procesar la asignación",
|
||||
},
|
||||
schema: {
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
personRequired: "La persona es obligatoria",
|
||||
itemIdRequired: "El artículo es obligatorio",
|
||||
quantityMinOne: "La cantidad debe ser al menos 1",
|
||||
assetIdRequired:
|
||||
@@ -572,8 +572,8 @@ describe("i18n dictionaries", () => {
|
||||
deliveryNotePlaceholder: "Delivery note",
|
||||
statusLabel: "Status",
|
||||
statusPlaceholder: "Select a status",
|
||||
recipientLabel: "Recipient",
|
||||
recipientPlaceholder: "Select a recipient",
|
||||
personLabel: "Person",
|
||||
personPlaceholder: "Select a person",
|
||||
createSubmit: "Create Asset",
|
||||
updateSubmit: "Update Asset",
|
||||
},
|
||||
@@ -600,7 +600,7 @@ describe("i18n dictionaries", () => {
|
||||
assignmentAlreadyReturned: "Assignment already returned",
|
||||
previousItemNotFound: "Previous item not found for available asset",
|
||||
insufficientStock: "Item does not have enough stock",
|
||||
recipientRequired: "Recipient is required",
|
||||
personRequired: "Person is required",
|
||||
invalidStatus: "Invalid status",
|
||||
genericFailure: "Error processing asset",
|
||||
},
|
||||
@@ -646,8 +646,8 @@ describe("i18n dictionaries", () => {
|
||||
deliveryNotePlaceholder: "Remito",
|
||||
statusLabel: "Estado",
|
||||
statusPlaceholder: "Selecciona un estado",
|
||||
recipientLabel: "Destinatario",
|
||||
recipientPlaceholder: "Selecciona un destinatario",
|
||||
personLabel: "Persona",
|
||||
personPlaceholder: "Selecciona una persona",
|
||||
createSubmit: "Crear activo",
|
||||
updateSubmit: "Actualizar activo",
|
||||
},
|
||||
@@ -675,7 +675,7 @@ describe("i18n dictionaries", () => {
|
||||
previousItemNotFound:
|
||||
"Artículo anterior no encontrado para el activo disponible",
|
||||
insufficientStock: "El artículo no tiene stock suficiente",
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
personRequired: "La persona es obligatoria",
|
||||
invalidStatus: "Estado inválido",
|
||||
genericFailure: "Error al procesar el activo",
|
||||
},
|
||||
@@ -865,7 +865,7 @@ describe("i18n dictionaries", () => {
|
||||
item: "Item",
|
||||
serialNumber: "Serial Number",
|
||||
quantity: "Quantity",
|
||||
recipient: "Recipient",
|
||||
person: "Person",
|
||||
date: "Date",
|
||||
},
|
||||
},
|
||||
@@ -899,7 +899,7 @@ describe("i18n dictionaries", () => {
|
||||
item: "Artículo",
|
||||
serialNumber: "Número de serie",
|
||||
quantity: "Cantidad",
|
||||
recipient: "Destinatario",
|
||||
person: "Persona",
|
||||
date: "Fecha",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -54,7 +54,7 @@ describe("asset schema localization", () => {
|
||||
itemId: "item-1",
|
||||
serialNumber: "SERIAL-1",
|
||||
status: "ASSIGNED",
|
||||
recipientId: "recipient-1",
|
||||
personId: "person-1",
|
||||
})
|
||||
|
||||
expect(createResult.success).toBe(true)
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from "@/schemas/assignment.schema"
|
||||
|
||||
const schemaCopy = {
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
personRequired: "La persona es obligatoria",
|
||||
itemIdRequired: "El artículo es obligatorio",
|
||||
quantityMinOne: "La cantidad debe ser al menos 1",
|
||||
assetIdRequired: "El activo es obligatorio cuando se especifica el artículo",
|
||||
@@ -16,7 +16,7 @@ const schemaCopy = {
|
||||
describe("assignment schema localization", () => {
|
||||
it("uses localized create validation messages for missing required fields", () => {
|
||||
const result = buildCreateAssignmentSchema(schemaCopy).safeParse({
|
||||
recipientId: "",
|
||||
personId: "",
|
||||
quantity: 0,
|
||||
})
|
||||
|
||||
@@ -24,7 +24,7 @@ describe("assignment schema localization", () => {
|
||||
if (!result.success) {
|
||||
const errors = result.error.flatten().fieldErrors
|
||||
|
||||
expect(errors.recipientId).toContain(schemaCopy.recipientRequired)
|
||||
expect(errors.personId).toContain(schemaCopy.personRequired)
|
||||
expect(errors.quantity).toContain(schemaCopy.quantityMinOne)
|
||||
}
|
||||
})
|
||||
@@ -33,7 +33,7 @@ describe("assignment schema localization", () => {
|
||||
const result = buildUpdateAssignmentSchema(schemaCopy).safeParse({
|
||||
id: "",
|
||||
itemId: "item-1",
|
||||
recipientId: "recipient-1",
|
||||
personId: "person-1",
|
||||
quantity: 1,
|
||||
assetId: "",
|
||||
})
|
||||
@@ -49,20 +49,20 @@ describe("assignment schema localization", () => {
|
||||
|
||||
it("preserves valid create and update payloads without errors", () => {
|
||||
const createResult = buildCreateAssignmentSchema(schemaCopy).safeParse({
|
||||
recipientId: "recipient-1",
|
||||
personId: "person-1",
|
||||
itemId: "item-1",
|
||||
quantity: 2,
|
||||
})
|
||||
|
||||
expect(createResult.success).toBe(true)
|
||||
if (createResult.success) {
|
||||
expect(createResult.data.recipientId).toBe("recipient-1")
|
||||
expect(createResult.data.personId).toBe("person-1")
|
||||
expect(createResult.data.quantity).toBe(2)
|
||||
}
|
||||
|
||||
const updateResult = buildUpdateAssignmentSchema(schemaCopy).safeParse({
|
||||
id: "assignment-1",
|
||||
recipientId: "recipient-1",
|
||||
personId: "person-1",
|
||||
itemId: "item-1",
|
||||
assetId: "asset-1",
|
||||
quantity: 1,
|
||||
@@ -76,7 +76,7 @@ describe("assignment schema localization", () => {
|
||||
|
||||
it("keeps optional assignment fields optional in create", () => {
|
||||
const result = buildCreateAssignmentSchema(schemaCopy).safeParse({
|
||||
recipientId: "recipient-1",
|
||||
personId: "person-1",
|
||||
quantity: 1,
|
||||
})
|
||||
|
||||
@@ -86,7 +86,7 @@ describe("assignment schema localization", () => {
|
||||
it("allows update without itemId when no assetId is required", () => {
|
||||
const result = buildUpdateAssignmentSchema(schemaCopy).safeParse({
|
||||
id: "assignment-1",
|
||||
recipientId: "recipient-1",
|
||||
personId: "person-1",
|
||||
quantity: 1,
|
||||
})
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ describe("core schemas", () => {
|
||||
expect(
|
||||
createAssignmentSchema.safeParse({
|
||||
itemId: "item-id",
|
||||
recipientId: "recipient-id",
|
||||
personId: "person-id",
|
||||
quantity: "2",
|
||||
}),
|
||||
).toMatchObject({ success: true, data: { quantity: 2 } })
|
||||
@@ -47,7 +47,7 @@ describe("core schemas", () => {
|
||||
expect(
|
||||
createAssignmentSchema.safeParse({
|
||||
itemId: "item-id",
|
||||
recipientId: "recipient-id",
|
||||
personId: "person-id",
|
||||
quantity: 0,
|
||||
}).success,
|
||||
).toBe(false)
|
||||
|
||||
Reference in New Issue
Block a user