feat: actualizar nombres de columnas y mejorar gestión de seriales en componentes
This commit is contained in:
parent
2bb50c48c9
commit
e51f3fad0f
@ -94,7 +94,7 @@ onMounted(() => {
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">NOMBRE</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">SKU</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">COMPONENTES</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">STOCK</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">PAQ. ESTIMADO</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">PRECIO</th>
|
||||
<th class="px-6 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">ACCIONES</th>
|
||||
</template>
|
||||
|
||||
@ -88,6 +88,11 @@ const serialsArray = computed(() => {
|
||||
.filter(s => s.length > 0);
|
||||
});
|
||||
|
||||
// Si tiene seriales y no permite decimales, la cantidad se controla por seriales
|
||||
const quantityLockedBySerials = computed(() => {
|
||||
return hasSerials.value && !allowsDecimals.value;
|
||||
});
|
||||
|
||||
const serialsValidation = computed(() => {
|
||||
if (!hasSerials.value) return { valid: true, message: '' };
|
||||
|
||||
@ -114,6 +119,13 @@ const serialsValidation = computed(() => {
|
||||
return { valid: true, message: '' };
|
||||
});
|
||||
|
||||
// Actualizar cantidad automáticamente cuando cambian los seriales
|
||||
const updateQuantityFromSerials = () => {
|
||||
if (!quantityLockedBySerials.value) return;
|
||||
const count = serialsArray.value.length;
|
||||
form.quantity = count > 0 ? count : 1;
|
||||
};
|
||||
|
||||
/** Métodos */
|
||||
const loadWarehouses = () => {
|
||||
loading.value = true;
|
||||
@ -305,11 +317,15 @@ watch(() => props.show, (isShown) => {
|
||||
<FormInput
|
||||
v-model="form.quantity"
|
||||
type="number"
|
||||
:min="allowsDecimals ? '0.001' : '1'"
|
||||
:step="allowsDecimals ? '0.001' : '1'"
|
||||
:placeholder="allowsDecimals ? '0.000' : '0'"
|
||||
min="1"
|
||||
step="1"
|
||||
placeholder="0"
|
||||
:disabled="quantityLockedBySerials"
|
||||
required
|
||||
/>
|
||||
<p v-if="quantityLockedBySerials" class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
Controlado por seriales
|
||||
</p>
|
||||
<FormError :message="form.errors?.quantity" />
|
||||
</div>
|
||||
|
||||
@ -321,7 +337,7 @@ watch(() => props.show, (isShown) => {
|
||||
NÚMEROS DE SERIE
|
||||
</label>
|
||||
</div>
|
||||
<SerialInputList v-model="serialsList" />
|
||||
<SerialInputList v-model="serialsList" @update:model-value="updateQuantityFromSerials" />
|
||||
|
||||
<!-- Validación -->
|
||||
<div class="mt-2 flex items-center justify-between">
|
||||
|
||||
@ -479,18 +479,15 @@ watch(() => form.warehouse_id, (newWarehouseId, oldWarehouseId) => {
|
||||
<input
|
||||
v-model="item.quantity"
|
||||
type="number"
|
||||
:min="item.allows_decimals ? '0.001' : '1'"
|
||||
:step="item.allows_decimals ? '0.001' : '1'"
|
||||
:placeholder="item.allows_decimals ? '0.000' : '0'"
|
||||
min="1"
|
||||
step="1"
|
||||
placeholder="0"
|
||||
:disabled="item.track_serials && canUseSerials(item)"
|
||||
class="w-full px-2 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
/>
|
||||
<p v-if="item.track_serials && canUseSerials(item)" class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
Controlado por seriales
|
||||
</p>
|
||||
<p v-else-if="item.allows_decimals" class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
Permite hasta 3 decimales (ej: 25.750 {{ item.unit_of_measure?.abbreviation }})
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Botón eliminar -->
|
||||
|
||||
@ -144,7 +144,7 @@ watch(() => props.show, (val) => {
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<div class="flex items-center gap-2">
|
||||
<GoogleIcon name="assignment" class="text-2xl text-emerald-600" />
|
||||
<h3 class="text-lg font-bold text-gray-900 dark:text-gray-100">Exportar Kardex</h3>
|
||||
<h3 class="text-lg font-bold text-gray-900 dark:text-gray-100">Exportar reporte</h3>
|
||||
</div>
|
||||
<button @click="emit('close')" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
|
||||
<GoogleIcon name="close" class="text-xl" />
|
||||
|
||||
@ -292,7 +292,8 @@ const ticketService = {
|
||||
quantity: 1,
|
||||
unit_price: bundlePrice,
|
||||
serials: data.serials,
|
||||
is_bundle: true
|
||||
is_bundle: true,
|
||||
components: data.components
|
||||
};
|
||||
})
|
||||
];
|
||||
@ -333,18 +334,41 @@ const ticketService = {
|
||||
|
||||
yPosition += 4;
|
||||
|
||||
// Números de serie (si existen)
|
||||
const serials = item.serials || item.serial_numbers || [];
|
||||
if (serials.length > 0) {
|
||||
doc.setFontSize(6);
|
||||
// Componentes del paquete (mostrar productos con SKU y sus seriales)
|
||||
if (item.is_bundle && item.components && item.components.length > 0) {
|
||||
doc.setFontSize(7);
|
||||
doc.setFont('helvetica', 'normal');
|
||||
doc.setTextColor(...darkGrayColor);
|
||||
|
||||
serials.forEach((serial) => {
|
||||
const serialNumber = typeof serial === 'string' ? serial : serial.serial_number;
|
||||
doc.text(` S/N: ${serialNumber}`, leftMargin, yPosition);
|
||||
item.components.forEach((comp) => {
|
||||
const compName = comp.product_name || comp.name || comp.inventory?.name || '';
|
||||
const compSku = comp.sku || comp.inventory?.sku || '';
|
||||
const label = compSku ? ` - ${compSku}` : ` - ${compName}`;
|
||||
doc.text(label, leftMargin, yPosition);
|
||||
yPosition += 3;
|
||||
|
||||
// Seriales del componente
|
||||
const compSerials = comp.serial_numbers || comp.serials || [];
|
||||
compSerials.forEach((serial) => {
|
||||
const serialNumber = typeof serial === 'string' ? serial : serial.serial_number;
|
||||
doc.text(`S/N: ${serialNumber}`, leftMargin, yPosition);
|
||||
yPosition += 3;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Números de serie para productos individuales (no bundle)
|
||||
const serials = item.serials || item.serial_numbers || [];
|
||||
if (serials.length > 0) {
|
||||
doc.setFontSize(7);
|
||||
doc.setFont('helvetica', 'normal');
|
||||
doc.setTextColor(...darkGrayColor);
|
||||
|
||||
serials.forEach((serial) => {
|
||||
const serialNumber = typeof serial === 'string' ? serial : serial.serial_number;
|
||||
doc.text(` S/N: ${serialNumber}`, leftMargin, yPosition);
|
||||
yPosition += 3;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
yPosition += 2;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user