Está en la página 1de 235

CONTRIBUCIÓN A LA COMUNIDAD DE SOFTWARE LIBRE UNICENTA

CARLOS ENRIQUE URREGO LEON

UNIVERSIDAD CATÓLICA DE PEREIRA


FACULTAD DE CIENCIAS BÁSICAS E INGENIERÍA
INGENIERÍA DE SISTEMAS Y TELECOMUNICACIONES
PEREIRA
2018
CONTRIBUCIÓN A LA COMUNIDAD DE SOFTWARE LIBRE UNICENTA.

CARLOS ENRIQUE URREGO LEON

Informe Final de Trabajo de Grado para optar al título de Ingeniero de


Sistemas y Telecomunicaciones

Director:
Msc. Andrés Mauricio Martínez Hincapié

UNIVERSIDAD CATÓLICA DE PEREIRA


FACULTAD DE CIENCIAS BÁSICAS E INGENIERÍA
INGENIERÍA DE SISTEMAS Y TELECOMUNICACIONES
PEREIRA
2018

2
DECLARACIÓN DE DERECHOS DE AUTOR

Esta obra está licenciada bajo la Licencia Creative Commons Atribución 3.0 No
portada. Para ver una copia de esta licencia, visite
http://creativecommons.org/licenses/by/3.0/ o envíe una carta a Creative
Commons, PO Box 1866, Mountain View, CA 94042, USA.

3
AGRADECIMIENTOS

Agradezco a todas las personas que hacen posible el crecimiento del


conocimiento, ya que sin ellas el desarrollo social no sería viable. Adicionalmente,
quiero agradecer a mi tutor por guiarme durante todo el proceso de elaboración
del proyecto y aportar a mi crecimiento como profesional y persona. Finalmente,
quiero agradecer a mis padres, quienes me han apoyado durante mi formación
como persona y como profesional.

4
DEDICATORIA

Dedico este proyecto a mis padres, mi hermano y todos quienes creen estar en
capacidad de cambiar el mundo.

5
TABLA DE CONTENIDO

INTRODUCCIÓN ................................................................................................... 15

1. PRIMERA PARTE: FORMULACIÓN DEL PROYECTO ................................ 17

1.1 SITUACIÓN PROBLEMÁTICA ..................................................................... 17

1. 2 JUSTIFICACIÓN ......................................................................................... 18

1.3 OBJETIVOS ................................................................................................ 19

1.3.1 Objetivo General ................................................................................... 19

1.3.2 Objetivos Específicos ........................................................................... 19

2. SEGUNDA PARTE: MARCO CONTEXTUAL ................................................... 20

3. TERCERA PARTE: MARCO TEÓRICO............................................................ 21

3.1 ANTECEDENTES ........................................................................................ 21

3.2 CONCEPTOS TEÓRICOS ........................................................................... 29

3.2.1 Conceptos de software. ......................................................................... 29

3.2.2 Conceptos de telecomunicaciones. ....................................................... 33

3.2.3 Conceptos web ...................................................................................... 35

3.2.3.4 ECMAScript: ........................................................................................... 36

3.2.4 Plataformas tecnológicas. ...................................................................... 36

4. CUARTA PARTE: MODELO TEÓRICO ............................................................ 42


4.1 PROTOTIPADO DE SOFTWARE ................................................................ 42

4.2 MODELO DE CICLO DE VIDA EN ESPIRAL............................................... 45

4.3. METODOLOGÍA PARA EL DESARROLLO INTEGRAL ............................. 47

5. RESULTADOS................................................................................................... 49

6
6. CONCLUSIONES ............................................................................................. 61

7. RECOMENDACIONES ..................................................................................... 63

8. BIBLIOGRAFÍA ................................................................................................. 64

9. ANEXOS ........................................................................................................... 71

ANEXO A: ESTADO DEL ARTE DE UNICENTA ............................................... 71

ANEXO B: INGENIERÍA INVERSA DE UNICENTA ........................................... 77

ANEXO C: DISGREGACIÓN DE PRODUCTO ................................................ 143

ANEXO D: SINCRONIZACIÓN CON WOOCOMMERCE ............................... 157

ANEXO E: OCTOPOS APP ............................................................................. 180

ANEXO F: ARTÍCULO PUBLICABLE............................................................. 209

ANEXO G: CONFIGURACIÓN DEL PROYECTO EN NETBEANS ................ 215

ANEXO H: MODELO RELACIONAL ............................................................... 224

ANEXO I: ACTAS DE REUNIÓN Y CARTA DE SATISFACCIÓN .................. 232

7
LISTA DE ILUSTACIONES

ILUSTRACIÓN 1. OPENBRAVO POS .................................................................................................. 22


ILUSTRACIÓN 2. MAIA POS................................................................................................................. 23
ILUSTRACIÓN 3. NORD POS ............................................................................................................... 24
ILUSTRACIÓN 4. MINPOS .......................................................................................... 25
ILUSTRACIÓN 5. REALCOMPUTER POS ........................................................................................... 26
ILUSTRACIÓN 6. STREAMLINE POS ............................................................................ 27
ILUSTRACIÓN 7. CHROMIS POS ................................................................................. 28
ILUSTRACIÓN 8. PARADIGMA DE PROTOTIPOS ............................................................................... 44
ILUSTRACIÓN 9. MODELO DE ESPIRAL ............................................................................................. 47
ILUSTRACIÓN 10. CLASE SAVEPROVIDER ...................................................................................... 50
ILUSTRACIÓN 11. MODELO RELACIONAL: DISGREGACIÓN DE PRODUCTO .............................. 53
ILUSTRACIÓN 12. DIAGRAMA DE CASOS DE USO: DISGREGACIÓN DE PRODUCTO ................ 54
ILUSTRACIÓN 13. INTERFAZ PARA AGREGAR UN PRODUCTO A DISGREGAR ............................ 55
ILUSTRACIÓN 14. MODELO RELACIONAL: SINCRONIZACIÓN CON W OOCOMMERCE ............. 56
ILUSTRACIÓN 15. DIAGRAMA DE ARQUITECTURA : SINCRONIZACIÓN CON WOOCOMMERCE
........................................................................................................................57
ILUSTRACIÓN 16. MOCKUP LISTADO DE CATEGORÍAS: OCTOPOS APP................................... 58
ILUSTRACIÓN 17. PEDIDO DE UNA MESA ......................................................................................... 59
ILUSTRACIÓN 18. RANKING CAPTERRA........................................................................................... 72
ILUSTRACIÓN 19. OFERTAS DE TRABAJO PARA DESARROLLO DE UNICENTA ......................... 74
ILUSTRACIÓN 20. CLASE DATALOGICSALES ................................................................................. 85
ILUSTRACIÓN 21. CLASE OCTOPOS ................................................................................................ 97
ILUSTRACIÓN 22. CLASE JROOTAPP ........................................................................................... 100
ILUSTRACIÓN 23. CLASE APPCONFIG .......................................................................................... 103
ILUSTRACIÓN 24. CLASE APPLOCAL ............................................................................................ 105
ILUSTRACIÓN 25. CLASE APPUSER .............................................................................................. 106
ILUSTRACIÓN 26. CLASE APPVIEW CONNECTION ...................................................................... 108
ILUSTRACIÓN 27. CLASE DATALOGICSYSTEM ........................................................................... 110
ILUSTRACIÓN 28. CLASE JPANELMENU ...................................................................................... 113

8
ILUSTRACIÓN 29. CLASE JPRINCIPALAPP................................................................................... 114
ILUSTRACIÓN 30. CLASE JROOTFRAME ...................................................................................... 116
ILUSTRACIÓN 31. CLASE OSVALIDATOR ..................................................................................... 118
ILUSTRACIÓN 32. CLASE BASESENTENCE .................................................................................. 120
ILUSTRACIÓN 33. CLASE SESSION ................................................................................................ 122
ILUSTRACIÓN 34. CLASE BASICEXCEPTION ............................................................................... 124
ILUSTRACIÓN 35. CLASE LOCALERESOURCES .......................................................................... 125
ILUSTRACIÓN 36. CLASE SAVEPROVIDER................................................................................... 127
ILUSTRACIÓN 37. CLASE PRODUCTSPANEL ............................................................................... 128
ILUSTRACIÓN 38. CLASE PRODUCTSEDITOR ............................................................................. 131
ILUSTRACIÓN 39. CLASE DIRTYMANAGER .................................................................................. 133
ILUSTRACIÓN 40. CLASE PRODUCTFILTER ................................................................................. 135
ILUSTRACIÓN 41. CLASE DATALOGICRECEIPTS ........................................................................ 137
ILUSTRACIÓN 42. DIAGRAMA DE CASOS DE USO – NIVEL 0: DISGREGACIÓN DE PRODUCTO
......................................................................................................................148
ILUSTRACIÓN 43. DIAGRAMA DE CASOS DE USO - NIVEL 1: DISGREGACIÓN DE PRODUCTO
......................................................................................................................148
ILUSTRACIÓN 44. DIAGRAMA DE ACTIVIDADES: DISGREGACIÓN DE PRODUCTO ................. 150
ILUSTRACIÓN 45. MODELO RELACIONAL: DISGREGACIÓN DE PRODUCTO ........................... 151
ILUSTRACIÓN 46. MOCKUP DE DISGREGACIÓN DE PRODUCTO .............................................. 151
ILUSTRACIÓN 47. MOCKUP DE BÚSQUEDA DE PRODUCTO....................................................... 152
ILUSTRACIÓN 48. CLASE PRODUCTSBUNDLEINFO ................................................................... 153
ILUSTRACIÓN 49. INTERFAZ PARA AGREGAR UN PRODUCTO A DISGREGAR ......................... 156
ILUSTRACIÓN 50. INTERFAZ DE BÚSQUEDA DE PRODUCTO ..................................................... 156
ILUSTRACIÓN 51. DIAGRAMA DE CASOS DE USO - NIVEL 0: SINCRONIZACIÓN CON
WOOCOMMERCE ...................................................................................................................... 162
ILUSTRACIÓN 52. DIAGRAMA DE CASOS DE USO - NIVEL 1: SINCRONIZACIÓN CON
WOOCOMMERCE ...................................................................................................................... 163
ILUSTRACIÓN 53. DIAGRAMA DE ACTIVIDADES: SINCRONIZACIÓN CON W OOCOMMERCE 164
ILUSTRACIÓN 54. MODELO RELACIONAL: SINCRONIZACIÓN CON W OOCOMMERCE .......... 165

9
ILUSTRACIÓN 55. DIAGRAMA DE DESPLIEGUE ............................................................................ 166
ILUSTRACIÓN 56. MOCKUP DE ATRIBUTOS PARA E-COMMERCE ............................................ 167
ILUSTRACIÓN 57. MOCKUP PARA MARCAR UN PRODUCTO COMO EN VENTA VIRTUAL ....... 167
ILUSTRACIÓN 58. CLASE APICOLLECTION ................................................................................. 168
ILUSTRACIÓN 59. CLASE PRODUCTAPI .................................................................... 170
ILUSTRACIÓN 60. INTERFAZ PARA MARCAR UN PRODUCTO COMO EN VENTA VIRTUAL...... 178
ILUSTRACIÓN 61. INTERFAZ DE ATRIBUTOS PARA E-COMMERCE ........................................... 179
ILUSTRACIÓN 62. DIAGRAMA DE CASO DE USO – NIVEL 0: OCTOPOS APP .......................... 185
ILUSTRACIÓN 63. DIAGRAMA DE CASO DE USO – NIVEL 1 : OCTOPOS APP ......................... 185
ILUSTRACIÓN 64. MOCKUP LISTADO DE MESAS: OCTOPOS APP .......................................... 186
ILUSTRACIÓN 65. MOCKUP LISTADO DE CATEGORÍAS: OCTOPOS APP ............................... 187
ILUSTRACIÓN 66. MOCKUP LISTADO DE PRODUCTOS: OCTOPOS APP ................................. 188
ILUSTRACIÓN 67. MOCKUP FINALIZACIÓN DE PEDIDO: OCTOPOS APP ................................. 189
ILUSTRACIÓN 68. USUARIOS DE LA APLICACIÓN ........................................................................ 203
ILUSTRACIÓN 69. LUGARES DEL RESTAURANTE ........................................................................ 204
ILUSTRACIÓN 70. PEDIDO ............................................................................................................... 205
ILUSTRACIÓN 71. CATEGORÍAS DE PRODUCTOS........................................................................ 206
ILUSTRACIÓN 72. SUB CATEGORÍAS DE PRODUCTOS ............................................................... 207
ILUSTRACIÓN 73. PRODUCTOS ...................................................................................................... 208
ILUSTRACIÓN 74. COMENZAR UN NUEVO PROYECTO EN NETBEANS ..................................... 216
ILUSTRACIÓN 75. NOMBRE Y LOCALIZACIÓN (NETBEANS) .......................................... 217
ILUSTRACIÓN 76. AÑADIR EL CÓDIGO DE UNICENTA OPOS..................................................... 218
ILUSTRACIÓN 77. INCLUIR/EXCLUIR ARCHIVOS .......................................................................... 219
ILUSTRACIÓN 78. INCLUIR/EXCLUIR ARCHIVOS .......................................................................... 220
ILUSTRACIÓN 79. AÑADIENDO LIBRERÍAS ................................................................................... 221
ILUSTRACIÓN 80. SELECCIONE 'AÑADIR JAR/CARPETAS' ........................................... 222
ILUSTRACIÓN 81. CONFIGURE LA CLASE PRINCIPAL ................................................................. 223
ILUSTRACIÓN 82. MODELO RELACIONAL PARTE 1 ...................................................... 224
ILUSTRACIÓN 83. MODELO RELACIONAL PARTE 2 ...................................................... 225
ILUSTRACIÓN 84. MODELO RELACIONAL PARTE 3 ...................................................... 226

10
ILUSTRACIÓN 85. MODELO RELACIONAL PARTE 4 ...................................................... 227
ILUSTRACIÓN 86. MODELO RELACIONAL PARTE 5 ...................................................... 228
ILUSTRACIÓN 87. MODELO RELACIONAL PARTE 6 ...................................................... 229
ILUSTRACIÓN 88. MODELO RELACIONAL PARTE 7 ...................................................... 230
ILUSTRACIÓN 89. MODELO RELACIONAL PARTE 9 ...................................................... 231
ILUSTRACIÓN 90. ACTA DE REUNION NRO. 1 ............................................................. 232
ILUSTRACIÓN 91. ACTA DE REUNION NRO. 2 ............................................................. 233
ILUSTRACIÓN 92. CARTA DE SATISFACCIÓN ............................................................................... 234
ILUSTRACIÓN 93. RUT ALMACEN TIENDA LOS CHIKOS ............................................................ 235

LISTA DE TABLAS

TABLA 1. DEFINICIÓN DE REQUISITO 3: DISGREGACIÓN DE PRODUCTO .................................. 53


TABLA 2. DEFINICIÓN DE REQUISITO 1: SINCRONIZACIÓN CON W OOCOMMERCE ................. 55
TABLA 3. DEFINICIÓN DE REQUISITO 8: OCTOPOS APP .............................................................. 57
TABLA 4. TABLAS DE LA BASE DE DATOS ........................................................................................ 79
TABLA 5. PONDERACIÓN DE REQUISITOS: DISGREGACIÓN DE PRODUCTOS ....................... 144
TABLA 6. DEFINICIÓN DE REQUISITO 1: DISGREGACIÓN DE PRODUCTO ............................... 145
TABLA 7. DEFINICIÓN DE REQUISITO 2: DISGREGACIÓN DE PRODUCTO ............................... 145
TABLA 8. DEFINICIÓN DE REQUISITO 3: DISGREGACIÓN DE PRODUCTO ............................... 146
TABLA 9. DEFINICIÓN DE REQUISITO 4: DISGREGACIÓN DE PRODUCTO ............................... 146
TABLA 10. DEFINICIÓN DE REQUISITO 5: DISGREGACIÓN DE PRODUCTO ............................ 146
TABLA 11. DEFINICIÓN DE REQUISITO 6: DISGREGACIÓN DE PRODUCTO ............................ 147
TABLA 12. PONDERACIÓN DE REQUISITOS: SINCRONIZACIÓN CON W OOCOMMERCE....... 158
TABLA 13. DEFINICIÓN DE REQUISITO 1: SINCRONIZACIÓN CON W OOCOMMERCE ........... 159
TABLA 14. DEFINICIÓN DE REQUISITO 2: SINCRONIZACIÓN CON W OOCOMMERCE ........... 159
TABLA 15. DEFINICIÓN DE REQUISITO 3: SINCRONIZACIÓN CON W OOCOMMERCE ........... 160
TABLA 16. DEFINICIÓN DE REQUISITO 4: SINCRONIZACIÓN CON W OOCOMMERCE ........... 160
TABLA 17. DEFINICIÓN DE REQUISITO 5: SINCRONIZACIÓN CON W OOCOMMERCE ........... 160
TABLA 18. CASOS DE PRUEBA: SINCRONIZACIÓN ..................................................................... 177
TABLA 19. REGISTRO DE BUGS: SINCRONIZACIÓN .................................................................... 178

11
TABLA 20. PONDERACIÓN DE REQUISITOS: OCTOPOS APP ...................................... 181
TABLA 21. DEFINICIÓN DE REQUISITO 1: OCTOPOS APP ......................................................... 182
TABLA 22. DEFINICIÓN DE REQUISITO 2: OCTOPOS APP ......................................................... 182
TABLA 23. DEFINICIÓN DE REQUISITO 3: OCTOPOS APP ......................................................... 182
TABLA 24. DEFINICIÓN DE REQUISITO 4: OCTOPOS APP ......................................................... 182
TABLA 25. DEFINICIÓN DE REQUISITO 5: OCTOPOS APP ......................................................... 183
TABLA 26. DEFINICIÓN DE REQUISITO 6: OCTOPOS APP ......................................................... 183
TABLA 27. DEFINICIÓN DE REQUISITO 7: OCTOPOS APP ......................................................... 183
TABLA 28. DEFINICIÓN DE REQUISITO 8: OCTOPOS APP ......................................................... 184
TABLA 29. DEFINICIÓN DE REQUISITO 9: OCTOPOS APP ......................................................... 184
TABLA 30. CASOS DE PRUEBA: OCTOPOS APP ....................................................... 201
TABLA 31. REGISTRO DE ERRORES: OCTOPOS APP ................................................ 201

12
RESUMEN

Unicenta es un software dedicado a suplir las necesidades encontradas en los


puntos de venta, se enfoca en los mercados minoristas tales como restaurantes,
hostelería, almacenes, supermercados; con base a exploraciones llevadas a cabo
en los diferentes sitios web especializados en dicho software, se evidenció la
necesidad de contar un una nueva rama, la cual, ofrece la posibilidad de
interactuar con plataformas de comercio electrónico y aplicaciones para móviles.

El proyecto incluye el desarrollo de tres funcionalidades hechas para dicho


software libre, con lo cual se crea un nuevo proyecto desprendido de Unicenta
denominado OctoPOS. Este nuevo proyecto está fundamentado bajo la filosofía
de software libre y fue desarrollado con la intención de divulgarlo, con el fin de
crear una comunidad a su alrededor.

Entre las nuevas funcionalidades desarrolladas, se añadió la sincronización de


productos en un sólo sentido con el plugin de wordpress, Woocommerce, el cual
proporciona una plataforma de comercio electrónico y por último se desarrolló una
aplicación para dispositivos móviles con sistema operativo android, que permite
realizar toma de pedidos.

Además de los desarrollos se realizó el proceso de ingeniería inversa del software


unicenta, creando así un documento donde se refleja el proceso realizado. Asi
mismo se escribió el estado del arte de unicenta, y por último se escribió un
documento que plasma la experiencia y todo lo aprendido durante todo el
desarrollo del proyecto.
Palabras clave: Unicenta; Software libre; Puntos de venta; E-commerce;
Woocommerce; NodeJs; Angular; Java.

13
ABSTRACT

Unicenta is a software dedicated to solve the needs found in the points of sale, it
focuses on retail markets such as restaurants, hotels, stores, supermarkets; Based
on explorations carried out in the different websites specialized in this software, the
need to have a new branch was demonstrated, which offers the possibility of
interacting with e-commerce platforms and mobile applications.

The project includes the development of three functionalities made for this
software, which creates a new project, forked from Unicenta called OctoPos. This
new project is based on the free software philosophy , and was developed with the
intention of divulge it, in order to create a community around it.

Among the new functionalities developed, synchronization of products in one


direction with the wordpress plugin, Woocommerce, was added, which provides an
e-commerce platform, and finally an application for mobile devices with an android
operating system was developed, which allows to perform taking orders.

In addition to the developments, the reverse engineering process of the Unicenta


software was carried out, thus creating a document that reflects the process. The
art state of Unicenta was also written, and finally a document that captures the
experience and everything learned during the whole development of the project
was written.

Keywords: Unicenta; Free software; Points of sale; Electronic commerce;


Woocommerce; NodeJs; Angular; Java.

14
INTRODUCCIÓN

Las comunidades de software libre se vienen dando desde la década de los 80's,
gracias a Richard Stallman, creador del movimiento de software libre, a partir de
ese momento, surgen infinidad de proyectos de esta índole alrededor del mundo,
uno de estos es Unicenta.

Unicenta oPOS es un software que comenzó en el 2010, nace como un proyecto


hobista por su fundador Jack Gerrard, ello después de la disolución de la
comunidad del proyecto Openbravo POS (proyecto antecesor de Unicenta). Este
proyecto nació por la necesidad de un software de bajo costo para puntos de
venta, debido a que los existentes en el mercado son demasiado costosos para
los pequeños negocios.

Lo que se logra durante la elaboración del proyecto, es desarrollar nuevas


funcionalidades para el comercio local, entre las cuales está la unión de Unicenta
con algún proyecto de software libre, que permita la creación de un e-commerce
sincronizado en una vía con el proyecto anteriormente mencionado.

Para lograr este objetivo es preciso crear una nueva rama de Unicenta alrededor
de la cual se cree una comunidad de desarrolladores, los cuales están interesados
en contribuir al proyecto de manera voluntaria.

Debido a que muchos desarrolladores buscan ser contribuyentes de este tipo de


comunidad, y deberán invertir en un principio tiempo en la curva de aprendizaje,
este documento espera ser apoyo para disminuir los tiempos de exploración.

La manera en la que se pretende acercar a la comunidad con el proyecto es a


través de la creación del mismo en las plataformas sourceforge, la cual le da una

15
posición libre al proyecto y en gitlab la cual facilitará el flujo de trabajo necesario
para poder contribuir a la comunidad.

16
1. PRIMERA PARTE: FORMULACIÓN DEL PROYECTO

1.1 SITUACIÓN PROBLEMÁTICA

Los directores del proyecto Unicenta no agregan las nuevas funcionalidades


desarrolladas por la comunidad, por tanto, su crecimiento no es potenciado con la
rapidez que la comunidad requiere. Además, no existe ningún proyecto que cuente
con todas las funcionalidades planteadas, en los objetivos del presente
documento. Adicionalmente, debido a que los proyectos de software libre no son
patrocinados directamente por una persona o empresa en particular, y en su
mayoría se distribuyen de forma gratuita, sin generar ganancia por el uso
particular de este, necesitan de una comunidad de personas que tengan un ideario
similar a las metas del proyecto, las cuales sean capaz de sostenerlo, ya sea con
su conocimiento y/o tiempo.

17
1. 2 JUSTIFICACIÓN

Las motivaciones que suscita el desarrollo del proyecto, atienden a razones de


interés general de la comunidad de software libre, es decir, la actual rama de
Unicenta no cuenta con algunas funcionalidades tales como la disgregación del
producto, la sincronización del programa con un comercio electrónico y el
desarrollo de una aplicación para dispositivos móviles, además, no posee un canal
de contribución directa la cual facilite la creación de una comunidad que soporte e
impulse el desarrollo del proyecto.

La oportunidad que se resalta en mayor medida en el desarrollo del proyecto, es la


posibilidad de proporcionar a las empresas una herramienta con funcionalidades
necesarias en la actualidad, distribuida bajo la licencia GPL V3, la cual brinda total
libertad a los usuarios, permitiendo así la conformación de una comunidad
alrededor del proyecto, la cual permita el crecimiento del mismo para de esta
manera realizar un aporte mayor al crecimiento del proyecto.

El proyecto cuenta con una característica novedosa dentro de la comunidad de la


Universidad Católica de Pereira, se refiere a que es el primer proyecto que
contribuirá a las comunidades de software libre, a través del mejoramiento y
distribución de un proyecto que es desarrollado bajo la filosofía de software libre y
por ende respeta las libertades de los usuarios.

El propósito del proyecto es apoyar el crecimiento de pequeños negocios


