FINAL
FINAL
Integrantes:
Fernando Andrés Mendiola Andrade 100%
Josías Leonardo Perales Tapia 100%
La Paz – Bolivia
I
3.1.1.1 RECOPILACION DE
INFORMACION
3.1 3.1.1.2 ESPECIFICACION DE Tabla de Equipo
PLANIFICACION PERSONAL INVOLUCRADO identificación
personal
2. REQUERIMIENTOS épicas Equipo
3.1.2.1 ESPECIFIACION DE tablas de
REQUERIMINETOS POR historias de
USUARIOS usuario
Diseño arquitectónico
Codificación capturas de
pantalla
Codificación de
interfaces modelo
relacional MySQL
Construcción de base
de datos diccionario de
datos
Diseño arquitectónico
Codificación capturas de
pantalla
Codificación de
interfaces modelo
relacional MySQL
Construcción de base
de datos diccionario de
datos
3.2.2.5 PRUEBAS Tabla de
prueba unitaria
3.2.3 ITERACION 3: MODULO DE Tabla de Perales
ADMINISTRACIÓN DE SISTEMA Planificación de Josías
Ventas
3.2.3.1 PLANIFICACION
Diseño arquitectónico
Codificación capturas de
pantalla
IV
Codificación de
interfaces modelo
relacional MySQL
Construcción de base
de datos diccionario de
datos
RECOPILACION DE INFORMACIÓN
REALIZACIÓN DEL CUESTIONARIO
A partir de la información recopilada en la entrevista, se procedió a realizar un
cuestionario para poder recopilar más información relevante y de una forma más
personalizada para el cliente. Luego pudimos reunirnos de nuevo con la propietaria del
negocio para poder realizarle el cuestionario.
TRANSCRIPCIÓN DEL CUESTIONARIO REALIZADO
Cuestionario:
1. ¿Actualmente cuentan con un sistema ya implementado?
R. - No, es totalmente manual el control que se hace, no hay un sistema.
2. ¿Su negocio cuenta con una jerarquía de roles?
R. - Somos tres personas, yo como propietaria, mi esposo está en el área de
comercialización y una persona más nos ayuda con la distribución y almacenamiento
3. ¿Qué servicios ofrece a sus clientes?
R. - Lo que hacemos es vender los productos de cosmética de diferentes marcas como
loreal, elementos relacionados con el area de cosmetica, salud y cosmetica natural
4. ¿Como maneja la entrada de nuevos productos al inventario?
R. - hacíamos el control en una hoja Excel, que nos permite la cantidad el control de los
productos, la fecha de vencimiento y el precio de compra para poder controlar el margen
de ganancia, sin embargo, la laptop que teníamos se dañó y desde entonces estamos
haciendo el control manual
5. ¿Ustedes son proveedores de estos productos?
R. - No, tenemos más o menos 20 proveedores
6. ¿Qué cualidades registra de los productos para mantener un control?
VII
Épicas
Épicas de administrador
Épicas de vendedor
AYUDANTE INVENTARIO
VENDEDOR
ADMINISTRADOR
ro:
Para: Tener un seguimiento de los clientes que compran en la tienda
DIAGRAMA DE GANTT
ANALISIS
DISEÑO
DISEÑO DE PROCESO
DIAGRAMA DE ACTIVIDADES
XIV
DISEÑO DE INTERFAZ
MOCKUPS
XV
DISEÑO DE NAVEGACIÓN
DIAGRAMA DE OBJETOS
DIAGRAMA ENTIDAD-RELACIÓN
XVI
DESARROLLO
CODIFICACIÓN
Funciones.js (compras)
XVII
$(document).ready(function () {
$("#procesarCompra").click(function () {
var fila = $("#tablaCompras tr").length;
if (fila < 2) {
Swal.fire({
icon: 'warning',
title: 'No hay productos en la venta',
showConfirmButton: false,
timer: 2500
})
} else {
const total = {
totalP: $("#total").val()
}
$.ajax({
url: base + "Compras/registrar",
type: 'POST',
data: total,
success: function (response) {
Swal.fire({
icon: 'success',
title: 'Compra Generado',
showConfirmButton: false,
timer: 1500
})
ListarCompras();
}
})
}
});
CODIFICACIÓN DE INTERFACES
Listar.php
</div>
</form>
<div class="row">
<div class="col-lg-12">
<div class="table-responsive">
<table class="table table-light mt-4"
id="tablaCompras">
<thead class="thead-dark">
<tr>
<th>Id</th>
<th>Producto</th>
<th>Cantidad</th>
<th>Precio</th>
<th>Total</th>
<th>Accion</th>
</tr>
</thead>
<tbody id="ListaCompras">
</tbody>
</table>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4 ml-auto">
<div class="form-group mt-2">
<strong class="text-primary"><i class="fas fa-
ad"></i> Total a pagar: </strong>
<input type="hidden" id="total" value="0.00"
name="total" class="form-control mb-2">
<strong id="totalV"></strong><br>
<button class="btn btn-danger" type="button"
id="AnularCompra"><i class="fas fa-ad"></i> Anular</button>
<button class="btn btn-success" type="button"
id="procesarCompra"><i class="fas fa-ad"></i> Procesar</button>
</div>
</div>
</div>
</div>
</section>
</div>
<?php pie() ?>
ListarCompras.php
<?php
require_once "Assets/pdf/fpdf.php";
$total = 0.00;
XXI
$pdf->Output();
?>
ComprasModel.php
?php
class ComprasModel extends Mysql{
XXII
{
$sql = "SELECT MAX(id) from compras";
$res = $this->select($sql);
return $res;
}
public function registrarCompra(String $total)
{
$return = "";
$this->total = $total;
$query = "INSERT INTO compras(total) VALUES (?)";
$data = array($this->total);
$resul = $this->insert($query, $data);
$return = $resul;
return $return;
}
PRUEBAS
3. Enviar el
formulario
C2 Verificar listado 1. Acceder a la N/A Mostrar lista de Exitosa
de compras página de listado compras con
de compras datos correctos
C3 Verificar 1. Acceder a la Producto: ID=1, Compra Exitosa
actualización de página de Cantidad=15, actualizada
compra edición de Proveedor: ID=2 correctamente
compra en la base de
datos
2. Modificar los
datos
3. Enviar el
formulario
C4 Verificar 1. Acceder a la Compra ID=1 Compra No
eliminación de página de listado eliminada Ejecutada
compra de compras correctamente
de la base de
2. Seleccionar datos
una compra
3. Eliminar la
compra
XXVII
DIAGRAMA DE GANTT
ANALISIS
DISEÑO
DISEÑO DE PROCESO
DIAGRAMA DE ACTIVIDADES
XXIX
DISEÑO DE INTERFAZ
MOCKUPS
DISEÑO DE NAVEGACIÓN
DIAGRAMA DE OBJETOS
XXX
DIAGRAMA ENTIDAD-RELACIÓN
DESARROLLO
XXXI
CODIFICACIÓN
Conexión.php
<?php
$host = "localhost";
$user = "root";
$clave = "";
$bd = "sis_venta";
$conexion = mysqli_connect($host,$user,$clave,$bd);
if (mysqli_connect_errno()){
echo "No se pudo conectar a la base de datos";
exit();
}
mysqli_select_db($conexion,$bd) or die("No se encuentra la base de
datos");
mysqli_set_charset($conexion,"utf8");
?>
agregar_producto.php (php)
<?php
include_once "includes/header.php";
include "../conexion.php";
$id_user = $_SESSION['idUser'];
$permiso = "productos";
$sql = mysqli_query($conexion, "SELECT p.*, d.* FROM permisos p INNER JOIN
detalle_permisos d ON p.id = d.id_permiso WHERE d.id_usuario = $id_user AND
p.nombre = '$permiso'");
$existe = mysqli_fetch_all($sql);
if (empty($existe) && $id_user != 1) {
header("Location: permisos.php");
}
if (empty($_GET['id'])) {
header("Location: productos.php");
} else {
$id_producto = $_GET['id'];
if (!is_numeric($id_producto)) {
header("Location: productos.php");
}
$consulta = mysqli_query($conexion, "SELECT * FROM producto WHERE
codproducto = $id_producto");
$data_producto = mysqli_fetch_assoc($consulta);
}
if (!empty($_POST)) {
$alert = "";
XXXII
if (!empty($_POST['cantidad']) || !empty($_POST['precio']) || !
empty($_POST['producto_id'])) {
$precio = $_POST['precio'];
$cantidad = $_POST['cantidad'];
$producto_id = $_GET['id'];
$total = $cantidad + $data_producto['existencia'];
$query_insert = mysqli_query($conexion, "UPDATE producto SET
existencia = $total WHERE codproducto = $id_producto");
if ($query_insert) {
$alert = '<div class="alert alert-success" role="alert">
Stock actualizado
</div>';
} else {
$alert = '<div class="alert alert-danger" role="alert">
Error al ingresar la cantidad
</div>';
}mysqli_close($conexion);
} else {
$alert = '<div class="alert alert-danger" role="alert">
Todo los campos son obligatorios
</div>';
}
editar_producto.php (php)
<?php
include_once "includes/header.php";
include "../conexion.php";
$id_user = $_SESSION['idUser'];
$permiso = "productos";
$sql = mysqli_query($conexion, "SELECT p.*, d.* FROM permisos p INNER JOIN
detalle_permisos d ON p.id = d.id_permiso WHERE d.id_usuario = $id_user AND
p.nombre = '$permiso'");
$existe = mysqli_fetch_all($sql);
if (empty($existe) && $id_user != 1) {
header("Location: permisos.php");
}
if (!empty($_POST)) {
$alert = "";
if (empty($_POST['codigo']) || empty($_POST['producto']) ||
empty($_POST['precio'])) {
$alert = '<div class="alert alert-primary" role="alert">
Todo los campos son requeridos
</div>';
} else {
$codproducto = $_GET['id'];
$codigo = $_POST['codigo'];
$producto = $_POST['producto'];
$precio = $_POST['precio'];
XXXIII
// Validar producto
if (empty($_REQUEST['id'])) {
header("Location: productos.php");
} else {
$id_producto = $_REQUEST['id'];
if (!is_numeric($id_producto)) {
header("Location: productos.php");
}
$query_producto = mysqli_query($conexion, "SELECT * FROM producto WHERE
codproducto = $id_producto");
$result_producto = mysqli_num_rows($query_producto);
if ($result_producto > 0) {
$data_producto = mysqli_fetch_assoc($query_producto);
} else {
header("Location: productos.php");
}
}
?>
Producto.php (php)
if (!empty($_POST)) {
$codigo = $_POST['codigo'];
$producto = $_POST['producto'];
$precio = $_POST['precio'];
$cantidad = $_POST['cantidad'];
$usuario_id = $_SESSION['idUser'];
$alert = "";
if (empty($codigo) || empty($producto) || empty($precio) || $precio <
0 || empty($cantidad) || $cantidad < 0) {
$alert = '<div class="alert alert-danger" role="alert">
Todo los campos son obligatorios
</div>';
} else {
$query = mysqli_query($conexion, "SELECT * FROM producto WHERE
codigo = '$codigo'");
$result = mysqli_fetch_array($query);
if ($result > 0) {
$alert = '<div class="alert alert-warning" role="alert">
El código ya existe
</div>';
} else {
$query_insert = mysqli_query($conexion,"INSERT INTO
producto(codigo,descripcion,precio,existencia,usuario_id) values ('$codigo',
'$producto','$precio','$cantidad','$usuario_id')");
if ($query_insert) {
$alert = '<div class="alert alert-success" role="alert">
Producto Registrado
</div>';
} else {
$alert = '<div class="alert alert-danger" role="alert">
Error al registrar el producto
</div>';
}
}
}
}
?>
XXXV
CODIFICACIÓN DE INTERFACES
agregar_producto.php (html)
<div class="row">
<div class="col-lg-6 m-auto">
<div class="card">
<div class="card-header bg-primary">
Agregar Producto
</div>
<div class="card-body">
<form action="" method="post">
<?php echo isset($alert) ? $alert : ''; ?>
<div class="form-group">
<label for="precio">Precio Actual</label>
<input type="text" class="form-control" value="<?php
echo $data_producto['precio']; ?>" disabled>
</div>
<div class="form-group">
<label for="precio">Cantidad de productos
Disponibles</label>
<input type="number" class="form-control" value="<?
php echo $data_producto['existencia']; ?>" disabled>
</div>
<div class="form-group">
<label for="precio">Nuevo Precio</label>
<input type="text" placeholder="Ingrese nombre del
precio" name="precio" class="form-control" value="<?php echo
$data_producto['precio']; ?>">
</div>
<div class="form-group">
<label for="cantidad">Agregar Cantidad</label>
<input type="number" placeholder="Ingrese cantidad"
name="cantidad" id="cantidad" class="form-control">
</div>
editar_producto.php (html)
<div class="row">
<div class="col-lg-6 m-auto">
<div class="card">
<div class="card-header bg-primary text-white">
Modificar producto
</div>
<div class="card-body">
<form action="" method="post">
<?php echo isset($alert) ? $alert : ''; ?>
<div class="form-group">
<label for="codigo">Código de Barras</label>
<input type="text" placeholder="Ingrese código de barras"
name="codigo" id="codigo" class="form-control" value="<?php echo
$data_producto['codigo']; ?>">
</div>
<div class="form-group">
<label for="producto">Producto</label>
<input type="text" class="form-control" placeholder="Ingrese
nombre del producto" name="producto" id="producto" value="<?php echo
$data_producto['descripcion']; ?>">
</div>
<div class="form-group">
<label for="precio">Precio</label>
<input type="text" placeholder="Ingrese precio" class="form-
control" name="precio" id="precio" value="<?php echo $data_producto['precio'];
?>">
</div>
<input type="submit" value="Actualizar Producto" class="btn btn-
primary">
<a href="productos.php" class="btn btn-danger">Atras</a>
</form>
</div>
</div>
</div>
</div>
XXXVII
Producto.php (html)
<form action="eliminar_producto.php?id=<?php
echo $data['codproducto']; ?>" method="post" class="confirmar d-inline">
<button class="btn btn-danger"
type="submit"><i class='fas fa-trash-alt'></i> </button>
</form>
<?php } ?>
</td>
</tr>
<?php }
} ?>
</tbody>
</table>
</div>
<div id="nuevo_producto" class="modal fade" tabindex="-1" role="dialog" aria-
labelledby="my-modal-title" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title" id="my-modal-title">Nuevo
Producto</h5>
<button class="close" data-dismiss="modal" aria-
label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form action="" method="post" autocomplete="off">
<?php echo isset($alert) ? $alert : ''; ?>
<div class="form-group">
<label for="codigo">Código de Barras</label>
<input type="text" placeholder="Ingrese código de
barras" name="codigo" id="codigo" class="form-control">
</div>
<div class="form-group">
<label for="producto">Producto</label>
<input type="text" placeholder="Ingrese nombre del
producto" name="producto" id="producto" class="form-control">
</div>
<div class="form-group">
<label for="precio">Precio</label>
<input type="text" placeholder="Ingrese precio"
class="form-control" name="precio" id="precio">
</div>
XXXIX
<div class="form-group">
<label for="cantidad">Cantidad</label>
<input type="number" placeholder="Ingrese cantidad"
class="form-control" name="cantidad" id="cantidad">
</div>
<input type="submit" value="Guardar Producto" class="btn
btn-primary">
</form>
</div>
</div>
</div>
</div>
PRUEBAS
3. Enviar el
formulario
P2 Verificar listado 1. Acceder a la N/A Mostrar lista de Exitosa
de productos página de productos con datos
listado de correctos
productos
P3 Verificar 1. Acceder a la Nombre: Producto actualizado Exitosa
actualización de página de "Producto B", correctamente en la
producto edición de Precio: 150, base de datos
producto Stock: 60
2. Modificar los
datos
3. Enviar el
formulario
P4 Verificar 1. Acceder a la Producto ID=1 Producto eliminado Exitosa
eliminación de página de correctamente de la
producto listado de base de datos
productos
2. Seleccionar
un producto
3. Eliminar el
producto
XLI
DIAGRAMA DE GANTT
ANALISIS
DISEÑO
DISEÑO DE PROCESO
DIAGRAMA DE ACTIVIDADES
XLIII
DISEÑO DE INTERFAZ
MOCKUPS
DISEÑO DE NAVEGACIÓN
DIAGRAMA DE OBJETOS
XLIV
DIAGRAMA ENTIDAD-RELACIÓN
XLV
DESARROLLO
CODIFICACIÓN
Rol.php (php)
require_once "../conexion.php";
$id = $_GET['id'];
$sqlpermisos = mysqli_query($conexion, "SELECT * FROM permisos");
$usuarios = mysqli_query($conexion, "SELECT * FROM usuario WHERE idusuario =
$id");
$consulta = mysqli_query($conexion, "SELECT * FROM detalle_permisos WHERE
id_usuario = $id");
$resultUsuario = mysqli_num_rows($usuarios);
if (empty($resultUsuario)) {
header("Location: usuarios.php");
}
$datos = array();
foreach ($consulta as $asignado) {
$datos[$asignado['id_permiso']] = true;
}
if (isset($_POST['permisos'])) {
$id_user = $_GET['id'];
$permisos = $_POST['permisos'];
mysqli_query($conexion, "DELETE FROM detalle_permisos WHERE id_usuario =
$id_user");
if ($permisos != "") {
foreach ($permisos as $permiso) {
$sql = mysqli_query($conexion, "INSERT INTO
detalle_permisos(id_usuario, id_permiso) VALUES ($id_user,$permiso)");
if ($sql == 1) {
header("Location: rol.php?id=".$id_user."&m=si");
} else {
$alert = '<div class="alert alert-primary" role="alert">
Error al actualizar permisos
</div>';
}
}
}
}
?>
XLVI
Usuarios.php (php)
CODIFICACIÓN DE INTERFACES
Rol.php (html)
<div class="row">
<?php } ?>
<?php while ($row = mysqli_fetch_assoc($sqlpermisos)) { ?>
<div class="form-check form-check-inline m-4">
<label for="permisos" class="p-2 text-
uppercase"><?php echo $row['nombre']; ?></label>
<input id="permisos" type="checkbox"
name="permisos[]" value="<?php echo $row['id']; ?>" <?php
if (isset($datos[$row['id']])) {
echo "checked";
?>>
</div>
<?php } ?>
<br>
<button class="btn btn-primary btn-block"
type="submit">Modificar</button>
</form>
</div>
</div>
</div>
</div>
Usuarios.php (html)
XLVIII
<th>Usuario</th>
<th>Nombre</th>
<th>Correo</th>
<th>Estado</th>
<th></th>
</tr>
</thead>
<tbody>
<?php ?>
<?php
include "../conexion.php";
} ?>
</tbody>
</table>
</div>
PRUEBAS
3. Enviar el
formulario
A2 Verificar 1. Acceder a la N/A Mostrar lista de Exitosa
listado de página de listado usuarios con
usuarios de usuarios datos correctos
A3 Verificar 1. Acceder a la Nombre: "Usuario B", Usuario No
actualización página de edición Email: actualizado ejecutada
de usuario de usuario "[email protected]", correctamente
Rol: "User" en la base de
2. Modificar los datos
datos
3. Enviar el
formulario
A4 Verificar 1. Acceder a la Usuario ID=1 Usuario Exitosa
eliminación de página de listado eliminado
usuario de usuarios correctamente
de la base de
2. Seleccionar un datos
usuario
3. Eliminar el
usuario
PLANIFICACION:
DIAGRAMA DE GANTT
ANALISIS:
Actores: Vendedor
Tipo: Primario
DISEÑO:
LII
DESARROLLO:
añadir cliente
LIII
editar cliente
Eliminar cliente
PRUEBA:
mysqli_error($conexion)); }
$existe =
mysqli_fetch_all($sql);
Las
variables
No hay $id_use
escape r y php $id_user =
de $permis mysqli_real_escape_string($conexio
Uso de
variables o deberían mysqli_real_escape_strin n, $_SESSION['idUser']); $permiso
para ser =
g para escapar las variables. mysqli_real_escape_string($conexio
prevenir escapadas
SQL para n, $permiso);
Injection prevenir
SQL
Injection.
Las
variables php <td><?php echo
que se htmlspecialchars($row['id']); ?></td>
Falta de <td><?php echo
muestran en Uso de
sanitización htmlspecialchars($row['nombre']); ?
el HTML htmlspecialchars
de salida ></td> <td><?php echo
deben ser para sanitizar las htmlspecialchars($row['total']); ?
para prevenir
sanitizadas variables. ></td> <td><?php echo
XSS
para htmlspecialchars($row['fecha']); ?
prevenir ></td>
XSS.
PLANIFICACION:
LV
ANALISIS:
Actores: Administrador
Tipo: Secundario
DISEÑO:
LVI
DESARROLLO:
PRUEBA:
LVII
PLANIFICACION:
LVIII
ANALISIS:
Actores: Vendedor
Tipo: Primario
DISEÑO:
DESARROLLO:
Interfaz de ventas
LIX
Lista de ventas
PRUEBA:
LX
VENTAS:
LISTA_VENTAS
LXI