Product Model
TheProducto model represents items in your inventory with the following fields:
Unique product identifier (auto-generated)
Foreign key to the owner User (admin who created the product)
Barcode identifier (unique per user, max 50 characters)
Product name (max 100 characters, required)
Product category (max 50 characters, optional)
Purchase cost (10 digits, 2 decimals, default: 0.00)
Selling price (10 digits, 2 decimals)
Available quantity (positive integer, default: 0)
Timestamp when product was created (auto-generated)
Timestamp of last update (auto-updated)
List Products
Requires authentication. Returns products owned by the authenticated user (admin) or their creator (vendedor).
Query Parameters
Filter products by category (case-insensitive exact match)
Sort field. Options:
nombre, precio, stock, categoria, -precio (descending)Page number for pagination (7 items per page)
Example: Filter and Sort
Response
Returns rendered HTML template with paginated product list. Seeproducts_lista.html template.
Create Product
Request Parameters
Product name (max 100 characters)
Barcode (must be unique per user, max 50 characters)
Product category (max 50 characters)
Purchase cost (e.g., “1200.00”)
Selling price (e.g., “1500.00”)
Initial stock quantity
Response
Success (HTTP 302):- Redirects to
/productos/ - Flash message: “Producto agregado correctamente.”
- Re-renders form with error messages
- Flash message: “Revisa los campos marcados en el formulario.”
- Redirects to error page (vendedor users)
Validation Rules
nombreis requiredcodigo_de_barrasmust be unique within user’s products (constraint:unique_together=('codigo_de_barras', 'usuario'))precio_compraandpreciomust be non-negative decimalsstockmust be non-negative integer
Update Product
URL Parameters
Product ID to update
Request Parameters
Same as Create Product - all fields are editable.Response
Success (HTTP 302):- Redirects to
/productos/ - Flash message: “Producto actualizado correctamente.”
- Product doesn’t exist or doesn’t belong to authenticated user
- Re-renders form with error messages
Delete Product
URL Parameters
Product ID to delete
Response
Success (HTTP 302):- Product deleted
- Redirects to
/productos/ - Flash message: “Producto eliminado correctamente.”
- Cannot delete due to foreign key constraint (product has sales)
- Redirects to
/productos/ - Error message: “No se puede eliminar el producto '' porque está relacionado con una venta. Para eliminar este producto, primero debes eliminar la(s) venta(s) asociada(s).”
- Product doesn’t exist or doesn’t belong to user
GET Request
Accessing the delete URL via GET shows confirmation page:producto_confirmar_eliminar.html template.
Business Logic
Stock Management
Product stock is automatically decremented when:- Sale created:
producto.stock -= cantidad - Sale detail updated:
producto.stock -= (new_cantidad - old_cantidad)
- Sale deleted:
producto.stock += cantidad - Sale detail deleted:
producto.stock += cantidad
Purchase Integration
When products are purchased:- Stock incremented:
producto.stock += cantidad_comprada - Purchase price updated:
producto.precio_compra = precio_compra_detalle - Optionally, selling price updated:
producto.precio = precio_venta_detalle
Multi-Tenancy
Products are isolated per user:- Admin users see only their own products
- Vendedor users see products owned by their
creado_poradmin - Enforced at database level:
usuarioforeign key - Enforced in views:
Producto.objects.filter(usuario=request.user)
Barcode Uniqueness
Theunique_together constraint allows:
- Same barcode for different users (multi-tenant isolation)
- Different products with unique barcodes per user
Example Workflow
Create Product with Stock
Related Endpoints
- Sales API - Product selection in sales
- Purchases API - Product stock replenishment
- See
applications/productos/views.pysource:/home/daytona/workspace/source/applications/productos/views.py