dedicados al retail, restaurantes, cafés y todo tipo de negocios que vendan
productos al detal, y de esta forma, impulsar el crecimiento de las pymes mediante
un proyecto cuya filosofía se enfoca en el usuario, sus libertades y el crecimiento
social a través de la creación de conocimiento y herramientas de libre distribución.

18
1.3 OBJETIVOS

1.3.1 Objetivo General

Contribuir a la comunidad de software libre Unicenta, a través de la creación de


una branch que permita la gestión de un software de comercio electrónico y
atención a las mesas

1.3.2 Objetivos Específicos

● Crear un documento con el estado del arte de Unicenta.

● Documentar el proceso de Ingeniería inversa al Software UnIcenta oPOS.

● Adaptar el módulo de disgregación de productos.

● Desarrollar la sincronización de Unicenta oPOS con un proyecto de


creación de ecommerce.

● Programar un módulo para pedidos a través de dispositivos móviles


android.

● Escribir un artículo publicable con lo aprendido a través de su desarrollo.

19
2. SEGUNDA PARTE: MARCO CONTEXTUAL

El proyecto se desarrolló teniendo como marco el sector de ventas al detalle, al


ser un derivado del software para puntos de venta (POS) Unicenta oPos, el cual
se dedica a suplir las necesidades de los pequeños negocios dedicados al sector
de venta minorista. Unicenta cuenta con más de 1’000.000 de descargas y es una
de las soluciones POS, más usadas en todo el mundo.

Además, gracias a la nueva funcionalidad agregada a Unicenta oPos, la cual


consiste en la sincronización con woocommerce, el proyecto incursiona en el
mundo del ecommerce, siendo apoyo para facilitar los procesos de gestión de
productos. Cabe mencionar que woocommerce cuenta con más de 53,769,700 [1]
de descargas, siendo así el plugin más usado como plataforma para llevar a cabo
los ecommerce; de este mismo modo, woocommerce soporta alrededor del 28%
[1] de todas las tiendas virtuales existentes en internet.

20
3. TERCERA PARTE: MARCO TEÓRICO

3.1 ANTECEDENTES

Unicenta es un proyecto derivado del software OpenBravo Pos el cual es


propiedad de la compañia OpenBravo, este proyecto comenzó siendo software
libre y como una comunidad, pero al pasar el tiempo fue privatizado y explotado de
forma comercial por la compañía; debido a esto surgieron derivados como lo es
Unicenta. Así como Unicenta es un proyecto derivado, existen otros mas que
tambien son derivados de OpenBravo, pero además, gracias a la gran acogida de
Unicenta por parte de la comunidad y a la falta de integración de las nuevas
funcionalidades aportadas por ésta al proyecto, han ido surgiendo otros proyectos
derivados de Unicenta. A continuación se mostrará un breve lista de estos
proyectos derivados, tanto de Unicenta como de OpenBravo, cada uno de los
proyectos tendra una imagen del software, la licencia bajo la cual se distribuye el
proyecto y una breve descripción.

Openbravo Java POS

Descripción: Openbravo POS fue creado en 2008 por Adrián Romero, es un punto
de venta diseñado para pantallas táctiles, soporta impresoras de tickets, pantalla
de cliente y lector de códigos de barras. Es multiusuario a la hora de proveer los
permisos para agregar productos, mostrar reportes y graficos [2]. Además, este es
el proyecto base de Unicenta y de muchos otros puntos de venta. En la ilustración
1 se puede apreciar una captura de pantalla del inicio de OpenBravo.

Licencia: GNU General Public License version 3.0 (GPLv3)

21
Ilustración 1. OpenBravo Pos

Fuente: https://sourceforge.net/projects/openbravopos/

PROYECTOS DERIVADOS DE OPENBRAVO:

Maia POS:

Descripción: Este es un proyecto derivado de OpenBravo POS desarrollado en el


año 2013 por la empresa Mexicana Sistemas del Golfo. Este proyecto realizó
algunas modificaciones al código base, agregando nuevas características, algunas
de las cuales son: idioma español y moneda mexicana por defecto, adicionalmente
se le hicieron mejoras al código para mejorar la gestión de la base de datos, se le
añadieron bibliotecas de java para mejorar el soporte de nuevas impresoras de

22
tickets, lectores de código de barras, básculas, etc. También se rediseñó la
interfaz gráfica, se mejoró la usabilidad, se añadieron validaciones para evitar
vender productos que no están en existencia, entre otras [3].En la ilustración 2 se
puede apreciar una captura de pantalla del inicio de Maia POS.

Licencia: GNU General Public License version 3.0 (GPLv3)

Ilustración 2. Maia Pos

Fuente: https://sourceforge.net/projects/maiapos/

Nord POS:

Descripción: Nord POS es un proyecto que toma como código base el de


OpenBravo POS, fue desarrollado por Andrey Svininykh en el año 2014, y es de
origen Kazajo. A diferencia con OpenBravo y sus otras derivaciones, Nord POS
fue desarrollado con soporte web y con compatibilidad para dispositivos móviles,
debido a esto Nord POS posee una interfaz gráfica diferente a la de OpenBravo

23
POS y brinda mayor funcionalidad a los usuarios. En la ilustración 3 se puede
apreciar una captura de pantalla de la toma de pedidos de Nord POS .

Licencia: Apache License V2.0, GNU General Public License version 3.0 (GPLv3)

Ilustración 3. Nord Pos

Fuente: https://sourceforge.net/projects/nordpos/

MinPOS:

Descripción: Este es uno de los proyectos derivados de OpenBravo POS más


recientes, fue desarrollado Minh Bang Chu en el año 2017, es de origen
vietnamita, aunque, su código tenga origen en OpenBravo, MinPOS tiene grandes

24
modificaciones y nuevas características, una de estas es el desarrollo de una
aplicación móvil para la toma de pedidos, aunque pretenden seguir desarrollando
funcionalidades para esta aplicación. En la ilustración 4 se puede apreciar una
captura de pantalla del inicio de MinPOS.

Licencia: GNU General Public License version 3.0 (GPLv3)

Ilustración 4. MinPOS

Fuente: https://sourceforge.net/projects/minpos/

PROYECTOS DERIVADOS DE UNICENTA:

RealComputer Pos:

Descripción: Es un proyecto derivado de Unicenta, publicado en el año 2016 por


Charles Requena, esta nueva rama es de origen peruano y basada en la versión
3.81 de Unicenta. Este proyecto realizó cambios en la interfaz gráfica, añadió

25
atajos de teclado, e hizo modificaciones en los permisos del rol empleado. En la
ilustración 5 se puede apreciar una captura de pantalla del inicio de RealComputer
POS.

Licencia: Creative Commons Attribution License

Ilustración 5. RealComputer Pos

Fuente: https://sourceforge.net/projects/realcomputer-pos/

Streamline POS:

Descripción: Este proyecto es una bifurcación de Unicenta, fue creado en el año


2016 por Chris Williams, es de origen estadounidense. El proyecto se enfoca en
dar soporte a la moneda americana y a una serie de tecnologías externas como lo
son la integración con tarjeta chip de tecnología EMV, e integración con
Woocommerce entre otras tecnologías. En la ilustración 6 se puede apreciar una
captura de pantalla del inicio de Streamline POS.

26
Licencia: GNU General Public License version 3.0 (GPLv3)

Ilustración 6. Streamline POS

Fuente: https://sourceforge.net/projects/streamline-pos/

Chromis POS:

Descripción: Este proyecto se basa en Unicenta, fue creado por John Lewis en el
año 2012, y es de origen Inglés. Este proyecto fue creado básicamente porque
John Lewis realizaba nuevas funcionalidades al código fuente de Unicenta las
cuales no eran incluidas en las nuevas versiones, así que Lewis decidió comenzar
su propio proyecto y agregó las nuevas funcionalidades desarrolladas por el, cabe
resaltar que la funcionalidad más importante en este proyecto y por la cual surgió,
es el módulo para la pantalla de la cocina. En la ilustración 7 se puede apreciar
una captura de pantalla del inicio de Chromis POS.

27
Licencia: GNU General Public License version 3.0 (GPLv3)

Ilustración 7. Chromis POS

Fuente: http://chromis.co.uk/chromispos/

28
3.2 CONCEPTOS TEÓRICOS

3.2.1 Conceptos de software.

3.2.1.1 Software libre:

Es aquel software que no vulnera las libertades básicas de un usuario, las cuales
son [4] :

● Libertad 0: La libertad de ejecutar el programa sea cual sea nuestro


propósito.
● Libertad 1: La libertad de estudiar el código del programa y poderlo adaptar
a las necesidades específicas del usuario, el código abierto es un requisito
fundamental para esto.
● Libertad 2: Es la libertad de redistribuir el código ya sea de forma gratuita o
paga y además también se refiere a la libertad de poder ayudar al prójimo.
● Libertad 3: Es la libertad de modificar el programa y poder redistribuir el
código con el fin de ayudar a la comunidad.

3.2.1.2 Definiciones necesarias en una comunidad de software libre:

● Comunidad: Aquel grupo de individuos que poseen una causa común, en el


caso de la comunidad de un proyecto, son todos aquellos interesados en el
mismo [5].

● Líder : Es la persona o grupos de personas, las cuales llevan el mando del


proyecto y por ende son los que toman las decisiones importantes dentro
del mismo, tales como las características, lanzamientos entre otras [6].

● Mantenedores: Son aquellas personas encargadas de ciertas partes del

29
proyecto, las cuales fueron delegadas con anterioridad por el líder [6].

● Comprometedores: Son un grupo de personas las cuales ya han contribuido


al proyecto y llevan un recorrido dentro de él, lo cual genera la confianza
suficiente para que, el código de estas personas no deba ser revisado por
un mantenedor, sino que pueda ser publicado directamente por el
comprometedor [6].

● Colaboradores: Son las personas que contribuyen al proyecto de alguna


manera ya sea con código, documentación o cualquier otro tipo de aporte.
Las contribuciones realizadas por estas personas deben ser revisadas por
un comprometedor o un mantenedor [6].

● Usuarios: Este es el grupo más importante de un proyecto, ya que estos


son los que usan el producto final y sin ellos no tendría ningún sentido el
proyecto, además juegan un rol muy importante el cual consiste en dar
informe sobre errores, petición de mejoras, entre otras [6].

● Revisar después de comprometer: Es una política de compromiso, la cual


requiere que todas las contribuciones sean revisadas antes de ser
publicadas, con el fin de evitar errores y mejorar la calidad del producto final
[5].

3.2.1.3 REST:

Según Fielding, REST es una arquitectura de software desarrollada a partir de


varias arquitecturas de red, que combinada con algunas restricciones adicionales
define una interface de conexión uniforme. Esta arquitectura se enfatiza en la
escalabilidad de los componentes, generalidad de las interfaces y un desarrollo
independiente de componentes. Además intenta minimizar la latencia y la

30
comunicación de la red, al mismo tiempo que maximiza la independencia y la
escalabilidad de las implementaciones de componentes. Esto se logra al colocar
restricciones en la semántica del conector, donde otros estilos se han centrado en
la semántica de los componentes [7].

3.2.1.5 Esquema de autenticación básica:

Este esquema, es definido en el RFC 2617 como un esquema de autenticación


básico, basado en que el usuario debe identificarse a través de un usuario y una
contraseña para cada dominio, en donde el servidor compara la igualdad de estos
parámetros con los almacenados en él, por tanto el servidor sólo procesa las
peticiones si pudo realizar la autentificación del usuario, es de aclarar que este
esquema de autentificación no es seguro, debido a que el nombre de usuario y la
contraseña viajan sin encriptar por la red [8].

3.2.1.6 Express:

Express es un marco de trabajo web minimalista de Node.js, el cual extiende las


capacidades de éste, dándole funcionalidades claves para el manejo de las
peticiones web, permitiendo así desarrollar un web server en pocas líneas de
código; con base a su ejecución, se ejecuta sobre la misma plataforma de node.js,
lo cual lo hace más fácil de configurar implementar y controlar, una de las
funcionalidades que agrega Express a Nodejs es por ejemplo, incluir cookies y
cabeceras HTTP, de forma más rápida y fácil [9][10].

3.2.1.7 Gson:

Es una librería de java usada para convertir los objetos java en su representación
JSON y viceversa. Una de las ventajas de Gson, sobre otros proyectos abiertos,
es que no usa anotaciones en las clases Java, sobre las cuales desea realizar las

31
conversiones, lo cual permite realizar las conversiones sin necesidad de tener
acceso al código fuente de la clase, además la mayoría no tiene un soporte
completo para las clases genéricas de java [11].

3.2.1.8 MySQL:

MySQL es un sistema de administración de base de datos, sus bases de datos


son relacionales. Además, es software de código abierto, el cual tiene diferentes
proyectos uno de estos es “MySQL database server”, el cual es rápido, confiable,
escalable y fácil de usar, lo que lo convierte en una opción perfecta para ser usado
en un sistema de información [12].

3.2.1.9 NPM:

Node package manager, es el gestor de paquetes por defecto de Node.js, el cual


contiene más de 600,000 paquetes dentro de su repositorio y además cuenta con
aproximadamente 3 billones de descargas por semana [13].

3.2.1.10 Package manager:

Un gestionador de paquetes, es una herramienta usada para mejorar el


rendimiento a la hora de instalar, actualizar y remover paquetes de una máquina
dentro de un proyecto. La mayoría de gestionadores, instalan automáticamente los
paquetes requeridos para que un paquete funcione, esto es llamada resolución de
dependencias lo hace gracias a que un gestionador de paquetes reúne
información acerca de los paquetes disponibles, dentro de un repositorio de
paquetes [14][15].

3.2.1.11 UML:

32
El lenguaje unificado para construcción de modelos según el “Object Modeling
Group” (OMG) es: “Un lenguaje que permite especificar, visualizar y construir los
artefactos de los sistemas de software. así como para el modelado de negocios y
otros sistemas no software”. Este lenguaje de modelado fue desarrollado a
petición del OMG por Booch, Rumbaugh y Jacobson en 1997 [16].

3.2.2 Conceptos de telecomunicaciones.

3.2.2.1 UUID:

Los UUID (Universally unique identifier) son una cadena de 16 octetos, la cual es
un identificador único en el espacio tiempo, con respecto al espacio de todos los
UUID. Los UUID tiene múltiples usos desde identificar objetos persistentes en una
red, hasta identificar objetos de corta vida. La representación interna de un UUID
es una secuencia de bits descrita en la sección 4 del rfc 4122 [17][18].

3.2.2.2 BASE64:

Según el RFC 4648 la codificación en base 64, fue diseñado para la


representación arbitraria de una secuencia de octetos de forma que se usen letras
tanto en mayúscula como en minúscula, pero que pueda ser leída por un humano.
Esta codificación convierte un archivo a una cadena de caracteres, los cuales son
representados por los caracteres de 0 a 64 del código ASCII, esta codificación usa
un carácter adicional “=” el cual es usado para relleno [19][20].

3.2.2.3 URI:

Como es definido en el RFC 3986, un URI (Identificador de Recurso Uniforme) es


un identificador el cual permite la identificación uniforme de recursos, a través de
un conjunto extensible de esquemas de nombres definidos por separado, este tipo

33
de identificación, permite identificar cualquier tipo de recursos sin ninguna
limitación, las reglas de sintaxis pueden ser encontradas en la sección 3 del RFC
3986 [21].

3.2.2.4 Identificador:

Un identificador es el atributo de un objeto el cual incorpora toda la información


necesaria, para distinguir este objeto de cualquier otro objeto que habite dentro del
mismo espacio. Aunque se debe tener en cuenta, que un identificador en muchos
casos no define la identidad del objeto que se desea distinguir [21].

3.2.2.5 HTTP:

El protocolo de transferencia de hipertexto es definido en el RFC 2616 de la


siguiente manera: es un protocolo de petición/respuesta, el cual se ubica en la
capa de aplicación para sistemas de información distribuidos, colaborativos e
hipermedia. El protocolo HTTP ha sido usado por la iniciativa de información World
Wide Web desde 1990. La primera versión de HTTP fue un simple protocolo
encargado de transferir datos en bruto a través de Internet [22].

3.2.2.6 Conexión:

Es un circuito virtual ubicado en la capa de transporte, que permite establecer una


comunicación entre dos programas [22].

3.2.2.7 Cliente:

Es un programa que establece conexión con un servidor con el propósito de enviar


peticiones [22].

34
3.2.2.8 Servidor:

Es un programa aplicación que acepta peticiones para generar una respuesta,


cualquier programa puede ser cliente y servidor [22].

3.2.3 Conceptos web.

3.2.3.1 JSON:

JSON (JavaScript Object Notation), es un formato para la serialización de datos


estructurados. Las metas de diseño de JSON fueron ser minimalista, portable y
textual, también cabe resaltar que la notación de objetos de javascript permite
representar cuatro tipos de datos primitivos y dos tipos de datos estructurados.
Este es definido en “ECMAScript Programming Language Standard” en su tercera
edición [23][24].

3.2.3.2 Web server:

Equipo computacional, comúnmente de altas prestaciones, dedicado a ofrecer


servicios a los diferentes requerimientos vía redes y telecomunicaciones. Todo se
logra procesando peticiones HTTP, las cuales, en la mayoría de casos espera
respuestas. Un servidor web dentro de su lógica, implementa el protocolo HTTP,
administra los recursos web y proporciona capacidades administrativas de servidor
[9][25].

3.2.3.3 Backend service:

Como es descrito por Dayley, los backend services son todos aquellos servicios
que funcionan detrás del servidor, los cuales proporcionan los datos necesarios
para construir la respuesta que se enviará de vuelta a los clientes. Un ejemplo de

35
un backend service, es una base de datos, la cual almacena la información del
sistema; cuando el servidor recibe una petición de un cliente, en donde pide
ciertos datos, un proceso del backend trae la información de la base de datos le da
formato y devuelve la respuesta al cliente [9].

3.2.3.4 ECMAScript:

Como es definido en el documento “Especificación de lenguaje ECMAScript 2019”


por Terlson, Farias y Harlband, ECMAScript es un lenguaje de programación
orientado a objetos, el cual fue diseñado originalmente para ser utilizado como un
lenguaje de scripting, pero se ha utilizado ampliamente como un lenguaje de
programación de propósito general, su sintaxis se asemeja a la sintaxis de Java
pero a diferencia de ésta, la sintaxis de ECMAScript es un poco más relajada para
permitir que sirva como un lenguaje de scripting fácil de usar [26].

3.2.3.5 Hipertexto:

La palabra hipertexto fue acuñada por primera vez en el año de 1965 en el artículo
titulado “A File Structure for the Complex, the Changing, and the
Indeterminate” escrito por T. H. Nelson en donde definió teóricamente hipertexto
como: El cuerpo de un material escrito o pictórico interconectado de tal forma que
sus contenidos e interrelaciones puedan contener anotaciones, adiciones y notas
de pie de página de las personas que hayan estudiado dicho material. Además
resaltaba que si este tipo de estructura de archivo era bien diseñada y
administrada tendría un gran potencial para la educación, gracias a que
aumentaba el rango de opciones para los estudiantes [27][28].

3.2.4 Plataformas tecnológicas.

36
3.2.4.1 Source forge:

Es el proveedor almacenamiento de proyectos de código abierto más antiguo, fue


lanzado en 1999, aloja más de 500000 proyectos y tiene más de 4 millones de
descargas diarias [29].

3.2.4.2 JAVA:

Java es un lenguaje de programación desarrollado por Sun Microsystems. Java


fue presentado en la segunda mitad del año 1995 y desde entonces se ha
convertido en un lenguaje de programación muy popular. Java es un lenguaje muy
valorado porque los programas Java se pueden ejecutar en diversas plataformas
con sistemas operativos como Windows, Mac OS,Linux o Solaris [30].

3.2.4.3 Node.js:

Node.js es un framework de desarrollo basado en el motor de javascript V8 de


google, y es usado para desarrollar aplicaciones de red escalables, gracias a que
logra un alto rendimiento a través de E/S sin bloqueo y un bucle de eventos de un
sólo hilo. El código de nodejs está escrito en javascript y es compilado en el motor
V8, de esta manera, se puede escribir el código tanto del servidor como del cliente
en javascript, del lado del servidor se puede escribir desde un servidor web hasta
los scripts necesarios para soportar el servidor [9][31][32].

3.2.4.4 POSTMAN:

Es un ambiente de desarrollo de APIs, usado por los desarrolladores para realizar


pruebas de funcionamiento de sus propias APIs y de esta forma agilizar sus
procesos de desarrollo y prueba. Algunas de las funcionalidades de Postman son:
enviar una petición HTTP, poder escribir pruebas en la plataforma, crear y correr

37
una colección de peticiones o pruebas, entre otras. Lo que hace de postman una
herramienta esencial a la hora de desarrollo APIs [33].

3.2.4.5 TypeScript:

TypeScript fue creado con el propósito de satisfacer principalmente las


necesidades de los equipos de desarrollo de javascript, gracias a que typescript
permite la definición de interfaces entre componentes y usar la ya conocida
programación orientada a objetos, permite dar orden y estructura a los proyectos
de javascript, además permite a los programadores de JavaScript utilizar prácticas
y herramientas de desarrollo altamente productivas: verificación estática,
navegación basada en símbolos, finalización de enunciados y refactorización de
código. Debido a que TypeScript no es más que un mejoramiento sintáctico de
javascript, todos los proyectos existentes de javascript también son un proyecto de
TypeScript [34][35].

La sintaxis de TypeScript incluye todas las características de ECMAScript 2015,


incluidas las clases y los módulos, además proporciona la capacidad de traducir
estas características a código compatible con ECMAScript 3 o 5.

3.2.4.6 PhoneGap:

PhoneGap es un framework de desarrollo que permite el desarrollo de


aplicaciones híbridas, se destaca su funcionalidad, Cabe resaltar que, las
aplicaciones generadas por phonegap no son aplicaciones nativas, aunque
phonegap da un gran soporte de compatibilidad con las plataformas móviles, lo
cual permite el desarrollo de la mayoría de funcionalidades posibles en una
plataforma móvil, en otras palabras phonegap proporciona un puente entre el
mundo de JavaScript y el mundo móvil, dando a JavaScript, acceso a las

38
capacidades del dispositivo como lo son: cámara, gps, información del dispositivo,
entre otras [36].

3.2.4.7 Apache server:

Apache HTTP Server Project, es un proyecto de software colaborativo que hace


parte de Apache Software Foundation, este proyecto es un servidor web el cual
fue lanzado al mercado por primera vez el primero de diciembre de 1995 y
además es de vital importancia para la Apache Software Foundation, debido a que
esta fue creada gracias a la formación del grupo de trabajo de apache server [37].

3.2.4.8 JavaScript:

JavaScript es un lenguaje de programación interpretado, es decir se va leyendo


cada línea en tiempo de ejecución. Este lenguaje posee capacidades para la
orientación a objetos, sin embargo, es un lenguaje bajamente tipado, lo cual puede
generar conflictos a la hora de operar variables llegado el caso en el que el
desarrollador pretenda operar variables de tipos totalmente diferentes como lo son
un number y un string, además, cabe resaltar que JavaScript tiene como datos
primitivos: number, string y boolean; adicionalmente soporta arreglos, fechas y
objetos de expresión regular [38][39].

3.2.4.9 Chrome V8:

Chrome V8 es el motor de JavaScript de google, éste está escrito en C++ y es de


código abierto; este motor es usado en proyectos como el navegador de google y
Node.js, este motor implementa ECMAScript y puede ser ejecutado en sistemas
operativos como Windows 7 en adelante, macOS 10 y sistemas linux. Su código
puede ser incrustado en cualquier proyecto de C++, o puede ser ejecutado de
manera independiente [40].

39
3.2.4.10 Android:

Android es un sistema operativo móvil basado en el kernel de linux, este es


actualmente desarrollado por Google. Principalmente es diseñado para el
funcionamiento en dispositivos móviles, con una pantalla táctil como lo son una
tablet o un smartphone. Actualmente, Android es un sistema operativo de código
abierto capaz de manejar toda la electrónica de un dispositivo móvil, gracias a que
es abierto cualquier persona puede tomar este código para desarrollar su propio
sistema operativo [41][42][43].

3.2.4.11 Base de datos :

Una base de datos puede ser definida como todo conjunto de datos ordenados y
relacionados entre sí. Sin embargo un base datos debe cumplir con las siguientes
propiedades como lo expresa Elmasri y Navathe:

- Una base de datos debe representar algún aspecto del mundo real.
- Una base de datos es un conjunto de datos lógicamente coherente y con
significado, es decir si tengo una colección de datos aleatorios no lo puedo
llamar base de datos.
- Una base de datos es diseñada y desarrollada con un propósito específico.

En pocas palabras una base de datos debe tener un grupo de usuarios destinados
a aprovechar los recursos que esta puede proporcionar [44].

