Skip to main content
Blueprint Not Currently RegisteredThe furniture type module code exists in app/catalogs/furniture_type/, but the blueprint is not currently registered in the application factory (app/__init__.py). To enable this catalog, add the following to create_app():
from .catalogs.furniture_type import furniture_type_bp
app.register_blueprint(furniture_type_bp, url_prefix='/furniture-types')

Overview

The Furniture Types catalog defines categories of furniture products manufactured by the system. Examples include tables, chairs, closets, and other furniture items. The code is implemented but requires blueprint registration to be accessible.

Data Model

The FurnitureType model is defined in app/models/furniture_type.py:6:
class FurnitureType(db.Model):
    __tablename__ = 'furniture_type'
    
    id_furniture_type = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False, unique=True)
    active = db.Column(db.Boolean, nullable=False, default=True)
    
    created_at = db.Column(db.TIMESTAMP, server_default=func.current_timestamp())
    updated_at = db.Column(db.TIMESTAMP, server_onupdate=func.current_timestamp())
    deleted_at = db.Column(db.TIMESTAMP, nullable=True)
    
    created_by = db.Column(db.String(100), nullable=True)
    updated_by = db.Column(db.String(100), nullable=True)
    deleted_by = db.Column(db.String(100), nullable=True)

Fields

FieldTypeDescription
id_furniture_typeIntegerPrimary key
nameString(50)Unique furniture type name
activeBooleanSoft delete flag
created_atTimestampRecord creation date
updated_atTimestampLast modification date
deleted_atTimestampLogical deletion date

Service Layer

The FurnitureTypeService class in app/catalogs/furniture_type/services.py:13 provides business logic:

Get All Furniture Types

Retrieves all active furniture types:
furniture_types = FurnitureTypeService.get_all()
Implementation from services.py:17:
@staticmethod
def get_all() -> list[FurnitureType]:
    return FurnitureType.query.filter_by(active=True).all()

Create Furniture Type

Creates a new furniture type:
data = {"name": "Dining Table"}
furniture_type = FurnitureTypeService.create(data)
Implementation from services.py:27:
@staticmethod
def create(data: dict) -> dict:
    name = data.get("name")
    
    if not name or not name.strip():
        raise ValidationError("El nombre del tipo de mueble es requerido")
    
    name = name.strip()
    
    existing = FurnitureType.query.filter_by(name=name).first()
    if existing:
        raise ConflictError(f"Ya existe un tipo de mueble con el nombre '{name}'")
    
    furniture_type = FurnitureType(name=name)
    db.session.add(furniture_type)
    db.session.commit()
    
    return furniture_type.to_dict()

Get Furniture Type by ID

Retrieves a specific furniture type:
furniture_type = FurnitureTypeService.get_by_id(id_furniture_type)
Implementation from services.py:64:
@staticmethod
def get_by_id(id_furniture_type: int) -> FurnitureType:
    furniture_type = FurnitureType.query.get(id_furniture_type)
    if not furniture_type:
        raise NotFoundError(f"No se encontró el tipo de mueble con ID {id_furniture_type}")
    return furniture_type

Update Furniture Type

Updates an existing furniture type:
data = {"name": "Coffee Table"}
FurnitureTypeService.update(id_furniture_type, data)
Implementation from services.py:83:
@staticmethod
def update(id_furniture_type: int, data: dict) -> dict:
    furniture_type = FurnitureTypeService.get_by_id(id_furniture_type)
    
    name = data.get("name")
    if not name or not name.strip():
        raise ValidationError("El nombre del furniture_type es requerido")
    
    name = name.strip()
    
    existing = FurnitureType.query.filter(
        FurnitureType.name == name, 
        FurnitureType.id_furniture_type != id_furniture_type
    ).first()
    if existing:
        raise ConflictError(f"Ya existe un tipo de mueble con el nombre '{name}'")
    
    furniture_type.name = name
    db.session.commit()
    
    return furniture_type.to_dict()

Delete Furniture Type

