Ir al contenido

Compras

Generada 2026-09-10. Fuente: exploración de código de controlgmg-v2 + navegación en vivo en QA (kimi webbridge)

  • verificación directa contra el schema real de PRD (dump gmg_prd3_09-10-2026.sql, solo estructura de tablas cargada en la BD local gmg_09_010_2026, sin datos), en el marco del ticket GMG-3123 (“Filtro guía de pago”). Comparar contra compras-cotizadas.md — Compras y Compras Cotizadas comparten la misma tabla (orders) y la misma clase base Order (QuotedOrder extends Order), distinguidos por un global scope is_quoted (0 = Compras, 1 = Cotizadas).
  • Modelo: App\Core\Purchases\Order (app/Core/Purchases/Order.php), tabla orders.
  • Fillable clave: user_id, team_id, company_id, to_check, additional_deduction, policy_number, policy_amount, is_accounted, policy_found, payment_type, checkbook_id, payment_method, deposit_account, beneficiary, bank_id, status, limit_payment_date, supplier_id.
  • Campo clave para este proyecto — limit_payment_date (columna date, nullable): agregada por database/migrations/2020_06_12_113439_add_limit_payment_date_to_orders_table.php (after('policy_number')). Existe desde 2020 — no es un campo nuevo, solo no se filtra correctamente (ver hallazgo abajo).
  • Status (enum en Order.php): new, approved, not-approved, pending-to-authorize, request-authorized, rejected-by-banks, rejected-by-authorizer, banks-authorized-documents, banks-authorized, rejected-by-finance, paid, request-paid-pending-invoice, request-paid-pending-subs.
  • getModule() → Module::compras → mapeado a Order::class en Module::moduleModelMap.
  • getActionUrlAttribute() → /compras?order_id=$id.

⚠️ Hallazgo crítico (bug real, motivo por el que GMG-3123 no es solo “diseñar una UI nueva”)

