En el contexto de la modelación de precios, esta página se erige como un compendio detallado de los procesos emprendidos para abordar específicamente a aquellos clientes que contribuyen significativamente al 80% de las ventas. El enfoque preciso y riguroso aplicado a esta iniciativa no solo refleja la importancia estratégica de estos clientes destacados, sino también la necesidad de una comprensión profunda y personalizada de sus patrones de comportamiento y preferencias.
La documentación aquí presentada ofrece una mirada minuciosa a la metodología empleada en la realización de la modelación de precios para este segmento de clientes clave. Desde el análisis inicial de datos hasta la implementación de algoritmos específicos, cada paso ha sido deliberado y estratégicamente concebido para maximizar la eficacia de la modelación y, por ende, optimizar la estrategia de precios aplicada a estos clientes estratégicos.
Adentrándonos en los pormenores, se explorará cómo se llevó a cabo la identificación y selección de variables clave, la aplicación de técnicas de modelado predictivo y la validación de resultados. Este enfoque detallado no solo brinda una comprensión clara del proceso, sino que también sienta las bases para futuras iteraciones y mejoras en la estrategia de precios, asegurando así una adaptabilidad continua en un entorno comercial dinámico. En última instancia, esta página actúa como un recurso integral para aquellos interesados en comprender la fundamentación y ejecución de la modelación de precios centrada en los clientes más influyentes.
Simulador de Precios GCC
Entendimiento del proyecto
El proyecto se centra en el Revenue Growth Management, enfocado en una estrategia de precios
La aplicación del simulador ya se ha entregado al equipo de GCC.
Por lo que esta guía se enfoca en su funcionamiento y conceptos técnicos para futuras referencias o fases de mantenimiento, si aplica.
Conceptos técnicos aplicación
La aplicación se encuentra alojada en los servidores de GCC, por lo tanto, para acceder a ella necesitamos estar conectados en su red.
Para conectarnos a su red es necesario acceder a su VPN y con ello podremos acceder a la app (posteriormente se detallan los accesos a la VPN y la app)
, y los dueños de este son la gente de infraestructura de GCC
El backend de la app está construido con Nodejs, usando Sequelize como ORM para la base de datos PostgreSQL
La base de datos PostgreSQL, el backend y el front de la app están configurados como servicios Docker, se tiene configurado en el tema de la infraestructura cuando se realiza un push reiniciar los servicios, estos servicios fueron creados y son mantenidos por el equipo de infraestructura de GCC, cualquier tema con estos, se deberá contactar a ellos (se deja el contacto del equipo en la parte final de la guía)
Estructura de la aplicación
Aplicación en producción
Funcionamiento general de la app
La aplicación se basa en una propuesta de un Excel, por lo que tiene una vista enfocada principalmente en una página donde se realizan varios cálculos.
Como primer lugar tendremos la sección de filtros, donde los usuarios podrán elegir el producto PDM que quieren consultar para realizar sus simulaciones (Block, Cemento Envasado, Cemento Granel, Cemento Mega bolsa y Concreto) e inferir las utilidades y participación de mercado de acuerdo con los ajustes al precio que realicen. En la siguiente opción tienen la posibilidad de elegir porque filtrar, ya sea por área o por cluster, de ahí se cargarán las áreas o clusters disponibles para continuar cargando los datos.
En las siguientes secciones de la app se cuentan con tablas y gráficos que se irán actualizando conforme se elijan filtros y se modifiquen datos de entrada. Primero tendremos una tabla de variabilidad en los precios donde se irá ajustando el precio de los siguientes meses usando el input Delta Precio, luego veremos la gráfica de como irá cambiando la PDM a lo largo de los periodos, así como gráficas de utilidad bruta, de delta precio, una gráfica con proyecciones más a futuro de campana de utilidad bruta, y otra de volumen, una sección con datos de entrada del producto seleccionado que se actualizará de acuerdo con los filtros seleccionados y los ajustes realizados en el precio, una tabla completa de la variabilidad en los periodos con otros datos que no se muestran en las gráficas, y por último la lista de clientes disponibles de acuerdo con la selección actual.
En la parte final de la app tendremos botones de acción, donde podremos guardar la simulación actual en la base de datos pensando en futuras consultas, exportar la simulación como PDF (donde se nos abrirá un PDF en una nueva pestaña con una presentación de la simulación), exportar la simulación como Excel o resetear todos los campos.
Módulos
La app cuenta con algunos módulos para dividir las responsabilidades
Home
Este es el módulo principal de la app, y el que contiene el componte donde se encuentra la mayor parte de la lógica y cálculos que se realizan en la app
Shared
En este módulo se encuentran los archivos compartidos en la aplicación, como los modelos, pipes y servicios
Reports Bi
En este módulo cuenta con un componente en el que únicamente se embebe el archivo de PowerBi proporcionado por el equipo de datos
App
Aquí se encuentran las configuraciones generales de la app, y las configuraciones para Azure Active Directory
Componentes
Saved Queries
Este componente se enfoca en la vista de las consultas que se han guardado en la app, su principal función es consultar la base de datos en busca de las consultas guardadas, y desplegarlas en una tabla, proporcionando la opción de ver cada una de las consultas, cargando el componente Home y enviando como parámetro el ID de la consulta que se quiera ver.
Modal Name Query
Modal donde se recibe como input el nombre de la consulta que realicen los usuarios
Select Popover
Componente que renderiza un popover mostrando la lista de clientes disponibles según la consulta que se realice en la app
Servicios
DbService
En este servicio se encuentran los métodos para realizar el fetch a los distintos endpoints del backend
PdfService
Servicio para crear el archivo PDF en la app
Backend
El backend está construido en Nodejs y se encuentra en el mismo repositorio del proyecto, en la carpeta api
Ahí se encuentran definidos los archivos para los modelos y los controladores, dejamos un archivo env.dev.txt donde se encuentran las conexiones para la base de datos de forma local, y el archivo .env se usa para las conexiones con la base de datos del servidor (conectarse a la VPN primero para realizar las conexiones a la base)
Estructura de la base de datos
La base de datos tiene la siguiente estructura:
Se recomienda usar una herramienta de gestión de bases de datos PostgreSQL como
para consultar las tablas y los modelos de datos. Los modelos también se pueden consultar en el proyecto dirigiéndonos a la carpeta api < models.
En caso de que se necesite una actualización de forma manual, será necesario importar las bases de datos en pgAdmin 4, asegurarse de que las bases contengan la columna id, createdAt y updatedAt, o agregarlas ya que Postgres las tiene por defecto. Todas las tablas se encuentran en formato csv.
ElasticidadCruzadaConcretos: En esta tabla se encuentran los datos de elasticidad cruzada y propiedades que están relacionadas con el producto Concreto.
analyticalBases: Esta tabla ya no se encuentra en uso.
areas: Esta tabla contiene el catalogo de areas que usa la aplicación, no se actualizará en el futuro ya que son datos que no cambian.
clusters: Tabla que contiene el catálogo de clusters y cuantos clientes existen en cada cluster.
coeficienteClusters: Tabla que contiene la relación de clusters con clientes y el valor del coeficiente para cada caso (el coeficiente es el valor de la elasticidad).
coeficienteElasticidades: Tabla que contiene la relación entre las areas, los productos (pdm) y el valor de su coeficiente.
concretoTotalMercados: Tabla contiene las ventas relacionadas por ciudad y por producto (pdm) a lo largo del tiempo.
customerFilters: Tabla que contiene la relación entre los clientes y su volumen de los últimos 3 meses, esta tabla se genera con el archivo Clientes_Estandar 80 tomando unicamente las columnas de Customer number agregado y Volumen 3M.
customerPrices: Tabla que contiene la relación entre los clientes, productos (pdm), zonas, areas, precios y cluster.
customers: Esta tabla ya no se encuentra en uso.
dataPdms: Tabla que contiene los datos de los productos y sus valores de precio iniciales. Esta tabla no se actualizará en el futuro, a menos que se tenga un cambio en los productos.
demos: Esta tabla ya no se encuentra en uso.
elasticidadCruzadaBlocks: En esta tabla se encuentran los datos de elasticidad cruzada y propiedades que están relacionadas con el producto Block.
elasticidadCruzadaCemento: En esta tabla se encuentran los datos de elasticidad cruzada y propiedades que están relacionadas con el producto Cemento.
elasticidadPdmBocks: Tabla que contiene la relación de zonas con el block y sus propiedades (precio, volumen).
elasticidadPdmCemento: Tabla que contiene la relación de zonas y areas con el cemento y sus propiedades (precio, volumen).
elasticidadPdmConcreto: Tabla que contiene la relación de zonas de Concreto y sus propiedades (precio, volumen).
products: Tabla con relaciones de pdm y productos, catálogo de productos.
savedQueries: Simulaciones guardadas por parte de los usuarios de la app.
zones: Catálogo de zonas. Esta tabla no se actualizará en el futuro.
A continuación se adjunta una carpeta con la última actualización de la app 28-feb-2024
, ellos proporcionan acceso tanto a la VPN como al mismo repositorio.Proporcionan el acceso mes a mes, por lo que es necesario mandarles correo para solicitar una extensión de los mismos.
Una vez teniendo el acceso y realizando la clonación en local del proyecto, el servidor de desarrollo se levanta con las instrucciones conocidas de npm run start, cabe aclarar que se nos solicitó cambiar el puerto de la app al puerto 3000, para el backend el puerto es el 3001, esto ya está realizado.
Cambiar los datos de environment.dev.ts al archivo environment.ts para ejecutarlo en local, regresar los cambios antes de que se haga un push al repositorio remoto.
Guía accesos VPN y servidor GCC
La aplicación se encuentra alojada en los servidores de GCC, por lo que primero tenemos que conectarnos a su VPN para estar dentro de su red, y una vez ahí podremos acceder tanto a su servidor como a la liga de la aplicación.
Una vez instalado aparecerá una pantalla como esta
Se deberá introducir la dirección 201.174.23.28 y hacer click en Connect
Si se tuviera algún problema o nuestro firewall bloqueo la conexión, se puede dar click en Permitir conexión, o asegurarse de tener activadas estas preferencias entrando desde el ícono de configuración de Cisco AnyConnect
Una vez completado lo anterior, nos solicitará un usuario y contraseña, estos son:
Usuario: exchemt_dg
Password: Bienvenido.1
Con estos datos, se habrá conectado correctamente a la VPN, y se podrá acceder tanto al servidor como a la
Si se necesita acceder al servidor desde la consola, se podrá realizar usando el comando
ssh root@172.16.248.167
Con esto nos conectará el servidor de la app 172.16.248.167 usando ssh, nos solicitará una contraseña, la cual es: "aanT&7p>·lp
Con ello podremos acceder al servidor para bajar cambios del repositorio, levantar servicios docker, y realizar las configuraciones necesarias. (Ahora la app se ha entregado, por lo que no es recomendable acceder al servidor)
A continuación se deja un archivo donde se listan las credenciales para acceder, mismas que se han especificado antes:
SimulaPrecServ.txt
852 B
Guía actualizar la app
Para actualizar la app, necesitarás realizar un push al
remoto, rama dev. Esto ocasionará que las rutinas de docker se ejecuten y se reinicien todos los servicios configurados por el equipo de infraestructura.
Se tienen a consideración dos temas:
Al reiniciar los servicios, se eliminan los datos de la base de datos: se recomienda exportar los archivos de las tablas en csv si se realizó alguna modificación en los datos antes de realizar el push para posteriormente importar estas bases cuando se inicialice el servicio de nuevo, este proceso es muy sencillo de realizar usando
Generalmente el servicio de la app no se inicializa de nuevo: Cuando hacemos el push al repositorio, no siempre se reinicia el servicio de la app, por lo que recomendamos primero bajar los cambios en el servidor, para ello primero tienes que acceder al servidor remoto por consola, navegar a la carpeta del front y bajar los cambios, se recomienda bajar los cambios justo después de realizar el push.
cd /data/containers/qa/dev-simuladorprecios/front
git fetch
git merge origin/dev
Luego comprobar si el servicio está inicializado usando docker service ls
Si notamos que el servicio dev_dev-simuladorprecios-app tiene en REPLICAS 0/1 el servicio no se levantó, por lo que necesitamos ejecutar el siguiente comando para asegurarnos que el servicio se active de nuevo
docker service update --force dev_dev-simuladorprecios-app
Otra forma de revisar los servicios activos es ingresando a la consola Traefik:
Realizado lo anterior ya se habrá completado la actualización de la app, tanto la base de datos, como nuestro front y backend se actualizarán a las nuevas versiones.
Guía automatización subida de datos en la aplicación
El proceso de actualización es el siguiente:
El equipo de GCC comparte sus bases crudas
BDS se encarga de limpiarlas, implementar los algoritmos necesarios y obtener nuevas bases de datos
Estas últimas bases de datos se usan para alimentar la aplicación y son las que se cargan en Postgres
GCC realiza un corte cada mes, por lo que quieren actualizar estos datos cada mes, para tener la aplicación actualizada siempre a futuro.
El último proceso a realizar es la generación de un ejecutable (.exe). Este ejecutable será una encapsulación de un archivo python donde se realiza el proceso de limpieza de bases de datos crudas de GCC, se obtiene como salida bases limpias y organizadas, y por último se actualizarían estas bases de datos en el servidor.
El proceso se realizaría primero ajustando parámetros de los códigos que tiene BDS, una vez teniendo esto se necesita generar plantillas para que el equipo de GCC alimente con sus actualizaciones, esto nos aseguraría tener una estandarización en las bases de datos, y no estar modificando los códigos respecto a los cambios constantes que realiza GCC en sus bases de datos.
La última parte sería integrar estos códigos en un archivo de Python en el cual se ejecutarán en orden (teniendo en cuenta que algunos códigos tienen como salida la entrada de otros) para que al final se realze una conexión a la base de datos y se actualicen las bases con los nuevos datos.
A continuación se listan enlaces de referencia que pueden ser de ayuda en este proceso:
Como guardar datos en Postgres usando Python
Configurar la conexión a la base de datos PostgreSQL:
Antes de ejecutar tu código, asegúrate de tener instalada la biblioteca psycopg2 y configura la conexión a tu base de datos PostgreSQL. Puedes agregar esta configuración al principio de tu script:
Asegúrate de reemplazar 'tu_host', 'tu_base_de_datos', 'tu_usuario', 'tu_contraseña', y 'tu_puerto' con los valores específicos de tu entorno.
Crear la tabla en PostgreSQL (si no existe):
Antes de insertar datos, puedes verificar si la tabla ya existe en PostgreSQL y, si no, crearla. Puedes agregar esta parte de código después de la configuración de la conexión:
Insertar datos en PostgreSQL:
Después de crear la tabla, puedes adaptar la parte de tu código que exporta a CSV para insertar los datos directamente en la base de datos PostgreSQL. Reemplaza la línea que guarda en CSV con el siguiente bloque:
Esto utiliza el método to_sql de Pandas para insertar directamente en la tabla de PostgreSQL. Ajusta el parámetro if_exists según tus necesidades (en este caso, 'replace' reemplazará la tabla si ya existe).
Cerrar la conexión después de insertar los datos:
Finalmente, no olvides cerrar la conexión después de insertar los datos:
Leer un archivo realizando un request en Python
Para leer un archivo que se encuentra en una ubicación remota en un notebook, puedes utilizar la biblioteca requests en Python para descargar el contenido del archivo y luego leerlo. Aquí tienes un ejemplo de cómo hacerlo:
Ejecutar varios archivos de Python en un orden específico
Para lograr esto, puedes utilizar un enfoque de secuencia de comandos (scripting) en Python y aprovechar el módulo subprocess para ejecutar los scripts en orden. Asegúrate de que cada script guarde el archivo .csv que se genera de manera adecuada para que el siguiente script pueda acceder a él. Aquí te muestro un ejemplo de cómo podrías hacerlo:
Supongamos que tienes los siguientes scripts:
script1.py
script2.py
script3.py
... (hasta script10.py)
El script script1.py generará un archivo .csv que luego será utilizado por script2.py, y así sucesivamente.
Aquí está el código para el script principal que ejecutará los otros scripts en orden:
Para lograr esto, puedes utilizar un enfoque de secuencia de comandos (scripting) en Python y aprovechar el módulo subprocess para ejecutar los scripts en orden. Asegúrate de que cada script guarde el archivo .csv que se genera de manera adecuada para que el siguiente script pueda acceder a él. Aquí te muestro un ejemplo de cómo podrías hacerlo:
Supongamos que tienes los siguientes scripts:
script1.py
script2.py
script3.py
... (hasta script10.py)
El script script1.py generará un archivo .csv que luego será utilizado por script2.py, y así sucesivamente.
Aquí está el código para el script principal que ejecutará los otros scripts en orden:
# Continuar ejecutando los scripts restantes de manera similar...
Puedes agregar más líneas para ejecutar los scripts restantes de manera similar hasta script10.py.
Dentro de cada script (script1.py, script2.py, etc.), asegúrate de guardar el archivo .csv generado en una ubicación conocida y accesible para los siguientes scripts.
Si necesitas pasar argumentos entre los scripts, puedes hacerlo a través de argumentos de línea de comandos o almacenar información en archivos intermedios. Por ejemplo, puedes guardar la ubicación del archivo .csv en un archivo de configuración después de que se haya generado en script1.py, y luego leer esa ubicación desde script2.py.