Performs a soft delete:
FurnitureTypeService.delete(id_furniture_type)
Implementation from services.py:123:
@staticmethod
def delete(id_furniture_type: int) -> None:
    furniture_type = FurnitureTypeService.get_by_id(id_furniture_type)
    furniture_type.active = False
    furniture_type.deleted_at = func.current_timestamp()
    db.session.commit()

Routes

The routes module (app/catalogs/furniture_type/routes.py) defines HTTP endpoints:

List Furniture Types

Endpoint: GET /furniture-types/ From routes.py:13:
@furniture_type_bp.route("/", methods=["GET"])
def list_furniture_type():
    furniture_type = FurnitureTypeService.get_all()
    return render_template("furniture_type/list.html", furniture_type=furniture_type)

Create Furniture Type

Endpoint: GET/POST /furniture-types/create From routes.py:25:
@furniture_type_bp.route("/create", methods=["GET", "POST"])
def create_furniture_type():
    form = FurnitureTypeForm()
    
    if form.validate_on_submit():
        data = {"name": form.name.data}
        try:
            FurnitureTypeService.create(data)
            flash("Tipo de mueble creado exitosamente", "success")
            return redirect(url_for("furniture_type.create_furniture_type"))
        except ConflictError as e:
            flash(e.message, "error")
    
    return render_template("furniture_type/create.html", form=form)

Form Definition

The FurnitureTypeForm class in app/catalogs/furniture_type/forms.py:10 defines the input form:
class FurnitureTypeForm(FlaskForm):
    name = StringField(
        "Nombre",
        validators=[
            DataRequired(message="El nombre del tipo de mueble es requerido"),
            Length(max=50, message="El nombre no puede exceder 50 caracteres"),
        ],
    )

Validators

1

DataRequired

Ensures the name field is not empty
2

Length

Validates that the name does not exceed 50 characters

Usage Examples

Common Furniture Types

Typical categories in a furniture manufacturing system:

Seating

  • Chair (Silla)
  • Armchair (Sillón)
  • Bench (Banco)
  • Stool (Taburete)

Tables

  • Dining Table (Mesa de comedor)
  • Coffee Table (Mesa de centro)
  • Desk (Escritorio)
  • Side Table (Mesa auxiliar)

Storage

  • Closet (Closet)
  • Dresser (Cómoda)
  • Bookshelf (Librero)
  • Cabinet (Gabinete)

Beds

  • Bed Frame (Cama)
  • Bunk Bed (Litera)
  • Headboard (Cabecera)
  • Nightstand (Buró)

Creating Furniture Types

from app.catalogs.furniture_type.services import FurnitureTypeService

# Create common furniture types
furniture_types = [
    {"name": "Mesa"},
    {"name": "Silla"},
    {"name": "Closet"},
    {"name": "Escritorio"}
]

for ft_data in furniture_types:
    try:
        result = FurnitureTypeService.create(ft_data)
        print(f"Created: {result['name']}")
    except ConflictError as e:
        print(f"Already exists: {ft_data['name']}")

Listing Furniture Types

# Get all active furniture types
furniture_types = FurnitureTypeService.get_all()
for ft in furniture_types:
    print(f"ID {ft.id_furniture_type}: {ft.name}")

Best Practices

Define broad categories rather than specific products:
  • Good: “Table”, “Chair”, “Cabinet”
  • Avoid: “4-Person Oak Dining Table”, “Red Office Chair”
Use singular nouns and maintain consistent language:
# Good
"Chair", "Table", "Closet"

# Avoid
"Chairs", "dining tables", "CLOSET"
Furniture types should be reusable across multiple products:
  • One “Table” type can apply to dining tables, coffee tables, etc.
  • Use additional attributes (size, color, wood type) to differentiate

Integration with Production

Furniture types serve as categories for finished products:
# Example: Link furniture type to product
product = {
    "name": "Oak Dining Table",
    "furniture_type_id": 1,  # References "Table" furniture type
    "wood_type_id": 2,       # Oak
    "color_id": 5            # Natural
}
Furniture types are foundational data for the inventory and production modules.

Build docs developers (and LLMs) love