Juan Felipe Zapata Moreno 093cea3c4c feat: reportes de movimientos, inventario por almacén y series
- Habilita vista de stock con filtros y selección de series en traspasos.
- Implementa servicio de tickets PDF y corrige datos (ubicación/negocio).
- Renombra botón a Reporte y elimina opción de almacén principal.
2026-02-08 20:26:59 -06:00

141 lines
5.3 KiB
Vue

<script setup>
import { watch } from 'vue';
import { useForm, apiURL } from '@Services/Api';
import Modal from '@Holos/Modal.vue';
import FormInput from '@Holos/Form/Input.vue';
import FormError from '@Holos/Form/Elements/Error.vue';
/** Eventos */
const emit = defineEmits(['close', 'updated']);
/** Propiedades */
const props = defineProps({
show: Boolean,
warehouse: Object
});
/** Formulario */
const form = useForm({
code: '',
name: '',
is_active: true,
is_main: false,
});
/** Métodos */
const updateWarehouse = () => {
form.put(apiURL(`almacenes/${props.warehouse.id}`), {
onSuccess: () => {
window.Notify.success('Almacén actualizado exitosamente');
emit('updated');
closeModal();
},
onError: () => {
window.Notify.error('Error al actualizar el almacén');
}
});
};
const closeModal = () => {
form.reset();
emit('close');
};
/** Observadores */
watch(() => props.warehouse, (newWarehouse) => {
if (newWarehouse) {
form.code = newWarehouse.code || '';
form.name = newWarehouse.name || '';
form.is_active = newWarehouse.is_active ?? true;
form.is_main = newWarehouse.is_main ?? false;
}
}, { immediate: true });
</script>
<template>
<Modal :show="show" max-width="md" @close="closeModal">
<div class="p-6">
<!-- Header -->
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-bold text-gray-900 dark:text-gray-100">
Editar Almacén
</h3>
<button
@click="closeModal"
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<!-- Formulario -->
<form @submit.prevent="updateWarehouse" class="space-y-4">
<div class="grid grid-cols-2 gap-4">
<!-- Código -->
<div>
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
CÓDIGO
</label>
<FormInput
v-model="form.code"
type="text"
placeholder="Ej: TIENDA-01"
/>
<FormError :message="form.errors?.code" />
</div>
<!-- Nombre -->
<div>
<label class="block text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase mb-1.5">
NOMBRE
</label>
<FormInput
v-model="form.name"
type="text"
placeholder="Nombre del almacén"
/>
<FormError :message="form.errors?.name" />
</div>
<!-- Estado -->
<div class="col-span-2">
<label class="flex items-center gap-2 cursor-pointer">
<input
v-model="form.is_active"
type="checkbox"
class="w-4 h-4 text-indigo-600 bg-gray-100 border-gray-300 rounded focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">
Almacén activo
</span>
</label>
<FormError :message="form.errors?.is_active" />
</div>
</div>
<!-- Botones -->
<div class="flex items-center justify-end gap-3 mt-6">
<button
type="button"
@click="closeModal"
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
>
Cancelar
</button>
<button
type="submit"
:disabled="form.processing"
class="px-4 py-2 text-sm font-semibold text-white bg-gray-900 rounded-lg hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-900 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
<span v-if="form.processing">Actualizando...</span>
<span v-else>Actualizar</span>
</button>
</div>
</form>
</div>
</Modal>
</template>