# Catálogo + Micro ERP

Aplicación unificada en PHP y SQLite para catálogo público, carrito con cierre por WhatsApp y gestión interna de consignación. El proyecto final es esta carpeta `microerp`; no requiere MariaDB, MySQL, Laragon, Node, Composer ni frameworks.

## Funciones incluidas

- Catálogo público responsive con búsqueda, categorías, destacados y estado vacío.
- Detalle individual por slug, SEO, Open Graph, Schema.org, sitemap y robots.
- Carrito persistente en `localStorage`, cantidades limitadas por stock y cierre por WhatsApp.
- Validación en servidor del estado, precio y stock antes de registrar el pedido.
- Eventos de pedido sin nombre, teléfono ni datos personales del comprador.
- Login, CSRF, sesiones seguras y límite básico de intentos.
- CRUD de categorías, productos, proveedores y clientes.
- Fotos JPG, PNG y WebP con MIME real, nombre aleatorio y bloqueo de ejecución.
- Stock único por lotes, ventas FIFO, retiros internos, devoluciones, pagos, liquidaciones, reportes y auditoría.
- Configuración del comercio, WhatsApp, SEO y Analytics/Ads opcionales.

## Requisitos

- PHP 8.2 o superior.
- Extensiones `pdo_sqlite`, `sqlite3`, `mbstring`, `fileinfo` y `json`.
- Escritura para el usuario web en `database`, `uploads/productos` y `storage`.
- `sqlite3` CLI sólo para los scripts de backup y restauración en Ubuntu.

## Inicio rápido en Windows, sin Laragon

1. Verificá las extensiones:

   ```powershell
   php -m
   ```

2. Copiá la configuración:

   ```powershell
   Copy-Item config\config.example.php config\config.php
   ```

3. Para desarrollo, cambiá en `config/config.php`:

   ```php
   'environment' => 'development',
   'debug' => true,
   ```

4. Desde esta carpeta iniciá PHP:

   ```powershell
   php -S 127.0.0.1:8080 router.php
   ```

5. Abrí `http://127.0.0.1:8080/install.php`.

También funciona con un Apache existente, incluido XAMPP, usando un `DocumentRoot` o `Alias` normal y `mod_rewrite`. No se usan rutas, dominios ni servicios de Laragon. Más detalles en [README-WINDOWS.md](README-WINDOWS.md).

## Configuración

El único archivo de configuración es `config/config.php`; `config/config.example.php` es la plantilla. Permite definir:

- `environment` y `debug`;
- `timezone`;
- `base_path` para raíz o subcarpeta;
- `public_url`;
- ruta de la base SQLite;
- uploads y límite de imagen;
- logs, sesiones y cookies seguras.

En el panel **Configuración** se administran nombre del comercio, moneda, zona horaria, WhatsApp, textos públicos, SEO y los identificadores opcionales de Google.

Ejemplos de `base_path`:

```php
'base_path' => '',          // https://ejemplo.com/
'base_path' => '/catalogo', // https://ejemplo.com/catalogo/
```

## Modelo de datos único

El catálogo y el ERP usan el mismo archivo `database/microerp.sqlite` y las mismas tablas:

- `productos`: presentación pública, precio y metadatos internos.
- `categorias`: una sola clasificación para administración y catálogo.
- `configuracion`: preferencias internas y públicas.
- `usuarios`: autenticación administrativa.
- `lotes`: fuente única de stock disponible.
- `retiros_stock`: consumos personales, muestras y mermas separados de las ventas.
- `eventos_pedido`: cierres del carrito sin información personal.

El stock público se calcula desde `lotes.cantidad_disponible`. No existe un segundo campo editable que pueda quedar desactualizado.

## Migración de una instalación anterior

Al iniciar, `app/migrations.php` agrega de forma idempotente slugs, descripción corta, precio anterior, destacado, orden de catálogo, `eventos_pedido` y retiros internos. No borra ni reescribe ventas, lotes o productos.

Antes de actualizar:

```bash
./scripts/backup.sh
```

`database/migration.sql` documenta la alternativa manual de una sola ejecución. La migración automática es la opción recomendada.

## Producción en Ubuntu

La guía completa está en [README-UBUNTU.md](README-UBUNTU.md). Se incluyen:

- `deploy/apache-microerp.conf`;
- `deploy/nginx-microerp.conf`;
- `.htaccess`;
- bloqueo de ejecución en `uploads/productos/.htaccess`;
- `scripts/backup.sh` y `scripts/restore.sh`.

Activá HTTPS y mantené `environment=production` y `debug=false`.

## Pruebas

Sintaxis de todos los PHP:

```powershell
Get-ChildItem -Recurse -Filter *.php | ForEach-Object { php -l $_.FullName }
```

Pruebas con bases SQLite temporales:

```bash
php tests/migration.php
php tests/integration.php
php tests/catalog.php
```

`tests/integration.php` cubre ventas, FIFO, devoluciones, retiros internos, correcciones históricas, pagos y liquidaciones. `tests/catalog.php` verifica catálogo vacío, esquema público, stock por lotes, precio único, slugs y eventos sin datos personales.

## Estructura

```text
admin/                 enrutador del panel
api/                   catálogo y validación de pedidos
app/                   bootstrap, utilidades, migraciones y servicios
assets/                una hoja CSS visual y JavaScript vanilla
config/                única configuración portable
database/              esquema, migración y SQLite generado
deploy/                ejemplos Apache y Nginx
docs/                  auditoría, arquitectura y checklist
modules/               módulos administrativos
partials/              layouts público y administrativo
scripts/               backup, restauración y correcciones auditadas
storage/               logs, sesiones y backups
tests/                 pruebas temporales
uploads/productos/     imágenes validadas
index.php              catálogo público
producto.php           detalle público
carrito.php            revisión del carrito
router.php             rutas amigables con PHP integrado
sitemap.php            sitemap dinámico
robots.php             robots dinámico
```

## Límites deliberados

- WhatsApp inicia una conversación; no confirma una venta ni descuenta stock.
- No hay pagos en línea, facturación fiscal ni cuentas de compradores.
- Analytics y Ads no cargan scripts si sus identificadores están vacíos.
- Los movimientos contables no se eliminan físicamente; se anulan para preservar la auditoría.
