# Changelog / handoff — Edit/Delete + Redesign 2026-07-21

Documento de referencia para agentes y desarrolladores.  
Resume lo implementado el **2026-07-21**: edición/eliminación de ventas y pagos, recibo de venta, y rediseño visual (tema LoteManager).

---

## 1. Commits

| Hash | Mensaje | Alcance |
|------|---------|---------|
| `bcc10b3a` | `EDIT AND DELETE` | 14 archivos, +1212 / −81 |
| `db4ccd56` | `Redesign` | 62 archivos, +506 / −137 |
| **Total día** | | **69 archivos, +1709 / −209** |

Rama: `main`.

### Orden de los commits

1. **EDIT AND DELETE** — funcionalidad de negocio (CRUD update/delete, recibo venta, permisos UI).
2. **Redesign** — capa visual (CSS theme, shell light, copy LoteManager, limpieza sidenav).

---

## 2. Contexto de la sesión (cronología)

1. Implementar **editar y eliminar ventas** (lista + detalle).
2. Implementar **editar y eliminar pagos** (lista).
3. Validaciones de saldo al editar pagos (`SaleBalanceService`).
4. Al eliminar venta: soft-delete en cascada de sus pagos.
5. Nuevo **recibo / estado de cuenta de venta** imprimible.
6. Rediseño visual inspirado en Keenthemes Summit (light-first).
7. Branding `package.json` → `lotemanager` / Sistematlan.
8. Documentación de handoff (este paquete).

---

## 3. Funcionalidad de negocio

### 3.1 Editar venta

| | |
|--|--|
| **UI** | Lista `/ventas` (icono lápiz) · Detalle `/venta/{id}` (botón **Modificar**) |
| **Modal** | `app/Views/modals/editSale.php` (`#editSale-modal`) |
| **Endpoint** | `POST /sale/update/{id}` → `Sale::update` |
| **Campos** | `order_date`, `client`, `block`, `lot`, `amount`, `front_payment`, `sale_type`, `payment_method`, `order_status` |
| **Notas** | Al cambiar `order_date` se recalcula `payment_day`. `front_payment` **solo actualiza el campo de la venta**, no reescribe pagos históricos. Tras guardar se llama `SaleBalanceService::recalculate` (pending + status desde pagos reales). No se aceptan `created_by` ni `pending` desde el cliente. |

### 3.2 Eliminar venta

| | |
|--|--|
| **UI** | Lista `/ventas` (icono basura) + SweetAlert de confirmación |
| **Endpoint** | `DELETE /sale/{id}` (resource) → `Sale::delete` |
| **Comportamiento** | Transacción: soft-delete de **todos los pagos** de la venta + soft-delete de la venta. Marca `deleted_by` cuando hay usuario de sesión. |

### 3.3 Editar pago

| | |
|--|--|
| **UI** | Lista `/pagos` (icono lápiz) |
| **Modal** | `app/Views/modals/editPayment.php` (`#editPayment-modal`) |
| **Endpoint** | `POST /payment/update/{id}` → `Payment::update` |
| **Campos editables** | `payment_date`, `amount`, `payment_method` |
| **No editable** | Venta asociada (`sale`), cliente, `created_by` |
| **Tope de monto** | `max = currentPending(sale) + monto_actual_del_pago` |
| **Post-save** | `SaleBalanceService::recalculate($saleId)` |

### 3.4 Eliminar pago

| | |
|--|--|
| **UI** | Lista `/pagos` + confirmación |
| **Endpoint** | `DELETE /payment/{id}` → `Payment::delete` |
| **Post-delete** | Recalcula pending de la venta asociada |

### 3.5 Recibo / estado de cuenta de venta

| | |
|--|--|
| **Ruta** | `GET /venta/{id}/recibo` → `Home::saleReceipt` |
| **Vista** | `app/Views/components/saleReceipt.php` |
| **Contenido** | Datos de venta + cliente, total pagado, pendiente, listado de pagos |
| **Print** | CSS `@media print` oculta shell (sidenav, topbar, botones) |
| **Entrada** | Botón **Imprimir** en detalle de venta |

Recibo de pago individual sigue en `GET /pago/{id}/recibo` (`receipt.php`).

---

## 4. Rutas nuevas / relevantes

```php
// Páginas
$routes->get('/venta/(:num)/recibo', 'Home::saleReceipt/$1', $filter);

// Updates vía POST (body legible en $_POST; PUT no siempre rellena getPost)
$routes->post('sale/update/(:num)', 'Sale::update/$1', $filter);
$routes->post('payment/update/(:num)', 'Payment::update/$1', $filter);

// REST (ya existían; delete/update vía resource)
$routes->resource('sale', $filter);
$routes->resource('payment', $filter);
```

