2. Terminal Punto de Venta
Tecnologías:
● Python 2.7 + GTK3
● WSDL SOAP ( suds )
● Escpos raw
3. Terminal Punto de Venta
● Necesidades básicas
Vista general:
● Celeridad ( xmlrpc a netrpc en comunicación, depurar código y
llamadas a OpenERP )
● Efectividad ( bajo nivel de incidencias )
● Varios métodos de pago ( Efectivo, Pasarela de pago .. )
● Interconexión con dispositivos ( Pin Pad, impresión, Lector de
códigos, ventana de cortesía, etc.)
● Sistema multiusuario ( logueo )
● Intuitivo y fácil aprendizaje ( Modo Operativo al resto de
Modos )
4. Terminal Punto de Venta
● Reflejo entre Vista y Ticket físico
Captura:
● “Botonera” (Previsión pantalla táctil, cada botón tiene su tecla)
5. Terminal Punto de Venta
● Necesidades avanzadas
Vista general:
● LOG ( necesario el control en transacciones con pasarela de
pago, estado de los periféricos )
● Actualización TPV's en serie (scp, ssh, scripts)
● Independencia del código fuente ( programable -teclas y
comandos-, adaptable )
● Combinación de pagos ( varias tarjetas, tarjeta – efectivo )
6. Terminal Punto de Venta
Peculiaridades del cliente:
● CRM y sistema de puntos
● Descuentos y tarifas
● Más formas de pago (financiado)
● Importación de tickets (compra previa + otros productos)
7. Terminal Punto de Venta
Peculiaridades técnicas:
● Codificación / Decodificación en impresión. UTF-8 a cp850
● SIPAY: Pasarela:
● Especificacion del web service en un archivo WSDL
● La comunicación no es directa con el web service
● Uso de un concentrador (software intermedio escuchando por
el puerto localhost:17000)
10. Terminal Punto de Venta
Peculiaridades técnicas (Sipay Y SUDS):
bstr = Element('ns1:BeginSellTransactionRequest')
header = Element('ns1:Header')
code = Element('ns1:ClientId').setText("13")
store = Element('ns1:StoreId').setText("13")
pos = Element('ns1:PosId').setText(controller.connection.idPos)
lang = Element('ns1:Lang').setText("0")
extra = Element('ns1:ExtraData1').setText("No Info")
header.append(code)
header.append(store)
header.append(pos)
header.append(lang)
header.append(extra)
amount = Element('ns1:Amount').setText(string)
ticket = Element('ns1:TicketNumber').setText(ticket)
bstr.append(header)
bstr.append(amount)
bstr.append(ticket)
try:
response = self.client.service.BeginSellTransaction (bstr)
except Exception as e:
controller.logger.error("Error en la inicializacion de la transaccion: ")
print e
return False
11. Terminal Punto de VentaTerminal Punto de Venta
● SUDS: Fundamental uso de la clase Plugin en sudssuds
● La librería no empaqueta los mensajes SOAP como
esperamos
● class MyPlugin(MessagePlugin)
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<ns1:BeginSellTransactionRequest>
<ns1:Header>
<ns1:ClientId/>
<ns1:StoreId/>
<ns1:PosId/>
<ns1:Lang/>
<ns1:ExtraData1/>
</ns1:Header>
<ns1:Amount/>
<ns1:TicketNumber/>
</ns1:BeginSellTransactionRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
12. Terminal Punto de Venta
Class MyPlugin:
● Def marshalled(self,context):
● context.envelope.nsprefixes['ns1'] = "http://tempuri.org/"
● context.envelope.walk(self.addAttributeForValue)
if node.name == 'InitializeDeviceRequest' and node.prefix=='ns0':if node.name == 'InitializeDeviceRequest' and node.prefix=='ns0':
node.setPrefix('ns1')node.setPrefix('ns1')
children = node.getChildren()children = node.getChildren()
for child in children:for child in children:
if child.name == 'InitializeDeviceRequest' and not child.prefix:if child.name == 'InitializeDeviceRequest' and not child.prefix:
toDelete.append(child)toDelete.append(child)
grandChildren = children[0]._ElementWrapper__content.childrengrandChildren = children[0]._ElementWrapper__content.children
for grand in grandChildren:for grand in grandChildren:
toAdd.append(grand)toAdd.append(grand)
for delete in toDelete:for delete in toDelete:
children.remove(delete)children.remove(delete)
for grand in toAdd:for grand in toAdd:
children.append(grandchildren.append(grand))