diff --git a/src/lang/es.js b/src/lang/es.js
index c15bdb8..62503a1 100644
--- a/src/lang/es.js
+++ b/src/lang/es.js
@@ -452,7 +452,7 @@ export default {
pos: {
title: 'Punto de Venta',
subtitle: 'Gestión de ventas y caja',
- category: 'Categorías',
+ category: 'Clasificaciones',
bundles: 'Paquetes',
inventory: 'Productos',
prices: 'Precios',
@@ -512,13 +512,13 @@ export default {
inactive: 'Inactivo',
},
category: {
- title: 'Gestión De Categorías',
- description: 'Administra las categorías de productos.',
+ title: 'Gestión De Clasificaciones',
+ description: 'Administra las clasificaciones de productos.',
create: {
- title: 'Nueva Categoría',
+ title: 'Nueva Clasificación',
},
edit: {
- title: 'Editar Categoría',
+ title: 'Editar Clasificación',
},
},
prices: {
diff --git a/src/pages/POS/Category/CreateModal.vue b/src/pages/POS/Category/CreateModal.vue
index f50a37f..c33b8c0 100644
--- a/src/pages/POS/Category/CreateModal.vue
+++ b/src/pages/POS/Category/CreateModal.vue
@@ -23,9 +23,9 @@ const form = useForm({
/** Métodos */
const createCategory = () => {
form.post(apiURL('categorias'), {
- onSuccess: () => {
+ onSuccess: (data) => {
Notify.success('Categoría creada exitosamente');
- emit('created');
+ emit('created', data?.model);
closeModal();
},
onError: () => {
diff --git a/src/pages/POS/Category/Index.vue b/src/pages/POS/Category/Index.vue
index 23702ad..9c5ea48 100644
--- a/src/pages/POS/Category/Index.vue
+++ b/src/pages/POS/Category/Index.vue
@@ -1,5 +1,6 @@
+
+
+
+
+
+
+
+ Crear Subcategoría
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/POS/Category/Subcategories/DeleteModal.vue b/src/pages/POS/Category/Subcategories/DeleteModal.vue
new file mode 100644
index 0000000..e4f286b
--- /dev/null
+++ b/src/pages/POS/Category/Subcategories/DeleteModal.vue
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Eliminar Subcategoría
+
+
+
+
+
+
+
+
+ ¿Estás seguro de que deseas eliminar esta subcategoría?
+
+
+
+
+
+
+
+
+
+ {{ subcategory.name }}
+
+
+ {{ subcategory.description }}
+
+
+ Sin descripción
+
+
+
+
+ {{ subcategory.is_active ? 'Activo' : 'Inactivo' }}
+
+
+
+
+
+
+
+
+ Los productos que tenían asignada esta subcategoría quedarán sin subcategoría automáticamente.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/POS/Category/Subcategories/EditModal.vue b/src/pages/POS/Category/Subcategories/EditModal.vue
new file mode 100644
index 0000000..065d107
--- /dev/null
+++ b/src/pages/POS/Category/Subcategories/EditModal.vue
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+ Editar Subcategoría
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/POS/Category/Subcategories/Index.vue b/src/pages/POS/Category/Subcategories/Index.vue
new file mode 100644
index 0000000..8261684
--- /dev/null
+++ b/src/pages/POS/Category/Subcategories/Index.vue
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+
Categoría
+
+ {{ categoryName || 'Subcategorías' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
searcher.pagination(page)"
+ >
+
+ | NOMBRE |
+ DESCRIPCIÓN |
+ ESTADO |
+ ACCIONES |
+
+
+
+ |
+ {{ model.name }}
+ |
+
+ {{ model.description || '-' }}
+ |
+
+
+ {{ model.is_active ? 'Activo' : 'Inactivo' }}
+
+ |
+
+
+
+
+
+ |
+
+
+
+
+
+
+ No hay subcategorías registradas
+
+ |
+
+
+
+
+
diff --git a/src/pages/POS/Inventory/CreateModal.vue b/src/pages/POS/Inventory/CreateModal.vue
index 74041a0..54ead43 100644
--- a/src/pages/POS/Inventory/CreateModal.vue
+++ b/src/pages/POS/Inventory/CreateModal.vue
@@ -5,6 +5,9 @@ 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';
+import GoogleIcon from '@Shared/GoogleIcon.vue';
+import CategoryCreateModal from '@Pages/POS/Category/CreateModal.vue';
+import SubcategoryCreateModal from '@Pages/POS/Category/Subcategories/CreateModal.vue';
/** Eventos */
const emit = defineEmits(['close', 'created']);
@@ -16,7 +19,10 @@ const props = defineProps({
/** Estado */
const categories = ref([]);
+const subcategories = ref([]);
const units = ref([]);
+const showCategoryCreate = ref(false);
+const showSubcategoryCreate = ref(false);
/** Formulario */
const form = useForm({
@@ -25,6 +31,7 @@ const form = useForm({
sku: '',
barcode: '',
category_id: '',
+ subcategory_id: '',
unit_of_measure_id: null,
retail_price: 0,
tax: 16,
@@ -60,6 +67,12 @@ const loadCategories = async () => {
}
};
+const onCategoryChange = () => {
+ const selected = categories.value.find(c => c.id == form.category_id);
+ subcategories.value = selected?.subcategories ?? [];
+ form.subcategory_id = '';
+};
+
const loadUnits = async () => {
try {
const response = await fetch(apiURL('unidades-medida/active'), {
@@ -117,8 +130,23 @@ const createProduct = () => {
});
};
+const onCategoryCreated = async (newCategory) => {
+ if (newCategory) {
+ form.category_id = newCategory.id;
+ }
+ await loadCategories();
+};
+
+const onSubcategoryCreated = (newSubcategory) => {
+ if (newSubcategory) {
+ subcategories.value.push(newSubcategory);
+ form.subcategory_id = newSubcategory.id;
+ }
+};
+
const closeModal = () => {
form.reset();
+ subcategories.value = [];
emit('close');
};
@@ -216,28 +244,72 @@ watch(() => form.track_serials, () => {
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/POS/Inventory/EditModal.vue b/src/pages/POS/Inventory/EditModal.vue
index ada0859..af51d65 100644
--- a/src/pages/POS/Inventory/EditModal.vue
+++ b/src/pages/POS/Inventory/EditModal.vue
@@ -21,6 +21,7 @@ const props = defineProps({
/** Estado */
const categories = ref([]);
+const subcategories = ref([]);
const units = ref([]);
const activeTab = ref('general');
@@ -40,6 +41,7 @@ const form = useForm({
sku: '',
barcode: '',
category_id: '',
+ subcategory_id: '',
unit_of_measure_id: null,
retail_price: 0,
tax: 16,
@@ -92,12 +94,23 @@ const loadCategories = async () => {
const result = await response.json();
if (result.data && result.data.categories && result.data.categories.data) {
categories.value = result.data.categories.data;
+ // Actualizar subcategorías si ya hay una categoría seleccionada
+ if (form.category_id) {
+ const selected = categories.value.find(c => c.id == form.category_id);
+ subcategories.value = selected?.subcategories ?? [];
+ }
}
} catch (error) {
console.error('Error loading categories:', error);
}
};
+const onCategoryChange = () => {
+ const selected = categories.value.find(c => c.id == form.category_id);
+ subcategories.value = selected?.subcategories ?? [];
+ form.subcategory_id = '';
+};
+
const loadUnits = async () => {
try {
const response = await fetch(apiURL('unidades-medida/active'), {
@@ -275,6 +288,7 @@ watch(() => props.product, (newProduct) => {
form.sku = newProduct.sku || '';
form.barcode = newProduct.barcode || '';
form.category_id = newProduct.category_id || '';
+ form.subcategory_id = newProduct.subcategory_id || '';
form.unit_of_measure_id = newProduct.unit_of_measure_id || null;
form.cost = parseFloat(newProduct.price?.cost || 0);
form.retail_price = parseFloat(newProduct.price?.retail_price || 0);
@@ -285,11 +299,11 @@ watch(() => props.product, (newProduct) => {
}
}, { immediate: true });
-watch(() => props.show, (newValue) => {
+watch(() => props.show, async (newValue) => {
if (newValue) {
- loadCategories();
loadUnits();
activeTab.value = 'general';
+ await loadCategories();
}
});
@@ -424,14 +438,15 @@ watch(activeTab, (tab) => {
+
+
+
+
+
+
+
-
+ |
{{ model.category?.name || '-' }}
+
+ {{ model.subcategory.name }}
+
|
diff --git a/src/router/Index.js b/src/router/Index.js
index db4a6bf..ed5f6bf 100644
--- a/src/router/Index.js
+++ b/src/router/Index.js
@@ -37,6 +37,11 @@ const router = createRouter({
name: 'pos.category.index',
component: () => import('@Pages/POS/Category/Index.vue')
},
+ {
+ path: 'category/:id/subcategories',
+ name: 'pos.category.subcategories',
+ component: () => import('@Pages/POS/Category/Subcategories/Index.vue')
+ },
{
path: 'bundles',
name: 'pos.bundles.index',
|