Sección titulada «⚠️ Hallazgo crítico (bug real, motivo por el que GMG-3123 no es solo “diseñar una UI nueva”)»
  • El filtro etiquetado “Fecha de pago” en la UI envía el request param limit_payment_date desde el frontend (resources/js/components/Purchases/Orders/MainPurchases.vue:76-79) — el nombre del param sí coincide con la columna real.
  • Pero el backend (OrderController@getOrders, app/Http/Controllers/Purchases/Orders/OrderController.php:246) usa ese param para filtrar orders.updated_at, NO orders.limit_payment_date. Es decir: el nombre del parámetro es correcto, pero la implementación filtra la columna equivocada.
  • El mismo patrón (mismo bug) está duplicado en otros dos lugares: getProductGroupReport (L310-322) y OrderRepository::getQueryToProductGroupDetailExport (L39-51).
  • Por separado (hallazgo aparte, no bloqueante para GMG-3123 pero vale la pena flaggear): la columna ordenable “Fecha Límite” de la tabla usa field="approvals.limit_payment_date" para el sort — pero esa columna no existe en approvals (confirmado contra el schema real de PRD: la tabla approvals solo tiene id, user_id, approvable_type, approvable_id, type, approval_requested_at, approved_at, not_approved_at, created_at, updated_at, deleted_at, not_approved_comment, expiration_date — es polimórfica, approvable_type/approvable_id, usada por QuotedOrder, ProductTender, etc., no solo por Order). Sort roto/no-op — no se confirmó el efecto exacto en runtime (¿error 500 o simplemente no ordena?), por verificar.
  • orders.limit_payment_date confirmado en el schema real de PRD: date DEFAULT NULL, sin default, columna número 9 de la tabla (después de policy_found, antes de payment_type) — coincide con lo documentado por migración. La tabla orders en PRD tiene AUTO_INCREMENT en ~224,428 (total histórico combinado Compras + Compras Cotizadas).
  • Implicación para la implementación de GMG-3123:
    1. El nuevo filtro de rango sobre la fecha límite de pago real necesita un request param distinto (limit_payment_date ya está tomado por el filtro de “Fecha de pago”/updated_at).
    2. Hay que agregar el nuevo filtro (whereBetween sobre orders.limit_payment_date) en los 3 lugares: OrderController@getOrders:246, getProductGroupReport:310-322, OrderRepository::getQueryToProductGroupDetailExport:39-51.
    3. En frontend, clonar el componente date-range ya usado para “Fecha de pago” (MainPurchases.vue:76-79), con su propio v-model.
    4. Opcional/aparte: corregir el sort roto de “Fecha Límite”.
  • routes/purchases/orders/orders.php, montada bajo /orders en el router (ver compras-cotizadas.md para el listado de rutas hermanas bajo /orders/quoted/*, /orders/product-groups/*, /orders/reports/*). No se listó línea por línea el contenido exacto de orders.php en esta pasada — por verificar.
  • Ruta /compras → resources/js/components/Purchases/Orders/MainPurchases.vue (resources/js/routes.js:177-179, guard can('view-purchase')).
  • Fila: PurchaseRow.vue.
  • Edición del campo real limit_payment_date: FormSections/GeneralPolicyForm.vue:66-69 (v-model="form.limit_payment_date") — visible en el panel de detalle expandido, sección “Generales AS-400”, campo “Fecha límite de pago” (confirmado en vivo, ver abajo).

Rutas Vue hermanas bajo /compras/* (otros módulos, no confundir con Compras)

Sección titulada «Rutas Vue hermanas bajo /compras/* (otros módulos, no confundir con Compras)»
Ruta Componente Permiso
/compras/grupos-productos Purchases/ProductGroups/MainProductGroup.vue view-product-group
/compras/reportes Purchases/Orders/Reports/OrdersReports.vue view-purchase
/compras/cotizadas Purchases/QuotedOrders/QuotedOrderPage.vue view-quoted-order (módulo separado, ver compras-cotizadas.md)
/compras/producto/licitaciones Products/Tenders/ProductTenderPage.vue view-product-tender (ver compras-cotizadas.md)

Filtros verificados en vivo (QA, 2026-09-10, qa.controlgmg.com/compras)

Sección titulada «Filtros verificados en vivo (QA, 2026-09-10, qa.controlgmg.com/compras)»
  • Búsqueda global (Buscar en cualquier campo...), Buscar por solicitante, Buscar por concepto.
  • Fecha de creación (rango: Fecha inicial - Fecha final) — funcional.
  • Fecha de pago (rango: Fecha inicial - Fecha final) — funcional pero filtra updated_at, no limit_payment_date real (ver hallazgo arriba).
  • No tiene los documentos (select), checkbox No tiene comprobante de pago.
  • Estatus (checkboxes múltiples): Nueva, Rechazada por autorizador, Rechazada por Bancos, Pagada, Pendiente de Autorización, Autorizada por Bancos, Pagada pendiente facturas, Autorizada, Rechazada por Finanzas, Pagada pendiente subs póliza.
  • KPI tiles clicables (funcionan como atajo de filtro por estatus — confirmado sin querer al hacer click y ver la lista filtrarse): Autorización (46), Autorizada (5), Por Pagar (4), Rechazada (2), Pagada facturas pendientes (66), Pagada pend subs póliza (6).
  • Columnas de tabla (con sort ↑↓): Empresa, Chequera, Póliza, Por comprobar, Tipo de Pago, Captura, Pago, Fecha Límite (sin filtro propio, solo sort — y ese sort está roto, ver hallazgo arriba).
  • Total registros observado: 73,014.

Panel de detalle expandido (fila) — verificado en vivo

Sección titulada «Panel de detalle expandido (fila) — verificado en vivo»

Al hacer click en el chevron de una fila se despliega:

  1. Header: “Fecha de creación: [fecha] hrs por: [usuario]” + botones Solicitar aprobación / Cancelar / Guardar / Borrar.
  2. Generales AS-400 (columna izquierda): Emp (select), Chequera (select), Póliza, Monto póliza, Fecha límite de pago (date picker — vacío en el fixture observado), Póliza / Subir Archivo. Barra “Última sincronización: Sin sincronizar” + botón refresh manual.
  3. Pagos (columna derecha): radio Transferencia / Cheque / Pago al extranjero, toggles Por comprobar y Sin Factura CFDI/No Deducible, radio Pago PUE / PPD, Beneficiario (texto), Banco (select), Cuenta CLABE Depósito.
  4. Artículos/Facturas: lista de conceptos comprados con Factura PDF/Factura XML y estado (ej. “Pendiente…”).

Fixture de prueba observado (QA, 2026-09-10)

Sección titulada «Fixture de prueba observado (QA, 2026-09-10)»
  • Solicita: Angi Espejel · 1 Artículo(s) · MXN $64,260.00 · Estatus: Nueva · 10-ago-26 12:29 hrs · 0%.
  • Fecha límite de pago: vacío en este registro.
  • Beneficiario: MARTIN MIRANDA RAMIREZ · Banco: BANORTE · Concepto: “Compra Llantas Gallo — COMPRA DE LLANTAS GALLO” · $64,260.00 · Facturas: pendientes.
  • Otros registros vistos en lista (variedad de estatus): Juan Carlos Oropeza (Solicitud Autorizada, 30%), Nely Martinez (Autorizada por Bancos, 60%), Lourdes Perez Dominguez (Solicitud Pendiente de Autorización, 20%, x2).

view-purchase, create-purchase, update-purchase, delete-purchase, authorize-purchase, approve-purchase, view-all-purchase, confirm-policy-number-purchase, upload-invoice-purchase, upload-policy-purchase, upload-proof-purchase, download-excel-purchase, reopen-purchase, update-complementary-purchase (app/Core/Security/PermissionConst.php).

Selectores usados por el tester (riesgo de fragilidad)

Sección titulada «Selectores usados por el tester (riesgo de fragilidad)»

Aún no existe un spec de Playwright para Compras (a diferencia de Tractores/Remolques). Si se escribe uno:

  • El patrón de fila-con-chevron es idéntico al de Tractores/Remolques: buscar el texto identificador de la fila (solicitante o folio) y subir por ancestros hasta encontrar el botón del chevron (confirmado en esta sesión vía evaluate — el chevron es un <span> sin ref de accesibilidad directo salvo por snapshot).
  • Los KPI tiles de estatus son clicables y filtran la lista — si un test hace click ahí sin querer (por ejemplo al buscar el chevron de la primera fila) puede quedar en un estado filtrado inesperado; más seguro recargar la página (page.goto('/compras')) entre tests que si acaso tocan esa zona.

Copia de la estructura de tablas de PRD (gmg_prd3) cargada en MySQL local (Laragon, W:\laragon\bin\mysql\mysql-8.0.30-winx64\bin\mysql.exe -u root), base gmg_09_010_2026 — solo estructura, sin datos (17 tablas relacionadas a Compras/Compras Cotizadas: orders, order_product, approvals, product_groups, product_inventories, product_inventory_movements, product_outputs, product_tenders, product_tender_quotes, products, outputs, output_receivers, suppliers, bills, bill_concepts, bill_payments, billables). Útil para verificar columnas/FKs reales sin releer el dump completo (6.2 GB) en W:\_backups\controlgmg.com\db_controlgmg-v2\gmg_prd3_09-10-2026.sql. Si se necesita otra tabla, extraerla del dump con un awk que capture desde -- Table structure for table hasta -- Dumping data for table (no cargar el dump completo — son ~6 GB con datos reales de producción).

  • Contenido línea por línea de routes/purchases/orders/orders.php.
  • Efecto runtime exacto del sort roto sobre approvals.limit_payment_date (¿error 500 o simplemente no ordena?).
  • Si Compras Cotizadas’ backend (QuotedOrderController) tiene el mismo bug updated_at vs limit_payment_date para su propio filtro “Fecha de pago” — no verificado, ver compras-cotizadas.md.