Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Drago177 committed Nov 21, 2024
2 parents f93188e + a33d09b commit 8b72e90
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 27 deletions.
2 changes: 2 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import os
from colorama import Fore, Back, Style
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
from routes.clientes import clientes


app = Flask(__name__)
Expand Down Expand Up @@ -59,6 +60,7 @@ def load_user(user_id):
app.register_blueprint(asig_operador_vehiculo)
app.register_blueprint(modelos_vehiculos)
app.register_blueprint(proveedores_repuesto)
app.register_blueprint(clientes)

def crear_triggers():
with open('triggers.sql', 'r') as file:
Expand Down
48 changes: 48 additions & 0 deletions models/bitacora_asignaciones.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from datetime import datetime
from sqlalchemy import ForeignKey, Date, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from extensiones import db
from .vehiculo import Vehiculo
from .usuario import Usuario

class BitacoraAsignaciones(db.Model):
id: Mapped[int] = mapped_column(primary_key=True)
id_vehiculo: Mapped[int] = mapped_column(ForeignKey('vehiculo.id'))
id_usuario: Mapped[int] = mapped_column(ForeignKey('usuario.id'))
fecha_hora_asignacion: Mapped[datetime] = mapped_column(default=func.now())
fecha_hora_desasignacion: Mapped[datetime] = mapped_column(nullable=True)

vehiculo: Mapped['Vehiculo'] = relationship('Vehiculo', backref='bitacoras_asignaciones')
usuario: Mapped['Usuario'] = relationship('Usuario', backref='bitacoras_asignaciones')

def serialize(self):
return {
'id': self.id,
'vehiculo': self.vehiculo.serialize() if self.vehiculo else None,
'usuario': self.usuario.serialize() if self.usuario else None,
'fecha_hora_asignacion': self.fecha_hora_asignacion,
'fecha_hora_desasignacion': self.fecha_hora_desasignacion,
}

@staticmethod
def agregar(bitacora):
db.session.add(bitacora)
db.session.commit()

@staticmethod
def listar():
return BitacoraAsignaciones.query.order_by(BitacoraAsignaciones.id.desc()).all()

@staticmethod
def listar_json():
return [bitacora.serialize() for bitacora in BitacoraAsignaciones.listar()]

@staticmethod
def encontrarPorId(id):
return BitacoraAsignaciones.query.get(id)

@staticmethod
def agregarFechaHoraDesasignacion(id):
bitacora = BitacoraAsignaciones.encontrarPorId(id)
bitacora.fecha_hora_desasignacion = func.now()
db.session.commit()
6 changes: 5 additions & 1 deletion models/cliente.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class Cliente(db.Model):
direccion: Mapped[str] = mapped_column(nullable=True)
email: Mapped[str] = mapped_column(nullable=True)
telefono: Mapped[str] = mapped_column(nullable=True)
usuario_cliente: Mapped[str] = mapped_column(nullable=True)
contrasena: Mapped[str] = mapped_column(nullable=True)

def serialize(self):
return {
Expand All @@ -18,7 +20,9 @@ def serialize(self):
'nombre': self.nombre,
'direccion': self.direccion,
'email': self.email,
'telefono': self.telefono
'telefono': self.telefono,
'usuario_cliente': self.usuario_cliente,
'contrasena': self.contrasena
}

@staticmethod
Expand Down
3 changes: 3 additions & 0 deletions models/usuario.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ def agregar(nombre, contrasena, rol):
@staticmethod
def buscar(nombre):
return Usuario.query.filter_by(nombre=nombre).first()

def buscarPorId(id):
return Usuario.query.get(id)


def is_active(self):
Expand Down
2 changes: 1 addition & 1 deletion models/vehiculo.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def actualizar():

@staticmethod
def encontrarPorId(id):
return db.session.get(Vehiculo, id)
return Vehiculo.query.get(id)

@staticmethod
def encontrarPorPatente(patente):
Expand Down
53 changes: 29 additions & 24 deletions routes/asig_operador_vehiculo.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
from flask import Blueprint
from flask import Blueprint, jsonify
from models.usuario import Usuario
from models.vehiculo import Vehiculo
from models.bitacora_asignaciones import BitacoraAsignaciones

asig_operador_vehiculo = Blueprint('asig_operador_vehiculo', __name__)

