elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Security Series.XSS. [Cross Site Scripting]


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Ejercicios
| | | |-+  Proyecto: Gestión de facturas (visita guiada)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Proyecto: Gestión de facturas (visita guiada)  (Leído 10,106 veces)
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Proyecto: Gestión de facturas (visita guiada)
« en: 7 Julio 2004, 05:05 am »

Dado que he puesto un ejercicio 17 que en realidad es un proyecto voy a hacerlo yo aquí paso a paso para que podais seguirme.

Este post está bloqueado para que no se me pierda el hilo, pero si teneis problemas posteadlas y en paz.

Voy a utilizar el modelo de objetos DAO por ser mas comprensible.


« Última modificación: 7 Julio 2004, 05:29 am por soplo » En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #1 en: 7 Julio 2004, 05:28 am »

Creación de base de datos

Utilizaré la utilidad de devstudio 6.0 para crear la base de datos.

La estructura es:

Código:
Tabla clientes
Codigo autonumérico
Nombre texto 20
Apellidos texto 40
Dirección texto 50
Población texto 20
CodigoPostal texto 5
Telefono texto 12
DNI texto 10
Indexada por Codigo sin duplicados. Nombre de Indice: 'indice'

Código:
Articulos
Codigo autonumerico
Nombre texto 20
precio moneda
Indexada por Codigo sin duplicados. Nombre de Indice: 'indice'

Código:
Tabla facturas
Codigo autonumerico
CodigoCliente long
NumFactura texto 10
FechaFactura date
FormaPago texto 20
Importe currency
Impuestos currency
Total currency
Indexada por Codigo sin duplicados. Nombre del Indice: 'Indice'

Código:
tabla EntradasFacturas
CodigoFactura long
CodigoArticulo long
Cantidad single
Importe currency
Indexada por CodigoFactura con duplicados. Nombre del índice: 'indice'

Como veis en cada tabla creo un índice que me permitirá acceder a cada registro directamente.

Por sencillez voy a obviar relaciones entre tablas y no voy a realizar ninguna relación, pero debeis considerar lo siguiente:

Cada factura tiene un registro (y solo uno) en la tabla facturas. Aquí se almacenan los datos básicos de la factura. Esto es 'qué cliente', 'Qué fecha','Qué numero','qué importe total','como se paga'. Cada factura tiene un código único que la identifica y en este caso se llama 'codigo'. La tabla facturas está indexada por él para poder acceder directamente a cada factura.

En una factura se pueden comprar varias cosas. Por eso hay una segunda tabla llamada 'EntradasFacturas'. Esta tabla almacena las líneas (el detalle) de cada factura. Aquí hay cosas como 'Qué se ha comprado','qué cantidad','a que precio'. Para saber a que factura corresponde cada línea hay un CodigoFactura de manera que si una factura tiene por código el valor '7887' en facturas, todas sus entradas en la tabla 'EntradasFacturas' tienen ese valor en el campo CodigoFactura.

Para los interesados sería una buena idea establecer una relación de integridad referencial uno a varios entre estas dos tablas (tema que como dije voy a obviar).

Cada entrada también tiene un código que la identifica de forma precisa.

Para rellenar esas facturas tendré que acceder a los clientes (razón por la que tengo un código en clientes que identifica a cada cliente y un código en artículos que identifica a cada artículo).


En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #2 en: 7 Julio 2004, 05:39 am »

Realización del módulo inicial de aplicación

Voy a realizar un módulo que se cargará inicialmente al llamar a la aplicación.

Su labor: mostrará una página de presentación mientras el programa se carga y además leerá la configuración inicial de un archivo de texto llamado 'config.ini' que estará en c:\'

Esta configuración inicial indica donde está la base de datos que queremos usar.

Declaración de variables globales. Funcionarán en todo el proyecto. 'BaseDeDatos' es un string que contendrá la dirección completa a mi base de datos mdb. Su valor será algo así como 'c:\documents and Settings\usuario\Mis Documentos\MiBase.mdb'
Código:
Global BaseDeDatos as string, Trayecto as string