**Por qué POST para update:** en algunos stacks, `PUT` no popula `$_POST` / `getPost()` de forma fiable con `application/x-www-form-urlencoded`. Los formularios de edición usan `POST` + CSRF.

---

## 5. Auth / permisos (estado actual 2026-07-21)

### Permisos declarados (`AuthGroups`)

Nuevo permiso de matriz:

- `payments.edit` → **Editar pagos**
- Grupo `user` ahora incluye: `sales.edit`, `payments.edit` (además de create/reportes)

`sales.delete` / `payments.delete` siguen en matriz para admin/superadmin/developer (`sales.*`, `payments.*`), **pero** ver implementación real abajo.

### Implementación real en controllers (importante)

En `Sale::update`, `Sale::delete`, `Payment::update`, `Payment::delete` y flags de UI (`canEditSales`, `canEditPayments`):

```php
$user->inGroup('user')
```

**Implicaciones:**

1. Usuarios del grupo **`user`** ven botones de editar **y** eliminar ventas/pagos, y el backend lo permite.
2. Un usuario **solo** en `admin` / `superadmin` (sin grupo `user`) **podría no** pasar estos checks ni ver los botones — a diferencia de `Client::delete` / `Expense::delete`, que usan `can('*.delete') || inGroup('superadmin','admin')`.
3. Esto **difiere** del hardening 2026-07-10 documentado en `OPERATIONS.md` (“operador no borra”). Hoy el operador **sí puede** borrar ventas y pagos si está en grupo `user`.

**Mejora pendiente (para agentes futuros):** unificar checks a:

```php
$user->can('sales.edit') || $user->inGroup('superadmin', 'admin')
// delete → sales.delete / payments.delete
```

y alinear flags de vista con los mismos permisos.

---

## 6. Archivos tocados (mapa)

### Backend

| Archivo | Cambio |
|---------|--------|
| `app/Config/Routes.php` | Rutas recibo venta + POST update sale/payment |
| `app/Config/AuthGroups.php` | `payments.edit` + matrix `user` |
| `app/Controllers/Sale.php` | `update`, `delete` (cascada pagos), parse input |
| `app/Controllers/Payment.php` | `update` (tope saldo), `delete` + recalc |
| `app/Controllers/Home.php` | `saleReceipt`, flags `canEditSales` / `canEditPayments` |
| `app/Models/PaymentModel.php` | Ajuste menor (timestamps/allowed fields según diff) |

### Frontend negocio

| Archivo | Cambio |
|---------|--------|
| `app/Views/modals/editSale.php` | **Nuevo** modal editar venta |
| `app/Views/modals/editPayment.php` | **Nuevo** modal editar pago |
| `app/Views/components/sales.php` | Botones edit/delete + JS submit/confirm |
| `app/Views/components/payments.php` | Botones edit/delete + JS |
| `app/Views/components/saleDetail.php` | Imprimir + Modificar + modal |
| `app/Views/components/saleReceipt.php` | **Nuevo** estado de cuenta imprimible |
| `public/js/app-common.js` | Helpers AJAX / CSRF / utilidades usadas por forms |

### Redesign

| Archivo | Cambio |
|---------|--------|
| `public/css/lote-theme.css` | **Nuevo** tema (tokens, cards, botones, shell) |
| `app/Views/partials/head-css.php` | Include del theme CSS |
| `public/js/config.js` | Defaults light shell; key `__THEME_CONFIG_LOTE_V2__` |
| `app/Views/partials/sidenav.php` | Quita logo duplicado + bloque user-profile del sidenav |
| `app/Views/partials/page-title.php` | Breadcrumbs más limpios + `esc()` |
| `app/Views/partials/topbar.php` | Placeholder búsqueda LoteManager |
| `app/Views/components/start.php` | Acciones rápidas restyled |
| Muchas vistas auth/error | Title meta / branding menor |
| `package.json` | `name: lotemanager`, author Sistematlan |

---

## 7. Reglas de negocio relevantes (edit/delete)

### Al editar venta

```
front_payment ≤ amount
payment_day se deriva de order_date (misma lógica 8–21 → 15, else 1)
pending / order_status ← SaleBalanceService::recalculate (pagos reales mandan)
```

Cambiar `front_payment` **no** crea ni modifica el payment de enganche histórico.  
Si se necesita corregir un enganche mal capturado como pago, hay que **editar el pago** correspondiente.

### Al editar pago

```
amount > 0
amount ≤ pending_actual + amount_previo_del_pago
sale no se reasigna
pending de la venta se recalcula al final
```

### Al eliminar venta

Soft-delete de pagos hijos + venta. No hay hard delete.  
Los reportes que filtran `deleted_at IS NULL` dejan de verlos.

### Al eliminar pago

Soft-delete + recalc de la venta (pending sube, status puede volver a `Processing`).

---

## 8. UI / tema visual (Redesign)

### Objetivos

