Skip to main content

Introduction

The Catalogs & Configuration module provides centralized management of all master data used throughout the SASCOP BME SubTec system. This module ensures data consistency and provides the foundation for operational workflows.

Key Catalog Types

Products & Concepts

Manage ordinary and extraordinary work concepts with pricing and units

Sites & Fronts

Configure work locations, fronts, and operational sites

Clients & Responsibles

Manage client information and project leaders

Status & Types

Define workflow status and classification types

Architecture

Database Models

All catalog models are defined in catalogos_models.py with consistent structure:
operaciones/models/catalogos_models.py
class Sitio(models.Model):
    descripcion = models.CharField(max_length=100)
    activo = models.BooleanField(default=True)
    id_frente = models.ForeignKey(Frente, on_delete=models.CASCADE, blank=True, null=True)
    comentario = models.TextField(blank=True, null=True)
    
    class Meta:
        db_table = 'sitio'

    def __str__(self):
        return self.descripcion

Common Fields

All catalog models share these standard fields:
Primary descriptive field for the catalog item (50-200 characters)
Boolean flag for soft deletion (default: True). Inactive records are filtered from operations.
Optional text field for additional notes and documentation

API Patterns

Standard CRUD Operations

Each catalog follows a consistent API pattern:
def datatable_sitios(request):
    draw = int(request.GET.get('draw', 1))
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 10))
    search_value = request.GET.get('filtro', '')
    
    sitios = Sitio.objects.filter(activo=1).annotate(
        estado_texto=Case(
            When(activo=True, then=Value('Activo')),
            When(activo=False, then=Value('Inactivo')),
            default=Value('Desconocido'),
            output_field=CharField()
        ),
        frente_descripcion=F('id_frente__descripcion')
    ).order_by('id')
    
    if search_value:
        sitios = sitios.filter(
            Q(descripcion__icontains=search_value) |
            Q(activo__icontains=search_value)
        )
    
    total_records = sitios.count()
    sitios = sitios[start:start + length]
    
    data = []
    for sitio in sitios:
        data.append({
            'id': sitio.id,
            'descripcion': sitio.descripcion,
            'activo': sitio.estado_texto,
            'activo_bool': sitio.activo,
            'frente': sitio.frente_descripcion,
        })
    
    return JsonResponse({
        'draw': draw,
        'recordsTotal': total_records,
        'recordsFiltered': total_records,
        'data': data
    })

URL Configuration

Catalog endpoints follow RESTful conventions:
operaciones/urls.py
# URLs for Sites
path('catalogos/sitios/', catalogos.lista_sitios, name='lista_sitios'),
path('catalogos/datatable_sitios/', catalogos.datatable_sitios, name='datatable_sitios'),
path('catalogos/sitios/crear/', catalogos.crear_sitio, name='crear_sitio'),
path('catalogos/sitios/eliminar/', catalogos.eliminar_sitio, name='eliminar_sitio'),
path('catalogos/sitios/obtener/', catalogos.obtener_sitio, name='obtener_sitio'),
path('catalogos/sitios/editar/', catalogos.editar_sitio, name='editar_sitio'),
Soft Delete Pattern: All catalogs use soft deletion (activo=False) to maintain referential integrity and historical data.

Best Practices

1

Data Validation

Always validate required fields before creation:
if not id_partida:
    return JsonResponse({
        'exito': False, 
        'tipo_aviso': 'error', 
        'detalles': 'El ID de partida es obligatorio'
    })
2

Foreign Key Handling

Use select_related() and prefetch_related() for efficient queries:
productos = Producto.objects.filter(activo=1).select_related(
    'id_sitio', 'id_tipo_partida', 'id_unidad_medida'
)
3

Search Optimization

Implement case-insensitive search across relevant fields:
if search_value:
    tipos = tipos.filter(
        Q(descripcion__icontains=search_value) |
        Q(nivel_afectacion__icontains=search_value)
    )
4

Annotation for Display

Use Django’s annotate() to prepare display-ready data:
.annotate(
    estado_texto=Case(
        When(activo=True, then=Value('Activo')),
        When(activo=False, then=Value('Inactivo')),
        default=Value('Desconocido'),
        output_field=CharField()
    )
)

Security & Permissions

Catalog modifications require proper authentication and permissions:
@login_required(login_url='/accounts/login/')
def lista_tipos(request):
    # Only authenticated users can access catalogs
    ...

Products Catalog

Detailed product and concept management

Sites Configuration

Site and front configuration guide

Client Management

Client and responsible party setup

Status Definitions

Status and type configuration

Build docs developers (and LLMs) love