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 localgmg_09_010_2026, sin datos), en el marco del ticket GMG-3123 (“Filtro guía de pago”). Comparar contracompras-cotizadas.md— Compras y Compras Cotizadas comparten la misma tabla (orders) y la misma clase baseOrder(QuotedOrder extends Order), distinguidos por un global scopeis_quoted(0 = Compras, 1 = Cotizadas).
Backend
Sección titulada «Backend»- Modelo:
App\Core\Purchases\Order(app/Core/Purchases/Order.php), tablaorders. - 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(columnadate, nullable): agregada pordatabase/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 aOrder::classenModule::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_datedesde 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 filtrarorders.updated_at, NOorders.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) yOrderRepository::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 enapprovals(confirmado contra el schema real de PRD: la tablaapprovalssolo tieneid, 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 porQuotedOrder,ProductTender, etc., no solo porOrder). Sort roto/no-op — no se confirmó el efecto exacto en runtime (¿error 500 o simplemente no ordena?), por verificar. orders.limit_payment_dateconfirmado en el schema real de PRD:date DEFAULT NULL, sin default, columna número 9 de la tabla (después depolicy_found, antes depayment_type) — coincide con lo documentado por migración. La tablaordersen PRD tieneAUTO_INCREMENTen ~224,428 (total histórico combinado Compras + Compras Cotizadas).- Implicación para la implementación de GMG-3123:
- El nuevo filtro de rango sobre la fecha límite de pago real necesita un request param distinto
(
limit_payment_dateya está tomado por el filtro de “Fecha de pago”/updated_at). - Hay que agregar el nuevo filtro (
whereBetweensobreorders.limit_payment_date) en los 3 lugares:OrderController@getOrders:246,getProductGroupReport:310-322,OrderRepository::getQueryToProductGroupDetailExport:39-51. - En frontend, clonar el componente
date-rangeya usado para “Fecha de pago” (MainPurchases.vue:76-79), con su propiov-model. - Opcional/aparte: corregir el sort roto de “Fecha Límite”.
- El nuevo filtro de rango sobre la fecha límite de pago real necesita un request param distinto
(
Rutas backend
Sección titulada «Rutas backend»routes/purchases/orders/orders.php, montada bajo/ordersen el router (vercompras-cotizadas.mdpara el listado de rutas hermanas bajo/orders/quoted/*,/orders/product-groups/*,/orders/reports/*). No se listó línea por línea el contenido exacto deorders.phpen esta pasada — por verificar.
Frontend Vue 2
Sección titulada «Frontend Vue 2»- Ruta
/compras→resources/js/components/Purchases/Orders/MainPurchases.vue(resources/js/routes.js:177-179, guardcan('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, nolimit_payment_datereal (ver hallazgo arriba). No tiene los documentos(select), checkboxNo 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:
- Header: “Fecha de creación: [fecha] hrs por: [usuario]” + botones
Solicitar aprobación/Cancelar/Guardar/Borrar. - 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. - Pagos (columna derecha): radio
Transferencia/Cheque/Pago al extranjero, togglesPor comprobarySin Factura CFDI/No Deducible, radioPago PUE/PPD,Beneficiario(texto),Banco(select),Cuenta CLABE Depósito. - Artículos/Facturas: lista de conceptos comprados con
Factura PDF/Factura XMLy 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).
Permisos (Laratrust)
Sección titulada «Permisos (Laratrust)»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>sinrefde 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.
Acceso al schema real (BD local)
Sección titulada «Acceso al schema real (BD local)»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).
Por verificar
Sección titulada «Por verificar»- 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 bugupdated_atvslimit_payment_datepara su propio filtro “Fecha de pago” — no verificado, vercompras-cotizadas.md.