feat: agregar soporte para gestión de almacén principal en selección de seriales

This commit is contained in:
Juan Felipe Zapata Moreno 2026-03-04 17:17:08 -06:00
parent 54f15ab7b4
commit fe79f843f6
6 changed files with 38 additions and 7 deletions

View File

@ -17,6 +17,10 @@ const props = defineProps({
excludeSerials: { excludeSerials: {
type: Array, type: Array,
default: () => [] default: () => []
},
mainWarehouse: {
type: Boolean,
default: false
} }
}); });
@ -67,7 +71,7 @@ const loadComponents = async () => {
// Cargar seriales para cada componente // Cargar seriales para cada componente
await Promise.all(components.value.map(async (comp) => { await Promise.all(components.value.map(async (comp) => {
try { try {
const response = await serialService.getAvailableSerials(comp.inventory_id); const response = await serialService.getAvailableSerials(comp.inventory_id, null, { mainWarehouse: props.mainWarehouse });
const serials = (response.serials?.data || []).filter( const serials = (response.serials?.data || []).filter(
s => !props.excludeSerials.includes(s.serial_number) s => !props.excludeSerials.includes(s.serial_number)
); );

View File

@ -22,6 +22,10 @@ const props = defineProps({
type: Number, type: Number,
default: null default: null
}, },
mainWarehouse: {
type: Boolean,
default: false
},
preSelectedSerials: { preSelectedSerials: {
type: Array, type: Array,
default: () => [] default: () => []
@ -62,7 +66,7 @@ const canConfirm = computed(() => {
const loadSerials = async () => { const loadSerials = async () => {
loading.value = true; loading.value = true;
try { try {
const response = await serialService.getAvailableSerials(props.product.id, props.warehouseId); const response = await serialService.getAvailableSerials(props.product.id, props.warehouseId, { mainWarehouse: props.mainWarehouse });
const fetched = (response.serials?.data || []).filter( const fetched = (response.serials?.data || []).filter(
serial => !props.excludeSerials.includes(serial.serial_number) serial => !props.excludeSerials.includes(serial.serial_number)
); );

View File

@ -11,6 +11,8 @@ const router = useRouter();
/** Estado */ /** Estado */
const inventoryId = computed(() => route.params.id); const inventoryId = computed(() => route.params.id);
const warehouseId = computed(() => route.query.warehouse_id || null);
const isMainWarehouse = computed(() => !warehouseId.value || route.query.is_main === '1');
const inventory = ref(null); const inventory = ref(null);
const serials = ref({ data: [], total: 0 }); const serials = ref({ data: [], total: 0 });
const activeTab = ref('disponible'); const activeTab = ref('disponible');
@ -29,10 +31,17 @@ const searcher = useSearcher({
}); });
/** Métodos */ /** Métodos */
const warehouseFilters = () => {
if (!warehouseId.value) return {};
if (route.query.is_main === '1') return { main_warehouse: 1 };
return { warehouse_id: warehouseId.value };
};
const loadSerials = (filters = {}) => { const loadSerials = (filters = {}) => {
searcher.load({ searcher.load({
url: apiURL(`inventario/${inventoryId.value}/serials`), url: apiURL(`inventario/${inventoryId.value}/serials`),
filters: { filters: {
...warehouseFilters(),
...filters, ...filters,
status: activeTab.value status: activeTab.value
} }
@ -40,7 +49,7 @@ const loadSerials = (filters = {}) => {
}; };
const onSearch = (query) => { const onSearch = (query) => {
searcher.search(query, { status: activeTab.value }); searcher.search(query, { ...warehouseFilters(), status: activeTab.value });
}; };
const switchTab = (tab) => { const switchTab = (tab) => {
@ -138,6 +147,7 @@ onMounted(() => {
Disponibles Disponibles
</button> </button>
<button <button
v-if="isMainWarehouse"
@click="switchTab('vendido')" @click="switchTab('vendido')"
:class="[ :class="[
activeTab === 'vendido' activeTab === 'vendido'

View File

@ -947,6 +947,7 @@ watch(activeTab, (newTab) => {
:show="showSerialSelector" :show="showSerialSelector"
:product="serialSelectorProduct" :product="serialSelectorProduct"
:exclude-serials="cart.getSelectedSerials()" :exclude-serials="cart.getSelectedSerials()"
:main-warehouse="true"
@close="closeSerialSelector" @close="closeSerialSelector"
@confirm="handleSerialConfirm" @confirm="handleSerialConfirm"
/> />
@ -957,6 +958,7 @@ watch(activeTab, (newTab) => {
:show="showBundleSerialSelector" :show="showBundleSerialSelector"
:bundle="bundleSerialSelectorBundle" :bundle="bundleSerialSelectorBundle"
:exclude-serials="cart.getSelectedSerials()" :exclude-serials="cart.getSelectedSerials()"
:main-warehouse="true"
@close="closeBundleSerialSelector" @close="closeBundleSerialSelector"
@confirm="handleBundleSerialConfirm" @confirm="handleBundleSerialConfirm"
/> />

View File

@ -104,7 +104,14 @@ const goBack = () => {
}; };
const openSerials = (product) => { const openSerials = (product) => {
router.push({ name: 'pos.inventory.serials', params: { id: product.id } }); router.push({
name: 'pos.inventory.serials',
params: { id: product.id },
query: {
warehouse_id: warehouseId.value,
is_main: warehouse.value?.is_main ? '1' : '0'
}
});
}; };
/** Ciclos */ /** Ciclos */

View File

@ -27,12 +27,16 @@ const serialService = {
/** /**
* Obtener solo seriales disponibles de un producto * Obtener solo seriales disponibles de un producto
* @param {Number} inventoryId - ID del inventario * @param {Number} inventoryId - ID del inventario
* @param {Number} warehouseId - ID del almacén (opcional) * @param {Number|null} warehouseId - ID del almacén específico (gestión de inventario)
* @param {Object} options - Opciones adicionales
* @param {Boolean} options.mainWarehouse - Si true, filtra por almacén principal (?main_warehouse=1)
* @returns {Promise} * @returns {Promise}
*/ */
async getAvailableSerials(inventoryId, warehouseId = null) { async getAvailableSerials(inventoryId, warehouseId = null, options = {}) {
const filters = { status: 'disponible' }; const filters = { status: 'disponible' };
if (warehouseId) { if (options.mainWarehouse) {
filters.main_warehouse = 1;
} else if (warehouseId) {
filters.warehouse_id = warehouseId; filters.warehouse_id = warehouseId;
} }
return this.getSerials(inventoryId, filters); return this.getSerials(inventoryId, filters);