- C# 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Proyecto completo sin binarios: sin bin/obj/.vs, sin la DLL del fabricante de la impresora (autoreplyprint*.dll; licencia sin confirmar, ver KioskDemo/Lib/Impresora/LEEME.txt) y con las credenciales de Banorte del App.config reemplazadas por un marcador (BanorteUsuario, BanortePassword, BanorteKey: CAMBIAR-POR-LA-CREDENCIAL-REAL). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
| KioskDemo | ||
| .gitignore | ||
| CLAUDE.md | ||
| KioskDemo.sln | ||
| README.md | ||
Kiosco Demo (WPF · .NET Framework 4.8)
Proyecto de demostración de un kiosco de autoservicio con 3 operaciones: Depósito, Retiro y Compra de productos, conectado a un servidor WebSocket.
Requisitos
- Windows con Visual Studio 2019 o 2022 (con la carga de trabajo ".NET desktop development").
- Conexión a internet la primera vez que se abra el proyecto, para que NuGet restaure el paquete
Newtonsoft.Json.
Cómo abrir y ejecutar
- Abrir
KioskDemo.slncon Visual Studio. - Esperar a que se restauren los paquetes NuGet (automático).
- Presionar F5 para compilar y ejecutar.
La ventana inicia maximizada. Se puede ajustar el tamaño/comportamiento "kiosco" (pantalla completa sin bordes) en MainWindow.xaml cambiando WindowStyle a None.
Servidor WebSocket
La URL del servidor se configura en App.config (clave ServerUri), para poder apuntar a la máquina real del S_SDK sin recompilar:
<appSettings>
<add key="ServerUri" value="ws://127.0.0.1:8182/" />
</appSettings>
El default (127.0.0.1:8182) coincide con lo que trae S_SDK de fábrica (Properties.Settings.ipConnection / comConnection). Si el S_SDK real corre en otra máquina, edita ese archivo junto al .exe -no hace falta recompilar-.
Contrato de mensajes (confirmado con S_SDK real, integración 2026-07-09)
La app envía:
{ "Method": "StartPayment", "Amount": 500 }
Valores posibles de Method: StartPayment (compra, con Amount = costo; o depósito abierto, con Amount: 0 = sin monto objetivo), EndPayment (sin Amount; termina un depósito abierto), StartWithdrawal (retiro).
El servidor responde con uno o varios mensajes IdResult: 200 mientras dura la operación (uno por cada billete/moneda aceptado), y el mensaje definitivo trae "finalizado": true dentro de desc:
{
"Method": "StartPayment",
"IdResult": 200,
"desc": {
"totalDeposited": 100, "montoSolicitado": 75, "finalizado": true,
"billetes": { "total": 100, "denominaciones": { "100": 1 } },
"monedas": { "total": 0, "denominaciones": {} },
"cambio": { "monto": 25, "billetes": {...}, "monedas": {...} },
"entregado": { "billetes": {...}, "monedas": {...} }
}
}
IdResult: 200 = éxito (progreso o final, ver finalizado), 500 = error controlado (se muestra desc al usuario), 400 = error no controlado.
Importante para StartPayment: el servidor NO manda un ack inmediato al recibirlo -a diferencia de "Open"-, así que CompraView y DepositoView usan WebSocketService.SendFireAndForgetAsync + el evento MessageReceived, e ignoran todo mensaje hasta ver desc.finalizado == true. Usar SendCommandAsync (que resuelve con el primer mensaje) perdería el cambio/desglose y navegaría a "Gracias" antes de tiempo.
Depósito abierto: DepositoView manda { "Method": "StartPayment", "Amount": 0 } -con Amount: 0, el servidor (S_SDK) no persigue ningún monto: acepta billetes/monedas indefinidamente, empujando el desglose en vivo (mismo mecanismo que la compra), hasta que la app manda { "Method": "EndPayment" } (botón "Terminar depósito"). Ese cierre no tiene una respuesta directa propia: el resultado final llega como un mensaje StartPayment más, con desc.finalizado == true, el totalDeposited definitivo y su desglose -sin cambio/entregado, esos solo aplican cuando Amount > 0 (compra)-.
Toda esta lógica vive en Models/WsMessages.cs (estructuras, incluyendo PagoEstado/DescComoPago()) y Services/WebSocketService.cs (envío/recepción). Si el contrato cambia, solo hay que tocar esos dos archivos.
Flujo de pantallas
- Bienvenida (
Views/WelcomeView) — "Toca para iniciar". - Menú (
Views/MenuView) — Depósito / Retiro / Compra. - Depósito (
Views/DepositoView) — botón Iniciar →StartPaymentconAmount: 0(sin monto objetivo) → desglose de monedas ($0.50 a $20) y billetes ($20 a $1000) se actualiza en vivo conforme el servidor va reportando lo insertado → botón "Terminar depósito" envíaEndPayment. - Retiro (
Views/RetiroView) — montos rápidos $20/$50/$100/$200 u "Otro monto" con teclado numérico en pantalla (tope $1,000) → confirmar envíaStartWithdrawal. - Compra (
Views/CompraView) — catálogo con imagen/precio, carrito con cantidades → Pagar envíaStartPayment. - Gracias (
Views/GraciasView) — resumen de la operación (folio, fecha, detalle, total) común a las 3 operaciones, con botón Imprimir ticket (usa el diálogo de impresión de Windows) y Finalizar (regresa a Bienvenida).
Personalización rápida
- Catálogo de productos:
Models/Catalog.cs→ listaCatalogoDemo.Productos. Reemplazar por el catálogo real (nombre, precio, ruta de imagen) cuando esté disponible. - Colores / estilo:
Themes/Styles.xaml(paleta al inicio del archivo). - Imágenes:
Assets/Products,Assets/Cash,Assets/Icons— son ilustraciones planas generadas para la demo, se pueden sustituir por imágenes reales con el mismo nombre de archivo. - Monto máximo de retiro: constante
MontoMaximoenViews/RetiroView.xaml.cs.
Notas
- El proyecto usa el formato de csproj moderno (SDK-style) apuntando a
net48, lo que permite que Visual Studio restaureNewtonsoft.Jsonautomáticamente vía NuGet, sin pasos manuales. - El indicador de conexión (punto verde/rojo) en la barra superior refleja el estado real del WebSocket.
- Si el servidor no responde en 15 segundos, la app muestra un aviso de "Sin conexión" en vez de quedarse congelada.