- Light-first, compatible dark (`html[data-bs-theme="dark"]`).
- Primary CTA: `#236dc9`.
- Tipografía: Inter + system stack.
- Cards con bordes suaves, sombras ligeras, radios ~0.85rem.
- Inspiración: Keenthemes Summit (no dependencia npm de Summit).

### Config de layout por defecto

```js
// public/js/config.js
storageKey: "__THEME_CONFIG_LOTE_V2__"  // invalida sesiones con config vieja
sidenav-color: "light"
topbar-color: "light"
sidenav-size: "default"
```

### Assets

- CSS propio: `public/css/lote-theme.css` (no pasa por Gulp del tema Paces).
- Cargado desde `partials/head-css.php` después del CSS del tema base.
- Hard refresh recomendado post-deploy (CSS + config.js + app-common.js).

### Qué **no** se purgó

Las vistas demo del tema Paces (`auth-*`, `error-*`, `charts-*`, etc.) siguen en el repo; solo se ajustaron titles/meta menores. El producto real sigue en `Views/components/**` + layout `app.php`.

---

## 9. Flujos de usuario (post-cambio)

### Corregir una venta

1. Ir a `/ventas` o abrir `/venta/{id}`.
2. Editar → modal → Guardar.
3. Pending se recalcula automáticamente.

### Corregir un pago

1. Ir a `/pagos`.
2. Editar → ajustar monto/fecha/método (respeta tope de saldo).
3. Pending de la venta se actualiza.

### Imprimir estado de cuenta

1. `/venta/{id}` → **Imprimir** → `/venta/{id}/recibo` → `window.print()`.

### Borrar por error de captura

1. Confirmación SweetAlert.
2. Soft-delete; en ventas se llevan los pagos.

---

## 10. Deploy / checklist post-2026-07-21

No hay migraciones nuevas en este release.

```bash
git pull
# sin composer obligatorio si no hubo cambios PHP deps
# sin npm run build obligatorio (theme CSS es estático en public/css/)
```

Checklist QA:

- [ ] Hard refresh (Ctrl/Cmd+Shift+R) — theme + config v2
- [ ] `/ventas`: editar venta y ver cambios en detalle
- [ ] `/ventas`: eliminar venta con pagos → pagos también soft-deleted
- [ ] `/pagos`: editar monto > max disponible → error de validación
- [ ] `/pagos`: editar monto válido → pending de venta correcto
- [ ] `/pagos`: eliminar pago → pending de venta sube
- [ ] `/venta/{id}/recibo` imprime limpio
- [ ] Shell light: sidenav claro, primary azul, cards con sombra suave
- [ ] CSRF en POST update (meta + header AJAX)

---

## 11. Bugs / riesgos conocidos

| Riesgo | Detalle |
|--------|---------|
| Checks `inGroup('user')` | Admin-only puede quedar fuera de edit/delete; operador puede borrar |
| Editar `front_payment` | No sincroniza payment de enganche histórico |
| Sin tests nuevos | No hay PHPUnit para `Sale::update` / `Payment::update` |
| Cascada delete venta | Soft-delete de muchos pagos en loop; OK a escala actual |
| Theme cache navegador | Config key v2 mitiga; usuarios pueden necesitar hard refresh |

---

## 12. Mensajes a usuarios (copy)

Se prepararon dos textos de comunicación:

1. **Versión larga** (email / anuncio formal) — sesión de chat 2026-07-21.
2. **Versión WhatsApp** — corta, con emojis (misma sesión).

No viven en el repo salvo este puntero; se pueden re-derivar de las secciones 3 y 8.

---

## 13. Archivos “fuente de verdad” post-release

```
docs/README.md
docs/PROJECT_CONTEXT.md                    ← actualizado
docs/OPERATIONS.md                         ← actualizado
docs/CHANGELOG_HARDENING_2026-07-10.md     ← histórico saldos/CSRF/reportes
docs/CHANGELOG_EDIT_DELETE_REDESIGN_2026-07-21.md  ← este archivo

app/Controllers/Sale.php
app/Controllers/Payment.php
app/Libraries/SaleBalanceService.php
app/Views/modals/editSale.php
app/Views/modals/editPayment.php
app/Views/components/saleReceipt.php
public/css/lote-theme.css
public/js/config.js
```

---

## 14. Cómo retomar (agentes)

1. Leer `docs/README.md` → este changelog si el trabajo toca edit/delete o UI shell.
2. Pending **solo** vía `SaleBalanceService`.
3. Preferir permisos `can()` sobre `inGroup('user')` al endurecer auth.
4. No confiar en PUT form-urlencoded; usar `POST …/update/{id}` o JSON + raw input.
5. No tocar demos del tema salvo branding global.
6. Theme tokens viven en `lote-theme.css` + `config.js`.

---

*Fin del handoff 2026-07-21.*