3.2.4.12 DBMS:

Como es definido por Elmasri y Navathe, un sistema de gestión de bases de datos


(DBMS), es una colección de programas que permiten al usuario la creación y el

40
mantenimiento de una base de datos. Los DBMS facilitan el proceso de definir,
construir, manipular y compartir bases de datos entre varios usuarios [44].

3.2.4.13 Query:

El término query o consulta es una jerga usada para referirse a todo tipo de
interacción con una base de datos incluyendo la modificación de datos [44][45].

3.2.4.14 SQL:

El lenguaje estructurado de consultas o SQL, es un lenguaje de base de datos


diseñado para administrar datos en DBMS relacionales y originalmente basado en
álgebra relacional. Su alcance incluye consultas y actualizaciones de datos,
creación y modificación de esquemas y control de acceso a datos. Este fue
desarrollado por Donald D. Chamberlin y Raymond F. Boyce en la compañía IBM
a comienzos de los años 70’s, esta primera versión fue llamada SEQUEL [44][45].

41
4. CUARTA PARTE: MODELO TEÓRICO

4.1 PROTOTIPADO DE SOFTWARE

Como es definido por Sommerville “un prototipo es una versión inicial de un


sistema software que se utiliza para demostrar conceptos, probar opciones de
diseño y, en general, informarse más del problema y sus posibles soluciones. El
desarrollo rápido e iterativo del prototipo es esencial, de modo que los costes sean
controlados” [46] . Además, su objetivo principal, como lo expresa Pressman, es
“que el prototipo sirva como mecanismo para identificar los requerimientos del
software” [47].Igualmente, utilizando este paradigma de prototipado, como lo
expresan Kendall y Kendall, se reducen los tiempos entre la elicitación de los
requisitos y la entrega del sistema funcional [48].

Es de tener en cuenta, que existen diferentes clases de prototipos según Kendall y


Kendall, y estas son [48]:

● Prototipo corregido: Este prototipo es aquel que se desarrolla con el fin de


que sea funcional, sin tener en cuenta la eficiencia del algoritmo.

● Prototipo no funcional: Este es un modelo no funcional, su propósito es


probar algunos aspectos del diseño de la interfaz.

● Primer prototipo de una serie: Este es un modelo funcional del sistema, su


propósito principal es el de ser una prueba piloto del sistema.

● Prototipo de características seleccionadas: Este es un modelo funcional del


sistema,el cual debe incluir algunas de las características que debe tener el
sistema final.

42
Además, se debe considerar que un prototipo puede ser usado de distintas
maneras en un proceso de desarrollo de software, como lo expresa Sommerville, y
estas son [46] :

● En el proceso de ingeniería de requerimientos, un prototipo puede ayudar


en la obtención y validación de los requerimientos del sistema.

● En el proceso de diseño del sistema, se puede utilizar un prototipo para


explorar soluciones software particulares y para apoyar al diseño de las
interfaces de usuario.

● En el proceso de pruebas, se puede utilizar un prototipo para ejecutar


pruebas back-to-back con el sistema que se entregarán al cliente.

El paradigma de prototipos, cuenta con cinco fases (véase la ilustración 8) según


Pressmann, estas son [47]:

● Comunicación: Es esta fase el equipo se reúne para definir los objetivos e


identificar requerimientos.

● Plan rápido: Se planea una iteración para realizar el prototipo

● Modelado: Se modela el prototipo en forma de diseño rápido

● Construcción del prototipo: Se construye el prototipo

● Despliegue: Se entrega el prototipo y es evaluado por los participantes,


retroalimentando el equipo, con el fin de mejorar los requisitos

43
Ilustración 8. Paradigma de prototipos

Fuente: [47]

Como cualquier otro modelo de desarrollo posee sus ventajas y desventajas,


según Kendall y Kendall, estas son algunas de ellas [48]:

Ventajas:

● Es posible realizar modificaciones al sistema en etapas tempranas del


desarrollo.

● Existe la oportunidad de suspender el desarrollo de un sistema que no sea


funcional.

● Es posible desarrollar un sistema que satisfaga mejor las necesidades y


expectativas de los clientes.

Desventajas:

44
● El uso del paradigma de prototipos, puede ser difícil de manejar para
proyectos grandes.

● Tanto los usuarios como los analistas, puede adoptar un prototipo como si
fuera el desarrollo final, cuando el prototipo es deficiente y su propósito
nunca fue ser el sistema terminado.

4.2 MODELO DE CICLO DE VIDA EN ESPIRAL

Como lo expresa Pressman, este modelo, es un modelo evolutivo, que tiene el


potencial para hacer desarrollos rápidos, además, este es un enfoque realista para
el desarrollo de sistemas y de software a gran escala. También, es de tener en
cuenta que el modelo, usa los prototipos como mecanismo de reducción de
riesgos y permite aplicar el enfoque de hacer prototipos en cualquier etapa de la
evolución del producto [47]. Este, según Sommerville, es un proceso de desarrollo,
donde el proceso se representa como una espiral en la que cada vuelta de la
espiral incorpora las diferentes etapas en el proceso. Si se pasa de una vuelta de
la espiral a otra, se repiten todas las etapas del proceso [46].

Este modelo presenta varias fases de ciclo de vida (véase la ilustración 9), las
cuales son:

● Comunicación: En esta fase el equipo se reúne para plantear los objetivos


de la iteración.

● Planeación: Esta fase posee tres procesos, los cuales son:

○ Estimación: En esta subfase se realiza la estimación de tiempo y


costo de la iteración.

45
○ Programación: Se define el cronograma y los encargados de las
tareas.
○ Análisis de riesgos: Es una subfase muy importante dentro del
modelo, ya que permite identificar los riesgos por iteración, lo que
proporciona mayor control sobre los mismos y disminuye sus
probabilidades de ocurrencia.

● Modelado: En esta fase se realiza el análisis y el diseño del desarrollo de la


iteración.

● Construcción: Esta fase contempla el desarrollo del código y las pruebas


que se deben de realizar al mismo.

● Despliegue: Esta es la última fase del modelo, en esta fase se realiza la


entrega de la iteración y además, se realiza la retroalimentación por parte
del cliente y el equipo.

46
Ilustración 9. Modelo de espiral

Fuente: [47]

4.3. METODOLOGÍA PARA EL DESARROLLO INTEGRAL

Debido a que el proyecto presenta fases de desarrollo, es necesario adoptar


metodologías que faciliten la gestión del proceso del mismo, así pues, debido a la
naturaleza de los módulos y el tiempo que se tenía para el desarrollo, se optó por
realizar la combinación del modelo de desarrollo en espiral y el paradigma de
prototipado, combinación que permite un desarrollo ágil y una elicitación de
requisitos confiable. El resultado de esta combinación se especifica a
continuación.

Las fases usadas en el desarrollo de los módulos fueron los siguientes:

Planeación: en esta fase se planea el contenido de la iteración y el cronograma de


la misma, es de tener en cuenta, que en el caso específico del proyecto, cada una
de las iteraciones corresponde a un módulo.

Modelado: En esta fase se realiza el análisis y el diseño del desarrollo, debido a


que en esta fase se realiza la elicitación de requisitos, se usa el paradigma de
hacer prototipos para este objetivo. Los prototipos realizados son prototipos no
funcionales y realizados con una herramienta que facilita su desarrollo. Gracias a
que se usa el paradigma de prototipos la fase de modelado posee unas subfases,
las cuales son:

● Comunicación: Es esta fase el equipo se reúne para definir los objetivos e


identificar requerimientos.

● Plan rápido: Se planea una iteración para realizar el prototipo

47
● Modelado: Se modela el prototipo en forma de diseño rápido

● Construcción del prototipo: Se construye el prototipo

● Despliegue: Se entrega el prototipo y es evaluado por los participantes,


retroalimentando el equipo, con el fin de mejorar los requisitos

Ahora, ya teniendo los requisitos se realiza el proceso de diseño, haciendo un


diagrama de casos de uso y un modelo relacional de la base de datos.

Construcción: Esta fase pertenece a la codificación de los módulos y a la


realización de pruebas de los mismos. Para el desarrollo se usaron IDE’s como
Netbeans y VisualCode, cada uno de los cuales usado para la codificación en los
diferentes lenguajes usados en los módulos. Además, se realizaron algunas
pruebas unitarias a los módulos con el fin de verificar su funcionamiento.

48
5. RESULTADOS

En el desarrollo del estado del arte del proyecto Unicenta, se plasman sus
antecedentes, su historia y las oportunidades de trabajo que ha generado este
proyecto. Además, la importancia en el sector de ventas al por menor y los
proyectos que han surgido en base a Unicenta. Para profundizar en éste aspecto
es necesario consultar el ANEXO A: ESTADO DEL ARTE DE UNICENTA del
presente documento.

Siguiendo con el desarrollo de los objetivos, el proceso de ingeniería inversa del


proyecto fue una parte fundamental para lograr entender el funcionamiento de
unicenta, y de esta manera, desarrollar los módulos que se plantearon como
objetivos. Este proceso, se realizó en dos etapas principales: la primera, consistió
en el entendimiento de todo lo relacionado con la bases de datos del proyecto; la
segunda fase fue, el entendimiento del código y su funcionamiento. A
consecuencia, el resultado es un documento en el cual se describe todo el
proceso, allí se puede encontrar los diagramas de clases más importantes del
proyecto, una descripción de cada clase y fragmentos de código de las mismas,
un ejemplo de esto se puede observar a continuación:

Class SaveProvider:

Esta clase se encarga de almacenar las acciones de los botones guardar, agregar
y eliminar de cada una de las interfaces de gestión del sistema, su constructor es
polimorfo pero el constructor que se usa con más frecuencia es public
SaveProvider(SentenceExec sentupdate, SentenceExec sentinsert,
SentenceExec sentdelete), el cual recibe tres parámetros , de tipo
SentenceExec, cada uno de los cuales representa la acción que tomará uno de
los tres botones anteriormente mencionados. El diagrama de esta clase se puede
observar en la ilustración 10.

49
Ilustración 10. Clase SaveProvider

Fuente: elaboración propia