@asig_operador_vehiculo.route('/operadores/<string:nombre>/vehiculos/<int:id_vehiculo>/', methods=['PUT'])
def asignar(id_vehiculo, nombre):
@asig_operador_vehiculo.route('/asignacion/<int:id_usuario>/vehiculos/<int:id_vehiculo>/', methods=['PUT'])
def asignar(id_vehiculo, id_usuario):
vehiculo = Vehiculo.encontrarPorId(id_vehiculo)
usuario = Usuario.buscar(nombre)
if (vehiculo == None or usuario == None
or vehiculo.estado != 'ACTIVO'
or vehiculo.id_operador != None):
return "Vehiculo u Operador no encontrado", 404
vehiculo.id_operador = usuario.id
Vehiculo.actualizar()
return 'OK', 202
usuario = Usuario.buscarPorId(id_usuario)

bitacoraAsignaciones = BitacoraAsignaciones(
vehiculo=vehiculo,
usuario=usuario
)
BitacoraAsignaciones.agregar(bitacoraAsignaciones)

return bitacoraAsignaciones.serialize(), 201





@asig_operador_vehiculo.route('/operadores/<string:nombre>/vehiculos/desasign/<int:id_vehiculo>/', methods=['PUT'])
def desasignar(id_vehiculo, nombre):
vehiculo = Vehiculo.encontrarPorId(id_vehiculo)
usuario = Usuario.buscar(nombre)
print(vehiculo.id_operador)
print(usuario.id)
if (vehiculo == None or usuario == None
or vehiculo.estado != 'ACTIVO'
or vehiculo.id_operador != usuario.id):
return "Vehiculo u Operador no encontrado", 404
vehiculo.id_operador = None
Vehiculo.actualizar()
return 'OK', 202
@asig_operador_vehiculo.route('/desasignacion/<int:id_asignacion>', methods=['PUT'])
def desasignar(id_asignacion):
bitacora = BitacoraAsignaciones.encontrarPorId(id_asignacion)
BitacoraAsignaciones.agregarFechaHoraDesasignacion(id_asignacion)
return bitacora.serialize(), 201


# Obtener todas las asignaciones
@asig_operador_vehiculo.route('/asignaciones', methods=['GET'])
def obtener_asignaciones():
asignaciones = BitacoraAsignaciones.listar_json()
return jsonify(asignaciones)
127 changes: 127 additions & 0 deletions routes/clientes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required,create_access_token
from extensiones import db, bcrypt
from models.cliente import Cliente
from datetime import timedelta

clientes = Blueprint('clientes', __name__)

# Endpoint para listar todos los clientes
@clientes.route('/clientes', methods=['GET'])
@jwt_required()
def listar_clientes():
clientes = Cliente.listar_json()
return jsonify(clientes), 200


# Endpoint para agregar un nuevo cliente
@clientes.route('/clientes', methods=['POST'])
@jwt_required()
def agregar_cliente():
data = request.json

cuit = data.get('cuit')
nombre = data.get('nombre')
direccion = data.get('direccion')
email = data.get('email')
telefono = data.get('telefono')
usuario_cliente = data.get('usuario_cliente')
contrasena = data.get('contrasena')
id_operador = data.get('id_operador')

# Validación básica de datos obligatorios
if not cuit or not nombre or not usuario_cliente or not contrasena:
return jsonify(error='CUIT, Nombre, Usuario y Contraseña son obligatorios'), 400

# Verificar que el CUIT o el usuario no existan
if Cliente.query.filter_by(cuit=cuit).first():
return jsonify(error='CUIT ya registrado'), 400

if Cliente.query.filter_by(usuario_cliente=usuario_cliente).first():
return jsonify(error='Usuario ya registrado'), 400

# Encriptar la contraseña
contrasena_encriptada = bcrypt.generate_password_hash(contrasena).decode('utf-8')

# Crear y guardar el cliente
nuevo_cliente = Cliente(
cuit=cuit,
nombre=nombre,
direccion=direccion,
email=email,
telefono=telefono,
usuario_cliente=usuario_cliente,
contrasena=contrasena_encriptada,
id_operador=id_operador
)
Cliente.agregar(nuevo_cliente)
return jsonify(nuevo_cliente.serialize()), 201