Esta es la rutina principal. Para que sea la que se ejecute al inicio habrá que ir a las propiedades del proyecto e indicar que el objeto inicial es Main.

Código:
Sub main()
On Error GoTo fallo
Dim f As New frmSplash
Open "c:\Config.ini" For Input As 1
Input #1, BaseDeDatos, Trayecto, Usuario, Pass
Close #1
SaberParametros
Principal.Show

Exit Sub
fallo:
resp% = Msg("¡Datos de programa no encontrados!" & Chr(10) _
    & "¿Desea crear un nuevo conjunto de datos?", "SiNo")
If resp% = vbYes Then
    CfgDatos.Show vbModal
End If
End Sub

La función Msg la hago para facilitarme el uso de mensajes durante toda la aplicación.

Código:
Function Msg(txt As String, opcion As String)
Dim Opciones As Integer, Icono As Integer
Select Case opcion
    Case "SiNo": Icono = vbQuestion
                 Opciones = vbYesNo
    Case "Info": Icono = vbinfo
                 Opciones = vbInformation
    Case "Ok":   Icono = vbOKOnly
                 Opciones = vbOKOnly
    Case "Error": Icono = vbExclamation
                 Opciones = vbOKOnly
    Case "Fallo": Icono = vbCritical
                 Opciones = vbOKOnly
    Case Else
                  Opciones = vbOKOnly
                  Icono = vbInformation
                  txt = "Opción equivocada"
End Select
Msg = MsgBox(txt, Opciones + Icono, "Gestor de Datos")
End Function
« Última modificación: 7 Julio 2004, 06:57 am por soplo » En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #3 en: 7 Julio 2004, 06:40 am »

Realización de formulario de pantalla inicial

Para el formulario inicial he pensado utilizar el asistente para pantallas de bienvenida y modificarlo oportunamente.

Para que salgan los datos precisos en este formulario deberías comprobar que las propiedades del proyecto están bien puestas (nombre de aplicación, versión, etc).

Se llamará FrmSplash
« Última modificación: 7 Julio 2004, 06:58 am por soplo » En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #4 en: 7 Julio 2004, 06:56 am »

Creación de formulario para elegir base de datos a usar

Se llamará CfgDatos (Yo comienzo con Cfg todos los formularios que tienen que ver con configuración).

El código del botón de búsqueda (el que está en círculo). Utilizo un CommonDialog llamado Dialogo para seleccionar la base de datos que quiero usar.

Código:
sub Command1_Click()
Dim ConStr As String
On Error GoTo fallo
If Trayecto = "" Then
    Dialogo.InitDir = "c:\Mis Documentos"
Else
    Dialogo.InitDir = Trayecto
