# 🚩 Ejercicio 2 · El pasante fantasma

**Clase 2 — POO, Composer y tu primer Laravel**
· Dificultad: 🟡 intermedio · Tiempo estimado: 45–60 min

---

## La situación

El Liquidador ya no procesa un recibo suelto: ahora tiene un **registro de personal**
con distintos tipos de vínculo. Cada tipo cobra de forma diferente:

- **Planta permanente** → aporta 17% (jubilación + ley 19.032 + obra social)
- **Contratado** → aporta 11% (solo jubilación)
- **Pasante** → *nadie sabe, porque la clase no existe*

El programa no arranca:

```
✘ No puedo armar el registro.
  PHP no encuentra la clase App\Personal\Pasante.
```

## Tu misión

**Crear la clase que falta.** No hay ningún archivo con un `TODO` esperándote: esta
vez tenés que crear el archivo vos, y ahí está la primera parte del desafío.

Porque no alcanza con escribir la clase correcta: hay que ponerla **en el lugar
exacto**. PHP no tiene un registro central de clases — el autoload traduce el
namespace a una ruta de archivo y busca ahí. Si te equivocás de carpeta por una
letra, la clase "no existe".

> 🔍 **Pista cero:** abrí `src/composer.json` y `src/autoload.php`. Entre los dos
> está escrita la regla exacta. Y de guía, mirá dónde vive `App\Personal\Contratado`.

## El pedido de RRHH

> *"Los pasantes cobran una **beca**, no un sueldo, así que **no se les hace ningún
> descuento**. Pero la beca tiene un **tope de $800.000**: si el básico asignado es
> mayor, se le liquida el tope."*

En el registro hay dos pasantes, uno por debajo del tope y otro por encima. Si te
olvidás del tope, el primero te va a dar bien y el segundo mal — y el total no va
a cerrar.

## Cómo correrlo

Desde esta carpeta:

```bash
docker compose run --rm ejercicio
```

Corrélo cada vez que cambies algo. Te va a decir en qué paso estás:

```
  ✔  Paso 1 · La clase App\Personal\Pasante existe y el autoload la encuentra
  ✘  Paso 2 · Extiende Empleado y cumple el contrato Liquidable
```

Cuando los cinco pasos estén en verde, aparece tu bandera:

```
ipap{c02-xxxxxxxxxx}
```

Igual que la vez pasada: **no está escrita en ningún archivo**. Se calcula a partir
de lo que devuelve *tu* clase — incluido su nombre completo con namespace y de quién
hereda. Podés leer el verificador entero y no te va a servir para inventarla.

> **Sin Docker:** `cd src && php registro.php`

## Los archivos

| Archivo | Qué es |
|---|---|
| `src/composer.json` | La configuración real de PSR-4. **Leelo.** |
| `src/autoload.php` | El autoload escrito a mano y comentado: lo que Composer hace por vos, en 10 líneas |
| `src/app/Contratos/Liquidable.php` | El contrato que toda clase liquidable debe cumplir |
| `src/app/Personal/Empleado.php` | La clase abstracta base |
| `src/app/Personal/PlantaPermanente.php` | Ejemplo completo ← **tu modelo a imitar** |
| `src/app/Personal/Contratado.php` | Segundo ejemplo completo |
| `src/app/Personal/Pasante.php` | ❌ **No existe. Lo creás vos.** |
| `src/registro.php` | El programa principal (no se toca) |

## Lo que vas a practicar

| Paso | Concepto de la clase |
|------|----------------------|
| 1 | **Namespaces y autoload PSR-4**: el namespace *es* la ruta del archivo |
| 2 | **Herencia** (`extends`) y **contratos** (`implements` vía la clase padre) |
| 3 | Implementar los métodos que el contrato exige |
| 4 | **Encapsulamiento**: leer un dato `private` del padre a través de su método |
| 5 | **Polimorfismo**: el registro trata a los tres tipos igual y cada uno responde distinto |

## Si te trabás

1. **No carga la clase.** El mensaje de error te dice qué namespace busca PHP.
   Traducí ese namespace a una ruta usando la regla de `autoload.php`: cada `\` es
   una carpeta. Compará con dónde está `Contratado.php`.
2. **"no extiende a Empleado".** Mirá la primera línea de `PlantaPermanente` y copiá
   esa estructura. No hace falta escribir `implements Liquidable`: ya viene por
   herencia, porque `Empleado` lo implementa.
3. **Error raro que dice `null returned`.** Estás escribiendo `$this->sueldoBasico`
   (propiedad) en lugar de `$this->sueldoBasico()` (método). Esa propiedad es
   `private` en `Empleado`: desde una subclase no se ve. Es a propósito.
4. **No escribas un `__construct()`.** Heredá el de `Empleado` tal como hacen las
   otras dos clases.
5. **El tope.** Hay una función de PHP que devuelve el menor de dos valores. Una
   línea alcanza.

## Lo interesante de este ejercicio

Cuando termines, fijate en algo: **no tocaste `registro.php` ni una vez.** El programa
principal no sabe que existen los pasantes; recorre la lista, le pide a cada objeto
su `tipo()` y su `calcularNeto()`, y cada clase contesta a su manera.

Eso es polimorfismo, y es la razón por la que el contrato `Liquidable` existe.
Mañana aparece el "personal transitorio" con otra regla más: se agrega una clase y
listo. Nada de lo que ya funcionaba se toca.

Es exactamente la idea que en la Clase 7 va a volver como **inyección de dependencias**,
y la que sostiene todo Laravel por dentro.
