jueves, 1 de diciembre de 2022

Base de datos para un punto de venta

El siguiente código es para dar soporte a un sistema de venta mediante la inclusión de una base de datos relacional llamada ventas.


Código SQL para MySQL

-- ------------------------------------
-- Tabla "categoria"
-- ------------------------------------
CREATE TABLE `ventas`.`categoria` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`nombre` VARCHAR(50) NOT NULL , 
	`descripcion` TEXT NULL , 
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "producto"
-- ------------------------------------
CREATE TABLE `ventas`.`producto` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`nombre` VARCHAR(255) NOT NULL , 
	`precio` DECIMAL(10,2) NOT NULL , 
	`descripcion` TEXT NULL , 
	`cantidad` INT NOT NULL ,
	`categoria` INT NOT NULL , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_prod_cat
		FOREIGN KEY (categoria)
		REFERENCES categoria (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "cliente"
-- ------------------------------------
CREATE TABLE `ventas`.`cliente` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`dni` VARCHAR(20) NOT NULL UNIQUE , 
	`nombres` VARCHAR(150) NOT NULL , 
	`apellidos` VARCHAR(150) NOT NULL , 
	`correo` VARCHAR(200) NOT NULL UNIQUE , 
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "empleado"
-- ------------------------------------
CREATE TABLE `ventas`.`empleado` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`dni` VARCHAR(20) NOT NULL UNIQUE , 
	`nombres` VARCHAR(50) NOT NULL , 
	`paterno` VARCHAR(50) NOT NULL ,
	`materno` VARCHAR(50) NOT NULL , 
	`correo` VARCHAR(200) NOT NULL UNIQUE , 
	`telefono` VARCHAR(30) NOT NULL UNIQUE , 
	`clave` BLOB(200) NOT NULL ,
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "venta"
-- ------------------------------------
CREATE TABLE `ventas`.`venta` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`cliente` INT NOT NULL , 
	`empleado` INT NOT NULL , 
	`monto` DECIMAL(10,2) NOT NULL , 
	`fecha` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_venta_cliente
		FOREIGN KEY (cliente)
		REFERENCES cliente (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION ,
	CONSTRAINT fk_venta_empl
		FOREIGN KEY (empleado)
		REFERENCES empleado (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "detalle"
-- ------------------------------------
CREATE TABLE `ventas`.`detalle` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`venta` INT NOT NULL , 
	`producto` INT NOT NULL , 
	`precio` DECIMAL(10,2) NOT NULL , 
	`cantidad` INT NOT NULL , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_detalle_venta
		FOREIGN KEY (venta)
		REFERENCES venta (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION ,
	CONSTRAINT fk_detalle_prod
		FOREIGN KEY (producto)
		REFERENCES producto (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

Datos para inicializar la base de datos

-- ------------------------------------
-- Datos de inicialización
-- ------------------------------------
-- 3 empleados
INSERT INTO empleado(dni, nombres, paterno,
	materno, correo, telefono, clave) VALUES 
('10001000','PAUL','GARCIA','MATTOS','paul@mail.com',
	'999888777',AES_ENCRYPT('2022','2022')),
('20002000','LORENA','HERRERA','SOTELO','lorena@mail.com',
	'999888666',AES_ENCRYPT('123456','123456')),
('30003000','DEMETRIO','GARCIA','GARCIA','demetrio@mail.com',
	'999888555',AES_ENCRYPT('ADMIN','ADMIN'));

-- 2 clientes
INSERT INTO cliente (dni, nombres, apellidos, correo) VALUES 
('10101010','EMILIA','MELGAREJO CHAVEZ','emilia@mail.com'),
('10201020','KAREN','TORRES ALVA','karen@mail.com');

-- 2 categorias
INSERT INTO categoria(nombre, descripcion) VALUES 
('BEBIDAS',null),('ENTRADAS','Lorem ipsum');

-- 5 productos
INSERT INTO producto(nombre, descripcion, precio, cantidad, categoria)  VALUES 
('Soda 500ml', 'Gaseosa de 500ml en botella de vidrio', 4.50, 100, 1),
('Soda 1l', 'Gaseosa de 1 litro retornable', 7.50, 50, 1),
('Chicha morada 500ml', 'Chicha morada de 500ml retornable', 3.50, 40, 1),
('Causa rellena - 250gr', 'Porción de causa de 250 gramos', 10.50, 10, 2),
('Papa a la huancaína', null, 11.00, 10, 2);

-- 3 Ventas
INSERT INTO venta(cliente,empleado,monto,fecha) VALUES
(1,1,100,"2022-04-03 14:00:45"),
(1,2,100,"2022-05-01 22:00:00"),
(2,2,100,"2022-08-13 21:30:45");

-- Detalle de cada venta
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(1,4,10,5),
(1,1,5,10);
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(2,2,7.50,10),
(2,3,2.50,10);
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(3,4,10,10);

Vistas de la base de datos

-- VISTAS
-- ------------------------------------
-- productos_view
-- ------------------------------------
CREATE VIEW productos_view AS SELECT 
    p.id,
    p.nombre,
    p.precio,
    p.descripcion,
    p.cantidad,
    c.nombre AS categoria
FROM producto p INNER JOIN categoria c 
ON p.categoria = c.id;

-- ------------------------------------
-- venta_view
-- ------------------------------------
CREATE VIEW venta_view AS SELECT 
    v.id,
    CONCAT_WS(' ', c.nombres,c.apellidos) AS cliente,
    CONCAT_WS(' ', e.nombres,e.paterno,e.materno) AS empleado,
    v.fecha,
    v.monto,
    c.id AS id_cliente,
    e.id AS id_empleado
FROM venta v 
INNER JOIN cliente c ON v.cliente = c.id 
INNER JOIN empleado e ON v.empleado = e.id;

-- ------------------------------------
-- detalle_view
-- ------------------------------------
CREATE VIEW detalle_view AS SELECT 
    d.id,
    v.id AS venta,
    p.nombre AS producto,
    p.id AS id_producto,
    d.precio,
    d.cantidad
FROM detalle d 
INNER JOIN venta v ON d.venta = v.id 
INNER JOIN producto p ON d.producto = p.id;