End If
Dialogo.ShowOpen
BaseDeDatos = Dialogo.FileName
Trayecto = Left(BaseDeDatos, InStrRev(BaseDeDatos, "\") - 1)
PideDonde = BaseDeDatos
base.Close
set base=opendatabase(BaseDeDatos)
Exit Sub
fallo:
End Sub

Dialogo  tiene puestas las siguientes propiedades:
Código:
CancelError = true
Filename=Mi_base.mdb
filter='Datos de Mi Ejemplo | Mi_base.mdb'

El botón de grabar tiene el siguiente código
Código:
Private Sub Command2_Click()
Open "c:\Config.ini" For Output As 1
Write #1, PideDonde, Trayecto, PideUsuario, PidePass
Close #1
Unload Me
End Sub
De manera que al pulsarlo se graba config.ini y se sale del formulario

El formulario al cargarse realiza el siguiente código
Código:
Private Sub Form_Load()
On Error GoTo fallo
Open "c:\config.ini" For Input As #1
Input #1, BaseDeDatos, Trayecto, pideusuari$, pidepas$
Close #1
PideDonde = BaseDeDatos
PideUsuario = pideusuari$
PidePass = pidepas$
Exit Sub
fallo:

End Sub
En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #5 en: 7 Julio 2004, 07:05 am »

Creación del formulario principal de la aplicación

Utilizaré un formulario MDI al que llamaré 'principal'

En el crearé un menú con dos opciones (de momento) tal como se ve en la figura.

El código que tiene es el siguiente:

Al pinchar en la opción 'Parámetros generales'

Código:
Private Sub MnuParametros_Click()
Set parametros = New CfgDatos
CfgDatos.Left = (Screen.Width - CfgDatos.Width) / 2
CfgDatos.Top = (Screen.Height - CfgDatos.Height) / 2
CfgDatos.Show
End Sub

El código de terminar
Código:
Private sub MnuFin_Click()
end
End Sub
En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #6 en: 7 Julio 2004, 07:37 am »

Gestión de Clientes

Para la gestión de clientes he pensado utilizar un formulario donde saldrá un dbgrid enlazado a un control data (oculto) que mostrará los clientes.

Estos datos saldrán de un recordset de tipo snapshot por las siguientes razones:
1. Los datos serán de solo lectura lo que agiliza la consulta de datos
2. Se desea que los datos no sean actualizables aquí
3. Se podrá ordenar por donde se quiera y buscar con facilidad.

Al hacer doble click sobre el grid sale un menú que permite agregar, modificar, ver o borrar clientes.
En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #7 en: 7 Julio 2004, 07:54 am »

Formulario principal de clientes

Será un formulario child del mdi y aparecerá maximizado.

Se llamará ClientesGeneral

Para llamar a este formulario desde el menú principal tendremos que agregar una nueva opción al menú que será la opción de clientes. Al pinchar en aquella opción se ejecuta el siguiente código:

Código:
Private Sub MnuClientes_Click
load ClientesGeneral
ClientesGeneral.data1.databasename=BaseDeDatos
ClientesGeneral.data1.refresh
ClientesGeneral.show
End Sub
Con ello desde el formulario principal llamamos al formulario clientesgeneral. Antes de mostrarlo lo cargamos, le pasamos la información al data de donde se encuentra la base de datos (os recuerdo que hay una variable global llamada BaseDeDatos cuyo contenido precisamente esto) y luego mostramos el formulario.

De esta forma el formulario funcionará en cualquier lugar que esté la base de datos.

El código que hay en este formulario es el siguiente:

El código del control text
Código:
Private Sub Text1_Change()
Data1.Recordset.FindFirst "nombre like '*" & Text1 & "*'"
End Sub
De esta forma al escribir en este control se busca automáticamente al cliente que mas se acerque a lo escrito (pulsación a pulsación)

Botón de buscar siguiente
Código:
Private Sub Command2_Click()
Data1.Recordset.FindNext "nombre like '*" & Text1 & "*'"
End Sub
Si en la búsqueda del text hemos encontrado un cliente, pero buscamos otro cliente posterior con la misma condición este buscará desde donde estamos mientras que desde el text se busca desde el principio.

Los códigos del dbgrid
Código:
Private Sub DBGrid1_DblClick()
ClientesMenu.Show vbModal
End Sub
Al hacer doble click llamamos a otro formulario (que aún no hemos hecho) donde se dará la opción de agregar, eliminar, borrar, ...

Código:
Private Sub DBGrid1_HeadClick(ByVal ColIndex As Integer)
misql$ = Left(Data1.RecordSource, InStr(1, Data1.RecordSource, "order") - 1)
Data1.RecordSource = misql$ & "order by " & DBGrid1.Columns(ColIndex).DataField
Data1.Refresh
End Sub
Al hacer click en un encabezado del grid ordenamos por ahí

Y ya hemos terminado. Fijaos que poco código y que bien funciona.

Para que funcione perfecto os pongo las propiedades que tienen
El dbgrid
Código:
allowaddnew=false
allowupdate=false
allowdelete=false
Recordselector=false
marqueestyle=highlightrow

El data
Código:
visible=false
recordsettype=snapshot
recordsource='select * from clientes order by nombre'
databasename=''

Pues eso. 5 minutos y chachi piruli.
En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #8 en: 7 Julio 2004, 08:00 am »

Menú de Clientes

El menú de clientes será un formulario modal que saldrá centrado en la pantalla.

Luego explico estas  opciones. Ahora me voy a cenar!!
 ;D
En línea

Callar es asentir ¡No te dejes llevar!
soplo
Ex-Staff
*
Desconectado Desconectado

Mensajes: 3.592

Debian rool'z


Ver Perfil
Re: Proyecto: Gestión de facturas (visita guiada)
« Respuesta #9 en: 17 Julio 2004, 08:15 am »

Agregar/Modificar/Ver/Borrar Clientes

Agregar Clientes
Para agregar clientes he pensado en utilizar un formulario al que llamaré 'clientesficha.rm' que saldrá en blanco (naturalmente) que al rellenarlo y pulsar grabar se grabe en la tabla de clientes.

Voy a hacerlo de manera que el mismo formulario me valdrá luego sin apenas cambios para ver el cliente y modificar sus datos.

Fijaos además que inicialmente no hay ninguna conexión del formulario a la tabla. En el momento que se pulsa grabar se abre la conexión (en este caso un recordset dao), se graba y se cierra.

Esto es importante cuando hagais programación en red (no es este caso) porque si añadiera un registro inicialmente y luego al pulsar grabar hiciera el update lo que habría conseguido es tener ocupada la página de este registro hasta que el usuario pulse grabar. Mientras tanto esa página permanece bloqueada (no solo ese registro sino 64k bytes de datos) por lo que podría ocurrir que otro usuario no pueda modificar un cliente porque este no ha pulsado aún grabar.

Y puede ocurrir que deje el cliente a medio meter y se ponga a hablar por teléfono.

Por eso lo que hago es mostrar un formulario simple donde solo se rellenan datos. En el momento que se graba se abre la conexión, se mueven los campos a base de datos y se cierra la conexión.

Este el el código que hay al pulsar la opción de agregar clientes

Código:
Load ClientesFicha
ClientesFicha.Tag = "Agregar"
ClientesFicha.Show vbModal
Unload Me

Borrar Clientes
Para entrar en el menú hicimos doble click sobre un cliente en la pantalla general de clientes (ClientesGeneral.frm). Pues ese cliente es el cliente activo. Si ahora pulso Eliminar cliente elimino a este cliente.

Al hacer doble click sobre ese cliente naturalmente el data que proporciona el recordset en clientesgeneral se posicionó en ese registro. Os recuerdo que cada cliente tiene un código único que se genera automáticamente de forma que para saber que cliente es desde otro formulario solo tengo que preguntar por 'ClientesGeneral.data1.recordset.fields("codigo")'.

Este es el código para borrar clientes

Código:
On error goto fallo
resp% = Msg("¿Desea borrar este cliente con todos sus documentos correspondientes?", "SiNo")
If resp% = vbYes Then
       base.Execute "delete * from clientes where codigo=" & ClientesGeneral.data1.Recordset.Fields("codigo), dbFailOnError
       Msg "El cliente se ha borrado satisfactoriamente.", "Ok"
endif
exit sub
fallo:
msg "No se ha podido borrar al cliente. La causa ha sido el error nº " & err.number & "(" & err.description & "),"Ok"

Este caso solo borra a este cliente y se queda tan ancho, sin embargo tenemos que tener presente que en nuestra aplicación habrá registros de facturas que corresponden a este cliente y no puede ocurrir que haya facturas que no pertenezcan a ningún cliente.

Esto tiene dos soluciones
a) realizo una relación de integridad referencial entre clientes y facturas de forma que al eliminar el cliente se borran todas sus facturas (en este caso vale el código anterior). Ya indiqué al inicio de esta visita que esa opción la descartaba yo. Este es un curso de visual basic.

La otra opción es modificar el código anterior para borrar todos los registros de facturas que sean de este cliente. Dado que aún no hemos tocado el tema de facturas os recuerdo que cada factura tenía un registro (y solo uno) que identificaba de forma inequívoca a cada factura. En esta tabla había un campo llamado CodigoCliente que identifica al cliente de cada factura.

El código en este caso sería así
Código:
With ClientesGeneral.Data1.Recordset.Fields("codigo")
resp% = Msg("¿Desea borrar este cliente con todos sus documentos correspondientes?", "SiNo")
If resp% = vbYes Then
    BeginTrans
    base.Execute "delete * from facturas where codigocliente=" & .Value, dbFailOnError
    base.Execute "delete * from clientes where codigo=" & .Value, dbFailOnError
    CommitTrans
    Msg "El cliente se ha borrado satisfactoriamente.", "Ok"
End If
ClientesGeneral.Data1.Refresh
End With
Exit Sub
fallo:
rollback
Msg "No se ha borrado el cliente. Error número: " & Err.Number & "(" & Err.Description & ")", "Ok"

Como veis en este caso se debe borrar de dos tablas o de ninguna. Por ello creo una transacción (begintrans) y empiezo a borrar.
Si ocurre un error saltará a fallo donde hay una claúsula rollback que devolverá todas las cosas al estado anterior a begintrans.
Si no ocurre un error llegará a committrans que hará los cambios ya permanentes.
Fijaos que las órdenes sql llevan el parámetro dbfailonerror. Esto es porque si no lo llevan aunque ocurra un error no generan error.

Modificar Clienes
Para modificar un cliente haré algo muy parecido a la rutina de agregar clientes nuevos.
Solo que esta vez en vez de aparecer el formulario de antes (clientesficha) vacío esta vez aparecerá lleno con los datos del cliente.

Como en el caso de borrar para llegar aquí hay que pulsar doble click sobre un cliente y como el recordset de allí (clientesgeneral) se habrá posicionado sobre ese registro tengo el cliente que deseo modificar en 'clientesgeneral.data1.recordset.fields("codigo")'

Haré exactamente lo mismo posteriormente para consultar un cliente de forma que enviaré un parámetro que será 'M cuando quiera modificar y 'V' cuando quiera ver. Así en todo momento sabré en las rutinas posteriores que es lo que quiero hacer.

Como decía el caso es muy parecido al caso de agregar. Solo que necesitaré meter los datos en el formulario 'ClientesFicha' antes de mostrarlo. Para ello utilizaré una rutina llamada 'MoverAPantalla' que hará ese trabajo. Posteriormente hablaré de ella.

Ahora el código de este botón
Código:
On Error GoTo fallo
Load ClientesFicha 'cargar el formulario en memoria
ClientesFicha.Tag = "M" 'este es el parámetro que envío.
MoverAPantalla 'mover los campos al formulario
ClientesFicha.Show vbModal 'mostrar el formulario
Unload Me 'descargar el menú
Exit Sub
fallo:

Consultar Cliente
El caso de consultar un cliente es exactamente igual que el de modificar un cliente con solo dos modificaciones:
En el caso de consultas no existe la posibilidad de grabar
Tampoco existe la posibilidad de escribir en los datos que se muestran

El código de mostrar un cliente es el siguiente:

Código:
On Error GoTo fallo
Load ClientesFicha
With ClientesFicha
.Grabar.Visible = False 'que no se vea el botón de grabar
For x% = 0 To ClientesGeneral.text.count-1 'para cada textbox del formulario
    .Text1(x%).Locked = True 'impedir escribir en todos los campos
Next x%
.PideFpago.Locked = True
MoverAPantalla 'mover los campos al formulario
.Show vbModal 'mostrar el formulario
End With
Unload Me 'descargar el menú
Exit Sub
fallo:

Mover campos del recordset a pantalla
Por último me queda hacer la rutina de mover los campos del recordset a pantalla.

La rutina sería así

Código:
Sub MoverAPantalla()
Dim rec As Recordset 'creo un recordset tabla indexado
Set rec = base.OpenRecordset("clientes", dbOpenTable)
rec.Index = "codigo"
rec.Seek "=", ClientesGeneral.Data1.Recordset.Fields 'busco el cliente solicitado
If rec.NoMatch Then 'si no se encuentra
    Exit Sub 'salir
End If
With ClientesFicha
.Text1(0) = rec.Fields("codigo")
'.PideFecha = rec.Fields("fecha")
.Text1(1) = "" & rec.Fields("Nombre")
'.Text1(2) = "" & rec.Fields("Apellidos")
.Text1(2) = "" & rec.Fields("Direccion")
.Text1(3) = "" & rec.Fields("Poblacion")
.Text1(4) = "" & rec.Fields("CodigoPostal")
.Text1(5) = "" & rec.Fields("Telefono")
.Text1(6) = "" & rec.Fields("Dni")
End With
rec.close
End Sub

Fijaos una vez mas. He abierto un recordset de tipo tabla, he buscado lo que necesitaba, lo he movido a los campos del formulario y lo he cerrado.

Fijaos que para meter un dato de tipo string en un textbox he hecho esto:
Código:
.Text1(1) = "" & rec.Fields("Nombre")

La razón es que dentro de un campo de base de datos puede haber el valor null, pero ese valor no se puede meter en un textbox. Por eso concateno "" y el campo 'nombre'. Si está vacío meto en text1 el valor "". Si no está vacío meto el valor "" & "el nombre del sujeto".

El formulario del cliente

Al fin llegamos al formulario del cliente. Este formulario será un formulario sin nada especial. Cuando se muestre puede ocurrir que los textbox estén vacíos (caso de altas de clientes) o que estén llenos. Si están llenos entonces puede ocurrir que tengan puesto locked=true y no exista el botón 'grabar' porque es una simple consulta o bien que no ocurra esto porque es una modificación del cliente.

En la práctica solo hay código en dos botones:
El código del botón salir sin hacer nada. Como hemos llegado aquí limpiamente no hay nada que deshacer ni recordset que cerrar ni nada.
Código:
unload me

El código de grabar. Este botón solo se ve si se trata de agregar o modificar clientes.
El código sería este:

Código:
Private Sub Grabar_Click()
Dim rec As Recordset

Set rec = base.OpenRecordset("clientes", dbOpenTable)
rec.Index = "codigo"
If Me.Tag <> "M Then 'si se ha recibido el parámetro M se trata de una modificación
    rec.AddNew 'como no se ha recibido hay que agregar
Else
    rec.Seek "=", Text1(0) 'como si se ha recibido hay que buscar el cliente a modificar en la tabla
    rec.Edit 'y editarlo
End If
rec.Fields("Nombre") = Text1(1)
rec.Fields("Direccion") = Text1(2)
rec.Fields("Poblacion") = Text1(3)
rec.Fields("CodigoPostal") = Text1(4)
rec.Fields("Telefono") = Text1(5)
rec.Fields("DNI") = Text1(6)
rec.Update
ClientesGeneral.Data1.Refresh 'actualizar el panel general
Unload Me
End Sub

Ya tenemos terminados los clientes
« Última modificación: 17 Julio 2004, 08:23 am por soplo » En línea

Callar es asentir ¡No te dejes llevar!
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Facturas Movistar.
Foro Libre
B€T€B€ 4 3,196 Último mensaje 17 Enero 2013, 18:30 pm
por B€T€B€
Pinterest estrena una búsqueda guiada (Guided Search) basada en etiquetas
Noticias
wolfbcn 0 1,352 Último mensaje 25 Abril 2014, 21:37 pm
por wolfbcn
Mujer muere al ser guiada por Waze a la favela más peligrosa de Brasil
Noticias
wolfbcn 1 1,399 Último mensaje 7 Octubre 2015, 15:36 pm
por _Enko
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines