feat: agregar funcionalidad para gestionar usuarios y folios de resguardo en la asignación de activos fijos
This commit is contained in:
parent
1a5e70890c
commit
8205d4203b
@ -1,11 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Card from 'primevue/card';
|
import Card from 'primevue/card';
|
||||||
import InputText from 'primevue/inputtext';
|
import InputText from 'primevue/inputtext';
|
||||||
|
import Select from 'primevue/select';
|
||||||
import Textarea from 'primevue/textarea';
|
import Textarea from 'primevue/textarea';
|
||||||
import type { FixedAssetAssignmentFormData } from '../../types/fixedAssetAssignment';
|
import type { FixedAssetAssignmentFormData } from '../../types/fixedAssetAssignment';
|
||||||
|
import type { UserOption } from '../../services/fixedAssetsService';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
form: FixedAssetAssignmentFormData;
|
form: FixedAssetAssignmentFormData;
|
||||||
|
users: UserOption[];
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProps<Props>();
|
defineProps<Props>();
|
||||||
@ -29,6 +32,26 @@ defineProps<Props>();
|
|||||||
class="w-full"
|
class="w-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label class="text-sm font-semibold text-surface-800 dark:text-surface-100">Folio de Resguardo (Opcional)</label>
|
||||||
|
<InputText
|
||||||
|
v-model="form.receiptFolio"
|
||||||
|
class="w-full"
|
||||||
|
placeholder="Ej. GOLSRMVR-0170"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2 md:col-span-2">
|
||||||
|
<label class="text-sm font-semibold text-surface-800 dark:text-surface-100">Autoriza (Opcional)</label>
|
||||||
|
<Select
|
||||||
|
v-model="form.authorizedById"
|
||||||
|
:options="users"
|
||||||
|
optionLabel="full_name"
|
||||||
|
optionValue="id"
|
||||||
|
placeholder="Seleccione quien autoriza..."
|
||||||
|
class="w-full"
|
||||||
|
showClear
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="space-y-2 md:col-span-2">
|
<div class="space-y-2 md:col-span-2">
|
||||||
<label class="text-sm font-semibold text-surface-800 dark:text-surface-100">Notas o Comentarios (Opcional)</label>
|
<label class="text-sm font-semibold text-surface-800 dark:text-surface-100">Notas o Comentarios (Opcional)</label>
|
||||||
<Textarea
|
<Textarea
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import type {
|
|||||||
AssignmentEmployeeOption,
|
AssignmentEmployeeOption,
|
||||||
FixedAssetAssignmentFormData
|
FixedAssetAssignmentFormData
|
||||||
} from '../../types/fixedAssetAssignment';
|
} from '../../types/fixedAssetAssignment';
|
||||||
import { fixedAssetsService } from '../../services/fixedAssetsService';
|
import { fixedAssetsService, type UserOption } from '../../services/fixedAssetsService';
|
||||||
import { employeesService } from '@/modules/rh/components/employees/employees.services';
|
import { employeesService } from '@/modules/rh/components/employees/employees.services';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -24,20 +24,24 @@ const employeeSearch = ref('');
|
|||||||
|
|
||||||
const assets = ref<AssignmentAssetOption[]>([]);
|
const assets = ref<AssignmentAssetOption[]>([]);
|
||||||
const employees = ref<AssignmentEmployeeOption[]>([]);
|
const employees = ref<AssignmentEmployeeOption[]>([]);
|
||||||
|
const users = ref<UserOption[]>([]);
|
||||||
|
|
||||||
const form = ref<FixedAssetAssignmentFormData>({
|
const form = ref<FixedAssetAssignmentFormData>({
|
||||||
assetId: null,
|
assetId: null,
|
||||||
employeeId: null,
|
employeeId: null,
|
||||||
|
authorizedById: null,
|
||||||
assignedAt: new Date().toISOString().slice(0, 10),
|
assignedAt: new Date().toISOString().slice(0, 10),
|
||||||
|
receiptFolio: '',
|
||||||
notes: ''
|
notes: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
loadingData.value = true;
|
loadingData.value = true;
|
||||||
try {
|
try {
|
||||||
const [assetsRes, employeesRes] = await Promise.all([
|
const [assetsRes, employeesRes, usersRes] = await Promise.all([
|
||||||
fixedAssetsService.getAssets({ paginate: false, status: 1 }),
|
fixedAssetsService.getAssets({ paginate: false, status: 1 }),
|
||||||
employeesService.getEmployees({ paginate: false }),
|
employeesService.getEmployees({ paginate: false }),
|
||||||
|
fixedAssetsService.getUsers(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const allAssets = (assetsRes as any).data?.data ?? [];
|
const allAssets = (assetsRes as any).data?.data ?? [];
|
||||||
@ -59,6 +63,8 @@ onMounted(async () => {
|
|||||||
role: e.job_position?.name ?? '—',
|
role: e.job_position?.name ?? '—',
|
||||||
department: e.department?.name ?? '—',
|
department: e.department?.name ?? '—',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
users.value = usersRes;
|
||||||
} catch {
|
} catch {
|
||||||
toast.add({
|
toast.add({
|
||||||
severity: 'error',
|
severity: 'error',
|
||||||
@ -89,6 +95,8 @@ const save = async () => {
|
|||||||
await fixedAssetsService.assignAsset(form.value.assetId, {
|
await fixedAssetsService.assignAsset(form.value.assetId, {
|
||||||
employee_id: form.value.employeeId,
|
employee_id: form.value.employeeId,
|
||||||
assigned_at: form.value.assignedAt,
|
assigned_at: form.value.assignedAt,
|
||||||
|
receipt_folio: form.value.receiptFolio || undefined,
|
||||||
|
authorized_by: form.value.authorizedById ?? undefined,
|
||||||
notes: form.value.notes || undefined,
|
notes: form.value.notes || undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -139,7 +147,7 @@ const save = async () => {
|
|||||||
@update:selected-employee-id="form.employeeId = $event"
|
@update:selected-employee-id="form.employeeId = $event"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AssignmentDetailsCard :form="form" />
|
<AssignmentDetailsCard :form="form" :users="users" />
|
||||||
|
|
||||||
<div class="flex flex-wrap items-center justify-end gap-3">
|
<div class="flex flex-wrap items-center justify-end gap-3">
|
||||||
<Button label="Cancelar" text severity="secondary" @click="cancel" />
|
<Button label="Cancelar" text severity="secondary" @click="cancel" />
|
||||||
|
|||||||
@ -77,6 +77,11 @@ const goToOffboarding = (assignment: AssetAssignment) => {
|
|||||||
router.push(`/fixed-assets/assignments/${assignment.asset_id}/${assignment.id}/offboarding`);
|
router.push(`/fixed-assets/assignments/${assignment.asset_id}/${assignment.id}/offboarding`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const downloadResguardo = (assignment: AssetAssignment) => {
|
||||||
|
const url = fixedAssetsService.getResguardoUrl(assignment.asset_id, assignment.id);
|
||||||
|
window.open(url, '_blank');
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(loadAssignments);
|
onMounted(loadAssignments);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -175,6 +180,15 @@ onMounted(loadAssignments);
|
|||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 text-right">
|
<td class="px-4 py-3 text-right">
|
||||||
<div class="flex items-center justify-end gap-1">
|
<div class="flex items-center justify-end gap-1">
|
||||||
|
<Button
|
||||||
|
icon="pi pi-file-pdf"
|
||||||
|
text
|
||||||
|
rounded
|
||||||
|
size="small"
|
||||||
|
severity="secondary"
|
||||||
|
v-tooltip.top="'Descargar resguardo'"
|
||||||
|
@click="downloadResguardo(assignment)"
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
v-if="assignment.status.id === 1"
|
v-if="assignment.status.id === 1"
|
||||||
icon="pi pi-times-circle"
|
icon="pi pi-times-circle"
|
||||||
|
|||||||
@ -115,10 +115,22 @@ export interface AssetAssignmentsPaginatedResponse {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UserOption {
|
||||||
|
id: number;
|
||||||
|
full_name: string;
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UsersResponse {
|
||||||
|
status: string;
|
||||||
|
data: { data: UserOption[] };
|
||||||
|
}
|
||||||
|
|
||||||
interface AssignAssetData {
|
interface AssignAssetData {
|
||||||
employee_id: number;
|
employee_id: number;
|
||||||
assigned_at?: string;
|
assigned_at?: string;
|
||||||
receipt_folio?: string;
|
receipt_folio?: string;
|
||||||
|
authorized_by?: number;
|
||||||
notes?: string;
|
notes?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +196,16 @@ class FixedAssetsService {
|
|||||||
const response = await api.put<AssetAssignmentResponse>(`/api/assets/${assetId}/assignments/${assignmentId}/return`, data);
|
const response = await api.put<AssetAssignmentResponse>(`/api/assets/${assetId}/assignments/${assignmentId}/return`, data);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUsers(): Promise<UserOption[]> {
|
||||||
|
const response = await api.get<UsersResponse>('/api/admin/users', { params: { paginate: false } });
|
||||||
|
return response.data.data.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
getResguardoUrl(assetId: number, assignmentId: number): string {
|
||||||
|
const base = import.meta.env.VITE_API_URL || '';
|
||||||
|
return `${base}/api/asset-assignments-public/${assetId}/assignments/${assignmentId}/resguardo`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fixedAssetsService = new FixedAssetsService();
|
export const fixedAssetsService = new FixedAssetsService();
|
||||||
|
|||||||
@ -17,6 +17,8 @@ export interface AssignmentEmployeeOption {
|
|||||||
export interface FixedAssetAssignmentFormData {
|
export interface FixedAssetAssignmentFormData {
|
||||||
assetId: number | null;
|
assetId: number | null;
|
||||||
employeeId: number | null;
|
employeeId: number | null;
|
||||||
|
authorizedById: number | null;
|
||||||
assignedAt: string;
|
assignedAt: string;
|
||||||
|
receiptFolio: string;
|
||||||
notes: string;
|
notes: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user