Spaces:
Runtime error
Runtime error
JairoDanielMT
commited on
Commit
•
b293503
1
Parent(s):
295c33b
prescripcion ultimo registro y descargar prescripcion pdf
Browse files- .gitignore +2 -1
- app.py +70 -229
- conexion.py +48 -0
- generar_prescripcion_pdf.py +208 -0
- optica_copia.db +0 -0
- pdf/boleta/boleta_20231212224940.pdf +0 -0
- pdf/prescripcion/prescripcion_1_2023-12-12.pdf +0 -0
.gitignore
CHANGED
@@ -6,4 +6,5 @@ test2.py
|
|
6 |
test3.py
|
7 |
test4.py
|
8 |
test5.py
|
9 |
-
test6.py
|
|
|
|
6 |
test3.py
|
7 |
test4.py
|
8 |
test5.py
|
9 |
+
test6.py
|
10 |
+
.venv
|
app.py
CHANGED
@@ -1,18 +1,27 @@
|
|
1 |
# uvicorn app:app --host localhost --port 7860 --reload
|
2 |
-
|
3 |
-
import
|
4 |
-
from
|
|
|
|
|
|
|
5 |
from pydantic import BaseModel
|
6 |
-
from fastapi.middleware.cors import CORSMiddleware
|
7 |
from fastapi import FastAPI, HTTPException
|
|
|
8 |
from fastapi.responses import FileResponse
|
|
|
|
|
9 |
from reportlab.pdfgen import canvas
|
10 |
from reportlab.lib.pagesizes import letter
|
11 |
from reportlab.pdfbase import pdfmetrics
|
12 |
from reportlab.pdfbase.ttfonts import TTFont
|
13 |
from reportlab.platypus import Table, TableStyle
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
16 |
|
17 |
app = FastAPI()
|
18 |
|
@@ -26,57 +35,6 @@ app.add_middleware(
|
|
26 |
)
|
27 |
|
28 |
|
29 |
-
class DatabaseConnection:
|
30 |
-
"""
|
31 |
-
Clase para gestionar las conexiones a la base de datos con un pool.
|
32 |
-
"""
|
33 |
-
|
34 |
-
_instance = None
|
35 |
-
_lock = threading.Lock()
|
36 |
-
_connection_pool = Queue(maxsize=5)
|
37 |
-
|
38 |
-
def __new__(cls):
|
39 |
-
"""
|
40 |
-
Crea una nueva instancia de la clase si no existe.
|
41 |
-
"""
|
42 |
-
with cls._lock:
|
43 |
-
if cls._instance is None:
|
44 |
-
cls._instance = super().__new__(cls)
|
45 |
-
cls._instance.conn = cls._instance._create_connection()
|
46 |
-
return cls._instance
|
47 |
-
|
48 |
-
def _create_connection(self):
|
49 |
-
"""
|
50 |
-
Crea una conexión a la base de datos.
|
51 |
-
"""
|
52 |
-
if not self._connection_pool.empty():
|
53 |
-
return self._connection_pool.get()
|
54 |
-
else:
|
55 |
-
connection = sqlite3.connect("optica_copia.db")
|
56 |
-
connection.row_factory = sqlite3.Row
|
57 |
-
return connection
|
58 |
-
|
59 |
-
def get_connection(self):
|
60 |
-
"""
|
61 |
-
Obtener el objeto de conexión de la base de datos.
|
62 |
-
"""
|
63 |
-
return self._instance._create_connection()
|
64 |
-
|
65 |
-
def release_connection(self):
|
66 |
-
"""
|
67 |
-
Liberar la conexión de nuevo al pool.
|
68 |
-
"""
|
69 |
-
if self._instance is not None:
|
70 |
-
self._connection_pool.put(self._instance.conn)
|
71 |
-
self._instance.conn = None # Marcar la instancia como sin conexión
|
72 |
-
|
73 |
-
|
74 |
-
# Cargar varias tipografías
|
75 |
-
pdfmetrics.registerFont(TTFont("Craftcoke", "./font/Craftcoke.ttf"))
|
76 |
-
pdfmetrics.registerFont(TTFont("Oregon", "./font/Oregon.ttf"))
|
77 |
-
pdfmetrics.registerFont(TTFont("Roboto", "./font/Roboto.ttf"))
|
78 |
-
|
79 |
-
|
80 |
# saludo
|
81 |
@app.get("/")
|
82 |
def read_root():
|
@@ -801,13 +759,37 @@ def get_prescripcion(id_prescripcion: int):
|
|
801 |
return []
|
802 |
|
803 |
|
804 |
-
# post/prescripciones -> crear una prescripcion con una clase pydantic
|
805 |
class Prescripcion(BaseModel):
|
806 |
id_medidas: int
|
807 |
detalle_lunas: str
|
808 |
fecha: str
|
809 |
|
810 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
811 |
# metodo post de prescripciones con manejo de errores
|
812 |
@app.post("/prescripciones")
|
813 |
def create_prescripcion(prescripcion: Prescripcion):
|
@@ -928,170 +910,6 @@ def obtener_datos_prescripcion(id_prescripcion):
|
|
928 |
return []
|
929 |
|
930 |
|
931 |
-
class DatosPrescripcion:
|
932 |
-
def __init__(
|
933 |
-
self,
|
934 |
-
id_prescripcion,
|
935 |
-
fecha_prescripcion,
|
936 |
-
detalle_lunas,
|
937 |
-
esfera_od_lejos,
|
938 |
-
cilindro_od_lejos,
|
939 |
-
eje_od_lejos,
|
940 |
-
agudeza_visual_od_lejos,
|
941 |
-
esfera_oi_lejos,
|
942 |
-
cilindro_oi_lejos,
|
943 |
-
eje_oi_lejos,
|
944 |
-
agudeza_visual_oi_lejos,
|
945 |
-
esfera_od_cerca,
|
946 |
-
cilindro_od_cerca,
|
947 |
-
eje_od_cerca,
|
948 |
-
agudeza_visual_od_cerca,
|
949 |
-
esfera_oi_cerca,
|
950 |
-
cilindro_oi_cerca,
|
951 |
-
eje_oi_cerca,
|
952 |
-
agudeza_visual_oi_cerca,
|
953 |
-
id_cliente,
|
954 |
-
nombres_y_apellidos,
|
955 |
-
edad,
|
956 |
-
telefono,
|
957 |
-
direccion,
|
958 |
-
):
|
959 |
-
self.id_prescripcion = id_prescripcion
|
960 |
-
self.fecha_prescripcion = fecha_prescripcion
|
961 |
-
self.detalle_lunas = detalle_lunas
|
962 |
-
self.esfera_od_lejos = esfera_od_lejos
|
963 |
-
self.cilindro_od_lejos = cilindro_od_lejos
|
964 |
-
self.eje_od_lejos = eje_od_lejos
|
965 |
-
self.agudeza_visual_od_lejos = agudeza_visual_od_lejos
|
966 |
-
self.esfera_oi_lejos = esfera_oi_lejos
|
967 |
-
self.cilindro_oi_lejos = cilindro_oi_lejos
|
968 |
-
self.eje_oi_lejos = eje_oi_lejos
|
969 |
-
self.agudeza_visual_oi_lejos = agudeza_visual_oi_lejos
|
970 |
-
self.esfera_od_cerca = esfera_od_cerca
|
971 |
-
self.cilindro_od_cerca = cilindro_od_cerca
|
972 |
-
self.eje_od_cerca = eje_od_cerca
|
973 |
-
self.agudeza_visual_od_cerca = agudeza_visual_od_cerca
|
974 |
-
self.esfera_oi_cerca = esfera_oi_cerca
|
975 |
-
self.cilindro_oi_cerca = cilindro_oi_cerca
|
976 |
-
self.eje_oi_cerca = eje_oi_cerca
|
977 |
-
self.agudeza_visual_oi_cerca = agudeza_visual_oi_cerca
|
978 |
-
self.id_cliente = id_cliente
|
979 |
-
self.nombres_y_apellidos_cliente = nombres_y_apellidos
|
980 |
-
self.edad_cliente = edad
|
981 |
-
self.telefono_cliente = telefono
|
982 |
-
self.direccion_cliente = direccion
|
983 |
-
|
984 |
-
def generar_pdf(self, filename):
|
985 |
-
pdf = canvas.Canvas(filename)
|
986 |
-
pdf.setFont("Oregon", 12)
|
987 |
-
ubicacion_inicio = 780 # Posición inicial en y
|
988 |
-
pdf.drawCentredString(
|
989 |
-
300, ubicacion_inicio, "OPTICA ARTE VISUAL - PRESCRIPCIÓN"
|
990 |
-
)
|
991 |
-
pdf.drawString(
|
992 |
-
100,
|
993 |
-
ubicacion_inicio - 40,
|
994 |
-
f"Nombre del Cliente: {self.nombres_y_apellidos_cliente}",
|
995 |
-
)
|
996 |
-
pdf.drawString(
|
997 |
-
100, ubicacion_inicio - 60, f"Datos del cliente: {self.direccion_cliente}"
|
998 |
-
)
|
999 |
-
pdf.drawString(
|
1000 |
-
100, ubicacion_inicio - 80, f"Número telefónico: {self.telefono_cliente}"
|
1001 |
-
)
|
1002 |
-
pdf.drawString(
|
1003 |
-
100,
|
1004 |
-
ubicacion_inicio - 100,
|
1005 |
-
f"Código de prescripción: {self.id_prescripcion}",
|
1006 |
-
)
|
1007 |
-
pdf.drawString(100, ubicacion_inicio - 120, f"Fecha: {self.fecha_prescripcion}")
|
1008 |
-
pdf.drawString(
|
1009 |
-
100, ubicacion_inicio - 140, f"Descripción: {self.detalle_lunas}"
|
1010 |
-
)
|
1011 |
-
ubicacion_esfera = 150 # Posición inicial en x
|
1012 |
-
ubicacion_cilindro = ubicacion_esfera + 65 # Posición inicial en x + 65
|
1013 |
-
ubicacion_eje = ubicacion_cilindro + 75 # Posición anterior en x + 75
|
1014 |
-
ubicacion_agudeza = ubicacion_eje + 70 # Posición anterior en x + 70
|
1015 |
-
tabla_medidas = ubicacion_inicio - 170 # Posición inicial en y
|
1016 |
-
|
1017 |
-
pdf.drawString(ubicacion_esfera - 50, tabla_medidas, "Tabla de medidas:")
|
1018 |
-
# Para el ojo izquierdo de lejos
|
1019 |
-
pdf.drawString(
|
1020 |
-
ubicacion_esfera + 100, tabla_medidas - 20, "Ojo izquierdo de lejos"
|
1021 |
-
)
|
1022 |
-
pdf.line(
|
1023 |
-
x1=ubicacion_esfera,
|
1024 |
-
y1=tabla_medidas - 25,
|
1025 |
-
x2=ubicacion_esfera + 300,
|
1026 |
-
y2=tabla_medidas - 25,
|
1027 |
-
)
|
1028 |
-
pdf.drawString(ubicacion_esfera, tabla_medidas - 40, "Esfera")
|
1029 |
-
pdf.drawString(ubicacion_cilindro, tabla_medidas - 40, "Cilindro")
|
1030 |
-
pdf.drawString(ubicacion_eje, tabla_medidas - 40, "Eje")
|
1031 |
-
pdf.drawString(ubicacion_agudeza, tabla_medidas - 40, "Agudeza visual")
|
1032 |
-
pdf.drawString(ubicacion_esfera, tabla_medidas - 60, f"{self.esfera_oi_lejos}")
|
1033 |
-
pdf.drawString(
|
1034 |
-
ubicacion_cilindro, tabla_medidas - 60, f"{self.cilindro_oi_lejos}"
|
1035 |
-
)
|
1036 |
-
pdf.drawString(ubicacion_eje, tabla_medidas - 60, f"{self.eje_oi_lejos}")
|
1037 |
-
pdf.drawString(
|
1038 |
-
ubicacion_agudeza, tabla_medidas - 60, f"{self.agudeza_visual_oi_lejos}"
|
1039 |
-
)
|
1040 |
-
# Para el ojo derecho de lejos
|
1041 |
-
odl = tabla_medidas - 100 # Posición inicial en y
|
1042 |
-
pdf.drawString(ubicacion_esfera + 100, odl, "Ojo derecho de lejos")
|
1043 |
-
pdf.line(x1=ubicacion_esfera, y1=odl - 5, x2=ubicacion_esfera + 300, y2=odl - 5)
|
1044 |
-
pdf.drawString(ubicacion_esfera, odl - 20, "Esfera")
|
1045 |
-
pdf.drawString(ubicacion_cilindro, odl - 20, "Cilindro")
|
1046 |
-
pdf.drawString(ubicacion_eje, odl - 20, "Eje")
|
1047 |
-
pdf.drawString(ubicacion_agudeza, odl - 20, "Agudeza visual")
|
1048 |
-
pdf.drawString(ubicacion_esfera, odl - 40, f"{self.esfera_od_lejos}")
|
1049 |
-
pdf.drawString(ubicacion_cilindro, odl - 40, f"{self.cilindro_od_lejos}")
|
1050 |
-
pdf.drawString(ubicacion_eje, odl - 40, f"{self.eje_od_lejos}")
|
1051 |
-
pdf.drawString(ubicacion_agudeza, odl - 40, f"{self.agudeza_visual_od_lejos}")
|
1052 |
-
|
1053 |
-
oic = odl - 80 # Posición inicial en y
|
1054 |
-
pdf.drawString(ubicacion_esfera + 100, oic, "Ojo izquierdo de cerca")
|
1055 |
-
pdf.line(x1=ubicacion_esfera, y1=oic - 5, x2=ubicacion_esfera + 300, y2=oic - 5)
|
1056 |
-
# Para el ojo izquierdo de cerca
|
1057 |
-
pdf.drawString(ubicacion_esfera, oic - 20, "Esfera")
|
1058 |
-
pdf.drawString(ubicacion_cilindro, oic - 20, "Cilindro")
|
1059 |
-
pdf.drawString(ubicacion_eje, oic - 20, "Eje")
|
1060 |
-
pdf.drawString(ubicacion_agudeza, oic - 20, "Agudeza visual")
|
1061 |
-
pdf.drawString(ubicacion_esfera, oic - 40, f"{self.esfera_oi_cerca}")
|
1062 |
-
pdf.drawString(ubicacion_cilindro, oic - 40, f"{self.cilindro_oi_cerca}")
|
1063 |
-
pdf.drawString(ubicacion_eje, oic - 40, f"{self.eje_oi_cerca}")
|
1064 |
-
pdf.drawString(ubicacion_agudeza, oic - 40, f"{self.agudeza_visual_oi_cerca}")
|
1065 |
-
odc = oic - 80
|
1066 |
-
pdf.drawString(ubicacion_esfera + 100, odc, "Ojo derecho de cerca")
|
1067 |
-
pdf.line(x1=ubicacion_esfera, y1=odc - 5, x2=ubicacion_esfera + 300, y2=odc - 5)
|
1068 |
-
# Para el ojo derecho de cerca
|
1069 |
-
pdf.drawString(ubicacion_esfera, odc - 20, "Esfera")
|
1070 |
-
pdf.drawString(ubicacion_cilindro, odc - 20, "Cilindro")
|
1071 |
-
pdf.drawString(ubicacion_eje, odc - 20, "Eje")
|
1072 |
-
pdf.drawString(ubicacion_agudeza, odc - 20, "Agudeza visual")
|
1073 |
-
pdf.drawString(ubicacion_esfera, odc - 40, f"{self.esfera_od_cerca}")
|
1074 |
-
pdf.drawString(ubicacion_cilindro, odc - 40, f"{self.cilindro_od_cerca}")
|
1075 |
-
pdf.drawString(ubicacion_eje, odc - 40, f"{self.eje_od_cerca}")
|
1076 |
-
pdf.drawString(ubicacion_agudeza, odc - 40, f"{self.agudeza_visual_od_cerca}")
|
1077 |
-
|
1078 |
-
# Calcular el centro de la página
|
1079 |
-
centro_pagina = pdf._pagesize[0] / 2
|
1080 |
-
|
1081 |
-
# Texto y línea centrados
|
1082 |
-
texto_firma = " Firma o sello: "
|
1083 |
-
ancho_texto = pdf.stringWidth(texto_firma, "Helvetica", 12)
|
1084 |
-
inicio_linea = centro_pagina - ancho_texto / 2
|
1085 |
-
fin_linea = inicio_linea + ancho_texto
|
1086 |
-
# ubicacion en y dependiendo de la tabla de medidas
|
1087 |
-
firma_ubicacion = odc - 70
|
1088 |
-
pdf.drawString(inicio_linea, firma_ubicacion, texto_firma)
|
1089 |
-
pdf.line(inicio_linea, firma_ubicacion - 50, fin_linea, firma_ubicacion - 50)
|
1090 |
-
|
1091 |
-
pdf.save()
|
1092 |
-
print(f"PDF generado: {filename}")
|
1093 |
-
|
1094 |
-
|
1095 |
# crear endpoint para obtener los datos de la prescripción
|
1096 |
@app.get("/prescripcion/{id_prescripcion}")
|
1097 |
def obtener_datos_prescripcion_api(id_prescripcion: int):
|
@@ -1117,9 +935,6 @@ def obtener_pdf_prescripcion_api(prescripcion: PrescripcionPDF):
|
|
1117 |
obj_datos_prescripcion = DatosPrescripcion(*datos_prescripcion)
|
1118 |
directorio_pdf = "pdf/prescripcion/"
|
1119 |
os.makedirs(directorio_pdf, exist_ok=True)
|
1120 |
-
# importar libreria de fecha de hoy
|
1121 |
-
from datetime import date
|
1122 |
-
|
1123 |
# obtener la fecha de hoy
|
1124 |
fecha_hoy = date.today()
|
1125 |
# generar el nombre del archivo
|
@@ -1135,16 +950,13 @@ def obtener_pdf_prescripcion_api(prescripcion: PrescripcionPDF):
|
|
1135 |
|
1136 |
# crear endpoint retornando la url del PDF con los datos de la prescripción
|
1137 |
@app.get("/prescripcion/pdf/{id_prescripcion}")
|
1138 |
-
def
|
1139 |
datos_prescripcion = obtener_datos_prescripcion(id_prescripcion)
|
1140 |
if datos_prescripcion:
|
1141 |
# Crear un objeto de la clase DatosPrescripcion
|
1142 |
obj_datos_prescripcion = DatosPrescripcion(*datos_prescripcion)
|
1143 |
directorio_pdf = "pdf/prescripcion/"
|
1144 |
os.makedirs(directorio_pdf, exist_ok=True)
|
1145 |
-
# importar libreria de fecha de hoy
|
1146 |
-
from datetime import date
|
1147 |
-
|
1148 |
# obtener la fecha de hoy
|
1149 |
fecha_hoy = date.today()
|
1150 |
# generar el nombre del archivo
|
@@ -1157,6 +969,29 @@ def obtener_pdf_prescripcion(id_prescripcion: int):
|
|
1157 |
raise HTTPException(status_code=404, detail="Prescripción no encontrada")
|
1158 |
|
1159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1160 |
"""
|
1161 |
Table lunas_pedido {
|
1162 |
id_lunas_pedido INTEGER [primary key, unique, increment]
|
@@ -1688,6 +1523,12 @@ def delete_boleta(boleta: BoletaDelete):
|
|
1688 |
return []
|
1689 |
|
1690 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1691 |
def generar_boleta(idboleta, cliente, productos, adelanto, saldo):
|
1692 |
# crear directorio si no existe en pdf/boleta
|
1693 |
directorio_pdf = "pdf/boleta/"
|
|
|
1 |
# uvicorn app:app --host localhost --port 7860 --reload
|
2 |
+
# librerias propias del lenguaje
|
3 |
+
from datetime import datetime
|
4 |
+
from datetime import date
|
5 |
+
import os
|
6 |
+
|
7 |
+
# librerias para la API
|
8 |
from pydantic import BaseModel
|
|
|
9 |
from fastapi import FastAPI, HTTPException
|
10 |
+
from fastapi.middleware.cors import CORSMiddleware
|
11 |
from fastapi.responses import FileResponse
|
12 |
+
|
13 |
+
# librerias para el pdf
|
14 |
from reportlab.pdfgen import canvas
|
15 |
from reportlab.lib.pagesizes import letter
|
16 |
from reportlab.pdfbase import pdfmetrics
|
17 |
from reportlab.pdfbase.ttfonts import TTFont
|
18 |
from reportlab.platypus import Table, TableStyle
|
19 |
+
|
20 |
+
# importar clase conexion de conexion.py
|
21 |
+
from conexion import DatabaseConnection
|
22 |
+
|
23 |
+
# importar clase DatosPrescripcion
|
24 |
+
from generar_prescripcion_pdf import DatosPrescripcion
|
25 |
|
26 |
app = FastAPI()
|
27 |
|
|
|
35 |
)
|
36 |
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
# saludo
|
39 |
@app.get("/")
|
40 |
def read_root():
|
|
|
759 |
return []
|
760 |
|
761 |
|
|
|
762 |
class Prescripcion(BaseModel):
|
763 |
id_medidas: int
|
764 |
detalle_lunas: str
|
765 |
fecha: str
|
766 |
|
767 |
|
768 |
+
# post prescripcion con pydantic con retorna la todos los datos de la prescripcion
|
769 |
+
@app.post("/prescripcion/ultimoRegistro")
|
770 |
+
def post_prescripcion(prescripcion: Prescripcion):
|
771 |
+
try:
|
772 |
+
with DatabaseConnection().get_connection() as conn:
|
773 |
+
cursor = conn.cursor()
|
774 |
+
cursor.execute(
|
775 |
+
"INSERT INTO Prescripcion (id_medidas, detalle_lunas, fecha) VALUES (?, ?, ?)",
|
776 |
+
(
|
777 |
+
prescripcion.id_medidas,
|
778 |
+
prescripcion.detalle_lunas,
|
779 |
+
prescripcion.fecha,
|
780 |
+
),
|
781 |
+
)
|
782 |
+
conn.commit()
|
783 |
+
cursor.execute(
|
784 |
+
"SELECT * FROM Prescripcion ORDER BY id_prescripcion DESC LIMIT 1;"
|
785 |
+
)
|
786 |
+
prescripciones = cursor.fetchall()
|
787 |
+
return prescripciones
|
788 |
+
except Exception as e:
|
789 |
+
print(e)
|
790 |
+
return []
|
791 |
+
|
792 |
+
|
793 |
# metodo post de prescripciones con manejo de errores
|
794 |
@app.post("/prescripciones")
|
795 |
def create_prescripcion(prescripcion: Prescripcion):
|
|
|
910 |
return []
|
911 |
|
912 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
913 |
# crear endpoint para obtener los datos de la prescripción
|
914 |
@app.get("/prescripcion/{id_prescripcion}")
|
915 |
def obtener_datos_prescripcion_api(id_prescripcion: int):
|
|
|
935 |
obj_datos_prescripcion = DatosPrescripcion(*datos_prescripcion)
|
936 |
directorio_pdf = "pdf/prescripcion/"
|
937 |
os.makedirs(directorio_pdf, exist_ok=True)
|
|
|
|
|
|
|
938 |
# obtener la fecha de hoy
|
939 |
fecha_hoy = date.today()
|
940 |
# generar el nombre del archivo
|
|
|
950 |
|
951 |
# crear endpoint retornando la url del PDF con los datos de la prescripción
|
952 |
@app.get("/prescripcion/pdf/{id_prescripcion}")
|
953 |
+
def ver_prescripcion_pdf(id_prescripcion: int):
|
954 |
datos_prescripcion = obtener_datos_prescripcion(id_prescripcion)
|
955 |
if datos_prescripcion:
|
956 |
# Crear un objeto de la clase DatosPrescripcion
|
957 |
obj_datos_prescripcion = DatosPrescripcion(*datos_prescripcion)
|
958 |
directorio_pdf = "pdf/prescripcion/"
|
959 |
os.makedirs(directorio_pdf, exist_ok=True)
|
|
|
|
|
|
|
960 |
# obtener la fecha de hoy
|
961 |
fecha_hoy = date.today()
|
962 |
# generar el nombre del archivo
|
|
|
969 |
raise HTTPException(status_code=404, detail="Prescripción no encontrada")
|
970 |
|
971 |
|
972 |
+
# metodo get pdf de prescripcion
|
973 |
+
@app.get("/prescripcion/descargarPDF/{id_prescripcion}")
|
974 |
+
def descargar_prescripcion_pdf(id_prescripcion: int):
|
975 |
+
datos_prescripcion = obtener_datos_prescripcion(id_prescripcion)
|
976 |
+
if datos_prescripcion:
|
977 |
+
# Crear un objeto de la clase DatosPrescripcion
|
978 |
+
obj_datos_prescripcion = DatosPrescripcion(*datos_prescripcion)
|
979 |
+
directorio_pdf = "pdf/prescripcion/"
|
980 |
+
os.makedirs(directorio_pdf, exist_ok=True)
|
981 |
+
# obtener la fecha de hoy
|
982 |
+
fecha_hoy = date.today()
|
983 |
+
# generar el nombre del archivo
|
984 |
+
nombre_archivo = (
|
985 |
+
f"{directorio_pdf}prescripcion_{id_prescripcion}_{fecha_hoy}.pdf"
|
986 |
+
)
|
987 |
+
obj_datos_prescripcion.generar_pdf(f"{nombre_archivo}")
|
988 |
+
return FileResponse(
|
989 |
+
path=nombre_archivo, media_type="application/pdf", filename=nombre_archivo
|
990 |
+
)
|
991 |
+
else:
|
992 |
+
raise HTTPException(status_code=404, detail="Prescripción no encontrada")
|
993 |
+
|
994 |
+
|
995 |
"""
|
996 |
Table lunas_pedido {
|
997 |
id_lunas_pedido INTEGER [primary key, unique, increment]
|
|
|
1523 |
return []
|
1524 |
|
1525 |
|
1526 |
+
# Cargar varias tipografías
|
1527 |
+
pdfmetrics.registerFont(TTFont("Craftcoke", "./font/Craftcoke.ttf"))
|
1528 |
+
pdfmetrics.registerFont(TTFont("Oregon", "./font/Oregon.ttf"))
|
1529 |
+
pdfmetrics.registerFont(TTFont("Roboto", "./font/Roboto.ttf"))
|
1530 |
+
|
1531 |
+
|
1532 |
def generar_boleta(idboleta, cliente, productos, adelanto, saldo):
|
1533 |
# crear directorio si no existe en pdf/boleta
|
1534 |
directorio_pdf = "pdf/boleta/"
|
conexion.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from queue import Queue
|
2 |
+
import sqlite3
|
3 |
+
import threading
|
4 |
+
|
5 |
+
|
6 |
+
class DatabaseConnection:
|
7 |
+
"""
|
8 |
+
Clase para gestionar las conexiones a la base de datos con un pool.
|
9 |
+
"""
|
10 |
+
|
11 |
+
_instance = None
|
12 |
+
_lock = threading.Lock()
|
13 |
+
_connection_pool = Queue(maxsize=5)
|
14 |
+
|
15 |
+
def __new__(cls):
|
16 |
+
"""
|
17 |
+
Crea una nueva instancia de la clase si no existe.
|
18 |
+
"""
|
19 |
+
with cls._lock:
|
20 |
+
if cls._instance is None:
|
21 |
+
cls._instance = super().__new__(cls)
|
22 |
+
cls._instance.conn = cls._instance._create_connection()
|
23 |
+
return cls._instance
|
24 |
+
|
25 |
+
def _create_connection(self):
|
26 |
+
"""
|
27 |
+
Crea una conexión a la base de datos.
|
28 |
+
"""
|
29 |
+
if not self._connection_pool.empty():
|
30 |
+
return self._connection_pool.get()
|
31 |
+
else:
|
32 |
+
connection = sqlite3.connect("optica_copia.db")
|
33 |
+
connection.row_factory = sqlite3.Row
|
34 |
+
return connection
|
35 |
+
|
36 |
+
def get_connection(self):
|
37 |
+
"""
|
38 |
+
Obtener el objeto de conexión de la base de datos.
|
39 |
+
"""
|
40 |
+
return self._instance._create_connection()
|
41 |
+
|
42 |
+
def release_connection(self):
|
43 |
+
"""
|
44 |
+
Liberar la conexión de nuevo al pool.
|
45 |
+
"""
|
46 |
+
if self._instance is not None:
|
47 |
+
self._connection_pool.put(self._instance.conn)
|
48 |
+
self._instance.conn = None # Marcar la instancia como sin conexión
|
generar_prescripcion_pdf.py
ADDED
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# librerias para el pdf
|
2 |
+
from reportlab.pdfgen import canvas
|
3 |
+
from reportlab.pdfbase import pdfmetrics
|
4 |
+
from reportlab.pdfbase.ttfonts import TTFont
|
5 |
+
|
6 |
+
# Cargar varias tipografías
|
7 |
+
pdfmetrics.registerFont(TTFont("Craftcoke", "./font/Craftcoke.ttf"))
|
8 |
+
pdfmetrics.registerFont(TTFont("Oregon", "./font/Oregon.ttf"))
|
9 |
+
pdfmetrics.registerFont(TTFont("Roboto", "./font/Roboto.ttf"))
|
10 |
+
|
11 |
+
|
12 |
+
class DatosPrescripcion:
|
13 |
+
def __init__(
|
14 |
+
self,
|
15 |
+
id_prescripcion,
|
16 |
+
fecha_prescripcion,
|
17 |
+
detalle_lunas,
|
18 |
+
esfera_od_lejos,
|
19 |
+
cilindro_od_lejos,
|
20 |
+
eje_od_lejos,
|
21 |
+
agudeza_visual_od_lejos,
|
22 |
+
esfera_oi_lejos,
|
23 |
+
cilindro_oi_lejos,
|
24 |
+
eje_oi_lejos,
|
25 |
+
agudeza_visual_oi_lejos,
|
26 |
+
esfera_od_cerca,
|
27 |
+
cilindro_od_cerca,
|
28 |
+
eje_od_cerca,
|
29 |
+
agudeza_visual_od_cerca,
|
30 |
+
esfera_oi_cerca,
|
31 |
+
cilindro_oi_cerca,
|
32 |
+
eje_oi_cerca,
|
33 |
+
agudeza_visual_oi_cerca,
|
34 |
+
id_cliente,
|
35 |
+
nombres_y_apellidos,
|
36 |
+
edad,
|
37 |
+
telefono,
|
38 |
+
direccion,
|
39 |
+
):
|
40 |
+
"""
|
41 |
+
Clase que representa los datos de una prescripción.
|
42 |
+
|
43 |
+
Args:
|
44 |
+
id_prescripcion (int): El ID de la prescripción.
|
45 |
+
fecha_prescripcion (str): La fecha de la prescripción.
|
46 |
+
detalle_lunas (str): Los detalles de las lentes.
|
47 |
+
esfera_od_lejos (float): El valor de la esfera para el ojo derecho en visión lejana.
|
48 |
+
cilindro_od_lejos (float): El valor del cilindro para el ojo derecho en visión lejana.
|
49 |
+
eje_od_lejos (int): El valor del eje para el ojo derecho en visión lejana.
|
50 |
+
agudeza_visual_od_lejos (str): La agudeza visual para el ojo derecho en visión lejana.
|
51 |
+
esfera_oi_lejos (float): El valor de la esfera para el ojo izquierdo en visión lejana.
|
52 |
+
cilindro_oi_lejos (float): El valor del cilindro para el ojo izquierdo en visión lejana.
|
53 |
+
eje_oi_lejos (int): El valor del eje para el ojo izquierdo en visión lejana.
|
54 |
+
agudeza_visual_oi_lejos (str): La agudeza visual para el ojo izquierdo en visión lejana.
|
55 |
+
esfera_od_cerca (float): El valor de la esfera para el ojo derecho en visión cercana.
|
56 |
+
cilindro_od_cerca (float): El valor del cilindro para el ojo derecho en visión cercana.
|
57 |
+
eje_od_cerca (int): El valor del eje para el ojo derecho en visión cercana.
|
58 |
+
agudeza_visual_od_cerca (str): La agudeza visual para el ojo derecho en visión cercana.
|
59 |
+
esfera_oi_cerca (float): El valor de la esfera para el ojo izquierdo en visión cercana.
|
60 |
+
cilindro_oi_cerca (float): El valor del cilindro para el ojo izquierdo en visión cercana.
|
61 |
+
eje_oi_cerca (int): El valor del eje para el ojo izquierdo en visión cercana.
|
62 |
+
agudeza_visual_oi_cerca (str): La agudeza visual para el ojo izquierdo en visión cercana.
|
63 |
+
id_cliente (int): El ID del cliente.
|
64 |
+
nombres_y_apellidos (str): Los nombres y apellidos del cliente.
|
65 |
+
edad (int): La edad del cliente.
|
66 |
+
telefono (str): El número de teléfono del cliente.
|
67 |
+
direccion (str): La dirección del cliente.
|
68 |
+
"""
|
69 |
+
self.id_prescripcion = id_prescripcion
|
70 |
+
self.fecha_prescripcion = fecha_prescripcion
|
71 |
+
self.detalle_lunas = detalle_lunas
|
72 |
+
self.esfera_od_lejos = esfera_od_lejos
|
73 |
+
self.cilindro_od_lejos = cilindro_od_lejos
|
74 |
+
self.eje_od_lejos = eje_od_lejos
|
75 |
+
self.agudeza_visual_od_lejos = agudeza_visual_od_lejos
|
76 |
+
self.esfera_oi_lejos = esfera_oi_lejos
|
77 |
+
self.cilindro_oi_lejos = cilindro_oi_lejos
|
78 |
+
self.eje_oi_lejos = eje_oi_lejos
|
79 |
+
self.agudeza_visual_oi_lejos = agudeza_visual_oi_lejos
|
80 |
+
self.esfera_od_cerca = esfera_od_cerca
|
81 |
+
self.cilindro_od_cerca = cilindro_od_cerca
|
82 |
+
self.eje_od_cerca = eje_od_cerca
|
83 |
+
self.agudeza_visual_od_cerca = agudeza_visual_od_cerca
|
84 |
+
self.esfera_oi_cerca = esfera_oi_cerca
|
85 |
+
self.cilindro_oi_cerca = cilindro_oi_cerca
|
86 |
+
self.eje_oi_cerca = eje_oi_cerca
|
87 |
+
self.agudeza_visual_oi_cerca = agudeza_visual_oi_cerca
|
88 |
+
self.id_cliente = id_cliente
|
89 |
+
self.nombres_y_apellidos_cliente = nombres_y_apellidos
|
90 |
+
self.edad_cliente = edad
|
91 |
+
self.telefono_cliente = telefono
|
92 |
+
self.direccion_cliente = direccion
|
93 |
+
|
94 |
+
def generar_pdf(self, filename):
|
95 |
+
"""
|
96 |
+
Genera un archivo PDF con los datos de la prescripción.
|
97 |
+
|
98 |
+
Args:
|
99 |
+
filename (str): El nombre del archivo PDF a generar.
|
100 |
+
"""
|
101 |
+
pdf = canvas.Canvas(filename)
|
102 |
+
pdf.setFont("Oregon", 12)
|
103 |
+
ubicacion_inicio = 780 # Posición inicial en y
|
104 |
+
pdf.drawCentredString(
|
105 |
+
300, ubicacion_inicio, "OPTICA ARTE VISUAL - PRESCRIPCIÓN"
|
106 |
+
)
|
107 |
+
pdf.drawString(
|
108 |
+
100,
|
109 |
+
ubicacion_inicio - 40,
|
110 |
+
f"Nombre del Cliente: {self.nombres_y_apellidos_cliente}",
|
111 |
+
)
|
112 |
+
pdf.drawString(
|
113 |
+
100, ubicacion_inicio - 60, f"Datos del cliente: {self.direccion_cliente}"
|
114 |
+
)
|
115 |
+
pdf.drawString(
|
116 |
+
100, ubicacion_inicio - 80, f"Número telefónico: {self.telefono_cliente}"
|
117 |
+
)
|
118 |
+
pdf.drawString(
|
119 |
+
100,
|
120 |
+
ubicacion_inicio - 100,
|
121 |
+
f"Código de prescripción: {self.id_prescripcion}",
|
122 |
+
)
|
123 |
+
pdf.drawString(100, ubicacion_inicio - 120, f"Fecha: {self.fecha_prescripcion}")
|
124 |
+
pdf.drawString(
|
125 |
+
100, ubicacion_inicio - 140, f"Descripción: {self.detalle_lunas}"
|
126 |
+
)
|
127 |
+
ubicacion_esfera = 150 # Posición inicial en x
|
128 |
+
ubicacion_cilindro = ubicacion_esfera + 65 # Posición inicial en x + 65
|
129 |
+
ubicacion_eje = ubicacion_cilindro + 75 # Posición anterior en x + 75
|
130 |
+
ubicacion_agudeza = ubicacion_eje + 70 # Posición anterior en x + 70
|
131 |
+
tabla_medidas = ubicacion_inicio - 170 # Posición inicial en y
|
132 |
+
|
133 |
+
pdf.drawString(ubicacion_esfera - 50, tabla_medidas, "Tabla de medidas:")
|
134 |
+
# Para el ojo izquierdo de lejos
|
135 |
+
pdf.drawString(
|
136 |
+
ubicacion_esfera + 100, tabla_medidas - 20, "Ojo izquierdo de lejos"
|
137 |
+
)
|
138 |
+
pdf.line(
|
139 |
+
x1=ubicacion_esfera,
|
140 |
+
y1=tabla_medidas - 25,
|
141 |
+
x2=ubicacion_esfera + 300,
|
142 |
+
y2=tabla_medidas - 25,
|
143 |
+
)
|
144 |
+
pdf.drawString(ubicacion_esfera, tabla_medidas - 40, "Esfera")
|
145 |
+
pdf.drawString(ubicacion_cilindro, tabla_medidas - 40, "Cilindro")
|
146 |
+
pdf.drawString(ubicacion_eje, tabla_medidas - 40, "Eje")
|
147 |
+
pdf.drawString(ubicacion_agudeza, tabla_medidas - 40, "Agudeza visual")
|
148 |
+
pdf.drawString(ubicacion_esfera, tabla_medidas - 60, f"{self.esfera_oi_lejos}")
|
149 |
+
pdf.drawString(
|
150 |
+
ubicacion_cilindro, tabla_medidas - 60, f"{self.cilindro_oi_lejos}"
|
151 |
+
)
|
152 |
+
pdf.drawString(ubicacion_eje, tabla_medidas - 60, f"{self.eje_oi_lejos}")
|
153 |
+
pdf.drawString(
|
154 |
+
ubicacion_agudeza, tabla_medidas - 60, f"{self.agudeza_visual_oi_lejos}"
|
155 |
+
)
|
156 |
+
# Para el ojo derecho de lejos
|
157 |
+
odl = tabla_medidas - 100 # Posición inicial en y
|
158 |
+
pdf.drawString(ubicacion_esfera + 100, odl, "Ojo derecho de lejos")
|
159 |
+
pdf.line(x1=ubicacion_esfera, y1=odl - 5, x2=ubicacion_esfera + 300, y2=odl - 5)
|
160 |
+
pdf.drawString(ubicacion_esfera, odl - 20, "Esfera")
|
161 |
+
pdf.drawString(ubicacion_cilindro, odl - 20, "Cilindro")
|
162 |
+
pdf.drawString(ubicacion_eje, odl - 20, "Eje")
|
163 |
+
pdf.drawString(ubicacion_agudeza, odl - 20, "Agudeza visual")
|
164 |
+
pdf.drawString(ubicacion_esfera, odl - 40, f"{self.esfera_od_lejos}")
|
165 |
+
pdf.drawString(ubicacion_cilindro, odl - 40, f"{self.cilindro_od_lejos}")
|
166 |
+
pdf.drawString(ubicacion_eje, odl - 40, f"{self.eje_od_lejos}")
|
167 |
+
pdf.drawString(ubicacion_agudeza, odl - 40, f"{self.agudeza_visual_od_lejos}")
|
168 |
+
|
169 |
+
oic = odl - 80 # Posición inicial en y
|
170 |
+
pdf.drawString(ubicacion_esfera + 100, oic, "Ojo izquierdo de cerca")
|
171 |
+
pdf.line(x1=ubicacion_esfera, y1=oic - 5, x2=ubicacion_esfera + 300, y2=oic - 5)
|
172 |
+
# Para el ojo izquierdo de cerca
|
173 |
+
pdf.drawString(ubicacion_esfera, oic - 20, "Esfera")
|
174 |
+
pdf.drawString(ubicacion_cilindro, oic - 20, "Cilindro")
|
175 |
+
pdf.drawString(ubicacion_eje, oic - 20, "Eje")
|
176 |
+
pdf.drawString(ubicacion_agudeza, oic - 20, "Agudeza visual")
|
177 |
+
pdf.drawString(ubicacion_esfera, oic - 40, f"{self.esfera_oi_cerca}")
|
178 |
+
pdf.drawString(ubicacion_cilindro, oic - 40, f"{self.cilindro_oi_cerca}")
|
179 |
+
pdf.drawString(ubicacion_eje, oic - 40, f"{self.eje_oi_cerca}")
|
180 |
+
pdf.drawString(ubicacion_agudeza, oic - 40, f"{self.agudeza_visual_oi_cerca}")
|
181 |
+
odc = oic - 80
|
182 |
+
pdf.drawString(ubicacion_esfera + 100, odc, "Ojo derecho de cerca")
|
183 |
+
pdf.line(x1=ubicacion_esfera, y1=odc - 5, x2=ubicacion_esfera + 300, y2=odc - 5)
|
184 |
+
# Para el ojo derecho de cerca
|
185 |
+
pdf.drawString(ubicacion_esfera, odc - 20, "Esfera")
|
186 |
+
pdf.drawString(ubicacion_cilindro, odc - 20, "Cilindro")
|
187 |
+
pdf.drawString(ubicacion_eje, odc - 20, "Eje")
|
188 |
+
pdf.drawString(ubicacion_agudeza, odc - 20, "Agudeza visual")
|
189 |
+
pdf.drawString(ubicacion_esfera, odc - 40, f"{self.esfera_od_cerca}")
|
190 |
+
pdf.drawString(ubicacion_cilindro, odc - 40, f"{self.cilindro_od_cerca}")
|
191 |
+
pdf.drawString(ubicacion_eje, odc - 40, f"{self.eje_od_cerca}")
|
192 |
+
pdf.drawString(ubicacion_agudeza, odc - 40, f"{self.agudeza_visual_od_cerca}")
|
193 |
+
|
194 |
+
# Calcular el centro de la página
|
195 |
+
centro_pagina = pdf._pagesize[0] / 2
|
196 |
+
|
197 |
+
# Texto y línea centrados
|
198 |
+
texto_firma = " Firma o sello: "
|
199 |
+
ancho_texto = pdf.stringWidth(texto_firma, "Helvetica", 12)
|
200 |
+
inicio_linea = centro_pagina - ancho_texto / 2
|
201 |
+
fin_linea = inicio_linea + ancho_texto
|
202 |
+
# ubicacion en y dependiendo de la tabla de medidas
|
203 |
+
firma_ubicacion = odc - 70
|
204 |
+
pdf.drawString(inicio_linea, firma_ubicacion, texto_firma)
|
205 |
+
pdf.line(inicio_linea, firma_ubicacion - 50, fin_linea, firma_ubicacion - 50)
|
206 |
+
|
207 |
+
pdf.save()
|
208 |
+
print(f"PDF generado: {filename}")
|
optica_copia.db
CHANGED
Binary files a/optica_copia.db and b/optica_copia.db differ
|
|
pdf/boleta/boleta_20231212224940.pdf
ADDED
The diff for this file is too large to render.
See raw diff
|
|
pdf/prescripcion/prescripcion_1_2023-12-12.pdf
ADDED
Binary file (26.9 kB). View file
|
|