TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/dinogamer089/SiCom/llms.txt
Use this file to discover all available pages before exploring further.
negocio module (Maven artifact negocio) houses the entire business layer of SiCom. All business logic lives in the package mx.desarollo.facade, organised around a classic Facade → Delegate → DAO layering. A Facade class exposes coarse-grained operations to JSF backing beans; each Facade owns one or more Delegate instances (package mx.desarollo.delegate) that translate high-level requests into fine-grained DAO calls in the persistencia module. This two-step indirection keeps JSF beans free of persistence concerns and keeps the DAO layer free of business rules.
Delegate classes are instantiated directly inside each Facade constructor using
new DelegateXxx(). No CDI, no injection, no container lifecycle — this is a deliberate manual Facade pattern. If you introduce dependency injection in a future iteration, the Facade constructors are the only place that needs to change.ServiceFacadeLocator
Package:mx.desarollo.integration
ServiceFacadeLocator is a static factory that hands out lazily-initialised, module-scoped singleton instances of every Facade class. Each getInstanceFacadeXxx() method uses the standard null-check pattern:
| Facade class | Accessor |
|---|---|
FacadeLogin | ServiceFacadeLocator.getInstanceFacadeLogin() |
FacadeArticulo | ServiceFacadeLocator.getInstanceFacadeArticulo() |
FacadeRenta | ServiceFacadeLocator.getInstanceFacadeRenta() |
FacadeEmpleado | ServiceFacadeLocator.getInstanceFacadeEmpleado() |
FacadeCombinacionMesa | ServiceFacadeLocator.getInstanceFacadeCombinacionMesa() |
FacadeTarjetaAlmacen | ServiceFacadeLocator.getInstanceFacadeTarjetaAlmacen() |
FacadeDashboard and FacadeCarrito are not registered in ServiceFacadeLocator; backing beans that need them instantiate them directly with new FacadeDashboard() / new FacadeCarrito().
Usage example
FacadeArticulo
Package:mx.desarollo.facadeDelegate:
DelegateArticulo
Manages the full lifecycle of rental articles: catalogue display, creation with an associated image, retrieval, update, and soft-/hard-delete. All name uniqueness checks are applied at the Facade level before any persistence call is made.
listarCatalogoCliente()
DelegateArticulo.listarCatalogoCliente(), which calls ArticuloDAO.listarActivosConStock() — a JPQL query that filters for activo = true AND unidades > 0, ordered by category and name, with the Imagen association eagerly fetched to avoid LazyInitializationException in JSF.
Returns: List<Articulo> — may be empty; never null.
obtenerArticulos()
activo = true. Used in administration screens where soft-deleted articles must be hidden but stock-zero articles are still manageable.
Returns: List<Articulo> — active articles only; never null.
crearArticuloConImagen(Articulo articulo, Imagen imagen)
articulomust not benull.articulo.getNombre()must not be blank after trimming.- No existing article may share the same name (case- and whitespace-insensitive check via
DelegateArticulo.existsArticuloByNombre).
trim() and both entities are persisted atomically by ArticuloDAO.saveWithImage.
The article entity to persist. Must have a non-blank
nombre. The id field must be null (new record).The image entity to associate with the article. Persisted first so its generated ID can be set on the article before the article is persisted.
voidThrows:
IllegalArgumentException if articulo is null, the name is blank, or the name already exists.
eliminarArticuloPorId(Integer id)
findByIdWithImage, sets activo = false, and calls updateArticulo. This ensures referential integrity is never broken.
Primary key of the article to delete or deactivate.
void
obtenerArticuloPorId(Integer id)
Imagen association.
Primary key of the article.
Optional<Articulo> — empty if no article with that ID exists.
obtenerArticuloConImagenPorId(Integer id)
Imagen association eagerly fetched via JOIN FETCH. Use this variant in JSF views that render the article image to prevent LazyInitializationException after the EntityManager is closed.
Primary key of the article.
Optional<Articulo> with imagen populated; empty if the article does not exist.
actualizarArticulo(Articulo articulo)
crearArticuloConImagen, but excludes the article being updated from the duplicate check using existsArticuloByNombreExcludingId.
The detached article entity with updated fields.
articulo.getId() must not be null.voidThrows:
IllegalArgumentException if articulo is null, its id is null, the name is blank, or another article already uses that name.
FacadeRenta
Package:mx.desarollo.facadeDelegate:
DelegateRenta
Central facade for all rental and quotation operations, including state transitions, stock reservation management, employee assignment queries, and comment handling.
obtenerCotizaciones()
SOLICITADA (pending quotations awaiting administrator review). Each Renta is returned with its detallesRenta collection and the associated Articulo per detail eagerly fetched.
Returns: List<Renta>
obtenerRentas()
SOLICITADA. Used in the administrator’s rental-management screen to show confirmed, in-progress, and finalised rentals.
Returns: List<Renta>
obtenerRentaId(Integer idRenta)
idCliente, detallesRenta, and the Articulo within each detail.
Primary key of the rental.
Renta — null if no rental with that ID exists.
cambiarEstado(Integer idRenta, String nuevoEstado)
RentaDAO.cambiarEstadoRenta— executes the MySQL stored procedureCALL cambiar_estado_renta(:idRent, :nuevoEst)inside its own transaction.DelegateRenta.registrarMovimientosAutomaticos— for stateConfirmadoorFinalizada, creates aMovimientoAlmacenrecord (SALIDA or ENTRADA respectively) for every article in the rental’s detail lines and updatesStockDiario.DelegateRenta.liberarReservasCliente— for stateFinalizadaorCancelada, decrementsStockReservadoDiarioentries for every day in the rental range[fechaInicio, fecha].
Primary key of the rental to transition.
Target state string. Valid values include
"Confirmado", "Finalizada", "Cancelada", "En reparto", "En recoleccion", "Pendiente a reparto", "Pendiente a recoleccion".void
actualizarRenta(Renta renta)
Detached
Renta entity with updated fields. Must have a non-null id.void
registrarRenta(Cliente, List<Detallerenta>, LocalDate, LocalDate, LocalTime, String)
cliente.getId() is null the client is persisted first; the Renta header is saved next with its computed total; then each Detallerenta is linked to the new rental and persisted.
The client placing the rental. May be a new (unsaved) or existing entity.
Line items describing each article and quantity.
precioUnitario defaults to the article’s current precio if not set.Date articles are dispatched / pickup begins.
Return / delivery date (end of rental period).
Delivery or event time on
fecha.Initial state of the record; typically
"SOLICITADA" for a client quotation.void
obtenerRentasDisponiblesYAsignadas(Integer idEmpleado)
- Rentals in
Pendiente a repartowith no employee assigned yet (available for self-assignment). - All rentals in
Pendiente a recoleccion(public, any employee may take them). - Rentals already assigned to
idEmpleadoin statesEn repartoorEn recoleccion.
fechaInicio ASC, hora ASC.
Primary key of the currently-authenticated employee.
List<Renta> — null if no results are found (propagated NoResultException).
obtenerComentarios(Integer idRenta)
Primary key of the rental whose comments are requested.
List<Comentario> — empty list if idRenta is null or no comments exist.
guardarComentario(Comentario comentario)
Comentario entity must already have its idRenta association set before this call.
The comment entity to persist. Must reference a valid
Renta via idRenta.void
actualizarRentaConStock(Renta, LocalDate, LocalDate)
- Removed details — for line items present in the database but absent from
renta.getDetallesRenta(), the reserved stock for the original date range is decremented and theDetallerentarow is deleted. - Date-change path — if either date boundary changed, the entire previous reservation is released and new reservations are created for the new range, with availability validated first.
- Quantity-change path — if only quantities changed (dates unchanged), only the net delta is applied to
StockReservadoDiario.
The rental entity with updated header fields and detail list. Must have a non-null
id.The
fechaInicio value before the edit, needed to release previous reservations from the correct range.The
fecha (end date) value before the edit.voidThrows:
Exception if stock is insufficient for the new configuration or if the transaction fails.
FacadeEmpleado
Package:mx.desarollo.facadeDelegate:
DelegateEmpleado
CRUD operations for employee records, with password hashing delegated to DelegateEmpleado via jBCrypt. All password hashing (cost factor 12) occurs inside the delegate before any DAO call.
getAllEmpleados()
EmpleadoDAO.findAll().
Returns: List<Empleado>
saveEmpleado(Empleado empleado)
empleado.getContrasena() with BCrypt (cost 12) before calling EmpleadoDAO.save.
New employee entity. The
contrasena field must contain the plain-text password to be hashed.void
updateEmpleado(Empleado empleado)
contrasena differs from the stored BCrypt hash; if the incoming value is a plain-text password (does not start with $2), it is hashed before the update. If the employee no longer exists in the database, the password is hashed unconditionally.
Detached employee entity. If
contrasena is a plain-text value it will be hashed; if it is already a BCrypt hash it will be stored unchanged.void
deleteEmpleado(Empleado empleado)
tieneAsignacionesPendientes to prevent deletion of employees with active dispatch/collection assignments.
Managed or detached employee entity to delete.
void
findById(Integer id)
Primary key of the employee.
Empleado — null if no employee with that ID exists.
tieneAsignacionesPendientes(Integer empleadoId)
En reparto or En recoleccion. The UI uses this to guard the delete action with a warning dialog.
Primary key of the employee to check.
true if at least one such rental exists; false otherwise.
FacadeDashboard
Package:mx.desarollo.facadeDelegate:
DelegateDashboard (instantiated inline as private final DelegateDashboard delegate = new DelegateDashboard())
Aggregates business metrics for the analytics dashboard. All time-window calculations are performed in the Facade; the Delegate and DashboardDAO only receive resolved Date boundaries.
calcularMetricas(String rango, int nDias)
DashboardMetricsDTO with counts, totals, averages, percentage changes, and a top-5 article ranking.
Supported rango values:
| Value | Resolved window |
|---|---|
"HOY" | Today, compared against yesterday |
"ULTIMOS_30" | Rolling 30-day window ending today, compared against the preceding 30-day block |
| Any other string | Rolling nDias-day window ending today, compared against the preceding nDias-day block |
((current - previous) / previous) × 100. If previous is 0, the change is set to Double.NaN so the UI can display — instead of a misleading percentage.
The top-5 articles are fetched by delegate.findTopArticulosVendidos(start, end, 5) and augmented with a percentage-of-total column. An "Otros" entry is appended when the top-5 do not account for the full total.
Time-window selector. One of
"HOY", "ULTIMOS_30", or any other string (uses nDias).Number of days for the custom window. Ignored when
rango is "HOY" or "ULTIMOS_30".DashboardMetricsDTO — fully-populated DTO with current/prior period boundaries, rental counts, revenue totals, averages, percent changes, and the top-articles list.
obtenerDailyStatus(Date start, Date end)
Range start (inclusive).
Range end (inclusive).
List<DailyRentaStatusDTO>
obtenerFunnelCotizaciones(Date start, Date end)
aprobadas), and those that reached Finalizada (pagadas).
Range start (inclusive).
Range end (inclusive).
CotizacionFunnelDTO
obtenerEfectividadCotizaciones(Date start, Date end)
< $5,000, MEDIUM $5,000–$20,000, VIP > $20,000) and returns the count of quotations versus confirmed rentals in each bucket.
Range start (inclusive).
Range end (inclusive).
List<CotizacionEfectividadDTO>
obtenerMontosCotizaciones(Date start, Date end)
Range start (inclusive).
Range end (inclusive).
CotizacionMontosDTO with montoCotizado and montoCerrado fields.
Client metric methods
| Method | Description |
|---|---|
obtenerClientesTotales | Distinct client names regardless of date range (full-table count). |
obtenerClientesNuevos | Clients whose first-ever rental falls within [start, end]. |
obtenerClientesFrecuentesCount | Clients with more than one non-cancelled, non-quoted rental in the range. |
obtenerGrowthClientes | Daily cumulative client growth series for the date range (used in line chart). |
obtenerClientesFrecuentes | Top-N clients ordered by rental frequency (all time). |
Maximum number of results to return for
obtenerClientesFrecuentes.FacadeLogin
Package:mx.desarollo.facadeDelegate:
DelegateLogin
Authentication facade. Verifies credentials against both the Administrador and Empleado tables using BCrypt password verification, and provides account creation helpers.
login(String password, String correo)
AdministradorDAO.findByCorreo(correo); if a matching record is found and BCrypt.checkpw(password, admin.getContrasena()) passes, the Administrador object is returned. If that check fails, the same logic is applied against EmpleadoDAO.findByCorreo. If neither check succeeds, null is returned.
Plain-text password submitted by the user.
Email address used as the login identifier.
Administrador or Empleado on success; null on failure. The caller is responsible for casting and setting session scope.
saveAdministrador(Administrador admin)
admin.getContrasena() with BCrypt (default cost) and persists the administrator record.
New administrator entity with a plain-text password in
contrasena.void
saveEmpleado(Empleado empleado)
empleado.getContrasena() with BCrypt and persists the employee record. Equivalent to FacadeEmpleado.saveEmpleado but used in the login/registration flow where only DelegateLogin is available.
New employee entity with a plain-text password in
contrasena.void
FacadeCarrito
Package:mx.desarollo.facadeDelegate:
DelegateCarrito
Stock availability checks for the shopping-cart flow. All queries are read-only and consult StockReservadoDAO to account for reservations already in place for a given date or date range.
verificarStock(Articulo articulo, int cantidadSolicitada)
articulo.getUnidades()) without considering any date-based reservations. Useful for same-day or undated requests.
Article to check.
Number of units needed.
true if unidades >= cantidadSolicitada (or if unidades is null, assumed unlimited).
verificarStock(Articulo articulo, int cantidadSolicitada, LocalDate fecha)
fecha from total units before comparing with cantidadSolicitada.
Article to check.
Units requested.
Specific date for which to check availability.
true if (unidades - reservado) >= cantidadSolicitada.
obtenerDisponibleEnFecha(Articulo articulo, LocalDate fecha)
Article to query.
Date to check.
0 if the article is null or unidades is null.
verificarStockEnRango(Articulo, int, LocalDate, LocalDate)
[fechaInicio, fechaFin] via StockReservadoDAO.obtenerMaximoReservadoEnRango and compares the resulting available quantity against cantidadSolicitada.
Article to check.
Units requested for the entire period.
Start of the rental range (inclusive).
End of the rental range (inclusive).
true if the article can satisfy the request across every day in the range.
obtenerDisponibleEnRango(Articulo articulo, LocalDate fechaInicio, LocalDate fechaFin)
Article to query.
Range start (inclusive).
Range end (inclusive).
FacadeCombinacionMesa
Package:mx.desarollo.facadeDelegate:
DelegateCombinacionMesa (instantiated inline)
Manages table-textile combination records used in the visual catalogue. Enforces business rules about category and shape compatibility between the mesa, mantel, camino, and cubre articles before any persistence call.
obtenerPorMesaYTextiles(Integer idMesa, Integer idMantel, Integer idCamino, Integer idCubre)
ID of the table article.
ID of the tablecloth article.
ID of the table runner article; may be
null.ID of the tablecloth cover article; may be
null.Optional<CombinacionMesa> — empty if no matching combination exists.
obtenerTodas()
List<CombinacionMesa>
crearOActualizar(CombinacionMesa c)
mesa,mantel, andimagenmust all be non-null.mesa.categoriamust beCategoria.MESA.mantel.categoriamust beCategoria.TEXTILandmantel.textilTipomust beTextilTipo.MANTEL. The mantel’sformamust match the mesa’sforma.- If
caminois provided:camino.textilTipomust beTextilTipo.CAMINOand itsformamust match the mesa or beForma.UNIVERSAL. - If
cubreis provided:cubre.textilTipomust beTextilTipo.CUBREand itsformamust match the mesa or beForma.UNIVERSAL. - No combination with the identical four article IDs may already exist (unless
c.getId()matches the existing record — i.e. it is an update of the same combination).
The combination to save or update. For a new record,
id must be null.voidThrows:
IllegalArgumentException if any mandatory field is missing or a category/shape rule is violated. IllegalStateException if a duplicate combination already exists.
eliminar(Integer id)
Primary key of the combination to delete.
void
FacadeTarjetaAlmacen
Package:mx.desarollo.facadeDelegate:
DelegateTarjetaAlmacen
Inventory card (tarjeta de almacén) operations. Provides movement queries, initial inventory lookups, daily totals, and manual movement registration. Coordinates between MovimientoAlmacenDAO and StockDiarioDAO.
consultarMovimientosPorFecha(Integer idArticulo, LocalDate fecha)
fechaHoraRegistro ASC.
Primary key of the article.
Date to query.
List<MovimientoAlmacen>
consultarMovimientosPorRango(Integer idArticulo, LocalDate fechaInicio, LocalDate fechaFin)
fecha ASC, fechaHoraRegistro ASC.
Primary key of the article.
Start of the range (inclusive).
End of the range (inclusive).
List<MovimientoAlmacen>
obtenerInventarioInicial(Integer idArticulo, LocalDate fecha)
StockDiarioDAO.obtenerInventarioInicial, which falls back to the most recent prior StockDiario record or the article’s current unidades if no history exists.
Primary key of the article.
The date for which opening inventory is requested.
int.
calcularTotalesDiarios(Integer idArticulo, LocalDate fecha)
[entradas, salidas] — the sum of all ENTRADA-type movements and all SALIDA-type movements for the article on the given date.
Primary key of the article.
Date to aggregate.
int[] where index 0 = total entries (inbound), index 1 = total exits (outbound).
registrarMovimiento(MovimientoAlmacen movimiento)
DelegateRenta, not by this method.
The movement to persist. Must have
articulo, fecha, tipoMovimiento, cantidad, and concepto set before calling this method.void