Skip to main content

Unidad de Medida API

The Unidad de Medida (Units of Measurement) API provides read-only access to the units of measurement used throughout the POS system. These units are essential for defining product quantities, inventory management, and sales transactions.

Endpoints Overview

MethodEndpointAuthenticationDescription
GET/api/pos/unidadmedidaRequiredGet all units of measurement
The Unidad de Medida API is read-only. Unit management is typically handled through database administration tools or dedicated admin interfaces.

GET /api/pos/unidadmedida

Retrieve a complete list of all units of measurement in the system, ordered alphabetically by description.

Authentication

Authorization
string
required
Bearer token received from the login endpointExample: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response

Returns an array of unit of measurement objects, each containing:
um_codigo
string
Unique unit of measurement code identifier
um_descripcion
string
Unit description/name (e.g., “Kilogramo”, “Unidad”, “Litro”)
um_estado
string
Unit status (ACT for Active, INA for Inactive)

Example Request

curl -X GET http://localhost:3000/api/pos/unidadmedida \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

[
  {
    "um_codigo": "UN",
    "um_descripcion": "Unidad",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "KG",
    "um_descripcion": "Kilogramo",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "LT",
    "um_descripcion": "Litro",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "GR",
    "um_descripcion": "Gramo",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "ML",
    "um_descripcion": "Mililitro",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "CJ",
    "um_descripcion": "Caja",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "PQ",
    "um_descripcion": "Paquete",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "LB",
    "um_descripcion": "Libra",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "MT",
    "um_descripcion": "Metro",
    "um_estado": "ACT"
  },
  {
    "um_codigo": "GL",
    "um_descripcion": "Galón",
    "um_estado": "ACT"
  }
]
Results are ordered alphabetically by um_descripcion for easy reference in dropdown menus and selection interfaces.
{
  "message": "No se encontraron unidades de medida"
}
This response indicates that no units of measurement exist in the database. This should not occur in a properly initialized system.
{
  "message": "Token inválido o expirado"
}
This error occurs when:
  • No Authorization header is provided
  • The token is invalid or malformed
  • The token has expired

Usage Examples

JavaScript - Populate Dropdown

async function loadUnits() {
  try {
    const response = await fetch('http://localhost:3000/api/pos/unidadmedida', {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });
    
    const units = await response.json();
    
    const select = document.getElementById('unitSelect');
    units.forEach(unit => {
      const option = document.createElement('option');
      option.value = unit.um_codigo;
      option.textContent = unit.um_descripcion;
      select.appendChild(option);
    });
  } catch (error) {
    console.error('Error loading units:', error);
  }
}

Python - Create Unit Lookup Dictionary

import requests

def get_units_lookup(token):
    url = "http://localhost:3000/api/pos/unidadmedida"
    headers = {"Authorization": f"Bearer {token}"}
    
    response = requests.get(url, headers=headers)
    units = response.json()
    
    # Create a dictionary for quick lookups
    units_dict = {
        unit['um_codigo']: unit['um_descripcion']
        for unit in units
        if unit['um_estado'] == 'ACT'
    }
    
    return units_dict

# Usage
units = get_units_lookup(token)
print(units['KG'])  # Output: "Kilogramo"
print(units['UN'])  # Output: "Unidad"

React - Units Context Provider

import { createContext, useContext, useState, useEffect } from 'react';

const UnitsContext = createContext();

export function UnitsProvider({ children, token }) {
  const [units, setUnits] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUnits() {
      try {
        const response = await fetch('http://localhost:3000/api/pos/unidadmedida', {
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });
        
        const data = await response.json();
        setUnits(data);
      } catch (error) {
        console.error('Error loading units:', error);
      } finally {
        setLoading(false);
      }
    }

    fetchUnits();
  }, [token]);

  const getUnitDescription = (codigo) => {
    const unit = units.find(u => u.um_codigo === codigo);
    return unit ? unit.um_descripcion : codigo;
  };

  return (
    <UnitsContext.Provider value={{ units, loading, getUnitDescription }}>
      {children}
    </UnitsContext.Provider>
  );
}

export function useUnits() {
  return useContext(UnitsContext);
}

// Usage in component
function ProductDisplay({ product }) {
  const { getUnitDescription } = useUnits();
  
  return (
    <div>
      <h3>{product.name}</h3>
      <p>Precio: ${product.price} / {getUnitDescription(product.um_codigo)}</p>
    </div>
  );
}

TypeScript - Type-Safe Units

interface UnidadMedida {
  um_codigo: string;
  um_descripcion: string;
  um_estado: 'ACT' | 'INA';
}

class UnitsService {
  private static units: UnidadMedida[] = [];
  private static lastFetch: number = 0;
  private static CACHE_DURATION = 3600000; // 1 hour