@clientes.route('/clientes/login', methods=['POST'])
def login_cliente():
data = request.json
usuario_cliente = data.get('usuario_cliente')
contrasena = data.get('contrasena')

# Validar entrada
if not usuario_cliente or not contrasena:
return jsonify(error='Usuario y contraseña son requeridos'), 400

# Buscar cliente por usuario_cliente
cliente = Cliente.query.filter_by(usuario_cliente=usuario_cliente).first()
if not cliente:
return jsonify(error='Credenciales incorrectas'), 401

# Verificar contraseña
if not bcrypt.check_password_hash(cliente.contrasena, contrasena):
return jsonify(error='Credenciales incorrectas'), 401

# Generar token JWT
access_token = create_access_token(
identity=cliente.id,
expires_delta=timedelta(hours=1),
additional_claims={"usuario_cliente": cliente.usuario_cliente}
)

return jsonify(access_token=access_token, id=cliente.id, nombre=cliente.nombre), 200



# Endpoint para eliminar un cliente por ID
@clientes.route('/clientes/<int:id>', methods=['DELETE'])
@jwt_required()
def eliminar_cliente(id):
cliente = Cliente.encontrarPorId(id)
if not cliente:
return jsonify(error='Cliente no encontrado'), 404

Cliente.eliminar(cliente)
return jsonify(message='Cliente eliminado correctamente'), 200


# Endpoint para actualizar un cliente por ID
@clientes.route('/clientes/<int:id>', methods=['PUT'])
@jwt_required()
def actualizar_cliente(id):
data = request.json
cliente = Cliente.encontrarPorId(id)

if not cliente:
return jsonify(error='Cliente no encontrado'), 404

cliente.nombre = data.get('nombre', cliente.nombre)
cliente.direccion = data.get('direccion', cliente.direccion)
cliente.email = data.get('email', cliente.email)
cliente.telefono = data.get('telefono', cliente.telefono)
cliente.usuario_cliente = data.get('usuario_cliente', cliente.usuario_cliente)

# Encriptar la nueva contraseña si se proporciona
nueva_contrasena = data.get('contrasena')
if nueva_contrasena:
cliente.contrasena = bcrypt.generate_password_hash(nueva_contrasena).decode('utf-8')

cliente.id_operador = data.get('id_operador', cliente.id_operador)

Cliente.actualizar()
return jsonify(cliente.serialize()), 200
40 changes: 40 additions & 0 deletions routes/vehiculos.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ def listar_vehiculos():
vehiculos = Vehiculo.listar_json()
return jsonify(vehiculos)

@vehiculos.route('/vehiculos/<int:id>')
def obtener_vehiculo(id):
vehiculo = Vehiculo.encontrarPorId(id)
if not vehiculo:
return jsonify({'error': 'Vehiculo no encontrado'}), 404
return jsonify(vehiculo.serialize())

#endpoint de carga de vehiculo
@vehiculos.route('/vehiculos/alta', methods=['GET', 'POST'])
def cargar_vehiculo():
Expand Down Expand Up @@ -88,3 +95,36 @@ def baja_vehiculo():
flash('Vehiculo dado de baja', 'success')

redirect(url_for('listar_vehiculos'))



#cambiar estado de vehiculo
@vehiculos.route('/vehiculos/estado', methods=['PUT'])
def cambiar_estado():
patente = request.form['patente']
estado = request.form['estado']

vehiculo = Vehiculo.encontrarPorPatente(patente)

vehiculo.estado = estado

Vehiculo.actualizar()

flash('Estado cambiado con exito', 'success')

return jsonify(vehiculo.serialize()), 200


@vehiculos.route('/vehiculos/estadoXid', methods=['PUT'])
def cambiar_estadoXid():
id = request.form['id']
estado = request.form['estado']

vehiculo = Vehiculo.encontrarPorId(id)

vehiculo.estado = estado

Vehiculo.actualizar()


return jsonify(vehiculo.serialize()), 200
4 changes: 3 additions & 1 deletion tablas.sql
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ CREATE TABLE cliente (
nombre text,
direccion text,
email text,
telefono text
telefono text,
usuario_cliente text,
contrasena text
);

CREATE TABLE gasto (
Expand Down

0 comments on commit 8b72e90

Please sign in to comment.