164 lines
5.6 KiB
Vue

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { useToast } from 'primevue/usetoast';
import Toast from 'primevue/toast';
import Button from 'primevue/button';
import AssignmentAssetSelectorCard from './AssignmentAssetSelectorCard.vue';
import AssignmentEmployeeSelectorCard from './AssignmentEmployeeSelectorCard.vue';
import AssignmentDetailsCard from './AssignmentDetailsCard.vue';
import type {
AssignmentAssetOption,
AssignmentEmployeeOption,
FixedAssetAssignmentFormData
} from '../../types/fixedAssetAssignment';
import { fixedAssetsService, type UserOption } from '../../services/fixedAssetsService';
import { employeesService } from '@/modules/rh/components/employees/employees.services';
const router = useRouter();
const toast = useToast();
const loading = ref(false);
const loadingData = ref(false);
const assetSearch = ref('');
const employeeSearch = ref('');
const assets = ref<AssignmentAssetOption[]>([]);
const employees = ref<AssignmentEmployeeOption[]>([]);
const users = ref<UserOption[]>([]);
const form = ref<FixedAssetAssignmentFormData>({
assetId: null,
employeeId: null,
authorizedById: null,
assignedAt: new Date().toISOString().slice(0, 10),
receiptFolio: '',
notes: ''
});
onMounted(async () => {
loadingData.value = true;
try {
const [assetsRes, employeesRes, usersRes] = await Promise.all([
fixedAssetsService.getAssets({ paginate: false, status: 1 }),
employeesService.getEmployees({ paginate: false }),
fixedAssetsService.getUsers(),
]);
const allAssets = (assetsRes as any).data?.data ?? [];
assets.value = allAssets
.filter((a: any) => !a.active_assignment)
.map((a: any): AssignmentAssetOption => ({
id: a.id,
code: a.sku,
name: a.inventory_warehouse?.product?.name ?? a.sku,
serial: a.inventory_warehouse?.product?.serial_number ?? '—',
category: a.inventory_warehouse?.product?.category ?? '—',
}));
const allEmployees = (employeesRes as any).data ?? [];
employees.value = allEmployees.map((e: any): AssignmentEmployeeOption => ({
id: e.id,
initials: `${e.name[0]}${e.paternal[0]}`.toUpperCase(),
fullName: `${e.name} ${e.paternal} ${e.maternal}`.trim(),
role: e.job_position?.name ?? '—',
department: e.department?.name ?? '—',
}));
users.value = usersRes;
} catch {
toast.add({
severity: 'error',
summary: 'Error',
detail: 'No se pudieron cargar los datos. Intente de nuevo.',
life: 4000
});
} finally {
loadingData.value = false;
}
});
const cancel = () => router.push('/fixed-assets/assignments');
const save = async () => {
if (!form.value.assetId || !form.value.employeeId) {
toast.add({
severity: 'warn',
summary: 'Campos pendientes',
detail: 'Seleccione un activo y un colaborador para confirmar la asignacion.',
life: 3000
});
return;
}
loading.value = true;
try {
await fixedAssetsService.assignAsset(form.value.assetId, {
employee_id: form.value.employeeId,
assigned_at: form.value.assignedAt,
receipt_folio: form.value.receiptFolio || undefined,
authorized_by: form.value.authorizedById ?? undefined,
notes: form.value.notes || undefined,
});
toast.add({
severity: 'success',
summary: 'Asignacion registrada',
detail: 'La asignacion del activo al colaborador se registro correctamente.',
life: 2500
});
router.push('/fixed-assets/assignments');
} catch (error: any) {
const message = error?.response?.data?.message ?? 'Error al registrar la asignacion.';
toast.add({ severity: 'error', summary: 'Error', detail: message, life: 4000 });
} finally {
loading.value = false;
}
};
</script>
<template>
<section class="space-y-6">
<Toast position="bottom-right" />
<div>
<h1 class="text-3xl font-black tracking-tight text-surface-900 dark:text-surface-0">
Asignacion de Activo a Empleado
</h1>
<p class="mt-1 text-surface-500 dark:text-surface-400">
Registre la entrega de una herramienta o equipo a un colaborador del almacen.
</p>
</div>
<AssignmentAssetSelectorCard
:assets="assets"
:search-term="assetSearch"
:selected-asset-id="form.assetId"
:loading="loadingData"
@update:search-term="assetSearch = $event"
@update:selected-asset-id="form.assetId = $event"
/>
<AssignmentEmployeeSelectorCard
:employees="employees"
:search-term="employeeSearch"
:selected-employee-id="form.employeeId"
@update:search-term="employeeSearch = $event"
@update:selected-employee-id="form.employeeId = $event"
/>
<AssignmentDetailsCard :form="form" :users="users" />
<div class="flex flex-wrap items-center justify-end gap-3">
<Button label="Cancelar" text severity="secondary" @click="cancel" />
<Button
label="Confirmar Asignacion"
icon="pi pi-check-circle"
:loading="loading"
:disabled="loadingData"
@click="save"
/>
</div>
</section>
</template>