  static async getUnits(token: string): Promise<UnidadMedida[]> {
    const now = Date.now();
    
    // Return cached units if still fresh
    if (this.units.length > 0 && now - this.lastFetch < this.CACHE_DURATION) {
      return this.units;
    }

    const response = await fetch('http://localhost:3000/api/pos/unidadmedida', {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      throw new Error('Failed to fetch units of measurement');
    }

    this.units = await response.json();
    this.lastFetch = now;
    return this.units;
  }

  static getActiveUnits(): UnidadMedida[] {
    return this.units.filter(u => u.um_estado === 'ACT');
  }

  static findByCode(codigo: string): UnidadMedida | undefined {
    return this.units.find(u => u.um_codigo === codigo);
  }
}

// Usage
const units = await UnitsService.getUnits(token);
const kgUnit = UnitsService.findByCode('KG');
console.log(kgUnit?.um_descripcion); // "Kilogramo"

Error Codes

Status CodeDescription
200Request successful
401Unauthorized - invalid or missing token
404No units of measurement found in database
500Internal server error

Data Model

Unit of Measurement Object Structure

interface UnidadMedida {
  um_codigo: string;         // Primary key, unique identifier (e.g., "KG", "UN")
  um_descripcion: string;    // Unit name/description (e.g., "Kilogramo", "Unidad")
  um_estado: 'ACT' | 'INA'; // Active or Inactive status
}

Database Schema

The units are stored in the unidadmedida table with the following structure:
ColumnTypeDescription
um_codigoVARCHAR(10)Primary key, unit code (typically 2-3 characters)
um_descripcionVARCHAR(100)Unit name/description
um_estadoVARCHAR(3)Status: ACT (Active) or INA (Inactive)

Common Units Reference

The system typically includes these standard units of measurement:

Weight Units

CodeDescriptionCommon Use
KGKilogramoBulk materials, produce
GRGramoSmall quantities, ingredients
LBLibraAlternative weight measurement

Volume Units

CodeDescriptionCommon Use
LTLitroLiquids, beverages
MLMililitroSmall liquid quantities
GLGalónLarge liquid volumes

Count Units

CodeDescriptionCommon Use
UNUnidadIndividual items
CJCajaBoxed products
PQPaquetePackaged items

Measurement Units

CodeDescriptionCommon Use
MTMetroLength, fabric
CMCentímetroSmaller measurements

Common Use Cases

Product Definition

Units of measurement are essential for defining products and materials:
  • Product Registration: Select appropriate unit when creating products
  • Inventory Management: Track stock quantities in specific units
  • Pricing: Define prices per unit (e.g., $5.00 per KG)
  • Sales Transactions: Record sales quantities with units

Inventory Operations

  • Stock Counting: Record inventory in appropriate units
  • Conversions: Handle unit conversions (e.g., KG to GR)
  • Purchase Orders: Specify quantities with units
  • Transfers: Track material movements with units

Reporting

  • Stock Reports: Display inventory levels with units
  • Sales Reports: Show quantities sold by unit
  • Cost Analysis: Calculate costs per unit
  • Consumption Reports: Track material usage by unit

Integration Points

The Unidad de Medida API integrates with multiple POS modules:
Related Modules:
  • Productos: Products are assigned units through um_codigo
  • Materia Prima: Raw materials require unit definitions
  • Factura: Sales invoices record quantities with units
  • Orden de Compra: Purchase orders specify quantities in units
  • Kardex: Inventory movements track units

Best Practices

Performance Optimization:
  • Cache units data on the client side since it changes very rarely
  • Load units once on application startup
  • Use local storage or state management to avoid repeated API calls
  • Consider a cache TTL of 24 hours or more for units data
UI/UX Recommendations:
  • Display both code and description in selection interfaces
  • Use descriptions in read-only displays
  • Provide search/filter functionality in dropdowns for large unit lists
  • Show unit abbreviations (codes) in compact displays
State Handling:
  • Always filter by um_estado = 'ACT' when displaying units to users
  • Inactive units should only be visible in admin interfaces
  • Maintain backward compatibility - don’t delete historical unit references
  • Keep unit codes consistent across related systems

Validation and Constraints

When working with units of measurement:
  1. Foreign Key Constraints: Products and materials must reference valid um_codigo values
  2. Active Status: Only active units should be selectable in new records
  3. Historical Data: Inactive units may still appear in historical transactions
  4. Code Format: Unit codes are typically 2-3 uppercase characters

Implementation Notes

Controller Implementation

The unit controller is implemented in pos.unidadmedida.controller.js:
const getAll = async (req, res) => {
  const pool = connectFromJWT(req);

  try {
    const result = await getAllQuery(pool);

    if (!result.length) {
      return res.status(404).json({ message: 'No se encontraron unidades de medida' });
    }
    res.status(200).json(result);
  } catch (error) {
    res.status(500).json({ message: error.message });
  } finally {
    await pool.end();
  }
};

Model Implementation

The unit model in unidadmedida.model.js executes a simple query:
const getAllQuery = async (pool) => {
  const query = 'SELECT * FROM unidadmedida ORDER BY um_descripcion';
  const result = await pool.query(query);
  return result.rows;
};

Connection Management

Like all POS endpoints, units use JWT-based connection pooling:
  1. JWT token is verified by verifyToken middleware
  2. Database credentials are extracted from the token payload
  3. A dedicated connection pool is created with user credentials
  4. Query is executed with proper permission scope
  5. Connection pool is closed in the finally block
This ensures proper row-level security and audit trailing at the database level.

Extending Units

If you need to add new units of measurement to your system:
1

Define the Unit

Determine the appropriate code (2-3 chars) and description
2

Insert into Database

Add the unit directly to the unidadmedida table with um_estado = 'ACT'
3

Clear Client Caches

Ensure client applications refresh their cached unit data
4

Update Documentation

Document any custom units specific to your industry or business
Always consult with your database administrator before modifying master data tables like unidadmedida.

Build docs developers (and LLMs) love