Mercadona tiene un bug de presentación en sus tickets?

Ticket de Mercadona

El otro día, al salir del supermercado, me fijé en que el ticket tenía algo raro. Había dos líneas para el mismo producto y en una tenía 2 unidades y en la otra 1 unidad. Aparentemente parecía un bug de presentación ya que los datos eran correctos. Pero como soy curioso quería saber qué había pasado exactamente, así que le pregunté a Claude y esto es lo que me dijo. 👇

Análisis del bug con Claude Code

Lo primero: las cuentas cuadran (2,99 al 21% y 2,25 al 10%), así que es un bug de presentación/agrupación, no de importes.

Las causas más probables, ordenadas por probabilidad:

1. La agrupación solo mira la última línea, no todo el carrito. Es el clásico: al insertar un artículo se hace if (ultimaLinea.codigo == nuevo.codigo) ultimaLinea.cantidad++ en vez de buscar en toda la lista. Basta con que entre medias pasara algo que rompiera la adyacencia —un artículo escaneado y luego anulado, una línea cancelada que no se imprime— para que la tercera lata abriera línea nueva. Encaja con que las dos líneas salgan juntas en el ticket: el render respeta el orden de inserción y la línea intermedia desapareció.

2. Dos caminos distintos de creación de línea. Multiplicador manual (tecla «x2» + escaneo) vs. escaneo suelto. Si el modelo distingue LineaConCantidad de LineaSimple, o marca un flag tipo cantidadIntroducidaManualmente, la clave de agrupación deja de ser solo el código de artículo y ya no fusionan.

3. Mismo texto, distinto EAN. La descripción del ticket va truncada a ~20 caracteres. Podrían ser dos referencias distintas (lote, formato, proveedor) que comparten descripción y PVP pero tienen código diferente. Aquí la agrupación funcionaría correctamente: agrupa por código, no por nombre, y son códigos distintos.

Para distinguir entre 1/2 y 3, mira el ticket digital en la app: si ahí aparecen con EAN distinto, no hay bug, hay dos referencias. Si el EAN es el mismo, es agrupación defectuosa en el TPV.

Y esta es una de las cosas que me molan de mi trabajo. Analizar y pensar en problemas de negocio, entender por qué pasan y cuáles pueden ser las posibles soluciones. En Spalopia me enfrento a este tipo de problemas a diario por lo que suele ser bastante entretenido.

Code Smell – Parámetros de tipo booleano

Cuando recibes un parámetro que o bien es de tipo bool o bien se comporta como un bool (por ejemplo un parámetro que representa un tipo de cliente donde solo existen dos tipos), es muy probable que esa función o método tenga más de una responsabilidad.

En este vídeo explicamos este code smell y como solucionarlo.

Conviértete en Pro de PHP – Late Static Binding

Atendiendo a lo que tradicionalmente conocemos como herencia, esperaríamos que si yo redefino una función o una constante en una clase hija, esta se va a sobreescribir. En PHP esto no sucede así dependiendo de como hagamos la llamada.

En este vídeo explico con varios ejemplos como funciona el Late Static Binding, que es la forma de solucionar este comportamiento inesperado.

Symfony promueve las buenas prácticas

El equipo de Symfony ha hecho una serie de cambios, versión tras versión, orientados a promover las buenas prácticas a través del buen uso del contenedor de inyección de dependencias y el principio de inversión de dependencias. En este vídeo vemos como algunos proyectos usaban malas prácticas en su código, porque podían hacerlo, y como ahora es realmente complicado seguir haciéndolo.

Conceptos necesarios para entender el vídeo:

Las ayudas para todos están hechas para los ricos

A cuantos pobres conocéis comprándose un Tesla ( ni siquiera un Zoe)? Y a cuantos ricos?

A cuantos pobres conoces instalando placas solares en sus casas? Y a cuantos ricos?

A cuantos pobres conocéis haciendo al menos un viaje de vacaciones / ocio en coche al año? Y a cuantos ricos?

El Gobierno prorroga el descuento de 20 céntimos por litro de combustible

A cuantos pobres conoces que se hospeden por más de 100€ la noche? o simplemente que puedan irse de vacaciones? Y a cuantos ricos?

Una de cada tres ayudas del bono viaje valenciano fue a pagar estancias de más de 250 euros por noche
La falta de un filtro de renta en las solicitudes provoca situaciones llamativas, como que la ayuda sea empleada para pagar vacaciones de lujo. Es el caso de las 1.369 reservas que superan los 400 euros por noche, o las 1.800 de entre 350 y 400 euros. Más de una tercera parte de las ayudas fueron destinadas a sufragar alojamientos de más de 250 euros por pernoctación, con más de 14.500 reservas solo en ese rango. Si se tiene en cuenta el coste total del alojamiento, el Gobierno valenciano ha apoyado económicamente a un millar de personas en escapadas superiores a los 1.000 euros. Un 10% del total de estancias superaban los 800 euros.

El relato es importante, y cuando se anuncia este tipo de ayudas siempre lo hacen con la falacia de que son ayudas para todos, aunque la realidad es que los que principalmente se benefician son los ricos.

Fuera del relato esta es la realidad, los pobres dan paguitas a los ricos para que sigan siendo aún más ricos. Bueno, para los ricos las cosas suelen ser todo a lo grande, así que más que paguitas son pagazas.

Los botones del brillo no funcionan en Linux con una gráfica de Intel y i3 WM

Si estás usando i3 WM en Linux con una gráfica moderna de Intel, probablemente estés utilizando el driver de Mesa. En este caso el problema es que la orden «xbacklight«, que es la que utiliza el script por defecto, no te va a funcionar.

Yo estoy utilizando Endeavour OS con su configuración por defecto para i3 WM, y claro, me molestaba bastante no poder bajarle el brillo al portátil cuando no estaba conectado a la red eléctrica. La solución es cambiar la orden «xbacklight» por una llamada a «brightnessctl» equivalente.

Para ellos vamos a editar el archivos «~/.config/i3/scripts/volume_brightness.sh» y haremos los siguientes cambios:

--- volume_brightness-old.sh	2023-11-28 22:32:59.867716528 +0100
+++ volume_brightness.sh	2023-11-24 17:58:54.184428340 +0100
@@ -21,7 +21,10 @@
 
 # Uses regex to get brightness from xbacklight
 function get_brightness {
-    xbacklight | grep -Po '[0-9]{1,3}' | head -n 1
+    max=`brightnessctl m`
+    actual=`brightnessctl get`
+    echo $((actual*100/max))
 }
 
 # Returns a mute icon, a volume-low icon, or a volume-high icon, depending on the volume
@@ -84,13 +87,15 @@
 
     brightness_up)
     # Increases brightness and displays the notification
-    xbacklight -inc $brightness_step -time 0 
+    brightnessctl set +$brightness_step% 
     show_brightness_notif
     ;;
 
     brightness_down)
     # Decreases brightness and displays the notification
-    xbacklight -dec $brightness_step -time 0
+    brightnessctl set $brightness_step%- 
     show_brightness_notif
     ;;
 esac

Y lo tenemos. Ahora ya podemos subir y bajar el brillo sin problemas.

Inyección de dependencias vs Inversión de dependencias vs Contenedor de inyección de dependencias

Explicación de las diferencias entre estos tres conceptos que a veces se confunden:

  • Inyección de dependencias
  • Inversión de dependencias
  • Contenedor de inyección de dependencias

Veremos que problemas tiene cada uno, coo resolverlos y cuando usarlos.

Dependencias iconos creados por juicy_fish – Flaticon

Repo de ejemplo

Enlaces relacionados: