Skip to main content

Documentation 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.

Employees in SiCom — Eventos Campestre have a focused, task-oriented role: they see the pool of open and already-assigned rentals, claim deliveries or recolecciones, advance each rental through its logistics states, and optionally leave comments at key handoff points. Their access is intentionally narrow — they have no visibility into article management, quotation processing, client data, or analytics. This design keeps the employee interface simple and prevents accidental changes to business-critical data.

Authentication Flow

The login form at login.xhtml is shared between administrators and employees. When loginUI.login() receives credentials that resolve to an Empleado instance, the session stores the employee object and redirects directly to the employee task list:
// LoginBeanUI.java
Object result = loginHelper.login(correo, contrasena);

if (result instanceof mx.desarollo.entity.Administrador) {
    usuario = result;
    context.getExternalContext().redirect(
        context.getExternalContext().getRequestContextPath()
        + "/principalAdministrador.xhtml");
} else if (result instanceof mx.desarollo.entity.Empleado) {
    usuario = result;
    context.getExternalContext().redirect(
        context.getExternalContext().getRequestContextPath()
        + "/RentasEmpleado.xhtml");
}
LoginHelper delegates to ServiceFacadeLocator → FacadeLogin → DelegateLogin. Because the returned object is an Empleado, the administrator home page is never visited and the session usuario field holds only the employee entity.

Empleado Entity

The Empleado JPA entity maps to the empleado table:
// mx.desarollo.entity.Empleado
@Entity
@Table(name = "empleado")
public class Empleado {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "idempleado", nullable = false)
    private Integer id;

    @Size(max = 80) @NotNull
    @Column(name = "nombre", nullable = false, length = 80)
    private String nombre;

    @Size(max = 45) @NotNull
    @Column(name = "apellido_paterno", nullable = false, length = 45)
    private String apellidoPaterno;

    @Size(max = 45) @NotNull
    @Column(name = "apellido_materno", nullable = false, length = 45)
    private String apellidoMaterno;

    @Size(max = 45) @NotNull
    @Column(name = "correo", nullable = false, length = 45, unique = true)
    private String correo;

    @Size(max = 255) @NotNull
    @Column(name = "contrasena", nullable = false, length = 255)
    private String contrasena;

    @Transient
    public String getNombreCompleto() {
        return (nombre != null ? nombre : "") + " "
             + (apellidoPaterno != null ? apellidoPaterno : "") + " "
             + (apellidoMaterno != null ? apellidoMaterno : "");
    }
}
ColumnTypeConstraint
idempleadoINT AUTO_INCREMENTPrimary key
nombreVARCHAR(80)NOT NULL
apellido_paternoVARCHAR(45)NOT NULL
apellido_maternoVARCHAR(45)NOT NULL
correoVARCHAR(45)NOT NULL, UNIQUE
contrasenaVARCHAR(255)NOT NULL
The @Transient method getNombreCompleto() concatenates nombre, apellidoPaterno, and apellidoMaterno — it is not persisted to the database, but is used extensively in the UI to display the employee’s full name on rental cards and in the admin employee list.

Pages Accessible to Employees

Employees can only reach two views. Both register #{loginUI.preventBackAfterLogout} on preRenderView.
PagePurpose
RentasEmpleado.xhtmlTask list — all rentals in non-final states that are either unassigned or assigned to this employee
DetalleRentaEmpleado.xhtmlRental detail — full information for a single rental, state-advance controls, and comment entry

RentasEmpleado.xhtml — Task List

On preRenderView, empleadoRentaUI.cargarRentas() is called. The EmpleadoRentaBeanUI bean injects LoginBeanUI and extracts the authenticated employee:
// EmpleadoRentaBeanUI.java
@PostConstruct
public void init() {
    rentaHelper = new RentaHelper();
    if (loginBean != null && loginBean.getUsuario() instanceof Empleado) {
        this.empleadoLogueado = (Empleado) loginBean.getUsuario();
        cargarRentas();
    }
}

public void cargarRentas() {
    if (this.empleadoLogueado != null) {
        this.rentasPendientes =
            rentaHelper.obtenerRentasDisponiblesYAsignadas(
                this.empleadoLogueado.getId());
    }
}
obtenerRentasDisponiblesYAsignadas(idEmpleado) returns every rental that is either unassigned (idEmpleado IS NULL) or already assigned to this employee, and whose state is not a final state. The resulting list is rendered as a flex grid of cards. Each card shows:
  • A badge — orange DISPONIBLE for unassigned or Pendiente a recoleccion rentals; green ASIGNADA — [NOMBRE] for rentals already owned by this employee.
  • Client name and delivery address.
  • Delivery date (fechaInicio), recolección date (fecha), and time (hora).
  • Current status in italic.
