fix/conceptos-catalogo-general

This commit is contained in:
2026-04-22 07:44:07 -06:00
parent 41e262b577
commit ff1ff30e23
7 changed files with 66 additions and 10 deletions

View File

@@ -0,0 +1,27 @@
"""add description to classification concept
Revision ID: 1f4ba75eaa35
Revises: f1a2b3c4d5e6
Create Date: 2026-04-21 20:55:04.259655
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '1f4ba75eaa35'
down_revision: Union[str, Sequence[str], None] = 'f1a2b3c4d5e6'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
op.add_column('classification_concepts', sa.Column('description', sa.String(length=255), nullable=True), schema='a76')
def downgrade() -> None:
"""Downgrade schema."""
op.drop_column('classification_concepts', 'description', schema='a76')

View File

@@ -5,6 +5,7 @@ from pydantic import BaseModel, Field, ConfigDict
class ClassificationConceptBase(BaseModel):
classification: str = Field(..., max_length=30,
description="Classification")
description: Optional[str] = Field(None, max_length=255, description="Description")
class ClassificationConceptCreate(ClassificationConceptBase):
@@ -13,6 +14,7 @@ class ClassificationConceptCreate(ClassificationConceptBase):
class ClassificationConceptUpdate(BaseModel):
classification: Optional[str] = Field(None, max_length=30)
description: Optional[str] = Field(None, max_length=255)
class ClassificationConceptResponse(ClassificationConceptBase):

View File

@@ -17,3 +17,6 @@ class ClassificationConcept(Base, TenantScopedMixin, TimestampMixin):
classification: Mapped[str] = mapped_column(
String(30), nullable=False) # CLASIFICACION
description: Mapped[Optional[str]] = mapped_column(
String(255), nullable=True) # DESCRIPCION

View File

@@ -11,4 +11,5 @@ router = TenantCRUDRoutes(
tags=["a76.general_catalogs.classification_concepts"],
resource_name="Classification Concept",
enable_list=True,
enable_filters=True,
).router

View File

@@ -26,6 +26,12 @@ class ClassificationConceptService:
ClassificationConcept.company_id == company_id
)
if filters:
if filters.get("classification"):
query = query.filter(ClassificationConcept.classification.ilike(f"%{filters['classification']}%"))
if filters.get("description"):
query = query.filter(ClassificationConcept.description.ilike(f"%{filters['description']}%"))
total = query.count()
items = query.offset(skip).limit(limit).all()

View File

@@ -4,6 +4,7 @@ import type { ApiResponse } from '$lib/api';
export interface ClassificationConcept {
id: number;
classification: string;
description?: string;
tenant_id: number;
company_id: number;
created_at: string;
@@ -12,6 +13,7 @@ export interface ClassificationConcept {
export interface ClassificationConceptCreate {
classification: string;
description?: string;
}
export interface ClassificationConceptUpdate extends Partial<ClassificationConceptCreate> {}

View File

@@ -30,7 +30,8 @@
// 👇 3. Estado limpio: Solo lo que existe en la BD
let formData = $state({
classification: ''
classification: '',
description: ''
});
let loading = $state(false);
@@ -38,14 +39,18 @@
// Cargar datos al abrir
$effect(() => {
if (item) {
formData = {
classification: item.classification || ''
};
} else {
formData = {
classification: ''
};
if (open) {
if (item) {
formData = {
classification: item.classification || '',
description: item.description || ''
};
} else {
formData = {
classification: '',
description: ''
};
}
}
});
@@ -63,7 +68,8 @@
throw new Error('El nombre de la clasificación es requerido');
const dataToSend = {
classification: formData.classification.trim()
classification: formData.classification.trim(),
description: formData.description ? formData.description.trim() : null
};
// 👇 5. Llamar a la API pasando el companyId
@@ -112,6 +118,15 @@
maxlength={30}
/>
</div>
<div class="grid gap-2">
<Label for="description">Descripción</Label>
<Input
id="description"
bind:value={formData.description}
placeholder="Ej: Descripción general"
maxlength={255}
/>
</div>
</div>
<Dialog.Footer>