# Control Ganadero — puesta en marcha

Para **producción**, ver [DEPLOY_PRODUCCION.md](DEPLOY_PRODUCCION.md).

## Requisitos

- PHP 8.1+, Composer
- Node.js 18+ (Vite)
- MySQL/MariaDB o SQLite

## Instalación

```bash
cp .env.example .env   # si no existe
composer install
npm install
php artisan key:generate
```

Configure `DB_*` en `.env` y ejecute:

```bash
php artisan migrate
php artisan db:seed
php artisan storage:link
```

### Migraciones ganadería (orden)

Las tablas del rancho se crean en migraciones bajo `database/migrations/2026_05_23_*` y `2026_05_24_*`:

| Migración | Contenido |
|-----------|-----------|
| `100000_create_ranch_management_tables` | `cattle`, pesajes, materiales, gastos, engorda |
| `100001_seed_ranch_permissions` | Permisos `ranch.*` y rol Caporal |
| `110000_add_pasture_location_to_cattle` | Texto corral/pasto |
| `120000` / `120001` | Salud animal + permisos salud |
| `140000_add_profit_targets_to_fattening_lots` | Metas utilidad y precio |
| `150000_create_cattle_calving_events` | Partos |
| `160000_create_cattle_location_movements` | Movimientos |
| `170000_create_pastures_table` | Catálogo potreros + `pasture_id` |
| `180000_add_target_min_gdp_to_fattening_lots` | Meta GDP por lote |
| `2026_05_24_100000` | Meta GDP por animal |
| `2026_05_24_120000` | Foto del animal (`photo_path`) |

Si ya tenía BD antes de estas columnas, basta `php artisan migrate` (no hace falta `migrate:fresh`).

### Seeders ganadería

`php artisan db:seed` ejecuta:

1. `RanchMaterialTypeSeeder` — tipos de material (alimento, salud, etc.)
2. `RanchPastureSeeder` — potreros base (Norte, Sur, Maternidad)
3. `RanchCaporalUserSeeder` — usuario caporal de prueba
4. `RanchDemoDataSeeder` — solo si `RANCH_SEED_DEMO_DATA=true` (default en `local`)

### Datos de demostración

En entorno `local` se cargan automáticamente al hacer `db:seed`. También puede ejecutar:

```bash
php artisan ranch:seed-demo
```

Crea aretes `DEMO-*`: potrero demo, parto registrado, metas GDP, becerros con pesajes, gastos de lote en **varias fechas** (gráfica de inversión), lote de engorda abierto, venta y muerte. No duplica si ya existe `DEMO-001`.

Desactivar en producción: `RANCH_SEED_DEMO_DATA=false`.

## Usuario de prueba

Tras las migraciones iniciales:

| Campo | Valor |
|-------|--------|
| Rol | Email | Contraseña |
|-----|-------|------------|
| Administrador | `admin@gmail.com` | `password` |
| Caporal (campo) | `caporal@rancho.local` | `password` |

El Caporal puede operar ganado, pesajes y engorda; no tiene acceso al balance financiero por defecto.

El rol **Administrador** recibe todos los permisos `ranch.*` con la migración `2026_05_23_100001_seed_ranch_permissions`.

## Frontend

```bash
npm run dev
# o producción:
npm run build
```

Rutas principales: `/ganaderia/dashboard`, `/ganaderia/animales`, `/ganaderia/inventario-ubicacion`, `/ganaderia/pesajes`, `/ganaderia/bajas`, `/ganaderia/engorda`, `/ganaderia/lotes-cerrados`, `/ganaderia/gastos`, `/ganaderia/reportes`.

## Logo y datos del rancho

1. Inicie sesión como **Administrador**.
2. Menú lateral → **Datos del rancho** (`/admin/configuracion-empresa`).
3. Suba logo y favicon, complete nombre, RFC, dirección y guarde.
4. Si no hay logo cargado, se usa `public/logo-rancho.svg`.

## Lavandería legacy (opcional)

Las rutas TIBU/lavandería están en `routes/laundry_legacy.php` y **desactivadas** por defecto.

Para reactivarlas (migración gradual):

```env
RANCH_LEGACY_LAUNDRY_ROUTES=true
```

## Tests

```bash
php artisan test --testsuite=Ranch
# o archivo concreto:
php artisan test tests/Feature/RanchApiTest.php
```

## Permisos

| Permiso | Uso |
|---------|-----|
| `ranch.dashboard` | Panel resumen |
| `ranch.cattle.view` | Consultar inventario |
| `ranch.cattle.manage` | Altas y bajas |
| `ranch.weight.record` | Pesajes |
| `ranch.fattening.manage` | Lotes de engorda |
| `ranch.expenses.manage` | Gastos por materiales |
| `ranch.reports.view` | Balance por periodo |

Rol **Caporal**: operación diaria sin reportes financieros (sin `ranch.reports.view`). Ajuste permisos en **Roles** (`/roles/lista`).

## Exportar balance

En **Balance** (`/ganaderia/reportes`), genere el periodo y use **Exportar CSV** o **Exportar PDF**.

## Inventario por ubicación

En **Inventario por ubicación** (`/ganaderia/inventario-ubicacion`) agrupa cabezas por corral/pasto o lote de engorda, con último peso y GDP. Exportación CSV disponible. El panel de inicio muestra un resumen por ubicación.

## Fotos de animales

En el **expediente** (`Inventario y expediente` → **Expediente**), usuarios con `ranch.cattle.manage` pueden **Subir foto** (JPG, PNG, WebP o GIF, máx. 3 MB). La miniatura aparece en el listado de inventario.