public class SaveProvider {

protected SentenceExec m_sentupdate;


protected SentenceExec m_sentinsert;
protected SentenceExec m_sentdelete;
/** Creates a new instance of SavePrSentence
* @param sentupdate
* @param sentdelete
* @param sentinsert */
public SaveProvider(SentenceExec sentupdate, SentenceExec
sentinsert, SentenceExec sentdelete) {
m_sentupdate = sentupdate;
m_sentinsert = sentinsert;
m_sentdelete = sentdelete;
}

50
Además el documento también posee el modelo relacional de la base de datos,
una tabla donde se describe cada una de las tablas y por último los scripts sql, con
una descripción de su función, que posee el proyecto. Para una mejor ilustración
de lo anteriormente mencionado, a continuación se puede apreciar un fragmento
del documento donde se observa el desarrollo de lo antes mencionado.

Script MySQL-create.sql

Este script es el encargado de crear las tablas de la base de datos por primera
vez, es decir, que si se desea adicionar otra tabla al proyecto, el query debería de
ir dentro de este archivo.

/* Header line. Object: applications. Script date: 27/08/2015


08:42:37. */
CREATE TABLE `applications` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`version` varchar(255) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

/* Header line. Object: attribute. Script date: 27/08/2015


08:42:37. */
CREATE TABLE `attribute` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

51
/* Header line. Object: attributeinstance. Script date:
27/08/2015 08:42:37. */
CREATE TABLE `attributeinstance` (
`id` varchar(255) NOT NULL,
`attributesetinstance_id` varchar(255) NOT NULL,
`attribute_id` varchar(255) NOT NULL,
`value` varchar(255) default NULL,
KEY `attinst_att` ( `attribute_id` ),
KEY `attinst_set` ( `attributesetinstance_id` ),
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

Si se desea conocer este documento a profundidad, diríjase al ANEXO B:


INGENIERÍA INVERSA DE UNICENTA de este escrito.

Asimismo para el módulo de disgregación de productos se llevó a cabo el proceso


de ingeniería de software en donde se realizó la elicitación de requisitos a través
de dos metodologías de elicitación, lluvia de ideas y prototipado, lo cual arrojó
como resultado una lista de requisitos los cuales fueron analizados y debidamente
diligenciados en un formato que facilitó este proceso, teniendo así los requisitos
del proyecto. Para ejemplificar esto, se puede observar en la tabla 1 uno de los
requisitos del módulo de disgregación de producto.

52
Tabla 1. Definición de requisito 3: Disgregación de producto

Fuente: elaboración propia

Después de haber realizado la elicitación, se continuó con el diseño de este


módulo, para lograr este propósito se realizó un diagrama relacional, con el fin de
diseñar las tablas de la base de datos necesarias para el funcionamiento del
módulo, este diagrama es ilustrado en la ilustración 11.

Ilustración 11. Modelo relacional: Disgregación de producto

Fuente: elaboración propia

Adicionalmente, en el diseño se realizó un diagrama de casos de uso, un


diagrama de actividades y los mockups del módulo. En la ilustración 12, se puede
apreciar uno de los diagramas realizados.

53
Ilustración 12. Diagrama de casos de uso: Disgregación de producto

Fuente: elaboración propia

Después de realizar el diseño, se llevó a cabo el desarrollo del módulo, éste se


realizó re utilizando gran parte del código existente en el proyecto, el resultado de
todo este proceso fue el módulo funcional, en la ilustración 13 se puede observar
la ilustración respecto a una de la interfaces de usuarios desarrolladas, que
demuestra el cumplimiento del objetivo.

54
Ilustración 13. Interfaz para agregar un producto a disgregar

Fuente: elaboración propia

Igualmente, para mayor profundización sobre el desarrollo del módulo puede


dirigirse al ANEXO C: DISGREGACIÓN DE PRODUCTO de este documento.

Del mismo modo, para el módulo de sincronización con Woocommerce se llevó a


cabo el proceso de ingeniería de software, en donde se realizó la elicitación de
requisitos de igual manera como se realizó en el módulo de disgregación de
productos, dando como resultado los requisitos del módulo. Para soportar lo
anteriormente descrito, se puede evidenciar con la tabla 2:

Tabla 2. Definición de requisito 1: Sincronización con Woocommerce

Fuente: elaboración propia

55
Después de realizar la elicitación, se continuó con el diseño de este módulo, para
lograr este propósito se realizó un modelo relacional, con el fin de diseñar las
tablas de la base de datos necesarias, para el funcionamiento del módulo, este
diagrama es ilustrado en la ilustración 14.

Ilustración 14. Modelo relacional: Sincronización con Woocommerce

Fuente: elaboración propia

También cabe resaltar que para el desarrollo de este módulo, se tomaron dos
decisiones importantes: la primera, apunta a la elección de la plataforma de
comercio electrónico para llevar a cabo la sincronización y la segunda, la elección
de la herramienta para realizar la conexión de Unicenta con el ecommerce. Luego
de un proceso de inspección se llegó a la decisión que se usaría el plugin de
Wordpress, Woocommerce, como plataforma de comercio electrónico y que se
desarrollaría una API en NodeJS que sirviera como intermediaria. En la ilustración
15 se puede apreciar el diagrama de despliegue.

56
Ilustración 15. Diagrama de arquitectura : Sincronización con Woocommerce

Fuente: elaboración propia

En el caso en el que se desee ahondar en este desarrollo, acuda al ANEXO D:


SINCRONIZACIÓN CON WOOCOMMERCE de este documento.

De igual forma, para el desarrollo de la aplicación móvil se llevó a cabo el proceso


de ingeniería de software, en donde se realizó la elicitación de requisitos de la
misma manera como se realizó en los módulos anteriores, dando como resultado
los requisitos del módulo. Para demostrar en la tabla 3 se hace alusión a uno de
los requisitos del módulo.

Tabla 3. Definición de requisito 8: Octopos App

57
Fuente: elaboración propia

Seguidamente de haber realizado la elicitación, se continuó con el diseño de la


aplicación, en donde se realizó diagrama de casos de uso y mockups. En la
ilustración 16 se puede apreciar uno de los mockups realizados para la aplicación.

Ilustración 16. Mockup listado de categorías: Octopos App

Fuente: elaboración propia

58
Después de haber realizado todo el análisis y el diseño, se realizó la codificación
de la aplicación en angular. En esta fase, se describieron fragmentos del código
desarrollado para la aplicación, a continuación se aprecia en la ilustración 17 un
pantallazo de la aplicación funcional.

Ilustración 17. Pedido de una mesa

Fuente: elaboración propia

Si se desea tener más conocimiento sobre este desarrollo por favor consulte el
ANEXO E: OCTOPOS APP de este documento.

59
Como ruta final en la consecución del presente proyecto, se construyó un artículo
con el fin de divulgar el proceso; en dicho documento se habla sobre los procesos
realizados y las lecciones aprendidas durante el desarrollo. Si desea leer el
artículo por favor diríjase al ANEXO F: ARTÍCULO PUBLICABLE del presente
documento.

Ya como proceso de finalización, OctoPOS fue implementado en el almacen


Tienda los chikos, ubicado en el municipio de Santa Rosa de Cabal, Risaralda,
con el fin de llevar a cabo, una validación del producto final con un cliente real.
Primeramente, se realizó una reunión con el cliente, explicando las
funcionalidades del software y sus beneficios, en esta reunión se concretó que se
instalaría el proyecto, pasado un mes de su instalación, se hizo otra reunión, la
cual tenía como fin conocer la opinión del cliente acerca del funcionamiento del
producto. Esta reunión dio resultados positivos, llevándose así buenas referencias
del proyecto. Si se desea ver las actas de reunión y la carta de satisfacción
enviada por el cliente, por favor diríjase al ANEXO I: ACTAS DE REUNIÓN Y
CARTA DE SATISFACCIÓN.

En el caso que se desee conocer el código desarrollado la puede encontrar en sus


respectivos repositorios. Los links de acceso a los repositorios son los siguientes:

- OctoPOS (Java): https://gitlab.com/amartinezh/octopos


- OctoPOS API (NodeJS): https://gitlab.com/ceul/octoposapi
- OctoPOS App (Angular): https://gitlab.com/ceul/octoposapp

60
6. CONCLUSIONES

● La planificación de un desarrollo de software es una parte esencial del


proyecto, ya que sin esta la tendencia a cometer errores se amplifica y
posiblemente el proyecto no llegue a un feliz término.

● El proceso de ingeniería inversa del software es largo y tedioso, por esto se


hace de vital importancia de implantar una adecuada técnica de
documentación y un código legible, más aún en un proyecto de software
libre, la cual tiene comunidades activas.

● Tomando en cuenta la poca experiencia que se tenía con el lenguaje de


programación TypeScript y la facilidad con la que se aprendió, se puede
concluir que este lenguaje se puede usar para proyectos en los cuales el
equipo de trabajo tenga poca experiencia desarrollando, debido a que su
curva de aprendizaje es muy corta y se puede lograr grandes desarrollos
con el lenguaje.

● En este momento la mayoría de plataformas de comercio electrónico


cuentan con un web service que actúa como interfaz con otros sistemas,
pero en especial el web service del plugin de wordpress, woocommerce,
está muy bien documentada, la integración de otros sistemas con esta
REST API es relativamente fácil, por tanto, si en un futuro se debería elegir
una plataforma de comercio electrónico, se escogería woocommerce, ya
que la integración sería “rápida” y además la plataforma como tal, es lo
suficientemente robusta para soportar un gran número de usuarios y
transacciones.

● Aunque el sector de sistemas de información, dedicados al retail en este


momento tiene demasiadas propuestas y desarrollos con recorrido en el

61
mercado, sigue siendo un sector con potencial, el cual requiere de
proyectos diferentes e innovadores que tomen en cuenta los nuevos
factores que la sociedad requiere.

● Openbravo POS y Unicenta POS, han tenido un gran impacto alrededor de


todo el mundo, como se puede apreciar en los antecedentes, los proyectos
derivados de los mencionados, son desarrollados en varias partes del
mundo, y la mayoría de estos proyectos aún siguen activos y con
descargas mensuales, lo cual muestra una comunidad activa, a la espera
de nuevos proyectos como OctoPOS.

62
7. RECOMENDACIONES

● La seguridad que posee la API en este momento es baja, así que este es
un punto a mejorar, por tanto, en este momento es recomendable usar una
conexión HTTPS para evitar ataques informáticos tales como el phishing.

● Para una mayor funcionalidad para el usuario, se recomienda migrar la


aplicación completa a la versión para dispositivos móviles.

● Gracias a que la mayoría de plataformas de comercio electrónico cuentan


con una REST API, la comunicación con estas se facilita, por tanto, el
desarrollo de sincronización con otras plataformas sería de gran utilidad
para el usuario y seria un gran factor diferenciador del resto de programas
dedicados al sector del retail.

● El siguiente objetivo a alcanzar con el proyecto, es la generación de una


comunidad, que lo respalde, la cual aumente su funcionalidad y uso.

● Debido a que el programa de escritorio es desarrollado en el lenguaje de


programación Java, la conexión a la base de datos se logra usando el
paquete JDBC, el cual lastimosamente a la fecha no tiene aún un buen
soporte del motor de base de datos MySql en su versión 8.0, por esto se
recomienda que a la hora de la instalación del programa se instale MySql
en su versión 5.7.

63
8. BIBLIOGRAFÍA

[1] "WooCommerce - eCommerce for WordPress", WooCommerce, 2018. [Online].


Disponible: https://woocommerce.com/. [Accedido: 08- Nov- 2018].

[2] Openbravo POS, "Openbravo POS - Openbravo Forge",

Centralrepository.openbravo.com, 2008. [Online]. Disponible:

http://centralrepository.openbravo.com/openbravo/org.openbravo.forge.ui/ForgePr

ojectDetail/openbravopos. [Accedido: 13- Nov- 2018].

[3] Sistemas del golfo, "Maia POS", SourceForge, 2013. [Online]. Available:

https://sourceforge.net/projects/maiapos/. [Accessed: 13- Nov- 2018].

[4]R. Stallman, Software libre para una sociedad libre, 1st ed. Madrid: Traficantes

de Sueños, 2004, p. 45.

[5]Apache foundation, "Glossary of Apache-Related Terms", Apache.org, 2017.

[Online]. Disponible: https://www.apache.org/foundation/glossary.html. [Accedido:

12- Nov- 2017].

[6]S. Peters and N. Ruff, "Participating in Open Source Communities - The Linux
Foundation", The Linux Foundation, 2017. [Online]. Disponible:
https://www.linuxfoundation.org/participating-open-source-communities/.
[Accedido: 15- Oct- 2017].

[7]R. Fielding, "Fielding Dissertation: CHAPTER 5: Representational State Transfer

(REST)", Ics.uci.edu, 2018. [Online]. Disponible:

64
https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm. [Accedido:

20- Abr- 2018].

[8]J. Franks, P. Hallam-Baker, J. Hostetler, S. Lawrence, P. Leach, A. Luotonen


and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication",
RFC 2617, 1999. [Online]. Disponible: https://www.rfc-
editor.org/rfc/pdfrfc/rfc2617.txt.pdf. [Accedido: 21- Abr- 2018].

[9]B. Dayley, Node.js, MongoDB and AngularJS web development. Upper Saddle
River, NJ [etc.]: Addison-Wesley, 2014.

[10] "Express glossary", Expressjs.com, 2018. [Online]. Disponible:


https://expressjs.com/en/resources/glossary.html. [Accedido: 21- Jun 2018].

[11] "Gson", GitHub, 2018. [Online]. Disponible: https://github.com/google/gson.

[Accedido: 21- Jun- 2018].

[12] MySQL 8.0 Reference Manual. Oracle, 2018.

[13] "What is npm?", Docs.npmjs.com, 2018. [Online]. Disponible:

https://docs.npmjs.com/getting-started/what-is-npm. [Accedido: 21- Jun -2018].

[14]P. Abate, R. Di Cosmo, R. Treinen and S. Zacchiroli, "A modular package

manager architecture", Information and Software Technology, vol. 55, no. 2, pp.

459-474, 2013.

65
[15]J. Cappos, J. Samuel, S. Baker and J. Hartman, "A look in the mirror: Attacks

on Package Managers", Proceedings of the 15th ACM conference on Computer

and communications security - CCS '08, pp. 565-574, Alexandria, VA, USA, 2008.

[16]C. Larman, UML y patrones. Naucalpan de Juárez: Pearson Educación, 2003.

[17]"Universally Unique Identifiers (UUIDs)", Itu.int, 2018. [Online]. Disponible:

https://www.itu.int/en/ITU-T/asn1/Pages/UUID/uuids.aspx.

[18]P. Leach, M. Mealling and R. Salz, "A Universally Unique IDentifier (UUID)

URN Namespace", RFC 4122, 2018. [Online]. Disponible: https://www.rfc-

editor.org/rfc/pdfrfc/rfc4122.txt.pdf. [Accedido: 17- Abr- 2018].

[19]S. Josefsson, "The Base16, Base32, and Base64 Data Encodings", RFC 4648,
2006. [Online]. Disponible: https://www.rfc-editor.org/rfc/pdfrfc/rfc4648.txt.pdf.
[Accedido: 17- Abr- 2018].

[20]C. Xu, Y. Chen and K. Chiew, "An Approach to Image Spam Filtering Based on
Base64 Encoding and N-Gram Feature Extraction", 2010 22nd IEEE International
Conference on Tools with Artificial Intelligence,Arras, France, 2010.

[21]T. Berners-Lee, R. Fielding and L. Masinter, "Uniform Resource Identifier

(URI): Generic Syntax", RFC 3986, 2005. [Online]. Disponible: https://www.rfc-

editor.org/rfc/rfc3986.txt. [Accedido: 17 -Abr- 2018].

[22]R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach and T.


Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, 1999. [Online].
Disponible: https://www.rfc-editor.org/rfc/rfc2616.pdf.

66
[23]T. Bray, "The JavaScript Object Notation (JSON) Data Interchange Format",

RFC 7159, 2014. [Online]. Disponible: https://tools.ietf.org/pdf/rfc7159.pdf.

[Accedido: 20- Abr- 2018].

[24]ECMA International, The JSON Data Interchange Syntax, 2nd ed. ECMA

International, 2017.

[25]D. Gourley and B. Totty, HTTP: the definitive guide. Beijing: O'Reilly, 2002.

[26]ECMAScript community, "ECMAScript 2019 Language Specification",

Tc39.github.io, 2018. [Online]. Disponible: https://tc39.github.io/ecma262/#sec-

normative-references. [Accedido: 23- Jun- 2018].

[27]T. Nelson, "A file structure for the complex, the changing, and the

indeterminate", ACM 20th National Conference, pp. 84-100,Cleveland, Ohio, USA,

1965.

[28]N. Wardrip-Fruin, What Hypertext Is. 2004.

[29]Sourceforge, "About SourceForge", Sourceforge.net, 2018. [Online].

Disponible: https://sourceforge.net/about. [Accedido: 28- Feb- 2018].

[30]J. Martinez Ladrón de Guevara, Fundamentos de programacion en java. EME,

2018, p. 2

67
[31]N. Foundation, "About | Node.js", Node.js, 2018. [Online]. Disponible:
https://nodejs.org/en/about/. [Accedido: 21- Jun 2018].

[32]S. Tilkov and S. Vinoski, "Node.js: Using JavaScript to Build High-Performance

Network Programs", IEEE Internet Computing, vol. 14, no. 6, 2010.

[33]"Postman API", Postman API, 2018. [Online]. Disponible:

https://docs.api.getpostman.com/?_ga=2.62019052.1355013722.1538345190-

1742112975.1538345190#intro. [Accedido: 21- Jun- 2018].

[34]G. Bierman, M. Abadi and M. Torgersen, "Understanding TypeScript", ECOOP

2014 – Object-Oriented Programming, pp. 257-281, 2014.

[35]TypeScript Language Specification. Microsoft, 2018.

[36]J. Wargo, PhoneGap essentials. Upper Saddle River, NJ: Addison-Wesley,

2012.

[37]A. Group, "About the Apache HTTP Server Project - The Apache HTTP Server

Project", Httpd.apache.org, 2018. [Online]. Disponible:

http://httpd.apache.org/ABOUT_APACHE.html. [Accedido: 23- Jun- 2018].

[38]D. Flanagan, JavaScript: The Definitive Guide. Sebastopol, Calif.: O'Reilly,

2006.

[39]D. Crockford, JavaScript: The good parts. Farnham: O'Reilly, 2008.

68
[40]Google, "V8 JavaScript engine", V8.dev, 2018. [Online]. Disponible:

https://v8.dev/. [Accedido: 23- Jun- 2018].

[41]C. Alifery, Android Programming Cookbook. 2018.

[42]S. Holla and M. Katti, "ANDROID BASED MOBILE APPLICATION

DEVELOPMENT and its SECURITY", International Journal of Computer Trends

and Technology, vol. 3, no. 3, pp. 486-490, 2012.

[43]R. Meier, Professional Android 4 application development. Canadá: Wrox,

2012.

[44]R. Elmasri and S. Navathe, Fundamentals of database systems. Boston:

Addison Wesley, 2011.

[45]H. Garcia-Molina, J. Ullman and J. Widom, DATABASE SYSTEMS The

Complete Book, 2nd ed. Upper Saddle River, New Jersey: Pearson Education,

2009.

[46]I. Sommerville and M. Alfonso Galipienso, Ingeniería del software, 7th ed.

Madrid: Pearson Educación, 2005, pp. 68-69.

[47]R. Pressman, Ingeniería del software. México: MacGraw-Hill, 2010, pp. 37-40.

[48]K. Kendall, J. Kendall, A. Núñez Ramos and G. Trujano Mendoza, Análisis y


diseño de sistemas. México: Pretince Hall, 2005, pp. 151-158.

69
[49] Á. Manjavacas, ADAPTACIÓN E IMPLEMENTACIÓN DE MEJORAS EN UN
PROYECTO DE SOFTWARE LIBRE A UN SISTEMA CASH -FLOW MUY
EFICIENTE Y SEGURO. Madrid, España: Universidad Complutense de Madrid,
2016.

[50] Capterra, "Best Point of Sale Software | 2018 Reviews of the Most Popular
Systems", Capterra.com, 2018. [Online]. Disponible:
https://www.capterra.com/point-of-sale-
software/?utf8=%E2%9C%93&v=3#infographic. [Accedido: 22- May- 2018].

[51]J. Gerrad, "uniCenta oPOS Point Of Sale for SME Retailer and Hospitality
businesses", uniCenta, 2018. [Online]. Disponible: https://unicenta.com/about-
unicenta-opos-point-of-sale/. [Accedido: 25- May 2018].

[52] "Trabajos, empleo de Kitchen display software unicenta opos | Freelancer",


Freelancer.com.co, 2018. [Online]. Disponible: https://www.freelancer.com.co/job-
search/kitchen-display-software-unicenta-opos/. [Accedido: 25- May 2018].

70
9. ANEXOS

ANEXO A: ESTADO DEL ARTE DE UNICENTA

Unicenta oPOS es un software dedicado a suplir las necesidades encontradas en


los puntos de venta. Se enfoca en los mercados minoristas tales como
restaurantes, hostelería, almacenes, supermercados entre otros [49].

Algunas de las funciones que más se destacan en este software son:

● Conectividad con impresoras fiscales de 1ra y 2da generación,


comanderas, scanners, entre otras.
● Manejo de sesiones de usuario, distinción de roles.
● Gestión de artículos.
● Gestión de inventario.
● Gestión de caja.
● Gestión de proveedores.
● Generación de informes.

Este programa es desarrollado en el lenguaje de programación Java, posee una


fuerte orientación a objetos dentro de su código y utiliza como base de datos
principal MySQL. Estas dos características en su desarrollo permiten su fácil
portabilidad entre sistemas operativos y por esta razón puede ser ejecutado en
Linux, Windows y Mac OS X 10.6 o posterior.

El proyecto fue iniciado en el año 2010 por su fundador Jack Gerrard como un
proyecto hobista, pero su crecimiento llevó a que se crearan unas metas las
cuales desde su inicio hasta este momento han sido el horizonte del mismo, estas
metas a cumplir son:

71
● Desarrollar un punto de venta de código abierto de calidad comercial
● Hacerlo lo más accesible posible para todas las PYMEs.
● Ayudar a las empresas en ahorro de tiempo y dinero
● Construir una marca global en el nicho de POS.

Para alcanzar las metas anteriormente planteadas, se decidió que sería software
libre y se encontraría bajo la licencia GNU GPL V3, además, empezó a ser
distribuido a través de canales casuales como lo son su sitio web, la página por
excelencia de software libre sourceforge, entre otros métodos, en ninguno de los
cuales se forza al usuario a registrarse, características que según Jack Gerrard su
fundador, han sido la clave fundamental para el éxito del proyecto.

Como lo expresa Gerrard, el crecimiento y la popularidad del proyecto ha ido


creciendo, además, el dinero no fue un motivo para la existencia de uniCenta. Esto
se ve reflejado en la posición que ocupa Unicenta, como una de las soluciones
POS más usadas alrededor del mundo, con más de un millón de descargas desde
su inicio, gracias a lo mencionado el proyecto ocupa la cuarta posición, como se
observa en la ilustración 18, en la división de puntos de venta, en el ranking de la
página capterra, la cual se dedica a calificar software para distintas aplicaciones.

Ilustración 18. Ranking Capterra

Fuente: Capterra.com [50]

72
Adicionalmente y apoyando la idea de que Unicenta sigue creciendo, en el 2016
se introdujo el soporte por suscripción, gracias a las peticiones de algunos
usuarios que solicitaron este servicio [51]. Este servicio tiene dos planes
diferentes, el base y el plus.

El plan base tiene un costo anual de $US 77.32, este plan es recomendado para
los negocios usuarios o simplemente vendedores del proyecto, y presta los
siguientes beneficios:

● Descargas
● Código Fuente
● Notificaciones de actualización
● Reporte Web
● Soporte estándar en el foro
● Guías de usuario

El plan plus tiene un costo anual de $US 175, este plan es recomendado para
desarrolladores o empresas interesadas en mejorar las características y
funcionalidades del proyecto, y presta los siguientes beneficios:

● Downloads
● Source code
● Update Notifications
● Web Reporting
● Remote Order Display
● Priority Forum support
● User Guides
● Rate discount 15%
● Developer Guides

73
● Access to Beta’s
● Limited Developer support

De igual forma es un reflejo del impacto que Unicenta ha tenido alrededor mundo,
la cantidad de solicitudes de trabajo como freelancer para desarrollar alguna
nueva funcionalidad para el proyecto, y esto se puede observar en la ilustración
19, la cual fue tomada de la página web freelancer.com.

Ilustración 19. Ofertas de trabajo para desarrollo de Unicenta

Fuente: Frelancer.com [52]

El proyecto unicenta es un proyecto derivado del software OpenBravo Pos el cual


es propiedad de la compañía OpenBravo, este proyecto comenzó siendo software
libre y como una comunidad, pero al pasar el tiempo fue privatizado y explotado de
forma comercial por la compañía; debido a esto surgieron derivados como lo es
Unicenta. Además, cabe aclarar que OpenBravo también es un proyecto derivado,
este proyecto partió de la base del software llamado TinaPos.

74
Sabiendo entonces, que Unicenta oPos es un proyecto derivado de OpenBravo
Pos, a continuación se hará un listado de algunas de las modificaciones que
Unicenta realizó a OpenBravo en sus primeras versiones.

● Gestión de empleados
● Modificación de los reportes
● Modificación de los iconos
● Mostrar el cambio a la hora de realizar una venta
● Capacidad de modificar las conexiones a la base de datos desde la GUI.
● Gestión de clientes
● Posibilidad de importar productos especificando sus atributos en archivos
.csv.
● Entre otras

Del mismo modo, así como Unicenta oPos surgió como un proyecto derivado de
OpenBravo Pos, han surgido diferentes proyectos que se derivan de Unicenta.
Estos proyectos han surgido por diferentes circunstancias tales como el interés
privado de explotar el proyecto de forma comercial, u otros por razones un poco
más complejas, como lo son la falta de aceptación de nuevos aportes de personas
que pertenecían a la comunidad y querían aportar al proyecto, como es el caso del
proyecto Chromis el cual fue creado por John Lewis debido a que desde el año
2012 comenzó a dar soporte a sistemas pos de código abierto, en ese momento
se dio cuenta que existía la necesidad de una nueva funcionalidad, un módulo,
que funcionara con las pantallas de cocina, así que Lewis comenzó el desarrollo,
lo publicó y al pasar el tiempo sus cambios no eran adicionados a las nuevas
versiones de Unicenta, así que él, se ponía nuevamente en el trabajo de adicionar
su funcionalidad lo que conllevaba mucho esfuerzo y tiempo, y, al ver que los
usuarios se volvían dependientes de su módulo y no era adicionado al proyecto
decidió crear su nuevo proyecto derivado y lo llamó Chromis. Asi como este

75
proyecto surgieron algunos otros, a continuación se presenta una lista de
proyectos derivados de Unicenta:
● Grandpos (http://www.grandpos.com/)
● Mipos (https://www.mipos.com.au/)
● Chromis ( http://chromis.co.uk/)
● Streamline-pos (https://sourceforge.net/projects/streamline-pos/)

76
ANEXO B: INGENIERÍA INVERSA DE UNICENTA

LISTA DE ILUSTRACIONES

ILUSTRACIÓN 20. CLASE DATALOGICSALES .......................................................................................... 85


ILUSTRACIÓN 21. CLASE OCTOPOS ......................................................................................................... 97
ILUSTRACIÓN 22. CLASE JROOTAPP .................................................................................................... 100
ILUSTRACIÓN 23. CLASE APPCONFIG ................................................................................................... 103
ILUSTRACIÓN 24. CLASE APPLOCAL ..................................................................................................... 105
ILUSTRACIÓN 25. CLASE APPUSER ....................................................................................................... 106
ILUSTRACIÓN 26. CLASE APPVIEW CONNECTION ............................................................................... 108
ILUSTRACIÓN 27. CLASE DATALOGICSYSTEM .................................................................................... 110
ILUSTRACIÓN 28. CLASE JPANELMENU ............................................................................................... 113
ILUSTRACIÓN 29. CLASE JPRINCIPALAPP ............................................................................................ 114
ILUSTRACIÓN 30. CLASE JROOTFRAME ............................................................................................... 116
ILUSTRACIÓN 31. CLASE OSVALIDATOR .............................................................................................. 118
ILUSTRACIÓN 32. CLASE BASESENTENCE ........................................................................................... 120
ILUSTRACIÓN 33. CLASE SESSION......................................................................................................... 122
ILUSTRACIÓN 34. CLASE BASICEXCEPTION......................................................................................... 124
ILUSTRACIÓN 35. CLASE LOCALERESOURCES ................................................................................... 125
ILUSTRACIÓN 36. CLASE SAVEPROVIDER ............................................................................................ 127
ILUSTRACIÓN 37. CLASE PRODUCTSPANEL ........................................................................................ 128
ILUSTRACIÓN 38. CLASE PRODUCTSEDITOR ...................................................................................... 131
ILUSTRACIÓN 39. CLASE DIRTYMANAGER ........................................................................................... 133
ILUSTRACIÓN 40. CLASE PRODUCTFILTER .......................................................................................... 135
ILUSTRACIÓN 41. CLASE DATALOGICRECEIPTS ................................................................................. 137

LISTA DE TABLAS

TABLA 4. TABLAS DE LA BASE DE DATOS ................................................................................................. 79

77
En este anexo, se muestra el trabajo realizado para lograr alcanzar la ingeniería
inversa del software unicenta. Cabe resaltar, que este apartado es de vital
importancia para el entendimiento del proyecto y por ende es base fundamental
para lograr el desarrollo de las nuevas funcionalidades que hacen parte de este
proyecto de grado.

El proceso de ingeniería inversa se dividió en dos partes, el entendimiento de la


base de datos a través del análisis del modelo relacional de la base de datos de
unicenta y el entendimiento de su código fuente.

A. Base de datos

El primer paso realizado para el entendimiento de la base de datos, fue saber


sobre que motor de base datos estaba funcionando el proyecto, debido a que al
tener esta información se creaba una idea de cómo serían los tipos de datos
utilizados en esta base de datos, las restricciones que tendría y la sintaxis SQL
que se utiliza para su gestión, además, es un dato esencial para comenzar la
búsqueda de una herramienta que facilite el proceso de obtener el modelo
relacional de la base de datos del proyecto.

Al realizar la búsqueda de una herramienta para el propósito anteriormente


mencionado, se eligió el software dbeaver para lleva a cabo el cometido. Así pues
en el ANEXO H: MODELO RELACIONAL se puede observar el modelo relacional
de la base de datos.

Es de resaltar que el proyecto contiene más de 40 tablas, las cuales se


encuentran en su tercera forma normal, lo cual garantiza consistencia en los datos
almacenados, además se puede observar que las llaves primarias de todas las
tablas son de tipo varchar, esto se debe a que los desarrolladores optaron por
usar el método de identificación UUID, ya que este método se adapta muy bien a

78
la necesidad de identificación que se genera con el uso de los tickets de venta, los
cuales tienen un tiempo de vida de corta duración.

Después de realizar un análisis exhaustivo del modelo relacional ilustrado en la


ANEXO H: MODELO RELACIONAL, dio como resultado la tabla 4, en donde
puede detallarse un listado con todas las tablas de la base de datos, cada una de
las tablas posee una breve descripción de su propósito dentro del proyecto y
además muestra si la tabla posee o no una interfaz gráfica, lo que es de gran
ayuda al momento de entender el código y su funcionamiento.

Tabla 4. Tablas de la base de datos

TABLA DESCRIPCIÓN POSEE


INTERFA
GRÁFICA

applications Nombre y número de versión de la N


aplicación uniCenta oPOS

attribute Definición de término de atributo de un S


producto ej: talla, color, etc.

attributeinstance Es una lista de búsqueda de atributos S


asociados e instancia del conjunto de
atributos

attributeset Agrupación de atributos, se usa para S


definir qué atributos posee un producto

attributesetinstance Una colección de conjuntos de atributos S

79
attributeuse Vinculación del Atributo al producto S

attributevalue Valor del atributo S

breaks Lista de búsqueda de sesiones de S


personas predeterminadas

categories Categorías a las cuales pertenecen los S


Productos

closedcash Se usa para grabar los eventos del N


'Cerrado de caja'

csvimport Lista de Clientes, Productos y cantidad N


de stock

customers Clientes S

draweropened Lista de TODAS las aberturas de la caja N


registradora

floors Tabla de búsqueda de áreas físicas o S


virtuales del establecimiento

leaves Lista de entradas/salidas de personas S

lineremoved Lista de eliminación de ticketlines de la N


pantalla de ventas

locations Ubicaciones físicas o almacenes S

moorers Restos N

80
orders Lista dinámica de pedidos incompletos N
enviados a la impresora remota

payments Contiene TODOS los pagos recibidos N

people Usuarios S

pickup_number Número de orden incremental aplicado al N


boleto

places Posicionamiento del objeto físico en el S


piso, así como el estado actual

products Productos S

products_cat La categoría de un producto asignado N

products_com Productos auxiliares S

receipts Detalle de la liquidación de los boletos N

reservation_customers Lista de Reservas / clientes S

reservations Reservaciones S

resources Configuraciones de la aplicación S

roles Conjunto de personas S

sharedtickets Tiquetes Incompletos - no liquidados N

shift_breaks Descansos que ocurren por turnos S

shifts Sesiones de personas S

81
stockcurrent Valor unitario físico del producto N

stockdiary Lista de movimiento de productos N

stocklevel Valores mínimos / máximos del producto S

suppliers Proveedores S

taxcategories Lista de búsqueda de categorías de S


impuestos

taxcustcategories Lista de búsqueda de categorías de S


impuestos del cliente

taxes Definiciones de impuestos S

taxlines Registra los valores de la boleta de un N


boleto establecido

taxsuppcategories Categorías de impuestos del proveedor N

thirdparties Plantilla de tabla de ejemplo N

ticketlines Valores de línea de boleto de boleto fijo N

tickets Tickets N

ticketsnum Búsqueda de identificación de ticket N


secuencial

ticketsnum_payment Búsqueda de identificación de pago N


secuencial

ticketsnum_refund Id. secuencial de reembolso de ticket N

82
uom Unidad de medida S

vouchers Lista de búsqueda del tipo de pago S

Fuente: elaboración propia

B. Código fuente

El proyecto fue desarrollado con el lenguaje de programación Java, usando como


entorno de desarrollo integrado Netbeans, así que el primer paso para poder
entender el código del proyecto fue montar el código en dicha plataforma como lo
evidencia el ANEXO G: CONFIGURACIÓN DEL PROYECTO EN NETBEANS,
después de esto se comenzó con un proceso de depuración del proyecto, el cual
permitió seguir paso a paso los procesos realizados por el software, ver la
interacción entre clases y los tipos de dato que manejaba el programa, y de esta
manera, se fue construyendo un conocimiento frente a cómo funcionaba el
proyecto.

Además otro factor fundamental para entender la estructura del proyecto y su


funcionamiento fue el diagrama de clases del proyecto.

Conociendo el diagrama de clases, entendiendo los procesos y algoritmos del


proyecto, se generó la documentación de las clases más influyentes dentro del
proyecto y que fueron necesarias para el desarrollo de los otros módulos. Esta
documentación, como fue mencionado anteriormente, se generó por cada clase y
consiste en: El diagrama de clases de la clase documentada, una descripción de
la funcionalidad de la clase con sus respectivos parámetros de entrada y salida, y
por último un fragmento del código de la clase.

83
Adicionalmente, se documentaron también los scripts SQL de la base de datos, la
documentación de estos se realizó dando una descripción de lo que hace el script
y un fragmento de código.

Clase DataLogicSales:

Esta clase se encarga de realizar todas las transacciones relacionadas con el


negocio, tales como la gestión de productos, categorías, stock, tickets entre otros.
Esta es una clase que extiende de la clase BeanFactoryDataSingle, el constructor
de DataLogicSales no recibe ningún parámetro y su función principal es crear
objetos tales como productsRow, customerRow, entre otros, los cuales serán
usados en sus métodos. El diagrama de esta clase se puede observar en la
ilustración 20.

84
Ilustración 20. Clase DataLogicSales

Fuente: elaboración propia

public class DataLogicSales extends BeanFactoryDataSingle {

protected Session s;

protected Datas[] auxiliarDatas;


protected Datas[] stockdiaryDatas;
protected Datas[] paymenttabledatas;
protected Datas[] stockdatas;

85
protected Datas[] stockAdjustDatas;

protected Row productsRow;


protected Row customersRow;

private String pName;


private Double getTotal;
private Double getTendered;
private String getRetMsg;
private String getVoucher;

public static final String DEBT = "debt";


public static final String DEBT_PAID = "debtpaid";
protected static final String PREPAY = "prepay";
private static final Logger logger =
Logger.getLogger("com.openbravo.pos.forms.DataLogicSales");

private String getCardName;


protected SentenceExec m_createCat;
protected SentenceExec m_createSupp;

private API_interface m_apiConnection;


public DataLogicSales() {
stockdiaryDatas = new Datas[] {
Datas.STRING, Datas.TIMESTAMP, Datas.INT,
Datas.STRING,
Datas.STRING, Datas.STRING, Datas.DOUBLE,
Datas.DOUBLE,
Datas.STRING, Datas.STRING, Datas.STRING};

86
paymenttabledatas = new Datas[] {
Datas.STRING, Datas.STRING, Datas.TIMESTAMP,
Datas.STRING, Datas.STRING, Datas.DOUBLE,
Datas.STRING};

- getProductCatInsert() :

El método getProductCatInsert() ,es el encargado de insertar un nuevo


producto, este recibe como parámetros un objeto el cual contiene todos los
campos del nuevo producto, y finalmente el método retorna en un primer momento
una instancia de la clase SentenceExecTransaction(s) y a la hora de ser
llamada esta instancia, se ejecuta el método sobrescrito execInTransaction() ,
el cual retorna un entero que indica si la inserción fue o no fue exitosa.

public final SentenceExec getProductCatInsert() {


return new SentenceExecTransaction(s) {
@Override
public int execInTransaction(Object params) throws
BasicException {
Object[] values = (Object[]) params;
int i = new PreparedSentence(s
, "INSERT INTO products ("
+ "ID, "
+ "REFERENCE, "
+ "CODE, "
+ "CODETYPE, "

87
+ "NAME, "
+ "PRICEBUY, "
+ "PRICESELL, "
+ "CATEGORY, "
+ "PRINTTO, "
+ "SUPPLIER, "
+ "UOM,"
+ "FLAG, "
+ "DESCRIPTION, "
+ "SHORT_DESCRIPTION, "
+ "WEIGTH, "
+ "WIDTH, "
+ "LENGTH, "
+ "HEIGHT ) "
+ "VALUES ("
+ "?, ?, ?, ?, ?, ?, "
+ "?, ?, ?, ?, ?, ?, "
+ "?, ?, ?, ?, ?, ?, "
+ "?, ?, ?, ?, ?, ?, "
+ "?, ?, ?, ?, ?, ?,"
+ "?, ?, ?, ?, ?, ?)"
, new SerializerWriteBasicExt(productsRow.getDatas(),
new int[]{0,
1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35}))

88
.exec(params);

if((boolean) values[29]){
m_apiConnection.createProduct(params);
}

- getProductCatUpdate():

El método getProductCatUpdate() , es el encargado de actualizar un producto


existente, este recibe como parámetros un objeto el cual contiene todos los
campos del producto, finalmente el método retorna en un primer momento una
instancia de la clase SentenceExecTransaction(s) y a la hora de ser llamada
esta instancia se ejecuta el método sobrescrito execInTransaction() , el cual
retorna un entero que indica si la actualización fue o no exitosa.

public final SentenceExec getProductCatUpdate() {


return new SentenceExecTransaction(s) {
@Override
public int execInTransaction(Object params) throws
BasicException {
Object[] values = (Object[]) params;
int i = new PreparedSentence(s
, "UPDATE products SET "
+ "ID = ?, "
+ "REFERENCE = ?, "
+ "CODE = ?, "
+ "CODETYPE = ?, "

89
+ "NAME = ?, "
+ "PRICEBUY = ?, "
+ "PRICESELL = ?, "
+ "CATEGORY = ?, "
+ "TAXCAT = ?, "
+ "ATTRIBUTESET_ID = ?, "
+ "STOCKCOST = ?, "
+ "STOCKVOLUME = ?, "
+ "IMAGE = ?, "
, new SerializerWriteBasicExt(productsRow.getDatas(),
new int[]{0,
1, 2, 3, 4, 5,
6, 7, 8, 9, 10,
11, 12, 13, 14, 15,
16, 17, 18, 19, 20,
21, 22, 23, 24, 25,
26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 0}))
.exec(params);
if (i > 0) {
if (((Boolean)values[36])) {
if (new PreparedSentence(s
, "UPDATE products_cat SET
CATORDER = ? WHERE PRODUCT = ?"
, new
SerializerWriteBasicExt(productsRow.getDatas()
, new int[] {35,
0})).exec(params) == 0) {
new PreparedSentence(s

90
, "INSERT INTO products_cat (PRODUCT, CATORDER)
VALUES (?, ?)"
, new
SerializerWriteBasicExt(productsRow.getDatas(), new int[] {0,
37})).exec(params);
}
} else {
new PreparedSentence(s
, "DELETE FROM products_cat WHERE PRODUCT = ?"
, new
SerializerWriteBasicExt(productsRow.getDatas(), new int[]
{0})).exec(params);
}

- getProductCatDelete():

El método getProductCatDelete() , es el encargado de eliminar un producto


existente, este recibe como parámetros un objeto el cual contiene todos los
campos del producto, finalmente el método retorna en un primer momento una
instancia de la clase SentenceExecTransaction(s) y a la hora de ser llamada
esta instancia se ejecuta el método sobrescrito execInTransaction() , el cual
retorna una instancia de la clase PreparedSentence .

public final SentenceExec getProductCatDelete() {


return new SentenceExecTransaction(s) {
@Override
public int execInTransaction(Object params) throws
BasicException {

91
Object[] values = (Object[]) params;
new PreparedSentence(s
, "DELETE FROM products_cat WHERE PRODUCT = ?"
, new
SerializerWriteBasicExt(productsRow.getDatas(), new int[]
{0})).exec(params);

if((boolean) values[29]){
m_apiConnection.deleteProduct(params);
new PreparedSentence(s
, "DELETE FROM extern_product WHERE local_id = ?"
, new
SerializerWriteBasicExt(productsRow.getDatas(), new int[]
{0})).exec(params);
}

return new PreparedSentence(s


, "DELETE FROM products WHERE ID = ?"
, new
SerializerWriteBasicExt(productsRow.getDatas(), new int[]
{0})).exec(params);
}

- getStockDiaryInsert1():

El método getStockDiaryInsert1() , es el encargado de actualizar las


existencias del inventario, este recibe como parámetros un objeto el cual contiene
todos los campos necesarios para realizar esta actualización, finalmente el método
retorna en un primer momento una instancia de la clase

92
SentenceExecTransaction(s) y a la hora de ser llamada esta instancia se
ejecuta el método sobrescrito execInTransaction() , el cual retorna una
instancia de la clase PreparedSentence la cual será usada más adelante para
determinar si la transacción fue exitosa.

public final SentenceExec getStockDiaryInsert1() {


return new SentenceExecTransaction(s) {
@Override
public int execInTransaction(Object params) throws
BasicException {
int updateresult = ((Object[]) params)[5] == null
? new PreparedSentence(s
, "UPDATE stockcurrent SET UNITS = (UNITS + ?) "
+ "WHERE LOCATION = ? AND PRODUCT = ? "
+ "AND ATTRIBUTESETINSTANCE_ID IS NULL"
, new SerializerWriteBasicExt(stockdiaryDatas,
new int[] {6, 3, 4})).exec(params)
: new PreparedSentence(s
, "UPDATE stockcurrent SET UNITS = (UNITS + ?) "
+ "WHERE LOCATION = ? AND PRODUCT = ? "
+ "AND ATTRIBUTESETINSTANCE_ID = ?"
, new SerializerWriteBasicExt(stockdiaryDatas,
new int[] {6, 3, 4, 5})).exec(params);

if (updateresult == 0) {
new PreparedSentence(s
, "INSERT INTO stockcurrent (LOCATION, PRODUCT, "
+ "ATTRIBUTESETINSTANCE_ID, UNITS) "
+ "VALUES (?, ?, ?, ?)"

93
, new SerializerWriteBasicExt(stockdiaryDatas,
new int[] {3, 4, 5, 6})).exec(params);
}
m_apiConnection.updateStockProduct(params);
return new PreparedSentence(s
, "INSERT INTO stockdiary (ID, DATENEW, REASON,
LOCATION, PRODUCT, "
+ "ATTRIBUTESETINSTANCE_ID, UNITS,
PRICE, AppUser, "
+ "SUPPLIER, SUPPLIERDOC) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?)"
, new SerializerWriteBasicExt(stockdiaryDatas,
new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10})).exec(params);

- saveTicket():

El método saveTicket() , es el encargado de agregar un ticket cada vez que se


realiza una venta, este método recibe como parámetros un objeto tipo TicketInfo el
cual contiene toda la información necesaria del ticket y otro parámetro tipo String,
el cual indica la ubicación del producto. Este método no retorna ningún tipo de
respuesta.

public final void saveTicket(final TicketInfo ticket, final


String location) throws BasicException {

Transaction t;

94
t = new Transaction(s) {
@Override
public Object transact() throws BasicException {

// Set Receipt Id
if (ticket.getTicketId() == 0) {
switch (ticket.getTicketType()) {
case TicketInfo.RECEIPT_NORMAL:
ticket.setTicketId(getNextTicketIndex());
break;
case TicketInfo.RECEIPT_REFUND:
ticket.setTicketId(getNextTicketRefundIndex());
break;
case TicketInfo.RECEIPT_PAYMENT:
ticket.setTicketId(getNextTicketPaymentIndex());
break;
case TicketInfo.RECEIPT_NOSALE:
ticket.setTicketId(getNextTicketPaymentIndex());
break;
default:
throw new BasicException();
}
}

new PreparedSentence(s
, "INSERT INTO receipts (ID, MONEY, DATENEW,
ATTRIBUTES, PERSON) VALUES (?, ?, ?, ?, ?)"
, SerializerWriteParams.INSTANCE )
.exec(new DataParams() {

95
@Override
public void writeValues() throws BasicException {
setString(1, ticket.getId());
setString(2, ticket.getActiveCash());
setTimestamp(3, ticket.getDate());

try {
ByteArrayOutputStream o = new
ByteArrayOutputStream();
ticket.getProperties().storeToXML(o,
AppLocal.APP_NAME, "UTF-8");
setBytes(4, o.toByteArray());
} catch (IOException e) {
setBytes(4, null);
}
setString(5, ticket.getProperty("person"));
}
});

// new ticket
new PreparedSentence(s
, "INSERT INTO tickets (ID, TICKETTYPE, TICKETID,
PERSON, CUSTOMER, STATUS) "
+ "VALUES (?, ?, ?, ?, ?, ?)"

Class OctoPos:

Esta clase es la principal, posee el método main de todo el proyecto. La principal

96
función de esta clase, es cargar todos los datos necesarios para la sesión desde la
base de datos. Ya que las vistas del proyecto se construyen ,en su mayoría, de
forma recursiva, es decir se recicla demasiado código en cada una de las vistas,
esta clase se encarga de realizar la conexión a la base de datos, carga el estilo de
la vista, entre otras cosas. Además, desde esta clase se hace un llamado a la
clase JRootApp la cual es la vista principal del proyecto. El diagrama de esta clase
se puede observar en la ilustración 21.

Ilustración 21. Clase OctoPos

Fuente: elaboración propia

public class StartPOS {

private static final Logger logger =


Logger.getLogger("com.openbravo.pos.forms.StartPOS");

private StartPOS() {
}

public static boolean registerApp() {

InstanceQuery i = null;
try {
i = new InstanceQuery();

97
i.getAppMessage().restoreWindow();
return false;
} catch (RemoteException | NotBoundException e) {
return true;
}
}

public static void main (final String args[]) {

SwingUtilities.invokeLater ( new Runnable () {

@Override
public void run() {

if (!registerApp()) {
System.exit(1);
}

AppConfig config = new AppConfig(args);

config.load();

String slang =
config.getProperty("user.language");
String scountry =
config.getProperty("user.country");
String svariant =
config.getProperty("user.variant");
if (slang != null

98
&& !slang.equals("")
&& scountry != null
&& svariant != null) {

Locale.setDefault(new Locale(slang, scountry,


svariant));
}

Formats.setIntegerPattern(config.getProperty("format.integer
"));

Formats.setDoublePattern(config.getProperty("format.double")
);

Formats.setCurrencyPattern(config.getProperty("format.curren
cy"))

Class JRootApp:

La ilustración 22 muestra la clase de la vista principal de todo el proyecto, es


instanciada desde la clase octoPos, las funciones de esta clase son cargar toda la
información necesaria para cargar las vistas, como lo es el logo, la versión del
proyecto, su nombre, etc. También cumple la función de login y es el único método
de protección de todo el programa, además desde acá, se selecciona el usuario
con el que se desea ingresar al sistema, por tanto, se crea la sesión para ese
usuario con los privilegios que ese usuario tiene.

99
Ilustración 22. Clase JRootApp

Fuente: elaboración propia

100
public class JRootApp extends JPanel implements AppView,
DeviceMonitorEventListener {

private AppProperties m_props;


private Session session;
private DataLogicSystem m_dlSystem;

private Properties m_propsdb = null;


private String m_sActiveCashIndex;
private int m_iActiveCashSequence;
private Date m_dActiveCashDateStart;
private Date m_dActiveCashDateEnd;

private Double m_dActiveCashNotes;


private Double m_dActiveCashCoins;
private Double m_dActiveCashCards;

private String m_sClosedCashIndex;


private int m_iClosedCashSequence;
private Date m_dClosedCashDateStart;
private Date m_dClosedCashDateEnd;
public JRootApp() {

m_aBeanFactories = new HashMap<>();

initComponents ();
jScrollPane1.getVerticalScrollBar().setPreferredSize(new
Dimension(30, 30));
serverMonitor.setVisible(false);

101
}
private DSPortAdapter m_oneWireAdapter;
private DeviceMonitor m_oneWireMonitor;

private void initIButtonMonitor() {

assert m_oneWireMonitor == null;


try
{
m_oneWireAdapter =
OneWireAccessProvider.getDefaultAdapter();
m_oneWireAdapter.setSearchAllDevices();
m_oneWireAdapter.targetFamily(0x01);

m_oneWireAdapter.setSpeed(DSPortAdapter.SPEED_REGULAR);
m_oneWireMonitor = new
DeviceMonitor(m_oneWireAdapter);
// Normal state
m_oneWireMonitor.setMaxStateCount(5);
// Use for testing
// m_oneWireMonitor.setMaxStateCount(100);

m_oneWireMonitor.addDeviceMonitorEventListener(this);
new Thread(m_oneWireMonitor).start();

Class AppConfig:
Esta clase es la encargada de gestionar la configuración de la base de datos, las
impresoras y el mensaje que saldrá impreso en los tickets después de realizar una
venta.

102
Esta clase lee y modifica un archivo de configuración, el cual contiene toda la
información anteriormente mencionada. El diagrama de esta clase se puede
observar en la ilustración 23.

Ilustración 23. Clase AppConfig

Fuente: elaboración propia

public class AppConfig implements AppProperties {

private static final Logger logger =


Logger.getLogger("com.openbravo.pos.forms.AppConfig");

103
private static AppConfig m_instance = null;
private Properties m_propsconfig;
private File configfile;

/**
* Set configuration array
* @param args array strings
*/
public AppConfig(String[] args) {
if (args.length == 0) {
init(getDefaultConfig());
} else {
init(new File(args[0]));
}
}

Class AppLocal:

Esta clase, se encarga de cargar el nombre y la versión del proyecto, además


carga todos los recursos de traducción del proyecto. El diagrama de esta clase se
puede observar en la ilustración 24.

104
Ilustración 24. Clase AppLocal

Fuente: elaboración propia

public class AppLocal {

public static final String APP_NAME = "Octo Pos";


public static final String APP_ID = "OctoPos";
public static final String APP_VERSION = "5.1.0";

private static final LocaleResources m_resources;

static {
m_resources = new LocaleResources();
m_resources.addBundleName("pos_messages");
m_resources.addBundleName("erp_messages");
}

Class AppUser:

105
Esta clase, se encarga de cargar todos los atributos de un usuario, añadir los
permisos a cada uno de los roles y además es la encargada de realizar la
autentificación del sistema. El diagrama de esta clase se puede observar en la
ilustración 25.

Ilustración 25. Clase AppUser

Fuente: elaboración propia

public class AppUser {

106
private static final Logger logger =
Logger.getLogger("com.openbravo.pos.forms.AppUser");

private static SAXParser m_sp = null;


private static HashMap<String, String> m_oldclasses; // This
is for backwards compatibility purposes

private final String m_sId;


private final String m_sName;
private final String m_sCard;
private String m_sPassword;
private final String m_sRole;
private final Icon m_Icon;

private Set<String> m_apermissions;

static {
initOldClasses();
}

/** Creates a new instance of AppUser


* @param id
* @param name
* @param card
* @param password
* @param icon
* @param role */
public AppUser(String id, String name, String password,

107
String card, String role, Icon icon) {
m_sId = id;
m_sName = name;
m_sPassword = password;
m_sCard = card;
m_sRole = role;
m_Icon = icon;
m_apermissions = null;
}

Class AppViewConnection:

Esta clase es la encargada de crear las sesiones del sistema a través de su


método createSession.

El método mencionado recibe como parámetro un objeto tipo AppProperties en el


cual se encuentran los parámetros necesarios para crear una sesión del proyecto.
El diagrama de esta clase se puede observar en la ilustración 26.

Ilustración 26. Clase AppViewConnection

Fuente: elaboración propia

public class AppViewConnection {

108
/** Creates a new instance of AppViewConnection */
private AppViewConnection() {
}

/**
*
* @param props
* @return
* @throws BasicException
*/
public static Session createSession(AppProperties props)
throws BasicException {

try {
String dbURL=null;
String sDBUser=null;
String sDBPassword=null;

if (isJavaWebStart()) {
Class.forName(props.getProperty("db.driver"),
true, Thread.currentThread().getContextClassLoader());
} else {
ClassLoader cloader = new URLClassLoader(new
URL[] {
new

Class DataLogicSystem:

109
Esta clase es la encargada de generar todas las consultas, a la base de datos,
relacionadas con los datos necesarios para que el sistema funcione, tales como
los roles del sistema, los permisos que estos poseen, los clientes, lo proveedores,
entre otros.

El constructor de esta clase tiene como parámetro de entrada un objeto de tipo


Session, y no retorna nada. El diagrama de esta clase se puede observar en la
ilustración 27.

Ilustración 27. Clase DataLogicSystem

Fuente: elaboración propia

public class DataLogicSystem extends BeanFactoryDataSingle {

110
protected String m_sInitScript;
private SentenceFind m_version;
private SentenceExec m_dummy;
private String m_dbVersion;
protected SentenceList m_peoplevisible;
protected SentenceFind m_peoplebycard;

private String SQL;


private Map<String, byte[]> resourcescache;

private SentenceList m_voucherlist;

/** Creates a new instance of DataLogicSystem */


public DataLogicSystem() {
}

/**
*
* @param s
*/
@Override
public void init(Session s){

m_sInitScript = "/com/openbravo/pos/scripts/" +
s.DB.getName();
m_dbVersion = s.DB.getName();

m_version = new PreparedSentence(s, "SELECT VERSION FROM


applications WHERE ID = ?"

111
, SerializerWriteString.INSTANCE,
SerializerReadString.INSTANCE);

m_dummy = new StaticSentence(s, "SELECT * FROM people WHERE 1


= 0");

final ThumbNailBuilder tnb = new ThumbNailBuilder(32, 32,


"com/openbravo/images/user.png");

Class JPanelMenu:

Esta clase Es una interfaz gráfica, la cual se reutiliza cada vez que se va a
mostrar un menú, como por ejemplo en menú de configuración. Sobre esta interfaz
gráfica se construyen los menús. Esta clase recibe como parámetro un objeto tipo
“MenuDefinition”, su constructor no retorna ningún dato, pero a través del
método getComponet se retorna el objeto creado, para que sea manipulado en
otras clases. El diagrama de esta clase se puede observar en la ilustración 28.

112
Ilustración 28. Clase JPanelMenu

Fuente: elaboración propia

public class JPanelMenu extends JPanel implements JPanelView {

private final MenuDefinition m_menu;


private boolean created = false;

/** Creates new form JStockMenu


* @param menu */
public JPanelMenu(MenuDefinition menu) {

m_menu = menu;
created = false;

initComponents();

Class JPrincipalApp:

Esta es la clase grafica más importante, debido a que sobre esta interfaz se
construye todo el proyecto, esta clase se instancia una única vez durante toda la
ejecución y es reutilizada en todas las vistas del proyecto exceptuando la vista del
login. El constructor de esta clase recibe como parámetros un objeto tipo
JRootApp, el cual proviene de la primera vista, y además recibe otro objeto tipo
AppUser en el cual se encuentra encapsulado todos los permisos del usuario. El
diagrama de esta clase se puede observar en la ilustración 29.

113
Ilustración 29. Clase JPrincipalApp

114
Fuente: elaboración propia

public class JPrincipalApp extends javax.swing.JPanel implements


AppUserView {

private static final Logger logger =


Logger.getLogger("com.openbravo.pos.forms.JPrincipalApp");

private final JRootApp m_appview;


private final AppUser m_appuser;

private DataLogicSystem m_dlSystem;

private JLabel m_principalnotificator;

private JPanelView m_jLastView;


private Action m_actionfirst;

private Map<String, JPanelView> m_aPreparedViews; //


Prepared views
private Map<String, JPanelView> m_aCreatedViews;

private Icon menu_open;


private Icon menu_close;

//HS Updates
private CustomerInfo customerInfo;

/** Creates new form JPrincipalApp

115
* @param appview
* @param appuser */
public JPrincipalApp(JRootApp appview, AppUser appuser) {

Class JRootFrame:

Esta clase es llamada antes que la clase JRootApp, la clase JRootFrame invoca la
clase OSValidator para validar el sistema operativo en el que se está ejecutando el
programa, también hace un llamado a la clase AppProps la cual trae las
propiedades del sistema, y además invoca la clase JRootApp y le envía las
propiedades del sistema como parámetro, adicionalmente, define el título del
programa añadiendo el nombre del programa y su versión. El diagrama de esta
clase se puede observar en la ilustración 30.

Ilustración 30. Clase JRootFrame

Fuente: elaboración propia

116
public class JRootFrame extends javax.swing.JFrame implements
AppMessage {

private InstanceManager m_instmanager = null;

private JRootApp m_rootapp;


private AppProperties m_props;

private OSValidator m_OS;

/** Creates new form JRootFrame */


public JRootFrame() {

initComponents();
}

/**
*
* @param props
* @throws java.io.IOException
*/
public void initFrame(AppProperties props) throws
IOException {

m_OS = new OSValidator();


m_props = props;

Class OSValidator:

117
Esta clase es invocada una única vez en la ejecución del programa y es la
encargada de identificar sobre qué sistema operativo se está ejecutando el
proceso. El diagrama de esta clase se puede observar en la ilustración 31.

Ilustración 31. Clase OSValidator

Fuente: elaboración propia

public class OSValidator {

private String OS =
System.getProperty("os.name").toLowerCase();

/**
*
*/
public OSValidator() {

/**
*
* @return

118
*/
public String getOS(){
if (isWindows()) {
return("w");
} else if (isMac()) {
return("m");
} else if (isUnix()) {
return("l");
} else if (isSolaris()) {
return("s");
} else {
return("x");
}
}

Class BaseSentence:

Esta clase es invocada cada vez que el sistema necesita realizar una consulta a la
base de datos, debido a que la clase es abstracta no posee método constructor y
cada clase que hace uso de esta clase le da sentido a cada uno de sus métodos,
el uso de esta clase siempre se realiza a través de interfaces. El diagrama de esta
clase se puede observar en la ilustración 32.

119
Ilustración 32. Clase BaseSentence

Fuente: elaboración propia

public abstract class BaseSentence implements SentenceList,


SentenceFind, SentenceExec {
public abstract DataResultSet openExec(Object params) throws
BasicException;
public abstract DataResultSet moreResults() throws
BasicException;

/**
*
* @throws BasicException
*/
public abstract void closeExec() throws BasicException;

// Funciones

120
/**
*
* @return
* @throws BasicException
*/
@Override
public final int exec() throws BasicException {
return exec((Object) null);
}

Class Session:

Esta clase se encarga de la sesiones con la base de datos y de gestionar todas


las acciones que se van a realizar en la base de datos. Además posee un
constructor que recibe como parámetros la dirección donde se encuentra alojada
la base de datos, el usuario y contraseña como credenciales para la autenticación
ante el gestor de base de datos. El diagrama de esta clase se puede observar en
la ilustración 33.

121
Ilustración 33. Clase Session

Fuente: elaboración propia

public final class Session {

private final String m_surl;


private final String m_sappuser;
private final String m_spassword;

private Connection m_c;


private boolean m_bInTransaction;

/**
*
*/

122
public final SessionDB DB;

/** Creates a new instance of Session


* @param url
* @param user
* @param password
* @throws java.sql.SQLException */
public Session(String url, String user, String password)
throws SQLException {
m_surl = url;
m_sappuser = user;
m_spassword = password;

m_c = null;
m_bInTransaction = false;

connect(); // no lazy connection

DB = getDiff();
}

Class BasicException:

Esta es la clase encargada de realizar un manejo básico de los errores que


puedan surgir durante la ejecución del programa, cabe mencionar que su
constructor usa el concepto de polimorfismo, por tanto, puede recibir diferentes
parámetros según sea requerido. El diagrama de esta clase se puede observar en
la ilustración 34.

123
Ilustración 34. Clase BasicException

Fuente: elaboración propia

public class BasicException extends java.lang.Exception {

/**
* Creates a new instance of <code>DataException</code>
without detail message.
*/
public BasicException() {
}

/**
*
* @param msg
*/
public BasicException(String msg) {
super(msg);
}

/**
*
* @param msg

124
* @param cause
*/
public BasicException(String msg, Throwable cause) {
super(msg, cause);
}

Class LocaleResources:

Esta clase es la encargada de identificar la ruta donde se encuentran los recursos


del programa, tales como los mensajes del sistema y sus traducciones. El
diagrama de esta clase se puede observar en la ilustración 35.

Ilustración 35. Clase LocaleResources

Fuente: elaboración propia

public class LocaleResources {

private List<ResourceBundle> m_resources;


private ClassLoader m_localeloader;

/** Creates a new instance of LocaleResources */

125
public LocaleResources() {
// m_resources = new LinkedList<ResourceBundle>();
m_resources = new LinkedList<>();

File fuserdir = new File(System.getProperty("user.dir"));


File fresources = new File(fuserdir, "locales");
try {
m_localeloader = URLClassLoader.newInstance(
new URL[] { fresources.toURI().toURL() },
Thread.currentThread().getContextClassLoader());
} catch (MalformedURLException e) {
m_localeloader =
Thread.currentThread().getContextClassLoader();
}
}

public ResourceBundle getBundle(String bundlename) {


return ResourceBundle.getBundle(bundlename,
Locale.getDefault(), m_localeloader);
}

Class SaveProvider:

Esta clase se encarga de almacenar las acciones de los botones guardar, agregar
y eliminar de cada una de las interfaces de gestión del sistema, su constructor es
polimorfo pero el constructor que se usa con mas frecuencia es public
SaveProvider(SentenceExec sentupdate, SentenceExec sentinsert,
SentenceExec sentdelete), el cual recibe tres parámetros , de tipo
SentenceExec, cada uno de los cuales representa la acción que tomará uno de

126
los tres botones anteriormente mencionados. El diagrama de esta clase se puede
observar en la ilustración 36.

Ilustración 36. Clase SaveProvider

Fuente: elaboración propia

public class SaveProvider {

protected SentenceExec m_sentupdate;


protected SentenceExec m_sentinsert;
protected SentenceExec m_sentdelete;

/** Creates a new instance of SavePrSentence


* @param sentupdate
* @param sentdelete
* @param sentinsert */
public SaveProvider(SentenceExec sentupdate, SentenceExec
sentinsert, SentenceExec sentdelete) {

127
m_sentupdate = sentupdate;
m_sentinsert = sentinsert;
m_sentdelete = sentdelete;
}

Class ProductsPanel:

Esta clase se encarga de cargar el panel de acciones en la interfaz gráfica para


gestionar los productos, el constructor de esta clase no recibe parametros y
ademas el metodo constructor es sobre escrito con un método llamado init, en el
cual se carga una instancia de la clase SaveProvider con las acciones y además
se obtienen todos los productos agregados al sistema. El diagrama de esta clase
se puede observar en la ilustración 37.

Ilustración 37. Clase ProductsPanel

Fuente: elaboración propia

128
public class ProductsPanel extends JPanelTable2 implements
EditorListener {

private ProductsEditor jeditor;


private ProductFilter jproductfilter;

private DataLogicSales m_dlSales = null;


private API_interface m_ai = null;

public ProductsPanel() {
}

/**
*
*/
@Override
protected void init() {
m_dlSales = (DataLogicSales)
app.getBean("com.openbravo.pos.forms.DataLogicSales");

jproductfilter = new ProductFilter();


jproductfilter.init(app);

row = m_dlSales.getProductsRow();

lpr = new ListProviderCreator(m_dlSales.getProductCatQBF(),


jproductfilter);

spr = new SaveProvider(

129
m_dlSales.getProductCatUpdate(),
m_dlSales.getProductCatInsert(),
m_dlSales.getProductCatDelete()//,
//m_ai.createProduct(TOOL_TIP_TEXT_KEY)
);

jeditor = new ProductsEditor(app, dirty);


}

Class ProductsEditor:

Esta clase es la interfaz gráfica para crear, actualizar y eliminar un producto,en


esta clase se encuentran los 5 tabs de esta interfaz los cuales son: ‘General’,
‘Stock’, ‘Image’, ‘Button’ y ‘Properties’. El constructor de esta clase, recibe como
parámetros un objeto tipo AppView y otro parámetro tipo DirtyManager, el
resultado de esta clase es la interfaz gráfica. El diagrama de esta clase se puede
observar en la ilustración 38.

130
Ilustración 38. Clase ProductsEditor

Fuente: elaboración propia

public final class ProductsEditor extends javax.swing.JPanel


implements EditorRecord {

private static final long serialVersionUID = 1L;


private Object m_oId;

private final DataLogicSales dlSales;


private final DataLogicSuppliers m_dlSuppliers;

131
private final SentenceList m_sentcat;
private ComboBoxValModel m_CategoryModel;

private final SentenceList taxcatsent;


private ComboBoxValModel taxcatmodel;

private final SentenceList attsent;


private ComboBoxValModel attmodel;

private final SentenceList m_sentsuppliers;


private ComboBoxValModel m_SuppliersModel;

private final SentenceList taxsent;


private TaxesLogic taxeslogic;

public ProductsEditor(AppView app, DirtyManager dirty) {

setAppView(app);
dlSales = (DataLogicSales)
app.getBean("com.openbravo.pos.forms.DataLogicSales");
m_dlSuppliers = (DataLogicSuppliers)
app.getBean("com.openbravo.pos.suppliers.DataLogicSuppliers");

initComponents();

loadimage = dlSales.getProductImage(); // JG 3 feb 16


speedup

taxsent = dlSales.getTaxList();

132
m_sentcat = dlSales.getCategoriesList();
m_CategoryModel = new ComboBoxValModel();

taxcatsent = dlSales.getTaxCategoriesList();
taxcatmodel = new ComboBoxValModel();

Class DirtyManager:

Esta clase se encarga de estar al tanto si los datos de un formulario fueron o no


modificados, de esta manera, activar o desactivar las opciones de guardado. El
diagrama de esta clase se puede observar en la ilustración 39.

Ilustración 39. Clase DirtyManager

Fuente: elaboración propia

public class DirtyManager implements DocumentListener,

133
ChangeListener, ActionListener, PropertyChangeListener {

private boolean m_bDirty;


protected Vector listeners = new Vector();
/** Creates a new instance of DirtyManager */
public DirtyManager() {
m_bDirty = false;
}
/**
*
* @param l
*/
public void addDirtyListener(DirtyListener l) {
listeners.add(l);
}
/**
*
* @param l
*/
public void removeDirtyListener(DirtyListener l) {
listeners.remove(l);
}

Class ProductFilter:

Esta clase es un formulario el cual se es utilizado para generar un filtro de


búsqueda para un producto, este formulario permite agregar parámetros de filtrado
tales como: Categoría del producto, precio de compra, código de barras, entre
otros.Esta clase es usada en la mayoría de las interfaces para generar reportes

134
sobre los productos. El diagrama de esta clase se puede observar en la ilustración
40.

Ilustración 40. Clase ProductFilter

Fuente: elaboración propia

public class ProductFilter extends javax.swing.JPanel implements


ReportEditorCreator {

private SentenceList m_sentcat;


private ComboBoxValModel m_CategoryModel;

135
/** Creates new form JQBFProduct */
public ProductFilter() {

initComponents();
}

/**
*
* @param app
*/
@Override
public void init(AppView app) {

DataLogicSales dlSales = (DataLogicSales)


app.getBean("com.openbravo.pos.forms.DataLogicSales");

m_sentcat = dlSales.getCategoriesList();
m_CategoryModel = new ComboBoxValModel();

m_jCboName.setModel(ListQBFModelNumber.getMandatoryString())
;

m_jCboPriceBuy.setModel(ListQBFModelNumber.getMandatoryNumbe
r());

m_jCboPriceSell.setModel(ListQBFModelNumber.getMandatoryNumb
er());
}

136
Class DataLogicReceipts:

Esta clase se encarga de gestionar los permisos de los tickets que son
compartidos entre usuarios, es decir, esta clase puede bloquear la acción de
modificar un ticket a cualquier usuario. El diagrama de esta clase se puede
observar en la ilustración 41.

Ilustración 41. Clase DataLogicReceipts

Fuente: elaboración propia

public class DataLogicReceipts extends BeanFactoryDataSingle {


private Session s;
/** Creates a new instance of DataLogicReceipts */
public DataLogicReceipts() {

137
}
/**
*
* @param s
*/
@Override
public void init(Session s){
this.s = s;
}
/**
*
* @param Id
* @return
* @throws BasicException
*/
public final TicketInfo getSharedTicket(String Id) throws
BasicException {
if (Id == null) {
return null;
} else {
Object[]record = (Object[]) new StaticSentence(s
, "SELECT CONTENT, LOCKED FROM sharedtickets
WHERE ID = ?"
, SerializerWriteString.INSTANCE
, new SerializerReadBasic(new Datas[] {
Datas.SERIALIZABLE})).find(Id);
return record == null ? null : (TicketInfo) record[0];
}
}

138
Script MySQL-create.sql

Este script, es el encargado de crear las tablas de la base de datos por primera
vez, es decir, que si se desea adicionar otra tabla al proyecto, el query debería de
ir dentro de este archivo.

/* Header line. Object: applications. Script date: 27/08/2015


08:42:37. */
CREATE TABLE `applications` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`version` varchar(255) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

/* Header line. Object: attribute. Script date: 27/08/2015


08:42:37. */
CREATE TABLE `attribute` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

/* Header line. Object: attributeinstance. Script date:


27/08/2015 08:42:37. */
CREATE TABLE `attributeinstance` (
`id` varchar(255) NOT NULL,
`attributesetinstance_id` varchar(255) NOT NULL,
`attribute_id` varchar(255) NOT NULL,
`value` varchar(255) default NULL,
KEY `attinst_att` ( `attribute_id` ),
KEY `attinst_set` ( `attributesetinstance_id` ),
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

139
Script MySQL-check-tables.sql

Este script se encarga de verificar durante una actualización, si hay una tabla
dentro del proyecto que no exista y si es así la crea. Debido a esto acá también
debería ir el query si se llegase a crear una nueva tabla

*
* Script created by Jack, uniCenta 23/07/2016 08:00:00
*
* Check DB tables.
*/
/* Header line. Object: applications. Script date: 23/07/2016
08:00:00 */
CREATE TABLE IF NOT EXISTS `applications` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`version` varchar(255) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

/* Header line. Object: attribute. Script date: 23/07/2016


08:00:00 */
CREATE TABLE IF NOT EXISTS `attribute` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

/* Header line. Object: attributeinstance. Script date:


23/07/2016 08:00:00 */
CREATE TABLE IF NOT EXISTS `attributeinstance` (
`id` varchar(255) NOT NULL,
`attributesetinstance_id` varchar(255) NOT NULL,
`attribute_id` varchar(255) NOT NULL,
`value` varchar(255) default NULL,

140
KEY `attinst_att` ( `attribute_id` ),
KEY `attinst_set` ( `attributesetinstance_id` ),
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

Script MySQL-dropFKeys.sql

Este script es invocado a la hora de actualizar la versión de la base de datos, ya


que posiblemente se agreguen o se eliminen llaves foráneas, entonces se
eliminan todas las relaciones para de esta manera, evitar conflictos a la hora de la
actualización.

/*
* Script created by Jack, uniCenta 07/08/2016 08:00:00
*
*/

/* Header line. Object: applications. Script date: 07/08/2016


08:00:00 */

ALTER TABLE PEOPLE DROP FOREIGN KEY PEOPLE_FK_1;

ALTER TABLE ATTRIBUTEINSTANCE DROP FOREIGN KEY ATTINST_SET;


ALTER TABLE ATTRIBUTEINSTANCE DROP FOREIGN KEY ATTINST_ATT;

ALTER TABLE ATTRIBUTESETINSTANCE DROP FOREIGN KEY ATTSETINST_SET;

ALTER TABLE ATTRIBUTEUSE DROP FOREIGN KEY ATTUSE_SET;


ALTER TABLE ATTRIBUTEUSE DROP FOREIGN KEY ATTUSE_ATT;

ALTER TABLE ATTRIBUTEVALUE DROP FOREIGN KEY ATTVAL_ATT;

ALTER TABLE CATEGORIES DROP FOREIGN KEY CATEGORIES_FK_1;

ALTER TABLE CUSTOMERS DROP FOREIGN KEY CUSTOMERS_TAXCAT;

141
ALTER TABLE LEAVES DROP FOREIGN KEY lEAVES_PPLID;

ALTER TABLE PAYMENTS DROP FOREIGN KEY PAYMENTS_FK_RECEIPT;

ALTER TABLE PRODUCTS DROP FOREIGN KEY PRODUCTS_ATTRSET_FK;


ALTER TABLE PRODUCTS DROP FOREIGN KEY PRODUCTS_TAXCAT_FK;
ALTER TABLE PRODUCTS DROP FOREIGN KEY PRODUCTS_FK_1;

ALTER TABLE PRODUCTS_CAT DROP FOREIGN KEY PRODUCTS_CAT_FK_1;

142
ANEXO C: DISGREGACIÓN DE PRODUCTO

LISTA DE ILUSTRACIONES

ILUSTRACIÓN 42. DIAGRAMA DE CASOS DE USO – NIVEL 0: DISGREGACIÓN DE PRODUCTO ... 148
ILUSTRACIÓN 43. DIAGRAMA DE CASOS DE USO - NIVEL 1: DISGREGACIÓN DE PRODUCTO...... 148
ILUSTRACIÓN 44. DIAGRAMA DE ACTIVIDADES: DISGREGACIÓN DE PRODUCTO .......................... 150
ILUSTRACIÓN 45. MODELO RELACIONAL: DISGREGACIÓN DE PRODUCTO ..................................... 151
ILUSTRACIÓN 46. MOCKUP DE DISGREGACIÓN DE PRODUCTO ....................................................... 151
ILUSTRACIÓN 47. MOCKUP DE BÚSQUEDA DE PRODUCTO ................................................................ 152
ILUSTRACIÓN 48. CLASE PRODUCTSBUNDLEINFO ............................................................................. 153
ILUSTRACIÓN 49. INTERFAZ PARA AGREGAR UN PRODUCTO A DISGREGAR .................................. 156
ILUSTRACIÓN 50. INTERFAZ DE BÚSQUEDA DE PRODUCTO .............................................................. 156

LISTA DE TABLAS

TABLA 5. PONDERACIÓN DE REQUISITOS: DISGREGACIÓN DE PRODUCTOS ................................. 144


TABLA 6. DEFINICIÓN DE REQUISITO 1: DISGREGACIÓN DE PRODUCTO ........................................ 145
TABLA 7. DEFINICIÓN DE REQUISITO 2: DISGREGACIÓN DE PRODUCTO ........................................ 145
TABLA 8. DEFINICIÓN DE REQUISITO 3: DISGREGACIÓN DE PRODUCTO ........................................ 146
TABLA 9. DEFINICIÓN DE REQUISITO 4: DISGREGACIÓN DE PRODUCTO ........................................ 146
TABLA 10. DEFINICIÓN DE REQUISITO 5: DISGREGACIÓN DE PRODUCTO ...................................... 146
TABLA 11. DEFINICIÓN DE REQUISITO 6: DISGREGACIÓN DE PRODUCTO ...................................... 147

143
Como se plantea en los objetivos, una de las intenciones del proyecto es llevar a
cabo una adaptación de la disgregación de productos; ésta consiste en lograr que
un producto esté conformado por sub-productos, los cuales podrán ser tenidos en
cuenta en la gestión de Inventarios, sean gestionados en el comercio electrónico.

A continuación se detallan los elementos planteados en la gestión de requisitos


como parte de la Ingeniería de Software aplicada.

Análisis:

En esta fase del módulo, lo que se realizó fue primero que todo la elicitación de los
requisitos, los cuales fueron adquiridos utilizando dos métodos diferentes, la lluvia
de ideas y a través del prototipado. Después de haber adquirido dichos requisitos,
se realizó un análisis de los mismos en donde se realizó una ponderación de cada
uno de ellos y se clasificaron.

Requisitos:

En la tabla 5, se puede observar la ponderación de los requisitos del módulo.

Tabla 5. Ponderación de requisitos: Disgregación de productos

ID Nombre Ponderación

REQ1 Filtro de búsqueda 3.5

REQ2 Especificación de cabecera 4.5

REQ3 Añadir productos disgregados 4.5

REQ4 Cantidad necesaria del producto 4.5

REQ5 Listar productos del producto disgregado 3.9

REQ6 Reducción de stock en venta 4.5

Fuente: elaboración propia

144
En las tablas 6,7,8,9,10 y 11 se definen los requisitos para la disgregación de
productos.

Tabla 6. Definición de requisito 1: Disgregación de producto

Fuente: elaboración propia


Tabla 7. Definición de requisito 2: Disgregación de producto

Fuente: elaboración propia

145
Tabla 8. Definición de requisito 3: Disgregación de producto

Fuente: elaboración propia

Tabla 9. Definición de requisito 4: Disgregación de producto

Fuente: elaboración propia

Tabla 10. Definición de requisito 5: Disgregación de producto

Fuente: elaboración propia

146
Tabla 11. Definición de requisito 6: Disgregación de producto

Fuente: elaboración propia

147
Diagramas de casos de uso:

En la ilustraciones 42 y 43 se pueden observar los diagramas de casos de uso del


módulo.

Ilustración 42. Diagrama de casos de uso – nivel 0: Disgregación de producto

Fuente: elaboración propia

Ilustración 43. Diagrama de casos de uso - nivel 1: Disgregación de producto

Fuente: elaboración propia

148
Diagrama de actividades:

En la ilustración 44 se puede observar el diagrama de actividades del módulo.

149
Ilustración 44. Diagrama de actividades: Disgregación de producto

Fuente: elaboración propia

150
Modelo relacional:

En la ilustración 45 se puede observar el modelo relacional del módulo.

Ilustración 45. Modelo relacional: Disgregación de producto

Fuente: elaboración propia

Mockups:
En las ilustraciones 46 y 47, se puede observar los mockups del módulo.

Ilustración 46. Mockup de Disgregación de producto

Fuente: elaboración propia

151
Ilustración 47. Mockup de búsqueda de producto

Fuente: elaboración propia

Codificación:

Clase ProductsBundleInfo:

Esta clase es la clase que cumple función de modelo de un producto disgregado.


El diagrama de esta clase se puede observar en la ilustración 48.

152
Ilustración 48. Clase ProductsBundleInfo

Fuente: elaboración propia

public class ProductsBundleInfo {


private static final long serialVersionUID = 7587646873036L;

protected String id;


protected String productId;
protected String productBundleId;
protected Double quantity;

/**
*
* @param id
* @param productId
* @param productBundleId
* @param quantity
*/
public ProductsBundleInfo(String id, String productId,
String productBundleId, Double quantity) {

153
this.id = id;
this.productId = productId;
this.productBundleId = productBundleId;
this.quantity = quantity;
}

public void setM_ID(String id) {


this.id = id;
}

public void setM_sProduct(String productId) {


this.productId = productId;
}

public void setM_sProductBundle(String productBundleId) {


this.productBundleId = productBundleId;
}

Clase DataLogicSales:

Como fue mencionado en el ANEXO B: INGENIERÍA INVERSA DE UNICENTA, la


clase DataLogicSales, es la encargada de realizar las consultas a la base de
datos, por tanto, en esta clase se escribieron las consultas necesarias para el
funcionamiento del módulo, a continuación, se pueden apreciar fragmentos de
ellas.

/**
*
* @param productId The product id to look for bundle
* @return List of products part of the searched product
* @throws BasicException
*/
public final List<ProductsBundleInfo>
getProductsBundle(String productId) throws BasicException {
return new PreparedSentence(s

154
, "SELECT "
+ "ID, "
+ "PRODUCT, "
+ "PRODUCT_BUNDLE, "
+ "QUANTITY "
+ "FROM products_bundle WHERE PRODUCT = ?"
, SerializerWriteString.INSTANCE
,
ProductsBundleInfo.getSerializerRead()).list(productId);
}

private void adjustStock(Object params) throws BasicException {

List<ProductsBundleInfo> bundle = getProductsBundle((String)


((Object[])params)[0]);

if (bundle.size() > 0) {
for (ProductsBundleInfo component : bundle) {
Object[] adjustParams = new Object[4];
adjustParams[0] = component.getProductBundleId();
adjustParams[1] = ((Object[])params)[1];

adjustParams[2] = ((Object[])params)[2];
adjustParams[3] = ((Double)((Object[])params)[3])
* component.getQuantity();
adjustStock(adjustParams);
}
}

Resultados

A continuación, en las ilustraciones 49 y 50, se puede detallar el proceso de


disgregación de producto, el cual fue encontrado entre los procesos de gestión de
Unicenta y detallados en el presente documento; el proceso de análisis se llevó a
cabo procesando los requisitos e ilustrando el proceso de disgregación de
productos de la aplicación.

155
Ilustración 49. Interfaz para agregar un producto a disgregar

Fuente: elaboración propia

Ilustración 50. Interfaz de búsqueda de producto

Fuente: elaboración propia

156
ANEXO D: SINCRONIZACIÓN CON WOOCOMMERCE
LISTA DE ILUSTRACIONES

ILUSTRACIÓN 51. DIAGRAMA DE CASOS DE USO - NIVEL 0: SINCRONIZACIÓN CON


WOOCOMMERCE .............................................................................................................................. 162
ILUSTRACIÓN 52. DIAGRAMA DE CASOS DE USO - NIVEL 1: SINCRONIZACIÓN CON
WOOCOMMERCE .............................................................................................................................. 163
ILUSTRACIÓN 53. DIAGRAMA DE ACTIVIDADES: SINCRONIZACIÓN CON W OOCOMMERCE.......... 164
ILUSTRACIÓN 54. MODELO RELACIONAL: SINCRONIZACIÓN CON W OOCOMMERCE .................... 165
ILUSTRACIÓN 55. DIAGRAMA DE DESPLIEGUE ..................................................................................... 166
ILUSTRACIÓN 56. MOCKUP DE ATRIBUTOS PARA E-COMMERCE ...................................................... 167
ILUSTRACIÓN 57. MOCKUP PARA MARCAR UN PRODUCTO COMO EN VENTA VIRTUAL ................ 167
ILUSTRACIÓN 58. CLASE APICOLLECTION........................................................................................... 168
ILUSTRACIÓN 59. CLASE PRODUCTAPI ............................................................................. 170
ILUSTRACIÓN 60. INTERFAZ PARA MARCAR UN PRODUCTO COMO EN VENTA VIRTUAL ............... 178
ILUSTRACIÓN 61. INTERFAZ DE ATRIBUTOS PARA E-COMMERCE .................................................... 179

LISTA DE TABLAS

TABLA 12. PONDERACIÓN DE REQUISITOS: SINCRONIZACIÓN CON W OOCOMMERCE ................ 158


TABLA 13. DEFINICIÓN DE REQUISITO 1: SINCRONIZACIÓN CON W OOCOMMERCE ..................... 159
TABLA 14. DEFINICIÓN DE REQUISITO 2: SINCRONIZACIÓN CON W OOCOMMERCE ..................... 159
TABLA 15. DEFINICIÓN DE REQUISITO 3: SINCRONIZACIÓN CON W OOCOMMERCE ..................... 160
TABLA 16. DEFINICIÓN DE REQUISITO 4: SINCRONIZACIÓN CON W OOCOMMERCE ..................... 160
TABLA 17. DEFINICIÓN DE REQUISITO 5: SINCRONIZACIÓN CON W OOCOMMERCE ..................... 160
TABLA 18. CASOS DE PRUEBA: SINCRONIZACIÓN .............................................................................. 177
TABLA 19. REGISTRO DE BUGS: SINCRONIZACIÓN ............................................................................. 178

157
Uno de los objetivos específicos del proyecto, es la sincronización de unicenta con
una plataforma de comercio electrónico, en el presente anexo, se evidencia el
cumplimiento al objetivo anteriormente mencionado.

En primer lugar, antes de comenzar a desarrollar el proceso de análisis del


módulo, se seleccionó cuál sería la plataforma de comercio electrónico con la que
se realizará la sincronización, así que se eligió la plataforma Woocommerce la
cual brinda una muy buena documentación para los desarrolladores, además, es
un plugin de wordpress que cuenta con el respaldo de la comunidad de wordpress,
la cual es bastante grande y activa en la red, lo que brinda un canal de soporte
adicional a la documentación proporcionada por el proyecto. También cabe
resaltar que, Woocommerce es el plugin de wordpress, más usado como
plataforma para soportar tiendas virtuales, ésta es usada por alrededor del 28% [1]
de todas las tiendas virtuales en internet, con lo cual al hacer esta sincronización
impactaría de manera positiva un gran sector de las ventas electrónicas. Por estas
razones anteriormente expuestas, se seleccionó la plataforma Woocommerce
como la candidata ideal para llevar a cabo la sincronización.

A continuación, se detallan los elementos planteados en la gestión de requisitos,


como parte de la Ingeniería de Software aplicada.

Requisitos:

En la tabla 12, se puede observar la ponderación de los requisitos del módulo.

Tabla 12. Ponderación de requisitos: Sincronización con Woocommerce

ID NOMBRE PONDERACIÓN

158
REQ1 Definir productos en venta virtual 3.8

REQ2 Atributos necesarios para woocommerce 4.3

REQ3 Atributo venta virtual 4.6

Cumplir con requisitos rest API


REQ4 woocommerce 4.5

REQ5 Gestion de venta en woocommerce 4.7

4.5
REQ6 Gestión de stock en woocommerce

Fuente: elaboración propia

En las tablas 13, 14, 15,16 y 17 se definen los requisitos para la disgregación de
productos.

Tabla 13. Definición de requisito 1: Sincronización con Woocommerce

Fuente: elaboración propia


Tabla 14. Definición de requisito 2: Sincronización con Woocommerce

159
Fuente: elaboración propia
Tabla 15. Definición de requisito 3: Sincronización con Woocommerce

Fuente: elaboración propia


Tabla 16. Definición de requisito 4: Sincronización con Woocommerce

Fuente: elaboración propia


Tabla 17. Definición de requisito 5: Sincronización con Woocommerce

160
Fuente: elaboración propia
Diagrama de casos de uso:

En la ilustración 51 se puede observar el diagrama de casos de uso del módulo.

161
Ilustración 51. Diagrama de casos de uso - nivel 0: Sincronización con Woocommerce

Fuente: elaboración propia

162
Ilustración 52. Diagrama de casos de uso - nivel 1: Sincronización con Woocommerce

Fuente: elaboración propia

163
Diagrama de actividades:

En la ilustración 52 se puede observar el diagrama de actividades del módulo.

Ilustración 53. Diagrama de actividades: Sincronización con Woocommerce

Fuente: elaboración propia

164
Modelo relacional:

En la ilustración 53 se puede observar el modelo relacional del módulo.

Ilustración 54. Modelo relacional: Sincronización con Woocommerce

Fuente: elaboración propia

165
Diagrama de despliegue:

En la ilustración 54 se puede observar el diagrama de despliegue del proyecto


completo.

Ilustración 55. Diagrama de despliegue

Fuente: elaboración propia

MockUps:

A continuación, se pueden apreciar en las ilustraciones 55 y 56, los mockups


realizados para la sincronización.

166
Ilustración 56. Mockup de atributos para e-commerce

Fuente: elaboración propia

Ilustración 57. Mockup para marcar un producto como en venta virtual

Fuente: elaboración propia

167
Codificación:

A continuación, se podrán apreciar fragmentos del código desarrollado para el


funcionamiento del módulo, algunos de estos fragmentos cuentan con el diagrama
de clases a la cual pertenecen, las líneas y una descripción de la clase.

Clase APICollection (Java):

Esta clase se es la encargada de agrupar todos los métodos que se encargan de


consumir la API desarrollada en Node.js, esta clase no recibe ningún parámetro en
su constructor, pero sus métodos tienen la peculiaridad de que todos reciben un
parámetro tipo Object, esto se debe a que los objetos construidos por Unicenta,
no son mapeados en una clase si no que son construidos dentro de un Objeto.
Esto se convierte en un inconveniente a la hora de crear un JSON a partir de este
objeto no mapeado, por esta razón, todos los métodos de la clase crean una
nueva instancia del tipo de objeto necesario, es decir, si un método va a crear un
producto el objeto es enviado como parámetro al constructor de la clase producto,
que fue desarrollada, con el único fin de mapear los objetos, y de este modo poder
generar un JSON utilizando la librería Gson para poder realizar la petición a la
API. El diagrama de esta clase se puede observar en la ilustración 57

Ilustración 58. Clase APICollection

168
Fuente: elaboración propia

/**
* Last modification: 08-08-2018 12:31 am
* @description This is the collection of
* api interfaces, if you want to consume the api
* you wanna see the method in this class
* @author ceul
*/
public class APICollection implements API_interface{

private ProductAPIInterface productAPI;


private Product product;

public APICollection() {
productAPI = new ProductAPI();
}

public String createProduct(Object params) throws


BasicException{
this.product = new Product(params);
GsonBuilder builder = new GsonBuilder();
builder.setPrettyPrinting();
Gson gson = builder.create();
return productAPI.createProduct(gson.toJson(this.product));
}

public String updateProduct(Object params) throws


BasicException{
this.product = new Product(params);
GsonBuilder builder = new GsonBuilder();
builder.setPrettyPrinting();
Gson gson = builder.create();
return productAPI.updateProduct(gson.toJson(product));

Clase ProductAPI (Java):

169
Esta clase es la encargada de realizar las peticiones a la API. Todos los métodos
de esta clase corresponden a un servicio de la API, los métodos de esta clase
reciben como parámetro un String en donde viene el JSON con el cual se va a
realizar la petición. El diagrama de esta clase se puede observar en la ilustración
58.

Ilustración 59. Clase ProductAPI

Fuente: elaboración propia

/**
* Last modification: 08-08-2018 12:31 am
* @description
* @author ceul
**/
public class ProductAPI implements ProductAPIInterface {
private Http con;
private String resource;
private String url;

public String createProduct(String product){


try {
this.con.post(getUrl()+"/product/create", product);
return resource;

170
} catch (Exception e) {
return resource;
}
}

public String updateProduct(String product){


try {
this.con.post(getUrl()+"/product/update", product);
return resource;
} catch (Exception e) {
return resource;
}
}

public String deleteProduct(String product){


try {
this.con.post(getUrl()+"/product/delete", product);
return resource;
} catch (Exception e) {
return resource;

Clase ProductEditor (Java):

Esta clase es la interfaz gráfica, la cual permite agregar un producto, a


continuación se encuentran fragmentos de código de algunos métodos que
tuvieron que ser alterados, para agregar los nuevos campos que son necesarios
para el funcionamiento del módulo.

@Override
public void writeValueInsert() {
m_jWebSell.setSelected(false);
m_jDescription.setText(null);
m_jShortDescription.setText(null);
m_jLength.setText("0");
m_jWeigth.setText("0");

171
m_jWidth.setText("0");
m_jHeight.setText("0");
}

@Override
public Object createValue() throws BasicException {

Object[] myprod = new Object[38];

myprod[29] = Boolean.valueOf(m_jWebSell.isSelected());
myprod[30] = m_jDescription.getText();
myprod[31] = m_jShortDescription.getText();
myprod[32] =
Formats.DOUBLE.parseValue(m_jLength.getText());
myprod[33] =
Formats.DOUBLE.parseValue(m_jWeigth.getText());
myprod[34] =
Formats.DOUBLE.parseValue(m_jWidth.getText());
myprod[35] =
Formats.DOUBLE.parseValue(m_jHeight.getText());
myprod[36] = m_jInCatalog.isSelected();
myprod[37] =
Formats.INT.parseValue(m_jCatalogOrder.getText());
return myprod;
}

Clase WooProductDAO (TypeScript):

Esta clase hace parte de la API y es la que se encarga de realizar la interacción


con Woocommerce, el constructor de esta API recibe como parámetro un objeto
tipo WooCommerceAPI y no retorna nada, cada uno de los métodos presentes
dentro de esta clase, es una interacción diferente con la API de Woocommerce,
algunos de estos métodos reciben parámetros de diferentes tipos según sea la

172
necesidad, además, ciertos métodos también realizan la acción de realizar
consultas directamente a la base de datos del proyecto.

export class WooProductDAO {

constructor(private WooCommerce: WooCommerceAPI) {


productDAO= new OctoPosProductDAO();
}

/**
* Last modification: 09-07-2018 11:29 am
* @description This method consume the woocommerce api
* to get a list of products, return the response of
* woocomemerce's api
* @returns {json}
* @author Carlos Urrego
*/
public getProducts() {
try {
return this.WooCommerce.get('/products',
function(err, data, res){
if (err) {
return err;
} else {
return data;
}
});
} catch (error) {
console.log('An error occurred while the products
were obtained ' + error + ` ${WooProductDAO.name} ->
${this.getProducts.name}`);
return error;
}
}

/**

173
* Last modification: 06-07-2018 11:52 am
* @description This method consume the woocommerce api
* to get a product, return the response of
* woocomemerce's api
* @param id : string, is the product's id
* @returns {json}
* @author Carlos Urrego
*/
public getProductWithID(id: string) {
try {
return new Promise( ( resolve, reject ) => {
this.WooCommerce.get('products/' + id,
function(err, data, res){
if (err) {
resolve(err);
} else {
resolve(data);
}
});
} );

} catch (error) {
console.log('An error occurred while the product was
obtained ' + error + ` ${WooProductDAO.name} ->
${this.getProductWithID.name}`);
}
}

/**
* Last modification: 12-09-2018 17:40
* @description This method consume the woocommerce api
* to create a product, return the response of
* woocomemerce's api
* @param product : any, is the product object
* @returns {json}
* @author Carlos Urrego
*/
public async createProduct(product: OctoPosProduct) {

174
try {
let wooproduct =
this.OctoPosProducttoWoocommerce(product);
let imgUrl= await
this.uploadImage(product.image,product.id);
let cat = await
productDAO.getProductExternCategory(product.category);
if((<any> cat).length > 0){
wooproduct.categories = [{
id: cat[0].extern_id
}]

Clase Routes (TypeScript):

En esta clase se crean las rutas que va a aceptar la API, es decir, se exhiben los
servicios a los clientes, para cada uno de estos servicios se define el método por
el cual se va a acceder a él, el URL y cuál va a ser el proceso a realizar después
de recibida la petición.

export class Routes {

public productController: ProductController = new ProductController();

public routes(app): void {

app.route('/')
.get((req: Request, res: Response) => {
res.status(200).send({
message: 'GET request successfulll!!!!'
})
})

app.route('/product')
.post(this.productController.getProducts)

app.route('/product/read/:productId')
.post(this.productController.getProductWithID)

175
app.route('/product/create')
.post(this.productController.createProduct)

app.route('/product/update')
.post(this.productController.updateProduct)

app.route('/stock/update')
.post(this.productController.updateStockProduct)

Script SQL para la creación de tablas:

Este es un fragmento del script utilizado para la creación de las tablas necesarias
para el funcionamiento del módulo de sincronización.

CREATE TABLE `platform` (


`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

CREATE TABLE `conection` (


`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`user` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`version` varchar(255) NOT NULL,
`platform_id` varchar(255) NOT NULL,
PRIMARY KEY ( `id` ),
KEY `platform_fk_conection` ( `platform_id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

CREATE TABLE `extern_product` (


`id` varchar(255) NOT NULL,
`platform_id` varchar(255) NOT NULL,
`local_id` varchar(255) NOT NULL,
`extern_id` varchar(255) NOT NULL,

176
PRIMARY KEY ( `id` ),
KEY `platform_fk_extern_product` ( `platform_id` ),
KEY `product_fk_local_product` ( `local_id` )
) ENGINE = InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT = Compact;

ALTER TABLE `conection` ADD CONSTRAINT `platform_fk_conection`


FOREIGN KEY ( `platform_id` ) REFERENCES `platform` ( `id` );

Pruebas:

Como proceso final del desarrollo del módulo se llevaron a cabo, unas cuantas
pruebas las cuales quedaron registradas en las tablas 18 y 19.
Tabla 18. Casos de prueba: Sincronización

Fuente: elaboración propia

177
Tabla 19. Registro de bugs: Sincronización

Fuente: elaboración propia

Logros:

En las ilustraciones 59 y 60 se puede apreciar, las interfaces finales desarrolladas


en este módulo.

Ilustración 60. Interfaz para marcar un producto como en venta virtual

Fuente: elaboración propia

178
Ilustración 61. Interfaz de atributos para e-commerce

Fuente: elaboración propia

179
ANEXO E: OCTOPOS APP

LISTA DE ILUSTRACIONES

ILUSTRACIÓN 61. DIAGRAMA DE CASO DE USO – NIVEL 0: OCTOPOS APP.................................... 185


ILUSTRACIÓN 62. DIAGRAMA DE CASO DE USO – NIVEL 1 : OCTOPOS APP................................... 185
ILUSTRACIÓN 63. MOCKUP LISTADO DE MESAS: OCTOPOS APP .................................................... 186
ILUSTRACIÓN 64. MOCKUP LISTADO DE CATEGORÍAS: OCTOPOS APP ......................................... 187
ILUSTRACIÓN 65. MOCKUP LISTADO DE PRODUCTOS: OCTOPOS APP........................................... 188
ILUSTRACIÓN 66. MOCKUP FINALIZACIÓN DE PEDIDO: OCTOPOS APP .......................................... 189
ILUSTRACIÓN 67. USUARIOS DE LA APLICACIÓN ................................................................................. 203
ILUSTRACIÓN 68. LUGARES DEL RESTAURANTE ................................................................................. 204
ILUSTRACIÓN 69. PEDIDO ........................................................................................................................ 205
ILUSTRACIÓN 70. CATEGORÍAS DE PRODUCTOS................................................................................. 206
ILUSTRACIÓN 71. SUB CATEGORÍAS DE PRODUCTOS ........................................................................ 207
ILUSTRACIÓN 72. PRODUCTOS ............................................................................................................... 208

LISTA DE TABLAS

TABLA 20. PONDERACIÓN DE REQUISITOS: OCTOPOS APP ............................................... 181


TABLA 21. DEFINICIÓN DE REQUISITO 1: OCTOPOS APP .................................................................. 182
TABLA 22. DEFINICIÓN DE REQUISITO 2: OCTOPOS APP .................................................................. 182
TABLA 23. DEFINICIÓN DE REQUISITO 3: OCTOPOS APP .................................................................. 182
TABLA 24. DEFINICIÓN DE REQUISITO 4: OCTOPOS APP .................................................................. 182
TABLA 25. DEFINICIÓN DE REQUISITO 5: OCTOPOS APP .................................................................. 183
TABLA 26. DEFINICIÓN DE REQUISITO 6: OCTOPOS APP .................................................................. 183
TABLA 27. DEFINICIÓN DE REQUISITO 7: OCTOPOS APP .................................................................. 183
TABLA 28. DEFINICIÓN DE REQUISITO 8: OCTOPOS APP .................................................................. 184
TABLA 29. DEFINICIÓN DE REQUISITO 9: OCTOPOS APP .................................................................. 184
TABLA 30. CASOS DE PRUEBA: OCTOPOS APP ................................................................ 201
TABLA 31. REGISTRO DE ERRORES: OCTOPOS APP ......................................................... 201

180
Dentro de los objetivos específicos del proyecto, se plantea el desarrollo de una
aplicación para realizar pedidos desde dispositivos móviles, con sistema operativo
android, esta aplicación tiene como propósito facilitar los procesos de toma de
pedidos en restaurantes, cafés y bares.

La aplicación se limita a realizar pedidos y que estos queden registrados en la


base de datos. Debido a que se tomó la decisión de desarrollar una aplicación
híbrida, con el fin que la aplicación sea la base para un proyecto web, se optó por
desarrollar la aplicación en el framework Angular, ya que este tiene cierta
compatibilidad con los dispositivos móviles a la hora de crear una aplicación para
estas plataformas. Para crear la apk en base al código Angular se utilizó
Phonegap.

A continuación, se detallan los elementos planteados en la gestión de requisitos


como parte de la Ingeniería de Software aplicada.
Requisitos:

En la tabla 20, se puede observar la ponderación de los requisitos del módulo.

Tabla 20. Ponderación de requisitos: OctoPOS APP

ID NOMBRE PONDERACIÓN

REQ1 Mostrar mesas activas 2.9

REQ2 Mesas disponibles 3.8

REQ3 Cantidad del pedido 4.5

REQ4 Mostrar producto 4.5

REQ5 Mostrar categorías 4.5

REQ6 Plataforma 4.5

REQ7 Selección de zonas 4.5

REQ8 Selección de mesas 4.5

REQ9 Gestión de pedidos 4.5

181
Fuente: elaboración propia

De la tabla 21 a la 29 se definen los requisitos para la aplicación móvil.

Tabla 21. Definición de requisito 1: Octopos App

Fuente: elaboración propia


Tabla 22. Definición de requisito 2: Octopos App

Fuente: elaboración propia


Tabla 23. Definición de requisito 3: Octopos App

Fuente: elaboración propia


Tabla 24. Definición de requisito 4: Octopos App

182
Fuente: elaboración propia

Tabla 25. Definición de requisito 5: Octopos App

Fuente: elaboración propia

Tabla 26. Definición de requisito 6: Octopos App

Fuente: elaboración propia

Tabla 27. Definición de requisito 7: Octopos App

183
Fuente: elaboración propia

Tabla 28. Definición de requisito 8: Octopos App

Fuente: elaboración propia

Tabla 29. Definición de requisito 9: Octopos App

Fuente: elaboración propia

Diagramas de casos de uso:

184
En la ilustración 61 y 62, se aprecia el diagrama de casos de uso del módulo

Ilustración 62. Diagrama de caso de uso – nivel 0: Octopos App

Fuente: elaboración propia

Ilustración 63. Diagrama de caso de uso – nivel 1 : Octopos App

Fuente: elaboración propia

MockUps:

En las ilustraciones 63, 64, 65 y 66 se presentan los mockups de la aplicación.

185
Ilustración 64. Mockup listado de mesas: Octopos App

Fuente: elaboración propia

186
Ilustración 65. Mockup listado de categorías: Octopos App

Fuente: elaboración propia

187
Ilustración 66. Mockup listado de productos: Octopos App

Fuente: elaboración propia

188
Ilustración 67. Mockup finalización de pedido: Octopos App

Fuente: elaboración propia

189
Código:

Seguidamente, se podrán apreciar fragmentos del código desarrollado para la


aplicación, los fragmentos estarán acompañados por una descripción a cerca de
su funcionamiento. Para el desarrollo de la aplicación se desarrolló el Backend en
NodeJS y para el Frontend en Angular 6, así que esta sección del documento se
dividirá en una sección con código para el backend y otra para el frontend.

A. BackEnd (NodeJS):

Clase Routes:

Esta clase es la encargada de exponer los servicios de la API, para que puedan
ser consumidos, en el siguiente código se puede apreciar los servicios que
consume la aplicación para su funcionamiento.

import {Request, Response, NextFunction} from "express";


import { ProductController } from "../controllers/productController";
var cors = require('cors');
export class Routes {
public productController: ProductController = new ProductController();
public routes(app): void
app.route('/product/get-catalog')
.post(this.productController.getProductCatalog)
app.route('/categories/get-root')
.post(this.productController.getRootCatergories)
app.route('/categories/get-sub')
.post(this.productController.getSubCatergories)
app.route('/sharedticket/get')
.post(this.productController.getSharedTicket)
app.route('/sharedticket/create')

190
.post(this.productController.insertSharedTicket)
app.route('/sharedticket/update')
.post(this.productController.updateSharedTicket)
app.route('/sharedticket/delete')
.post(this.productController.deleteSharedTicket)
app.route('/user/get')
.post(this.productController.getUser)
app.route('/place/get')
.post(this.productController.getPlaces)
app.route('/floor/get')
.post(this.productController.getFloors)
app.route('/tax/get')
.post(this.productController.getTaxes)

Clase ProductsController:

Esta clase es el controlador de la API, esta se encarga de delegar los métodos


que van a resolver las peticiones de los usuarios.

export class ProductController {


public async getRootCatergories (req: Request, res: Response) {
try {
res.send(await OctoPos.getRootCatergories());
} catch (error) {
console.log('An error occurred while the categories were
obtained ' + error + ` ${ProductController.name}`);
}
}

public async getSubCatergories (req: Request, res: Response) {


try {
res.send(await OctoPos.getSubCatergories(req.body.category));

191
} catch (error) {
console.log('An error occurred while the categories were
obtained ' + error + ` ${ProductController.name}`);
}
}

public async getProductCatalog (req: Request, res: Response) {


try {
res.send(await OctoPos.getProductCatalog(req.body.category));
} catch (error) {
console.log('An error occurred while the product catalog was
obtained' + error + ` ${ProductController.name}`);
}
}

Clase OctoPosDAO:

Esta clase es la encargada de realizar las consultas a la base de datos, en el


siguiente código se puede apreciar dos de los muchos métodos usados para
realizar consultas, cabe resaltar que cada uno de esto métodos siempre devolverá
una promesa, de esta forma, se asegura el asincronismo de la API.

export class OctoPosProductDAO {


private connection;
constructor() {
this.connection = DataBaseService.getInstance();
}
public getRootCatergories() {
try {
let con = this.connection.getConnection();
return new Promise((resolve, reject) => {

192
return con.query(`SELECT
ID,
NAME,
IMAGE,
TEXTTIP,
CATSHOWNAME,
CATORDER
FROM categories
WHERE PARENTID IS NULL AND CATSHOWNAME = TRUE
ORDER BY CATORDER, NAME;`, (err, rows) => {
if (err)
return reject(err);
resolve(rows);
});
});

} catch (error) {
console.log('An error occurred while getting Root Catergories
:' + error + `: ${OctoPosProductDAO.name} ->
${this.getRootCatergories.name}`);
}
}

public getSubCatergories(parentid: string) {


try {
let con = this.connection.getConnection();
return new Promise((resolve, reject) => {
return con.query(`SELECT
ID,
NAME,
IMAGE,
TEXTTIP,
CATSHOWNAME,

193
CATORDER
FROM categories WHERE PARENTID = ${parentid}
ORDER BY CATORDER, NAME;`, (err, rows) => {
if (err)
return reject(err);
resolve(rows);
});
});

Clase DataBaseService:

Esta clase es la encargada de proporcionar a toda la API el servicio de conexión a


la base de datos, debido a que esta clase será altamente usada por motivos de
ahorro de espacio y rapidez, se decidió que la clase debería seguir un patrón de
diseño singleton, de esta manera, tener una sola instancia de la clase durante la
ejecución.

export class DataBaseService {


private static instance: DataBaseService;
private connection;

private constructor() {
try {
this.connection.getConnection((err, connection) => {
if (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
console.error('Database connection was
closed.')
}

194
if (err.code === 'ER_CON_COUNT_ERROR') {
console.error('Database has too many
connections.')
}
if (err.code === 'ECONNREFUSED') {
console.error('Database connection was
refused.')
}
}

if (connection) connection.release()

return
})
} catch (error) {
console.log('An error occurred while the connection
was created ' + error + ` ${DataBaseService.name} ->
constructor`);
}
}

static getInstance() {
try {
if (!DataBaseService.instance) {
DataBaseService.instance = new DataBaseService();
}
return DataBaseService.instance;
} catch (error) {
console.log('An error occurred while the instance was

195
returned ' + error + ` ${DataBaseService.name} ->
${this.getInstance.name}`);
}
}

B. FrontEnd (Angular 6):

HomeRoutes:

Este archivo exporta las rutas del módulo de Home de la aplicación, con el
respectivo componente en caso de ser invocadas y además con el título de cada
una de las páginas

export const homeRoutes: Routes = [


{
path: '',
component: HomeComponent,
data: {
pageTitle: 'Home'
}
},
{
path: 'users',
component: UsersComponent,
data: {
pageTitle: 'Users'
}
},
{
path: 'places',

196
component: PlacesComponent,
data: {
pageTitle: 'Places'
}
},
];
export const homeRouting: ModuleWithProviders =
RouterModule.forChild(homeRoutes);

Clase UserComponet:

Esta clase es el componente de usuario, esta clase implementa el método onInit,


en el cual se realiza la petición a la API para obtener los usuarios de la aplicación.
Además, tiene el método “goToPlaces”, el cual permite navegar a la página de
“Lugares” dentro de la aplicación, adicionalmente, almacena el nombre y el id del
usuario seleccionado en una variable global

@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styles: []
})
export class UsersComponent implements OnInit {
users: any[];
constructor(private userService: UserService,
private _router: Router,
private globalService: GlobalsService
) {
}

ngOnInit() {

197
try {
let servicio = this.userService.obtenerUsuarios().subscribe(
resp => {
this.users = resp;
console.log(this.users);
servicio.unsubscribe();
},
errResponse => {
servicio.unsubscribe();
throw new Error(errResponse);
}
);
}
catch (error) {
console.log(error);
}
}

goToPlaces(id: string, user: string) {


try {
debugger
this.globalService.globals.user=user;
this.globalService.globals.id=id;
this._router.navigate(['/order/places']);
}
catch (error) {
console.log(error);

Html UserComponet:

Este es el html usado por el componente de usuario, en este se realiza una


iteración, a través de la directiva ngFor, sobre un arreglo de usuarios para de esta
manera mostrar todos los usuarios de la aplicación.

198
<div id="content">
<div class="row">
<div class="col-sm-12">
<div class="col-sm-6 col-md-6 col-lg-4 col-xs-6" *ngFor="let
user of users">
<div class="product-content product-wrap clearfix" >
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="product-deatil">
<h5 class="name">
<a (click)="goToPlaces(user.ID,
user.NAME)">
{{ user.NAME }}
</a>
</h5>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Clase PlacesService:

Esta clase es el servicio que se encarga de realizar las peticiones a la API,


relacionadas con los “lugares” de la aplicación, en el método getPlaces, se
aprecia que usa el método “consumeservice” , el cual recibe como parámetro la
URL del servicio de la API que se desea consumir y adicionalmente, pero no

199
obligatorio, recibe los datos que sean necesarios para el consumo del servicio. Así
como esta clase existen más las cuales permiten la interacción con la API.

@Injectable()
export class PlacesService extends BaseService {

constructor(public http: HttpClient) {


super(http);
}

getPlaces(floor: string) {
try{
return this.consumeService('/place/get',{floor});
}
catch (error) {
console.log(error);
}
}

Pruebas:

En las tablas 30 y 31, se observan las pruebas realizadas a la aplicación.

200
Tabla 30. Casos de prueba: OctoPOS APP

Fuente: elaboración propia.

Tabla 31. Registro de errores: OctoPOS APP

Fuente: elaboración propia

201
Logros:

En las ilustraciones 66, 67, 68, 69, 70 y 71, se pueden apreciar los pantallazos de
la aplicación desarrollada, la cual cumple con el siguiente objetivo específico:
“Desarrollar un módulo para pedidos a través de dispositivos móviles android.”

202
Ilustración 68. Usuarios de la aplicación

Fuente: elaboración propia

203
Ilustración 69. Lugares del restaurante

Fuente: elaboración propia

204
Ilustración 70. Pedido

Fuente: elaboración propia

205
Ilustración 71. Categorías de productos

Fuente: elaboración propia

206
Ilustración 72. Sub categorías de productos

Fuente: elaboración propia

207
Ilustración 73. Productos

Fuente: elaboración propia

208
ANEXO F: ARTÍCULO PUBLICABLE

Experiencia en desarrollo de módulos para un software libre

Experience in developing modules for a free software

Experiência no desenvolvimento de módulos para um software

livre
Resumen — En el presente documento se verán comunidad, ya que al ser reconocido dentro de las
plasmados los aprendizajes obtenidos y los procesos comunidades, se va creando una reputación, la
realizados para llevar a cabo el desarrollo de tres cual servirá como apoyo a la hora de postularse a
módulos nuevos para el proyecto de software libre ofertas laborales o licitaciones en una empresa.
Unicenta.
Entre otros beneficios.
Palabras clave — Unicenta, NodeJS, Angular,
Software libre.
Las comunidades de software libre se
vienen dando desde la década de los 80's, gracias
Abstract - In this document, the lessons learned a Richard Stallman creador del movimiento de
and the processes carried out to carry out the software libre.
development of three new modules for the Unicenta A partir de este momento, han surgido
free software project will be captured. infinidad de proyectos de esta índole alrededor del
Keywords - Unicenta, NodeJS, Angular, Free mundo, uno de estos es Unicenta, un software
Software desarrollad para suplir las necesidades de los
pequeños negocios dedicados a la venta minorista.
Resumo - Neste documento, as lições aprendidas e
Este software es distribuido bajo la licencia GNU
os processos realizados para realizar o
desenvolvimento de três novos módulos para o General Public License version 3.0 (GPLv3), la
projeto de software livre da Unicenta serão cual convierte el proyecto en uno de software
capturados. libre.
Palavras chave- Unicenta, NodeJS, Angular, Unicenta en su versión 4.1 carece de algunas
Software Livre funcionalidades como la sincronización con un
Introducción comercio electrónico, aplicación para dispositivos
móviles, entre otras. Lo cual lleva a la necesidad
L A contribución a comunidades de software
libre es una actividad que, al menos las personas
o empresas involucradas en el sector de las
de desarrollar estos módulos, pero debido a que
los directores de Unicenta no agregan las nuevas
funcionalidades a su proyecto, se decidió crear un
tecnologías deberían realizar, ya que esta proyecto derivado de Unicenta denominado
actividad proporciona grandes beneficios OctoPOS.
devuelta, tales como conocimiento profundo sobre
un proyecto, lo cual beneficia demasiado a la hora II. MARCO TEORICO
de resolver posibles errores que surjan con el uso
del proyecto; reconocimiento dentro de la A. Antecedentes

209
Unicenta es un proyecto derivado del
software OpenBravo Pos el cual es propiedad de Chromis POS
la compañía OpenBravo, este proyecto comenzó
siendo software libre y como una comunidad, pero Descripción: Este proyecto se basa en
al pasar el tiempo fue privatizado y explotado de Unicenta, fue creado por John Lewis en el año
forma comercial por la compañía; debido a esto 2012, y es de origen Inglés. Este proyecto fue
surgieron derivados como lo es Unicenta. Así creado básicamente porque John Lewis realizaba
como Unicenta es un proyecto derivado, existen nuevas funcionalidades al código fuente de
otros mas que también son derivados de Unicenta las cuales no eran incluidas en las
OpenBravo, pero además, gracias a la gran nuevas versiones, así que Lewis decidió comenzar
acogida de Unicenta por parte de la comunidad y a su propio proyecto y agregó las nuevas
la falta de integración de las nuevas funcionalidades desarrolladas por el, cabe resaltar
funcionalidades aportadas por ésta al proyecto, que la funcionalidad más importante en este
han ido surgiendo otros proyectos derivados de proyecto y por la cual surgió, es el módulo para la
Unicenta. A continuación se mostrará un breve pantalla de la cocina. En la figura 2 se puede
lista de estos proyectos derivados, tanto de apreciar una captura de pantalla del inicio de
Unicenta como de OpenBravo, cada uno de los Chromis POS.
proyectos tendrá una breve descripción, la licencia Licencia: GNU General Public License
bajo la cual se distribuye el proyecto y una version 3.0 (GPLv3)
imagen del software

Openbravo Java POS

Descripción: Openbravo POS fue creado


en 2008 por Adrián Romero, es un punto de venta
diseñado para pantallas táctiles, soporta
impresoras de tickets, pantalla de cliente y lector
de códigos de barras. Es multiusuario a la hora de
proveer los permisos para agregar productos,
mostrar reportes y gráficos [1]. Además, este es el
proyecto base de Unicenta y de muchos otros
puntos de venta. En la figura 1 se puede apreciar
una captura de pantalla del inicio de OpenBravo.
Licencia: GNU General Public License
version 3.0 (GPLv3)

Fig. 2. Chromis POS

Nord POS

Descripción: Nord POS es un proyecto


que toma como código base el de OpenBravo
POS, fue desarrollado por Andrey Svininykh en el
año 2014, y es de origen Kazajo. A diferencia con
OpenBravo y sus otras derivaciones, Nord POS
fue desarrollado con soporte web y con
compatibilidad para dispositivos móviles, debido
a esto Nord POS posee una interfaz gráfica
diferente a la de OpenBravo POS y brinda mayor
funcionalidad a los usuarios. En la figura 3 se
puede apreciar una captura de pantalla de la toma
Fig. 1. OpenBravo Pos de pedidos de Nord POS .

210
Licencia: Apache License V2.0, GNU en este software son:
General Public License version 3.0 (GPLv3)
 Conectividad con impresoras fiscales de
1ra y 2da generación, comanderas,
scanners entre otras.
 Manejo de sesiones de usuario, distinción
de roles.
 Gestión de artículos.
 Gestión de inventario.
 Gestión de caja.
 Gestión de proveedores.
 Generación de informes.

Este programa es desarrollado en el lenguaje de


programación Java y posee una fuerte orientación
a objetos dentro de su código y utiliza como base
de datos principal MySQL. Estas dos
características en su desarrollo permiten su fácil
Fig. 3. Nord POS portabilidad entre sistemas operativos y por esta
razón puede ser ejecutado en Linux, Windows y
B. Conceptos teóricos Mac OS X 10.6 o posterior.
Durante el desarrollo se decidió que sería
A continuación, se dará la definición de software libre y se encontraría bajo la licencia
algunos de los conceptos necesarios para la GNU GPL V3, además empezó a ser distribuido a
comprensión del articulo. través de canales casuales como lo son su sitio
web, la página por excelencia de software libre
Software libre: es aquel software que no vulnera sourceforge, entre otros métodos, en ninguno de
las libertades básicas de un usuario, las cuales son los cuales se forza al usuario a registrarse,
[2] : características que según Jack Gerrard su
fundador, han sido la clave fundamental para el
 Libertad 0: La libertad de ejecutar el éxito del proyecto.
programa sea cual sea nuestro propósito. Como lo expresa Gerrard el crecimiento y la
 Libertad 1: La libertad de estudiar el popularidad del proyecto han ido creciendo de
código del programa y poderlo adaptar a boca en boca, además, el dinero no fue un motivo
las necesidades específicas del usuario, el para la existencia de uniCenta. Esto se ve
código abierto es un requisito reflejado en la posición que ocupa Unicenta como
fundamental para esto. una de las soluciones POS más usadas alrededor
 Libertad 2: Es la libertad de redistribuir del mundo, con más de un millón de descargas
el código ya sea de forma gratuita o paga desde su inicio, gracias a lo antes mencionado el
y además también se refiere a la libertad proyecto ocupa la cuarta posición, en la división
de poder ayudar al prójimo. de puntos de venta, en el ranking de la página
 Libertad 3: Es la libertad de modificar el capterra, la cual se dedica a calificar software para
programa y poder redistribuir el distintas aplicaciones.
código con el fin de ayudar a la
comunidad. Node.js: es un framework de desarrollo basado en
el motor de javascript V8 de google, y es usado
Unicenta oPOS: es un software dedicado a suplir para desarrollar aplicaciones de red escalables,
las necesidades encontradas en los puntos de gracias a que logra un alto rendimiento a través de
venta. Se enfoca en los mercados minoristas tales E/S sin bloqueo y un bucle de eventos de un sólo
como restaurantes, hostelería, almacenes, hilo. El código de nodejs está escrito en javascript
supermercados entre otros [3]. y es compilado en el motor V8, de esta manera, se
Algunas de las funciones que más se destacan puede escribir el código tanto del servidor como

211
del cliente en javascript, del lado del servidor se de estos módulos anteriormente mencionados, es
puede escribir desde un servidor web hasta los entender el funcionamiento del software base, en
scripts necesarios para soportar el servidor este caso Unicenta oPos , para esto se realizó un
[4][5][6]. proceso de ingeniería inversa el cual se dividió en
dos partes, el entendimiento de la base de datos a
REST: según Fielding, REST es una arquitectura través del análisis del modelo entidad relación de
de software desarrollada a partir de varias la base de datos de Unicenta y el entendimiento de
arquitecturas de red, que combinada con algunas su código fuente.
restricciones adicionales define una interface de Para poder entender la base de datos del
conexión uniforme. Esta arquitectura se enfatiza
proyecto el primer paso realizado fue saber sobre
en la escalabilidad de los componentes,
que motor de base datos estaba funcionando el
generalidad de las interfaces y un desarrollo
proyecto, debido a que al tener esta información
independiente de componentes. Además intenta
minimizar la latencia y la comunicación de la red, se creaba una idea de como serian los tipos de
al mismo tiempo que maximiza la independencia datos utilizados en esta base de datos, las
y la escalabilidad de las implementaciones de restricciones que tendría y la sintaxis SQL que se
componentes. Esto se logra al colocar utiliza para su gestión, además es un dato esencial
restricciones en la semántica del conector, donde para comenzar la búsqueda de una herramienta
otros estilos se han centrado en la semántica de los que facilite el proceso de obtener el modelo ER de
componentes [7]. la base de datos del proyecto.
Al realizar la búsqueda de una herramienta
III. PROBLEMA para el propósito anteriormente mencionado se
eligió el software dbeaver para lleva a cabo el
Los directores del proyecto Unicenta no cometido.
agregan las nuevas funcionalidades desarrolladas Es de resaltar que el proyecto contiene más de
por la comunidad, por tanto su crecimiento no es 40 tablas, las cuales se encuentran en su tercera
potenciado con la rapidez que la comunidad forma normal lo cual garantiza consistencia en los
requiere. Además, no existe ningún proyecto que datos almacenados, además se puede observar que
cuente con todas las funcionalidades planteadas, las llaves primarias de todas las tablas son de tipo
en los objetivos del presente documento. varchar, esto se debe a que los desarrolladores
Adicionalmente, debido a que los proyectos de
optaron por usar el metodo de identificacion
software libre no son patrocinados directamente
UUID, ya que este método se adapta muy bien a la
por una persona o empresa en particular, y en su
necesidad de identificación que se genera con el
mayoría se distribuyen de forma gratuita, sin
generar ganancia por el uso particular de este, uso de los tickets de venta, los cuales tienen un
necesitan de una comunidad de personas que tiempo de vida de corta duración.
tengan un ideario similar a las metas del proyecto, Ya entendiendo la base de datos del proyecto
las cuales sean capaz de sostenerlo, ya sea con su se inició con el entendimiento de su código el cual
conocimiento y/o tiempo. fue escrito en el lenguaje de programación Java
usando como entorno de desarrollo integrado
IV. RESULTADOS Netbeans, así que el primer paso para poder
entender el código del proyecto fue montar el
Aunque el Unicenta es un software maduro, código en dicha plataforma, después de esto se
con más de 7 años de trabajo, el mejoramiento del comenzó con un proceso de depuración del
mismo difícilmente acabará, gracias a que se van proyecto, el cual permitió seguir paso a paso los
creando nuevas necesidades en los usuarios. procesos realizados por el software, ver la
Gracias a esto se tomó la iniciativa del desarrollo interacción entre clases y los tipos de dato que
de dos nuevos módulos los cuales son: manejaba el programa y de esta manera se fue
construyendo un conocimiento frente a cómo
 Sincronización con Woocommerce funcionaba el proyecto.
 Una app móvil para la toma de pedidos Adicionalmente otro factor fundamental para
entender la estructura del proyecto y su
Pero una parte fundamental para el desarrollo funcionamiento, fue el diagrama de clases del
proyecto.

212
Ya conociendo el diagrama de clases, estas son: Es asíncrono y basado en eventos, es
entendiendo los procesos y algoritmos del muy rápido, posee un solo hilo pero es altamente
proyecto se generó la documentación de las clases escalable, su consumo de máquina es bajo, entre
más influyentes dentro del proyecto y que fueron otras. Lo que convierte a NodeJS la herramienta
necesarias para el desarrollo de los otros módulos. ideal para realizar el desarrollo.
Esta documentación, como fue mencionado Después de esto se procede al desarrollo de una
anteriormente, se generó por cada clase y consiste aplicación para realizar pedidos desde dispositivos
en: El diagrama de clases de la clase móviles con sistema operativo android, la cual
documentada, una descripción de la funcionalidad tiene como propósito facilitar los procesos de
de la clase con sus respectivos parámetros de toma de pedidos en restaurantes, cafés y bares.
entrada y salida, y por último un fragmento del La aplicación se limita a realizar pedidos y que
código de la clase. estos queden registrados en la base de datos.
Adicionalmente se documentaron también los Debido a que se tomó la decisión de desarrollar
scripts SQL de la base de datos, la documentación una aplicación híbrida ,con el fin que la aplicación
de estos se realizó dando una descripción de lo sea la base para un proyecto web, se optó por
que hace el script y un fragmento de código. desarrollar la aplicación en el framework de
Ya habiendo realizado el proceso de ingeniería desarrollo para JavaScript, Angular ya que este
se inició con el desarrollo del módulo de tiene cierta compatibilidad con los dispositivos
disgregación de productos el cual consiste en móviles a la hora de crear una aplicación basada
lograr que un producto esté conformado por sub- en el mismo. Para crear la apk en base al código
productos, los cuales podrán ser tenidos en cuenta Angular se hizo uso de Phonegap.
en la gestión de Inventarios. En este desarrollo se
puso a prueba el entendimiento adquirido después V. CONCLUSIÓN
de haber realizado la ingeniería inversa del
proyecto. El proceso de desarrollar nuevos
Seguidamente se procedió a desarrollar el módulos para un software libre, requiere de
módulo de sincronización con Woocommerce en tiempo y esfuerzo para entender su
el cual se realizó la selección de cuál sería la funcionamiento, el apoyo de la comunidad es
plataforma de comercio electrónico con la que se fundamental durante todo el proceso, ya que esta
realizará la sincronización, así que se eligió la se convierte en la fuente principal de información
y conocimiento del tema, lo que permite mejor
plataforma Woocommerce la cual brinda una muy
fluidez durante el desarrollo. Aunque el
buena documentación para los desarrolladores,
conocimiento de la comunidad es muy amplio , el
además, ya que es un plugin de wordpress cuenta
proceso de ingeniería inversa, permite ahondar
con el respaldo de la comunidad de wordpress, la mucho más en el funcionamiento del programa, lo
cual es bastante grande y activa en la red, lo que cual permite empoderarse más del proyecto para
brinda un canal de soporte adicional a la de esta forma se facilite el desarrollo de los
documentación proporcionada por el proyecto. módulos.
También cabe resaltar que Woocommerce es la En cuanto al desarrollo de los módulos se
plataforma más usada para soportar tiendas puede concluir que el uso de buenas prácticas de
virtuales, esta es usada por alrededor del 28% de programación tales como la documentación, el
todas las tiendas virtuales en internet, con lo cual manejo de versiones, entre otras; y adicionalmente
al hacer esta sincronización impactaría de manera la aplicación de la ingeniería del software y una
positiva un gran sector de las ventas electrónicas. buena planeación del proyecto, proporcionan unas
Por estas razones anteriormente expuestas se herramientas y una organización al mismo, lo cual
selecciono la plataforma Woocommerce como la asegura el buen término de cualquier desarrollo de
candidata ideal para llevar a cabo la software. Así también la elección correcta de las
sincronización. herramientas a usar en el desarrollo permiten
Adicionalmente se seleccionó también cual agilizar los procesos, e igualmente llevar a buen
seria la plataforma usada como intermediaria entre término el desarrollo
Unicenta oPos y Woocommerce, y se llegó a la
conclusión que se desarrollaría una API REST en Referencias
NodeJS gracias a sus características, algunas de

213
[1] Openbravo POS, "Openbravo POS - Openbravo Forge", [6] S. Tilkov and S. Vinoski, "Node.js: Using JavaScript to
Centralrepository.openbravo.com, 2008. [Online]. Build High-Performance Network Programs", IEEE
Disponible: Internet Computing, vol. 14, no. 6, 2010.
http://centralrepository.openbravo.com/openbravo/org.o [7] R. Fielding, "Fielding Dissertation: CHAPTER 5:
penbravo.forge.ui/ForgeProjectDetail/openbravopos. Representational State Transfer (REST)", Ics.uci.edu,
[Accedido: 13- Nov- 2018]. 2018. [Online]. Disponible:
[2] R. Stallman, Software libre para una sociedad libre, 1st https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_
ed. Madrid: Traficantes de Sueños, 2004, p. 45. arch_style.htm. [Accedido: 20- Abr- 2018].
[3] Á. Manjavacas, ADAPTACIÓN E
IMPLEMENTACIÓN DE MEJORAS EN UN
PROYECTO DE SOFTWARE LIBRE A UN SISTEMA
Carlos Enrique Urrego. Nació
CASH -FLOW MUY EFICIENTE Y SEGURO. Madrid,
en Pereira – Risaralda, Colombia, el 5
España: Universidad Complutense de Madrid, 2016.
de agosto de 1997. Estudiante de
[4] B. Dayley, Node.js, MongoDB and AngularJS web
Ingeniería de Sistemas y
development. Upper Saddle River, NJ [etc.]: Addison-
Telecomunicaciones de la Universidad
Wesley, 2014.
Católica de Pereira. Entre sus campos
[5] N. Foundation, "About | Node.js", Node.js, 2018.
de interés se encuentra el Software
[Online]. Disponible: https://nodejs.org/en/about/.
Libre, los algoritmos, y procesamiento
[Accedido: 21- Jun 2018].
de señales.

214
ANEXO G: CONFIGURACIÓN DEL PROYECTO EN NETBEANS

LISTA ILUSTRACIONES

ILUSTRACIÓN 72. COMENZAR UN NUEVO PROYECTO EN NETBEANS .............................................. 216


ILUSTRACIÓN 73. NOMBRE Y LOCALIZACIÓN (NETBEANS) ................................................... 217
ILUSTRACIÓN 74. AÑADIR EL CÓDIGO DE UNICENTA OPOS .............................................................. 218
ILUSTRACIÓN 75. INCLUIR/EXCLUIR ARCHIVOS ................................................................................... 219
ILUSTRACIÓN 76. INCLUIR/EXCLUIR ARCHIVOS ................................................................................... 220
ILUSTRACIÓN 77. AÑADIENDO LIBRERÍAS ............................................................................................ 221
ILUSTRACIÓN 78. SELECCIONE 'AÑADIR JAR/CARPETAS'.................................................... 222
ILUSTRACIÓN 79. CONFIGURE LA CLASE PRINCIPAL .......................................................................... 223

Para poder entrar a realizar ingeniería inversa del proyecto y poder contribuir a él,
inicialmente se necesita descargar el código fuente de Unicenta desde su página
oficial en sourceForge, después de esto, se procede a descomprimir el archivo.
Posteriormente, se pasará a configurar el proyecto en el IDE Netbeans, cabe
resaltar que el proyecto a la hora de desarrollar es más compatible con la
plataforma de netbeans debido a algunos plugins que este IDE posee. Los pasos
para configurar el proyecto en netbeans son los siguientes:

- Paso 1: Comenzar un nuevo proyecto en netbeans

Ir a Archivo > nuevo proyecto

En 'Categorías', se selecciona Java y después en seleccionar 'Proyecto' se da


click en la opción que dice 'Proyecto de java con un origen existente'

215
Ilustración 74. Comenzar un nuevo proyecto en netbeans

Fuente: elaboración propia

- Paso 2: Proporcionar nombre y la ubicación del proyecto

En 'Nombre del proyecto' se escribe el nombre que desee darle.

Para seleccionar la ubicación del proyecto, se da click en el botón de explorar y se


dirige hasta la carpeta donde se encuentra el proyecto y se selecciona.

216
Ilustración 75. Nombre y localización (NetBeans)

Fuente: elaboración propia

- Paso 3: Añadir el código de uniCenta oPos

Inicialmente, en esta pantalla verá que el complemento solo importara src-beans,


src-data y src-pos.

De click en el botón 'añadir carpeta' y añada las carpetas locales y los reportes,
una vez haya añadido esto, de click en siguiente - en este momento podrá dar
click en finalizar.

217
Ilustración 76. Añadir el código de uniCenta oPos

Fuente: elaboración propia

- Paso 4: Incluir/Excluir archivos


(opcional)

Haga los ajustes finales excluyendo o incluyendo archivos al proyecto.

218
Ilustración 77. Incluir/Excluir archivos

Fuente: elaboración propia

Una vez realizado los pasos anteriores, verá que el asistente hará el resto del
trabajo, porque crea los archivos y las carpetas necesarias del proyecto. Cuando
el asistente termine verá el proyecto con algunos archivos que tendrán
advertencias en rojo, esto pasa debido a que el asistente no agrega las librerías
necesarias para el proyecto.

219
Ilustración 78. Incluir/Excluir archivos

Fuente: elaboración propia

- Paso 5.1: Añadiendo Librerías

Navegue a donde haya descomprimido uniCenta oPos y seleccione la carpeta 'lib'.

Seleccione .jars en el pop up 'Añadir JAR/Carpeta' y seleccione todos los archivos


.jar – excluya las carpetas de linux, mac os x, solaris, y windows.

220
Ilustración 79. Añadiendo Librerías

Fuente: elaboración propia

- Paso 5.2: Seleccione 'Añadir JAR/carpetas'

Los archivos en la lista de librerías de tiempo de compilación como se muestran


acá han sido añadidas.

221
Ilustración 80. Seleccione 'Añadir JAR/carpetas'

Fuente: elaboración propia

- Paso 6: Configure la clase principal

Netbeans ahora guardará y actualizará el proyecto (sea paciente con las


actualizaciones) y empezará a ver que las advertencias en rojo comenzarán a
desaparecer.

Esta pantalla muestra todas las referencias a las librerías que han sido resueltas y
tu nuevo proyecto de unicenta está listo para comenzar.

Cuando corras el proyecto por primera vez netbeans te preguntará por la clase
principal del proyecto. Selecciona 'com.openbravo.pos.forms.StartPOS'.

222
Ilustración 81. Configure la clase principal

Fuente: elaboración propia

223
ANEXO H: MODELO RELACIONAL

Ilustración 82. Modelo relacional parte 1

Fuente: elaboración propia

224
Ilustración 83. Modelo relacional parte 2

Fuente: elaboración propia

225
Ilustración 84. Modelo relacional parte 3

Fuente: elaboración propia

226
Ilustración 85. Modelo relacional parte 4

Fuente: elaboración propia

227
Ilustración 86. Modelo relacional parte 5

Fuente: elaboración propia

228
Ilustración 87. Modelo relacional parte 6

Fuente: elaboración propia

229
Ilustración 88. Modelo relacional parte 7

Fuente: elaboración propia

230
Ilustración 89. Modelo relacional parte 9

Fuente: elaboración propia

231
ANEXO I: ACTAS DE REUNIÓN Y CARTA DE SATISFACCIÓN

En el presente anexo se pueden apreciar las actas de reunion en las ilustraciones


90 y 91. Además se puede observar, en la ilustración 92, una carta de satisfacción
por parte de la dueña del almacen Tienda los chikos y por ultimo en la ilustración
93, una copia del RUT (Registro Unico Tributario) del almacen Tienda los chikos.

Ilustración 90. Acta de reunion Nro. 1

232
Fuente: elaboración propia

Ilustración 91. Acta de reunion Nro. 2

Fuente: elaboración propia

233
Ilustración 92. Carta de satisfacción

Fuente: elaboración propia

234
Ilustración 93. RUT Almacen Tienda los chikos

Fuente: elaboración propia

235

También podría gustarte