diff --git a/README.md b/README.md index 3a9ee16..97d9411 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Actions Status](https://github.com/Arquisoft/dede_es2c/actions/workflows/asw2122.yml/badge.svg)](https://github.com/Arquisoft/dede_es2c/actions/workflows/asw2122.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_dede_es2c&metric=alert_status)](https://sonarcloud.io/summary/overall?id=Arquisoft_dede_es2c) -[![codecov](https://codecov.io/gh/arquisoft/dede_0/branch/master/graph/badge.svg?token=VN4XG9NTRO)](https://app.codecov.io/gh/Arquisoft/dede_es2c) +[![codecov](https://codecov.io/gh/arquisoft/dede_es2c/branch/master/graph/badge.svg?token=VN4XG9NTRO)](https://app.codecov.io/gh/Arquisoft/dede_es2c)

diff --git a/README_es.md b/README_es.md index 979354c..a73fbea 100644 --- a/README_es.md +++ b/README_es.md @@ -2,7 +2,7 @@ [![Actions Status](https://github.com/Arquisoft/dede_es2c/actions/workflows/asw2122.yml/badge.svg)](https://github.com/Arquisoft/dede_es2c/actions/workflows/asw2122.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_dede_es2c&metric=alert_status)](https://sonarcloud.io/summary/overall?id=Arquisoft_dede_es2c) -[![codecov](https://codecov.io/gh/arquisoft/dede_0/branch/master/graph/badge.svg?token=VN4XG9NTRO)](https://app.codecov.io/gh/Arquisoft/dede_es2c) +[![codecov](https://codecov.io/gh/arquisoft/dede_es2c/branch/master/graph/badge.svg?token=VN4XG9NTRO)](https://app.codecov.io/gh/Arquisoft/dede_es2c)

diff --git a/docs/03_system_scope_and_context.adoc b/docs/03_system_scope_and_context.adoc index c36f95f..9cdec75 100644 --- a/docs/03_system_scope_and_context.adoc +++ b/docs/03_system_scope_and_context.adoc @@ -13,26 +13,26 @@ image:03_Negocio.png["Diagrama Contexto Negocio"] [options="header",cols="1,2,2"] |=== |Comunicaciones |Entradas | Salidas -| _Usuario_ | _Interacciones con la aplicación_ |_Respuestas a esas interacciones_ +| _Usuario_ | _Interacciones con la aplicación_ | _Respuestas a esas interacciones_ | _POD del Usuario_ | _La inforamción relativa a cada usuario para respetar su privacidad_ | _Información que necesite la aplicación siempre cuando el usuario lo permita_ -| _DeDe_ | _Venta de productos_ | _Precio según dirección del cliente_ +| _DeDe_ | _Venta de productos_ | _Información que recibe de las APIs y de la base de datos_ | _Base de datos_ | _Peticiones por parte de la aplicación DeDe_ | _Respuesta de la información almacenada en esta base de datos_ -| _API_ | _Dirección de envío_ | _Precio de envío desde el almacén_ +| _EasyPost_ | _Dirección de envío_ | _Precio de envío desde el almacén_ +| _PostImages_ | _Imágenes para mostrar_ | _Imágenes necesarias para mostrar en la Aplicación_ |=== === Contexto técnico - -image:03_Tecnico.png["Diagrama Contexto Técnico"] +Se utiliza una arquitectura SOLID para respetar la privacidad del usuario, en este caso la direccion de envio de este. [options="header",cols="1,2"] |=== -|Objeto |Descripción -| _Usuario_ | _Persona que utilice la aplicación_ +| Tecnología |Descripción | _POD_ | _Lugar donde se almacena la información de cada cliente_ | _DeDe_ | _Aplicación descentralizada_ -| _Explorador Web_ | _Aplicación donde el usuario va a acceder a DeDe_ -| _HTTPS_ | _Protocolo que se utilizará para enviar y recibir información entre el navegador y la aplicación_ -| _Servidor Web_ | _Servidor que tendrá la aplicación DeDe almacenada (sin decidir)_ +| _EasyPost_ | _API usada para calcular los precios de envio_ +| _PostImages_ | _API que guarda las imagenes y las descarga para su uso en la aplicación_ +| _TypeScript_ | _Lenguaje utilizado para el desarrollo de la aplicación_ +| _React_ | _Libreria utilizada para generar de las interfaces de la aplicación_ |=== diff --git a/docs/04_solution_strategy.adoc b/docs/04_solution_strategy.adoc index 0a775c7..91cbbf0 100644 --- a/docs/04_solution_strategy.adoc +++ b/docs/04_solution_strategy.adoc @@ -10,25 +10,22 @@ - Node.js: entorno en tiempo de ejecución multiplataforma, de código abierto, para la capa del servidor basado en el lenguaje de programación JavaScript, asíncrono, con E/S de datos en una arquitectura orientada a eventos y basado en el motor V8 de Google. - MongoDB: sistema de base de datos NoSQL orientado a documentos. Además MongoDB es de código abierto por lo que se permite una mayor libertad de creación de documentos - MUI: Libreria de libre acceso para construir los diferentes componentes que utiliza la aplicación. La mayoria de componentes que se utilizan en nuestra aplicación son de esta librería y son personalizados según se necesita el formato de este. - -=== Como alcanzar los objetivos de calidad -[options="header",cols="1,2"] -|=== -|Objetivos de calidad| Solución -| Eficiencia | El acceso al pod del usuario se hará las minimas veces posibles. Realización de pruebas para comprobar como de rápido responde la aplicación -| Privacidad | Utilización de un POD por cada usuario, donde el usuario deberá dar permiso a la web para utilizar sus datos. -| Usabilidad | La página tendrá un aspecto parecido al resto de aplicaciones que existen sobre tiendas online. -|=== - -=== Descomposición de alto nivel del sistema -Todavía no se ha decidido como va a estar. +- Docker: Automatizacion del despligue medainte contenedores, se han creado dos contenedores, uno para la parte de 'front-end' y otro para 'back-end' +- AWS: Depligue de la página. +- EasyPost: API que calcula el precio de envío en funcion de una dirección +- PostImages: API utilizada para poder utilizar las imagenes en nuestra aplicación. +- SuperTest y Jest: Utilizado para poder realziar las diferentes pruebas. === Decisiones de organización * Revisiones y reuniones acordadas con antelación se realizarán a través de la aplicación Microsoft Teams. * Mensajería instantanea para acordar aquellas reuniones que se realicen de forma online, también para avisar de cambios pequeños. * GitHub para reflejar el trabajo que se esta realizando de varias formas: - ** Rama individual para cada uno, donde deberá realizar su trabajo. + ** Rama individual para cada uno, donde deberá realizar su trabajo. Rama Developer donde se iran incluyendo los cambios de todos los miembros para despues poder realizar de una manera más sencilla los cambios a master. ** Uso de wikis para recoger todo lo acordado en las reuniones y del registro arquitéctonico. ** Uso de issues para indicar las cosas que tiene que realizar cada miembro del equipo. ** Uso de Actions para commprobar el correcto funcionamiento de la aplicación - + ** Uso de Tableros para controlar como esta siendo el desarrollo del trabajo, se dividieron en 4 tableros: + *** FrontEnd + *** BackEnd + *** Documentación + *** Despliegue diff --git a/docs/08_concepts.adoc b/docs/08_concepts.adoc index fdd0afc..646e7c1 100644 --- a/docs/08_concepts.adoc +++ b/docs/08_concepts.adoc @@ -62,6 +62,10 @@ image:08_IniciarSesion.png["Página login"] image:08_Registro.png["Registro aplicación"] +* Comprobar los articulos que se desean comprar por parte del cliente + +image:08_Carrito.png["Registro aplicación"] + * Realizar el pago del carrito del usuario image:08_VentanaPago.png["Ventana Pego"] diff --git a/docs/images/03_Negocio.png b/docs/images/03_Negocio.png index 02f6b56..7619973 100644 Binary files a/docs/images/03_Negocio.png and b/docs/images/03_Negocio.png differ diff --git a/docs/images/03_Tecnico.png b/docs/images/03_Tecnico.png deleted file mode 100644 index 4c6369a..0000000 Binary files a/docs/images/03_Tecnico.png and /dev/null differ diff --git a/docs/images/06_Compra_Productos.png b/docs/images/06_Compra_Productos.png index 163c935..e96ae20 100644 Binary files a/docs/images/06_Compra_Productos.png and b/docs/images/06_Compra_Productos.png differ diff --git a/docs/images/08_Carrito.png b/docs/images/08_Carrito.png new file mode 100644 index 0000000..36fddcc Binary files /dev/null and b/docs/images/08_Carrito.png differ diff --git a/webapp/src/pages/Pago.tsx b/webapp/src/pages/Pago.tsx index 08b25e7..964e55a 100644 --- a/webapp/src/pages/Pago.tsx +++ b/webapp/src/pages/Pago.tsx @@ -66,10 +66,38 @@ const Pago: FC = () => { } async function allFunc(Titular: String, tarjeta: String,fecha:String,cvv:string){ + console.log(Number(cvv)) + console.log(new Date().getFullYear()); + console.log("fecha") + console.log( isNaN(Number(fecha[4]))); + if(fecha[2] !== '-' || fecha.length < 7 || fecha.length > 7 || isNaN(Number(fecha[0])) || isNaN(Number(fecha[1])) || isNaN(Number(fecha[3])) + || isNaN(Number(fecha[4])) || isNaN(Number(fecha[5])) || isNaN(Number(fecha[6]))){ + Swal.fire({ + title: "Formato fecha incorrecto", + text: "el formato de la fecha debe ser mm-yyyy, siendo mm mes e yyyy el año", + icon: "error", + }); + } else { + var mes = fecha[0] + fecha[1]; + var año = fecha[3] + fecha[4] + fecha[5] + fecha[6]; + console.log(año) + console.log(mes) + + if(isNaN(Number(cvv)) || isNaN(Number(tarjeta)) || titular === null || titular === '' || (Number.parseInt(mes) < new Date().getMonth() && + Number.parseInt(año) === new Date().getFullYear()) || Number.parseInt(año) < new Date().getFullYear() || Number.parseInt(mes) > 12 || Number.parseInt(mes) <= 0 + || tarjeta.length < 16 || tarjeta.length > 16 || cvv.length > 3 || cvv.length < 3){ + Swal.fire({ + title: "Creedenciales incorrectos", + text: "Los campos introducidos son incorrectos", + icon: "error", + }); + } else { + setPulse(true); var precio = localStorage.getItem("precioCarrito"); if(precio !== null){ const direccion = await getDireccionPod(webId); + if(direccion['street_address'] !== undefined){ await getPrecioEnvio(direccion); var parseado = JSON.parse(precio); console.log("Envio: " + envio) @@ -78,7 +106,7 @@ const Pago: FC = () => { title: "Precio Final", text: "El precio de los articulos es de " + parseado + " tras la suma" + " con el precio de envío de " + envio + ". El precio Final que se " + - " deberá abonar es de: " + precioFinal.toFixed(2), + " deberá abonar es de: " + (precioFinal*1.21).toFixed(2), icon: "warning", confirmButtonColor: '#3085d6', cancelButtonColor: '#d33', @@ -100,7 +128,7 @@ const Pago: FC = () => { nombre: JSON.parse(carrt2)[i]['nombre'], codigo: JSON.parse(carrt2)[i]['codigo'], descripcion: JSON.parse(carrt2)[i]['descripcion'], - precio: JSON.parse(carrt2)[i]['precio'], + precio: JSON.parse(carrt2)[i]['precio'] + envio, cantidad: JSON.parse(carrt2)[i]['cantidad'], url: JSON.parse(carrt2)[i]['url'], stock: JSON.parse(carrt2)[i]['cantidad'], @@ -120,8 +148,16 @@ const Pago: FC = () => { ); } }) - + } else{ + Swal.fire({ + title: "Creedenciales incorrectos", + text: "No se ha encontrado el POD con ese nombre", + icon: "error", + }); } + } + } +} } @@ -201,7 +237,7 @@ const Pago: FC = () => { id = "caducidad" required name = "Fecha de caducidad" - label = "Fecha de caducidad (yyyy-mm-dd)" + label = "Fecha de caducidad (mm-yyyy)" variant="outlined" size="small" value = {fechaCad} diff --git a/webapp/src/pages/admin/ProdAdmin.tsx b/webapp/src/pages/admin/ProdAdmin.tsx index 1eafcc6..943543e 100644 --- a/webapp/src/pages/admin/ProdAdmin.tsx +++ b/webapp/src/pages/admin/ProdAdmin.tsx @@ -229,7 +229,7 @@ const ProdAdmin = (produc: ProductsProps): JSX.Element => { {p.categoria} {p.descripcion} {p.precio} - 18 + 21 {p.stock} diff --git a/webapp/src/pages/user/OrderHistory.tsx b/webapp/src/pages/user/OrderHistory.tsx index 299a785..f85c6f4 100644 --- a/webapp/src/pages/user/OrderHistory.tsx +++ b/webapp/src/pages/user/OrderHistory.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import Table from '@mui/material/Table'; import { TableContainer, TableHead} from '@mui/material'; import TableBody from '@mui/material/TableBody'; @@ -37,14 +37,13 @@ const OrderHistory = () => { let [id, setId] = useState('') let [user, setUser] = React.useState({_id: "", name: "",email: "",surname: "", password: ""}); - id = getUserId() + setId(getUserId()) const getUser = async (id:String) => { const apiEndPoint= process.env.REACT_APP_API_URI || 'http://localhost:5000' const data = await axios.get(apiEndPoint + "/user/findById/" + id).then ( res => { setUser(res.data); - console.log(user.email) return res.data } ) @@ -52,7 +51,7 @@ const OrderHistory = () => { } getUser(id) - email = user.email + setEmail(user.email) async function cargarPedidosEmail() { setOrdersEmail(await getOrdersByEmail(email)) diff --git a/webapp/src/pages/user/Profile.tsx b/webapp/src/pages/user/Profile.tsx index 42902a0..89eed45 100644 --- a/webapp/src/pages/user/Profile.tsx +++ b/webapp/src/pages/user/Profile.tsx @@ -1,4 +1,4 @@ -import React, { useState, FC } from 'react'; +import React, { useState } from 'react'; import Container from '@mui/material/Container'; import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button'; @@ -25,10 +25,8 @@ const Profile = () => { let [id, setId] = useState('') const [name, setName] = useState('') const [surname, setSurname] = useState('') - const [email, setEmail] = useState('') - const [pulse, setPulse] = useState(false) - id = getUserId() + setId(getUserId()) const getUser = async (id:String) => { const apiEndPoint= process.env.REACT_APP_API_URI || 'http://localhost:5000' @@ -36,7 +34,6 @@ const Profile = () => { const data = await axios.get(apiEndPoint + "/user/findById/" + id).then ( res => { setUser(res.data); - console.log(user.email) return res.data } ) @@ -45,17 +42,17 @@ const Profile = () => { getUser(id) const updateUser = (id:String,name?:String,surname?:String,email?:String) => { - if(name == ''){ + if(name === ''){ name = user.name } - if(surname == ''){ + if(surname === ''){ surname = user.surname } axios.put("http://localhost:5000/user/update/" + id,{"name":name,"surname":surname}) .then(res => { console.log(res); console.log(res.data); - if(res.status == 404){ + if(res.status === 404){ Swal.fire({ title: "Perfil modificado", text: "El perfil ha sido modificado con exito", @@ -67,7 +64,6 @@ const Profile = () => { }) } async function allFunc(id:String,name:String,surname:String,email: String){ - setPulse(true); updateUser(id, name, surname, email); } return ( @@ -126,7 +122,7 @@ const Profile = () => { style={{position:'relative', top:-20}} /> - + Quiero cambiar mi contraseña. diff --git a/webapp/src/tests/user/OrderHistory.test.tsx b/webapp/src/tests/user/OrderHistory.test.tsx deleted file mode 100644 index eb87aea..0000000 --- a/webapp/src/tests/user/OrderHistory.test.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import OrderHistory from '../../pages/user/OrderHistory'; - -test('Carga bien historial pedidos', async () => { - render(); - - expect(screen.getByText(/Fecha de orden/i)).toBeInTheDocument(); -}) \ No newline at end of file diff --git a/webapp/src/tests/user/Profile.test.tsx b/webapp/src/tests/user/Profile.test.tsx deleted file mode 100644 index 7589e31..0000000 --- a/webapp/src/tests/user/Profile.test.tsx +++ /dev/null @@ -1,12 +0,0 @@ - -import { render, screen } from '@testing-library/react'; - -import Profile from '../../pages/user/Profile'; - -test('Carga correcta de la ventana SingUp',async () => { - render( - - ); - - expect(screen.getByText(/No hay sesión inciada, por favor inicie sesión/i)).toBeInTheDocument(); -}) \ No newline at end of file