Clicking any card navigates to DetalleRentaEmpleado.xhtml?idRenta={id}.

DetalleRentaEmpleado.xhtml — Rental Detail

EmpleadoRentaBeanUI.cargarRentaSeleccionada() loads the full Renta entity and computes the next logical state via rentaHelper.calcularSiguienteEstado(currentEstado).

Rental State Transitions

Employees trigger state advances from the detail view. The method verificarSiRequiereComentario() checks whether the target state requires a delivery or recolección comment before committing:
public void verificarSiRequiereComentario() {
    this.estadoPendienteDeGuardar = siguienteEstado;

    if ("Entregado".equals(siguienteEstado)
            || "Finalizada".equals(siguienteEstado)) {
        // Show comment dialog before advancing
        PrimeFaces.current().executeScript(
            "PF('dlgComentarioEstado').show();");
    } else {
        avanzarEstado(); // Advance directly without comment
    }
}
avanzarEstado() applies auto-assignment and name capture logic, then persists the change:
public boolean avanzarEstado() {
    // Auto-assign employee when starting delivery or recolección
    if ("En reparto".equals(siguienteEstado)
            || "En recoleccion".equals(siguienteEstado)) {
        rentaSeleccionada.setIdEmpleado(this.empleadoLogueado);
    }
    // Record who completed the delivery or recolección
    if ("Entregado".equals(siguienteEstado)) {
        rentaSeleccionada.setEntregado(this.empleadoLogueado.getNombre());
        rentaSeleccionada.setIdEmpleado(null); // Release assignment
    } else if ("Finalizada".equals(siguienteEstado)) {
        rentaSeleccionada.setRecogido(this.empleadoLogueado.getNombre());
        rentaSeleccionada.setIdEmpleado(null); // Release assignment
    }
    rentaSeleccionada.setEstado(siguienteEstado);
    rentaHelper.actualizarRenta(rentaSeleccionada);
    rentaHelper.cambiarEstado(rentaSeleccionada.getId(), siguienteEstado);
    cargarRentaSeleccionada();
    return true;
}
The typical transitions an employee performs are:
TriggerFrom stateTo stateComment required
Start delivery runAprobada / ConfirmadoEn repartoNo
Mark deliveredEn repartoEntregadoYes — “Detalles en la entrega”
Start recolecciónPendiente a recoleccionEn recoleccionNo
Mark finalisedEn recoleccionFinalizadaYes — “Detalles en la recolección”
When a comment is required, the dialog collects free-text, wraps it in a Comentario entity (type "Entrega" or "Recoleccion"), saves it, and then calls avanzarEstado().

Creating an Employee Account

Only an administrator can create employee accounts. The workflow is entirely within AdminEmpleados.xhtml, backed by empleadoUI (EmpleadoBeanUI):
  1. The administrator clicks AltaempleadoUI.prepararNuevoEmpleado() resets the form bean.
  2. The modal collects apellidoPaterno, apellidoMaterno, nombre, correo, and contrasena.
  3. On submit, empleadoUI.guardarEmpleado() validates all fields (including email format ^[^@\s]+@[^@\s]+\.[^@\s]+$) and calls facadeEmpleado.saveEmpleado(nuevoEmpleado).
  4. If a duplicate email is detected, the database throws a unique-constraint exception; the bean catches it and surfaces the message “El correo electrónico ya se encuentra registrado.”
Password resets are also available: the Restablecer Contraseña button opens a focused modal where the administrator enters a new password that empleadoUI.restablecerContrasena() applies to the selected employee via facadeEmpleado.updateEmpleado().
Employees have no access to any administrator pages. If an employee attempts to navigate directly to principalAdministrador.xhtml, Articulos.xhtml, AdminEmpleados.xhtml, Rentas.xhtml, Cotizaciones.xhtml, Dashboard.xhtml, or TarjetaAlmacen.xhtml, the preventBackAfterLogout() listener will detect that usuario is an Empleado (not an Administrador) with a valid correo, so notLoggedIn remains false — however, those pages do not render employee-specific navigation and the employee will see the admin layout without the correct data context. To strictly enforce role separation, consider adding a role check that redirects employees to RentasEmpleado.xhtml if they land on an admin-only page.

Build docs developers (and LLMs) love