API: `POST /api/ranch/cattle/{id}/photo` (multipart `photo`), `DELETE /api/ranch/cattle/{id}/photo`.

Requiere enlace de almacenamiento público (una vez por servidor):

```bash
php artisan storage:link
```

## Expediente por animal

Desde **Inventario y expediente** → **Expediente** (o `/ganaderia/animales/:id`) abre la ficha de cada cabeza:

- **Dinero invertido:** alimento asignado en engorda + salud (vacunas, tratamientos con gasto). Muestra total invertido, ingreso por venta (si aplica), utilidad neta, costo/utilidad por kg ganado, desglose por categoría y **gráfica de inversión acumulada en el tiempo** (cada gasto de lote se prorratea por fecha según animales presentes ese día).
- **Gráfica de desarrollo:** curva de peso (kg) y GDP entre pesajes, con línea de meta GDP (requiere al menos dos pesajes).
- **Historial:** salud, movimientos, engorda, pesajes, crías (vacas) y baja/venta.

Los costos de alimento se prorratean del lote de engorda según días del animal en el lote.

**Exportar PDF:** botón **Exportar expediente PDF** (`GET /api/ranch/cattle/{id}/expediente/pdf`) — resumen imprimible con datos, inversión, pesajes, engorda, salud y movimientos.

## Catálogo de potreros

En **Potreros** (`/ganaderia/potreros`) administra corrales y pastos. Los animales se asignan por lista (el campo texto `pasture_location` se mantiene sincronizado para reportes). La migración importa nombres distintos ya usados en el inventario.

## Movimientos de ubicación

En **Movimientos** (`/ganaderia/movimientos`) registra traslados de corral/pasto y consulta el historial (incluye entradas/salidas de engorda automáticas). Desde la hoja de vida: **Mover / historial**.

## Registro de partos

En **Partos** (`/ganaderia/partos`) registra el nacimiento: alta del becerro con vínculo a la madre, herencia de raza/corral y peso al nacer (primer pesaje). Incluye **reporte por periodo** (totales, por mes, por vaca) y **exportación CSV** (`GET /api/ranch/reports/calvings`). Desde la hoja de vida de una vaca activa: **Registrar parto**.

## Proyección de cierre (engorda abierta)

En **Proyección engorda** (`/ganaderia/engorda-proyeccion`) estima utilidad si cierras hoy cada lote abierto. Usa el último pesaje de cada animal; si no hay, estima con GDP histórico o `RANCH_FATTENING_DEFAULT_DAILY_GAIN` (0.8 kg/día por defecto). El panel avisa si hay lotes bajo la meta de utilidad.

**GDP en engorda:** meta en cascada **animal → lote → valor por defecto** (`RANCH_FATTENING_DEFAULT_MIN_GDP` / `RANCH_MIN_GDP_ALERT`). Edita la meta del animal en su hoja de vida. La proyección de engorda y el centro de alertas usan la meta efectiva por cabeza.

## Alertas de peso (GDP)

- **Rendimiento GDP** (`/ganaderia/rendimiento-peso`): lista animales con GDP bajo, sin pesaje reciente o sin segundo pesaje.
- El **panel** muestra cuántas alertas hay y enlaza al reporte.
- Umbrales en `.env`: `RANCH_MIN_GDP_ALERT=0.5`, `RANCH_DAYS_WITHOUT_WEIGH_ALERT=30`.

## Alertas por correo (GDP)

Configura destinatarios en `.env`:

```env
RANCH_ALERT_EMAILS=dueno@rancho.com,admin@gmail.com
MAIL_MAILER=smtp
# ... credenciales SMTP ...
```

**Envío manual** (solo si hay alertas):

```bash
php artisan ranch:notify-weight-alerts
```

**Desde la app:** en Rendimiento GDP → botón **Enviar alertas por correo**.

**Automático:** todos los días a las 07:00 (`ranch:notify-weight-alerts`) si `RANCH_SCHEDULE_WEIGHT_ALERTS=true`. Requiere cron del servidor:

```bash
php artisan schedule:run
```

Prueba sin alertas: `php artisan ranch:notify-weight-alerts --force`

## Alertas por correo (GDP en engorda abierta)

Mismo destinatario que alertas de peso (`RANCH_ALERT_EMAILS`).

**Envío manual** (solo si hay lotes abiertos con alerta GDP):

```bash
php artisan ranch:notify-open-lots-gdp-alerts
```

**Desde la app:** en **Proyección engorda** → **Enviar alertas GDP por correo**.

**Automático:** todos los días a las 08:00 si `RANCH_SCHEDULE_OPEN_LOTS_GDP_ALERTS=true` (por defecto activo).

Prueba sin alertas: `php artisan ranch:notify-open-lots-gdp-alerts --force`

## Resumen de partos por correo

Mismos destinatarios (`RANCH_ALERT_EMAILS`).

**Envío manual** (mes anterior completo por defecto):

```bash
php artisan ranch:notify-calving-report
```

Con periodo explícito:

```bash
php artisan ranch:notify-calving-report --from=2026-05-01 --to=2026-05-31
```

**Desde la app:** en **Partos** → reporte por periodo → **Enviar resumen por correo** (usa las fechas del filtro).

**Automático:** día **1 de cada mes a las 09:00**, resumen del **mes calendario anterior**, si `RANCH_SCHEDULE_CALVING_REPORT=true`.
