|
@@ -2,18 +2,17 @@ import json
|
|
|
from math import log
|
|
from math import log
|
|
|
import os
|
|
import os
|
|
|
import sqlite3
|
|
import sqlite3
|
|
|
-from typing import List, Dict, Optional, Any, Union
|
|
|
|
|
|
|
+from typing import List, Dict, Optional, Any
|
|
|
from abc import ABC, abstractmethod
|
|
from abc import ABC, abstractmethod
|
|
|
from config.settings import BG_DATA_PATH, DB_PATH, PRODUCT_DATA_PATH
|
|
from config.settings import BG_DATA_PATH, DB_PATH, PRODUCT_DATA_PATH
|
|
|
from logging import getLogger
|
|
from logging import getLogger
|
|
|
from datetime import datetime
|
|
from datetime import datetime
|
|
|
-import uuid
|
|
|
|
|
from cryptography.fernet import Fernet
|
|
from cryptography.fernet import Fernet
|
|
|
from config.settings import PIN_KEY
|
|
from config.settings import PIN_KEY
|
|
|
|
|
|
|
|
# Import models
|
|
# Import models
|
|
|
from models.user import User
|
|
from models.user import User
|
|
|
-from models.items import Product, ProductWithQuantity
|
|
|
|
|
|
|
+from models.items import Product
|
|
|
from models.sales import Sale
|
|
from models.sales import Sale
|
|
|
from models.blacklist import Blacklist
|
|
from models.blacklist import Blacklist
|
|
|
|
|
|
|
@@ -28,14 +27,14 @@ ESQUEMA DE BASE DE DATOS SQLITE (data.db)
|
|
|
-----------------------------------
|
|
-----------------------------------
|
|
|
- id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
- id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
|
- email TEXT UNIQUE NOT NULL
|
|
- email TEXT UNIQUE NOT NULL
|
|
|
-- nombre TEXT NOT NULL
|
|
|
|
|
|
|
+- name TEXT NOT NULL
|
|
|
- rut TEXT UNIQUE NOT NULL
|
|
- rut TEXT UNIQUE NOT NULL
|
|
|
- pin_hash TEXT NOT NULL (encriptado)
|
|
- pin_hash TEXT NOT NULL (encriptado)
|
|
|
- kleincoins TEXT NOT NULL (encriptado, valor por defecto "0")
|
|
- kleincoins TEXT NOT NULL (encriptado, valor por defecto "0")
|
|
|
- created_at TEXT NOT NULL (fecha de creación en formato ISO 8601)
|
|
- created_at TEXT NOT NULL (fecha de creación en formato ISO 8601)
|
|
|
(Guarda la información del usuario con su pin hasheado y kleincoins encriptadas)
|
|
(Guarda la información del usuario con su pin hasheado y kleincoins encriptadas)
|
|
|
|
|
|
|
|
-2. Tabla: productos
|
|
|
|
|
|
|
+2. Tabla: products
|
|
|
-----------------------------------
|
|
-----------------------------------
|
|
|
- id INTEGER PRIMARY KEY
|
|
- id INTEGER PRIMARY KEY
|
|
|
- name TEXT NOT NULL
|
|
- name TEXT NOT NULL
|
|
@@ -46,21 +45,21 @@ ESQUEMA DE BASE DE DATOS SQLITE (data.db)
|
|
|
- status INTEGER DEFAULT 1 NOT NULL CHECK (status IN (0, 1)) -- 0: Inactivo, 1: Activo
|
|
- status INTEGER DEFAULT 1 NOT NULL CHECK (status IN (0, 1)) -- 0: Inactivo, 1: Activo
|
|
|
(Guarda los productos disponibles para venta con su estado activo/inactivo)
|
|
(Guarda los productos disponibles para venta con su estado activo/inactivo)
|
|
|
|
|
|
|
|
-3. Tabla: ventas
|
|
|
|
|
|
|
+3. Tabla: sales
|
|
|
-----------------------------------
|
|
-----------------------------------
|
|
|
- id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
- id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
|
- user_id INTEGER NOT NULL (relación a users.id)
|
|
- user_id INTEGER NOT NULL (relación a users.id)
|
|
|
- total REAL NOT NULL (precio total de la venta)
|
|
- total REAL NOT NULL (precio total de la venta)
|
|
|
- fudo_id TEXT UNIQUE NOT NULL (ID string único por venta)
|
|
- fudo_id TEXT UNIQUE NOT NULL (ID string único por venta)
|
|
|
-- fecha TEXT NOT NULL (fecha y hora en formato ISO 8601)
|
|
|
|
|
|
|
+- date TEXT NOT NULL (fecha y hora en formato ISO 8601)
|
|
|
- table INTEGER NOT NULL (número de mesa)
|
|
- table INTEGER NOT NULL (número de mesa)
|
|
|
(Guarda cada venta, asociada a un usuario y mesa)
|
|
(Guarda cada venta, asociada a un usuario y mesa)
|
|
|
|
|
|
|
|
-4. Tabla: venta_productos
|
|
|
|
|
|
|
+4. Tabla: sale_products
|
|
|
-----------------------------------
|
|
-----------------------------------
|
|
|
-- venta_id INTEGER NOT NULL (relación a ventas.id)
|
|
|
|
|
-- producto_id INTEGER NOT NULL (relación a productos.id)
|
|
|
|
|
-- cantidad INTEGER NOT NULL DEFAULT 1 (cantidad del producto)
|
|
|
|
|
|
|
+- sale_id INTEGER NOT NULL (relación a sales.id)
|
|
|
|
|
+- product_id INTEGER NOT NULL (relación a products.id)
|
|
|
|
|
+- quantity INTEGER NOT NULL DEFAULT 1 (cantidad del producto)
|
|
|
(Relación muchos a muchos entre ventas y productos con cantidad)
|
|
(Relación muchos a muchos entre ventas y productos con cantidad)
|
|
|
|
|
|
|
|
5. Tabla: blacklist
|
|
5. Tabla: blacklist
|
|
@@ -71,9 +70,9 @@ ESQUEMA DE BASE DE DATOS SQLITE (data.db)
|
|
|
|
|
|
|
|
RELACIONES:
|
|
RELACIONES:
|
|
|
-----------------------------------
|
|
-----------------------------------
|
|
|
-- users puede tener muchas ventas
|
|
|
|
|
-- ventas puede tener muchos productos (y viceversa), por eso se usa una tabla intermedia (venta_productos)
|
|
|
|
|
-- productos pueden repetirse en múltiples ventas
|
|
|
|
|
|
|
+- users puede tener muchas sales
|
|
|
|
|
+- sales puede tener muchos productos (y viceversa), por eso se usa una tabla intermedia (sale_products)
|
|
|
|
|
+- products pueden repetirse en múltiples sales
|
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
# Base abstract class for data access
|
|
# Base abstract class for data access
|
|
@@ -117,14 +116,14 @@ class BaseDataService(ABC):
|
|
|
class UserDataService(BaseDataService):
|
|
class UserDataService(BaseDataService):
|
|
|
"""Service for managing user data"""
|
|
"""Service for managing user data"""
|
|
|
#region Create
|
|
#region Create
|
|
|
- def create(self, nombre: str, email: str, rut: str, pin_hash: str) -> int:
|
|
|
|
|
|
|
+ def create(self, name: str, email: str, rut: str, pin_hash: str) -> int:
|
|
|
"""Add a new user to the database"""
|
|
"""Add a new user to the database"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
try:
|
|
try:
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "INSERT INTO users (nombre, email, rut, pin_hash, kleincoins, created_at) VALUES (?, ?, ?, ?, ?, ?)",
|
|
|
|
|
- (nombre, email, rut, fernet.encrypt(pin_hash.encode()).decode(), fernet.encrypt(b"0").decode(), datetime.now().isoformat())
|
|
|
|
|
|
|
+ "INSERT INTO users (name, email, rut, pin_hash, kleincoins, created_at) VALUES (?, ?, ?, ?, ?, ?)",
|
|
|
|
|
+ (name, email, rut, fernet.encrypt(pin_hash.encode()).decode(), fernet.encrypt(b"0").decode(), datetime.now().isoformat())
|
|
|
)
|
|
)
|
|
|
conn.commit()
|
|
conn.commit()
|
|
|
user_id = cursor.lastrowid
|
|
user_id = cursor.lastrowid
|
|
@@ -152,7 +151,7 @@ class UserDataService(BaseDataService):
|
|
|
User(
|
|
User(
|
|
|
id=user[0],
|
|
id=user[0],
|
|
|
email=user[1],
|
|
email=user[1],
|
|
|
- nombre=user[2],
|
|
|
|
|
|
|
+ name=user[2],
|
|
|
rut=user[3],
|
|
rut=user[3],
|
|
|
pin_hash=fernet.decrypt(user[4].encode()).decode(),
|
|
pin_hash=fernet.decrypt(user[4].encode()).decode(),
|
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
@@ -171,7 +170,7 @@ class UserDataService(BaseDataService):
|
|
|
return User(
|
|
return User(
|
|
|
id=user[0],
|
|
id=user[0],
|
|
|
email=user[1],
|
|
email=user[1],
|
|
|
- nombre=user[2],
|
|
|
|
|
|
|
+ name=user[2],
|
|
|
rut=user[3],
|
|
rut=user[3],
|
|
|
pin_hash=fernet.decrypt(user[4].encode()).decode(),
|
|
pin_hash=fernet.decrypt(user[4].encode()).decode(),
|
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
@@ -191,7 +190,7 @@ class UserDataService(BaseDataService):
|
|
|
return User(
|
|
return User(
|
|
|
id=user[0],
|
|
id=user[0],
|
|
|
email=user[1],
|
|
email=user[1],
|
|
|
- nombre=user[2],
|
|
|
|
|
|
|
+ name=user[2],
|
|
|
rut=user[3],
|
|
rut=user[3],
|
|
|
pin_hash=user[4],
|
|
pin_hash=user[4],
|
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
@@ -221,7 +220,7 @@ class UserDataService(BaseDataService):
|
|
|
return User(
|
|
return User(
|
|
|
id=user[0],
|
|
id=user[0],
|
|
|
email=user[1],
|
|
email=user[1],
|
|
|
- nombre=user[2],
|
|
|
|
|
|
|
+ name=user[2],
|
|
|
rut=user[3],
|
|
rut=user[3],
|
|
|
pin_hash=fernet.decrypt(user[4].encode()).decode(),
|
|
pin_hash=fernet.decrypt(user[4].encode()).decode(),
|
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
kleincoins=fernet.decrypt(user[5].encode()).decode(),
|
|
@@ -230,7 +229,7 @@ class UserDataService(BaseDataService):
|
|
|
return None
|
|
return None
|
|
|
#endregion
|
|
#endregion
|
|
|
#region Update
|
|
#region Update
|
|
|
- def update(self, user_id: int, email=None, nombre=None, rut=None, pin_hash=None, kleincoins=None) -> bool:
|
|
|
|
|
|
|
+ def update(self, user_id: int, email=None, name=None, rut=None, pin_hash=None, kleincoins=None) -> bool:
|
|
|
"""Update user information in the database"""
|
|
"""Update user information in the database"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
@@ -239,9 +238,9 @@ class UserDataService(BaseDataService):
|
|
|
if email:
|
|
if email:
|
|
|
updates.append("email = ?")
|
|
updates.append("email = ?")
|
|
|
params.append(email)
|
|
params.append(email)
|
|
|
- if nombre:
|
|
|
|
|
- updates.append("nombre = ?")
|
|
|
|
|
- params.append(nombre)
|
|
|
|
|
|
|
+ if name:
|
|
|
|
|
+ updates.append("name = ?")
|
|
|
|
|
+ params.append(name)
|
|
|
if rut:
|
|
if rut:
|
|
|
updates.append("rut = ?")
|
|
updates.append("rut = ?")
|
|
|
params.append(rut)
|
|
params.append(rut)
|
|
@@ -348,7 +347,7 @@ class BlacklistDataService(BaseDataService):
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- SELECT b.id, b.user_id, u.email, u.nombre, u.rut
|
|
|
|
|
|
|
+ SELECT b.id, b.user_id, u.email, u.name, u.rut
|
|
|
FROM blacklist b
|
|
FROM blacklist b
|
|
|
LEFT JOIN users u ON b.user_id = u.id
|
|
LEFT JOIN users u ON b.user_id = u.id
|
|
|
""")
|
|
""")
|
|
@@ -359,7 +358,7 @@ class BlacklistDataService(BaseDataService):
|
|
|
id=row[0],
|
|
id=row[0],
|
|
|
user_id=row[1],
|
|
user_id=row[1],
|
|
|
email=row[2],
|
|
email=row[2],
|
|
|
- nombre=row[3],
|
|
|
|
|
|
|
+ name=row[3],
|
|
|
rut=row[4]
|
|
rut=row[4]
|
|
|
) for row in blacklisted
|
|
) for row in blacklisted
|
|
|
]
|
|
]
|
|
@@ -369,7 +368,7 @@ class BlacklistDataService(BaseDataService):
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- SELECT b.id, b.user_id, u.email, u.nombre, u.rut
|
|
|
|
|
|
|
+ SELECT b.id, b.user_id, u.email, u.name, u.rut
|
|
|
FROM blacklist b
|
|
FROM blacklist b
|
|
|
LEFT JOIN users u ON b.user_id = u.id
|
|
LEFT JOIN users u ON b.user_id = u.id
|
|
|
WHERE b.id = ?
|
|
WHERE b.id = ?
|
|
@@ -381,7 +380,7 @@ class BlacklistDataService(BaseDataService):
|
|
|
id=row[0],
|
|
id=row[0],
|
|
|
user_id=row[1],
|
|
user_id=row[1],
|
|
|
email=row[2],
|
|
email=row[2],
|
|
|
- nombre=row[3],
|
|
|
|
|
|
|
+ name=row[3],
|
|
|
rut=row[4]
|
|
rut=row[4]
|
|
|
)
|
|
)
|
|
|
return None
|
|
return None
|
|
@@ -450,7 +449,7 @@ class ProductDataService(BaseDataService):
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
try:
|
|
try:
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "INSERT INTO productos (id, name, type, description, price, image, status) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
|
|
|
|
|
+ "INSERT INTO products (id, name, type, description, price, image, status) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
|
(id, name, type, description, price, image, status)
|
|
(id, name, type, description, price, image, status)
|
|
|
)
|
|
)
|
|
|
conn.commit()
|
|
conn.commit()
|
|
@@ -490,7 +489,7 @@ class ProductDataService(BaseDataService):
|
|
|
"""Get all products from the database"""
|
|
"""Get all products from the database"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute("SELECT * FROM productos")
|
|
|
|
|
|
|
+ cursor.execute("SELECT * FROM products")
|
|
|
products = cursor.fetchall()
|
|
products = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return [
|
|
return [
|
|
@@ -509,7 +508,7 @@ class ProductDataService(BaseDataService):
|
|
|
"""Get product by ID"""
|
|
"""Get product by ID"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute("SELECT * FROM productos WHERE id = ?", (product_id,))
|
|
|
|
|
|
|
+ cursor.execute("SELECT * FROM products WHERE id = ?", (product_id,))
|
|
|
product = cursor.fetchone()
|
|
product = cursor.fetchone()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
if product:
|
|
if product:
|
|
@@ -528,7 +527,7 @@ class ProductDataService(BaseDataService):
|
|
|
"""Get products by type"""
|
|
"""Get products by type"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute("SELECT * FROM productos WHERE type = ?", (product_type,))
|
|
|
|
|
|
|
+ cursor.execute("SELECT * FROM products WHERE type = ?", (product_type,))
|
|
|
products = cursor.fetchall()
|
|
products = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return [
|
|
return [
|
|
@@ -547,7 +546,7 @@ class ProductDataService(BaseDataService):
|
|
|
"""Search products by name"""
|
|
"""Search products by name"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute("SELECT * FROM productos WHERE name LIKE ?", (f"%{name}%",))
|
|
|
|
|
|
|
+ cursor.execute("SELECT * FROM products WHERE name LIKE ?", (f"%{name}%",))
|
|
|
products = cursor.fetchall()
|
|
products = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return [
|
|
return [
|
|
@@ -569,7 +568,7 @@ class ProductDataService(BaseDataService):
|
|
|
placeholders = ', '.join('?' for _ in product_ids)
|
|
placeholders = ', '.join('?' for _ in product_ids)
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute(f"SELECT * FROM productos WHERE id IN ({placeholders})", product_ids)
|
|
|
|
|
|
|
+ cursor.execute(f"SELECT * FROM products WHERE id IN ({placeholders})", product_ids)
|
|
|
products = cursor.fetchall()
|
|
products = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return [
|
|
return [
|
|
@@ -613,7 +612,7 @@ class ProductDataService(BaseDataService):
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return False
|
|
return False
|
|
|
try:
|
|
try:
|
|
|
- cursor.execute(f"UPDATE productos SET {', '.join(updates)} WHERE id = ?", (*params, product_id))
|
|
|
|
|
|
|
+ cursor.execute(f"UPDATE products SET {', '.join(updates)} WHERE id = ?", (*params, product_id))
|
|
|
conn.commit()
|
|
conn.commit()
|
|
|
success = cursor.rowcount > 0
|
|
success = cursor.rowcount > 0
|
|
|
if success:
|
|
if success:
|
|
@@ -629,7 +628,7 @@ class ProductDataService(BaseDataService):
|
|
|
"""Get only active products (status = 1)"""
|
|
"""Get only active products (status = 1)"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute("SELECT * FROM productos WHERE status = 1")
|
|
|
|
|
|
|
+ cursor.execute("SELECT * FROM products WHERE status = 1")
|
|
|
products = cursor.fetchall()
|
|
products = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return [
|
|
return [
|
|
@@ -648,7 +647,7 @@ class ProductDataService(BaseDataService):
|
|
|
"""Get only inactive products (status = 0)"""
|
|
"""Get only inactive products (status = 0)"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute("SELECT * FROM productos WHERE status = 0")
|
|
|
|
|
|
|
+ cursor.execute("SELECT * FROM products WHERE status = 0")
|
|
|
products = cursor.fetchall()
|
|
products = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return [
|
|
return [
|
|
@@ -683,7 +682,7 @@ class ProductDataService(BaseDataService):
|
|
|
"""Delete a product from the database"""
|
|
"""Delete a product from the database"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
- cursor.execute("DELETE FROM productos WHERE id = ?", (product_id,))
|
|
|
|
|
|
|
+ cursor.execute("DELETE FROM products WHERE id = ?", (product_id,))
|
|
|
conn.commit()
|
|
conn.commit()
|
|
|
success = cursor.rowcount > 0
|
|
success = cursor.rowcount > 0
|
|
|
conn.close()
|
|
conn.close()
|
|
@@ -698,7 +697,7 @@ class ProductDataService(BaseDataService):
|
|
|
class SalesDataService(BaseDataService):
|
|
class SalesDataService(BaseDataService):
|
|
|
"""Service for managing sales"""
|
|
"""Service for managing sales"""
|
|
|
#region C
|
|
#region C
|
|
|
- def create(self, user_id: int,fudo_id:str, total: float, table: int, product_ids: List[int], quantities: Optional[List[int]] = None) -> int:
|
|
|
|
|
|
|
+ def create(self, user_id: int, fudo_id: str, total: float, table: int, product_ids: List[int], quantities: Optional[List[int]] = None) -> int:
|
|
|
"""Create a new sale with products and quantities"""
|
|
"""Create a new sale with products and quantities"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
@@ -707,7 +706,7 @@ class SalesDataService(BaseDataService):
|
|
|
|
|
|
|
|
# Insert sale
|
|
# Insert sale
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "INSERT INTO ventas (user_id, total, fudo_id, fecha, 'table') VALUES (?, ?, ?, ?, ?)",
|
|
|
|
|
|
|
+ "INSERT INTO sales (user_id, total, fudo_id, date, 'table') VALUES (?, ?, ?, ?, ?)",
|
|
|
(user_id, total, fudo_id, fecha, table)
|
|
(user_id, total, fudo_id, fecha, table)
|
|
|
)
|
|
)
|
|
|
sale_id = cursor.lastrowid
|
|
sale_id = cursor.lastrowid
|
|
@@ -720,7 +719,7 @@ class SalesDataService(BaseDataService):
|
|
|
for i, product_id in enumerate(product_ids):
|
|
for i, product_id in enumerate(product_ids):
|
|
|
quantity = quantities[i] if i < len(quantities) else 1
|
|
quantity = quantities[i] if i < len(quantities) else 1
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "INSERT INTO venta_productos (venta_id, producto_id, cantidad) VALUES (?, ?, ?)",
|
|
|
|
|
|
|
+ "INSERT INTO sale_products (sale_id, product_id, quantity) VALUES (?, ?, ?)",
|
|
|
(sale_id, product_id, quantity)
|
|
(sale_id, product_id, quantity)
|
|
|
)
|
|
)
|
|
|
|
|
|
|
@@ -745,7 +744,7 @@ class SalesDataService(BaseDataService):
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
try:
|
|
try:
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "INSERT INTO venta_productos (venta_id, producto_id, cantidad) VALUES (?, ?, ?)",
|
|
|
|
|
|
|
+ "INSERT INTO sale_products (sale_id, product_id, quantity) VALUES (?, ?, ?)",
|
|
|
(sale_id, product_id, quantity)
|
|
(sale_id, product_id, quantity)
|
|
|
)
|
|
)
|
|
|
conn.commit()
|
|
conn.commit()
|
|
@@ -759,6 +758,31 @@ class SalesDataService(BaseDataService):
|
|
|
finally:
|
|
finally:
|
|
|
conn.close()
|
|
conn.close()
|
|
|
|
|
|
|
|
|
|
+ def add_products_to_sale(self, sale_id: int, product_ids: List[int], quantities: Optional[List[int]] = None) -> bool:
|
|
|
|
|
+ """Add multiple products to an existing sale with quantities"""
|
|
|
|
|
+ conn = self._get_connection()
|
|
|
|
|
+ cursor = conn.cursor()
|
|
|
|
|
+ try:
|
|
|
|
|
+ if quantities is None:
|
|
|
|
|
+ quantities = [1] * len(product_ids) # Default quantity 1
|
|
|
|
|
+
|
|
|
|
|
+ for i, product_id in enumerate(product_ids):
|
|
|
|
|
+ quantity = quantities[i] if i < len(quantities) else 1
|
|
|
|
|
+ cursor.execute(
|
|
|
|
|
+ "INSERT INTO sale_products (sale_id, product_id, quantity) VALUES (?, ?, ?)",
|
|
|
|
|
+ (sale_id, product_id, quantity)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ conn.commit()
|
|
|
|
|
+ success = cursor.rowcount > 0
|
|
|
|
|
+ if success:
|
|
|
|
|
+ logger.info(f"Products added to sale {sale_id}.")
|
|
|
|
|
+ return success
|
|
|
|
|
+ except sqlite3.IntegrityError as e:
|
|
|
|
|
+ logger.error(f"Failed to add products to sale: {e}")
|
|
|
|
|
+ return False
|
|
|
|
|
+ finally:
|
|
|
|
|
+ conn.close()
|
|
|
#endregion
|
|
#endregion
|
|
|
#region R
|
|
#region R
|
|
|
def get_all(self) -> List[Sale]:
|
|
def get_all(self) -> List[Sale]:
|
|
@@ -766,10 +790,10 @@ class SalesDataService(BaseDataService):
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- SELECT v.id, v.user_id, v.total, v.fudo_id, v.fecha, v.table, u.nombre, u.email
|
|
|
|
|
- FROM ventas v
|
|
|
|
|
- LEFT JOIN users u ON v.user_id = u.id
|
|
|
|
|
- ORDER BY v.fecha DESC
|
|
|
|
|
|
|
+ SELECT s.id, s.user_id, s.total, s.fudo_id, s.date, s.table, u.name, u.email
|
|
|
|
|
+ FROM sales s
|
|
|
|
|
+ LEFT JOIN users u ON s.user_id = u.id
|
|
|
|
|
+ ORDER BY s.date DESC
|
|
|
""")
|
|
""")
|
|
|
sales = cursor.fetchall()
|
|
sales = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
@@ -779,10 +803,11 @@ class SalesDataService(BaseDataService):
|
|
|
user_id=sale[1],
|
|
user_id=sale[1],
|
|
|
total=sale[2],
|
|
total=sale[2],
|
|
|
fudo_id=sale[3],
|
|
fudo_id=sale[3],
|
|
|
- fecha=sale[4],
|
|
|
|
|
|
|
+ date=sale[4],
|
|
|
table=sale[5],
|
|
table=sale[5],
|
|
|
- user_name=sale[6],
|
|
|
|
|
- user_email=sale[7]
|
|
|
|
|
|
|
+ username=sale[6],
|
|
|
|
|
+ user_email=sale[7],
|
|
|
|
|
+ products=self.get_sale_products(sale[0])
|
|
|
) for sale in sales
|
|
) for sale in sales
|
|
|
]
|
|
]
|
|
|
|
|
|
|
@@ -791,10 +816,10 @@ class SalesDataService(BaseDataService):
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- SELECT v.id, v.user_id, v.total, v.fudo_id, v.fecha, v.table, u.nombre, u.email
|
|
|
|
|
- FROM ventas v
|
|
|
|
|
- LEFT JOIN users u ON v.user_id = u.id
|
|
|
|
|
- WHERE v.id = ?
|
|
|
|
|
|
|
+ SELECT s.id, s.user_id, s.total, s.fudo_id, s.date, s.table, u.name, u.email
|
|
|
|
|
+ FROM sales s
|
|
|
|
|
+ LEFT JOIN users u ON s.user_id = u.id
|
|
|
|
|
+ WHERE s.id = ?
|
|
|
""", (sale_id,))
|
|
""", (sale_id,))
|
|
|
sale = cursor.fetchone()
|
|
sale = cursor.fetchone()
|
|
|
conn.close()
|
|
conn.close()
|
|
@@ -804,9 +829,9 @@ class SalesDataService(BaseDataService):
|
|
|
user_id=sale[1],
|
|
user_id=sale[1],
|
|
|
total=sale[2],
|
|
total=sale[2],
|
|
|
fudo_id=sale[3],
|
|
fudo_id=sale[3],
|
|
|
- fecha=sale[4],
|
|
|
|
|
|
|
+ date=sale[4],
|
|
|
table=sale[5],
|
|
table=sale[5],
|
|
|
- user_name=sale[6],
|
|
|
|
|
|
|
+ username=sale[6],
|
|
|
user_email=sale[7]
|
|
user_email=sale[7]
|
|
|
)
|
|
)
|
|
|
return None
|
|
return None
|
|
@@ -816,10 +841,10 @@ class SalesDataService(BaseDataService):
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- SELECT v.id, v.user_id, v.total, v.fudo_id, v.fecha, v.table, u.nombre, u.email
|
|
|
|
|
- FROM ventas v
|
|
|
|
|
- LEFT JOIN users u ON v.user_id = u.id
|
|
|
|
|
- WHERE v.fudo_id = ?
|
|
|
|
|
|
|
+ SELECT s.id, s.user_id, s.total, s.fudo_id, s.date, s.table, u.name, u.email
|
|
|
|
|
+ FROM sales s
|
|
|
|
|
+ LEFT JOIN users u ON s.user_id = u.id
|
|
|
|
|
+ WHERE s.fudo_id = ?
|
|
|
""", (fudo_id,))
|
|
""", (fudo_id,))
|
|
|
sale = cursor.fetchone()
|
|
sale = cursor.fetchone()
|
|
|
conn.close()
|
|
conn.close()
|
|
@@ -829,9 +854,9 @@ class SalesDataService(BaseDataService):
|
|
|
user_id=sale[1],
|
|
user_id=sale[1],
|
|
|
total=sale[2],
|
|
total=sale[2],
|
|
|
fudo_id=sale[3],
|
|
fudo_id=sale[3],
|
|
|
- fecha=sale[4],
|
|
|
|
|
|
|
+ date=sale[4],
|
|
|
table=sale[5],
|
|
table=sale[5],
|
|
|
- user_name=sale[6],
|
|
|
|
|
|
|
+ username=sale[6],
|
|
|
user_email=sale[7]
|
|
user_email=sale[7]
|
|
|
)
|
|
)
|
|
|
return None
|
|
return None
|
|
@@ -842,43 +867,57 @@ class SalesDataService(BaseDataService):
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
"""
|
|
"""
|
|
|
- SELECT v.id, v.user_id, v.total, v.fudo_id, v.fecha, v."table", u.nombre, u.email
|
|
|
|
|
- FROM ventas v
|
|
|
|
|
- LEFT JOIN users u ON v.user_id = u.id
|
|
|
|
|
- WHERE v.user_id = ?
|
|
|
|
|
- ORDER BY v.fecha DESC
|
|
|
|
|
|
|
+ SELECT s.id, s.user_id, s.total, s.fudo_id, s.date, s."table", u.name, u.email
|
|
|
|
|
+ FROM sales s
|
|
|
|
|
+ LEFT JOIN users u ON s.user_id = u.id
|
|
|
|
|
+ WHERE s.user_id = ?
|
|
|
|
|
+ ORDER BY s.date DESC
|
|
|
""",
|
|
""",
|
|
|
(user_id,)
|
|
(user_id,)
|
|
|
)
|
|
)
|
|
|
|
|
+
|
|
|
sales = cursor.fetchall()
|
|
sales = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
|
|
+
|
|
|
return [
|
|
return [
|
|
|
Sale(
|
|
Sale(
|
|
|
id=sale[0],
|
|
id=sale[0],
|
|
|
user_id=sale[1],
|
|
user_id=sale[1],
|
|
|
total=sale[2],
|
|
total=sale[2],
|
|
|
fudo_id=sale[3],
|
|
fudo_id=sale[3],
|
|
|
- fecha=sale[4],
|
|
|
|
|
|
|
+ date=sale[4],
|
|
|
table=sale[5],
|
|
table=sale[5],
|
|
|
- user_name=sale[6],
|
|
|
|
|
- user_email=sale[7]
|
|
|
|
|
|
|
+ username=sale[6],
|
|
|
|
|
+ user_email=sale[7],
|
|
|
|
|
+ products=self.get_sale_products(sale[0])
|
|
|
) for sale in sales
|
|
) for sale in sales
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
- def get_sale_products(self, sale_id: int) -> List[ProductWithQuantity]:
|
|
|
|
|
|
|
+ def get_sale_products_ids(self, sale_id: int) -> List[int]:
|
|
|
|
|
+ """Get product IDs for a specific sale"""
|
|
|
|
|
+ conn = self._get_connection()
|
|
|
|
|
+ cursor = conn.cursor()
|
|
|
|
|
+ cursor.execute("""
|
|
|
|
|
+ SELECT product_id FROM sale_products WHERE sale_id = ?
|
|
|
|
|
+ """, (sale_id,))
|
|
|
|
|
+ products = cursor.fetchall()
|
|
|
|
|
+ conn.close()
|
|
|
|
|
+ return [product[0] for product in products]
|
|
|
|
|
+
|
|
|
|
|
+ def get_sale_products(self, sale_id: int) -> List[Product]:
|
|
|
"""Get products for a specific sale with quantities"""
|
|
"""Get products for a specific sale with quantities"""
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- SELECT p.id, p.name, p.type, p.description, p.price, p.image, p.status, vp.cantidad
|
|
|
|
|
- FROM venta_productos vp
|
|
|
|
|
- JOIN productos p ON vp.producto_id = p.id
|
|
|
|
|
- WHERE vp.venta_id = ?
|
|
|
|
|
|
|
+ SELECT p.id, p.name, p.type, p.description, p.price, p.image, p.status, sp.quantity
|
|
|
|
|
+ FROM sale_products sp
|
|
|
|
|
+ JOIN products p ON sp.product_id = p.id
|
|
|
|
|
+ WHERE sp.sale_id = ?
|
|
|
""", (sale_id,))
|
|
""", (sale_id,))
|
|
|
products = cursor.fetchall()
|
|
products = cursor.fetchall()
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return [
|
|
return [
|
|
|
- ProductWithQuantity(
|
|
|
|
|
|
|
+ Product(
|
|
|
id=product[0],
|
|
id=product[0],
|
|
|
name=product[1],
|
|
name=product[1],
|
|
|
type=product[2],
|
|
type=product[2],
|
|
@@ -886,7 +925,7 @@ class SalesDataService(BaseDataService):
|
|
|
price=product[4],
|
|
price=product[4],
|
|
|
image=product[5],
|
|
image=product[5],
|
|
|
status=product[6],
|
|
status=product[6],
|
|
|
- cantidad=product[7]
|
|
|
|
|
|
|
+ quantity=product[7]
|
|
|
) for product in products
|
|
) for product in products
|
|
|
]
|
|
]
|
|
|
|
|
|
|
@@ -896,11 +935,11 @@ class SalesDataService(BaseDataService):
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
"""
|
|
"""
|
|
|
- SELECT v.id, v.user_id, v.total, v.fudo_id, v.fecha, v."table", u.nombre, u.email
|
|
|
|
|
- FROM ventas v
|
|
|
|
|
- LEFT JOIN users u ON v.user_id = u.id
|
|
|
|
|
- WHERE v."table" = ?
|
|
|
|
|
- ORDER BY v.fecha DESC
|
|
|
|
|
|
|
+ SELECT s.id, s.user_id, s.total, s.fudo_id, s.date, s."table", u.name, u.email
|
|
|
|
|
+ FROM sales s
|
|
|
|
|
+ LEFT JOIN users u ON s.user_id = u.id
|
|
|
|
|
+ WHERE s."table" = ?
|
|
|
|
|
+ ORDER BY s.date DESC
|
|
|
""",
|
|
""",
|
|
|
(table,)
|
|
(table,)
|
|
|
)
|
|
)
|
|
@@ -912,9 +951,9 @@ class SalesDataService(BaseDataService):
|
|
|
user_id=sale[1],
|
|
user_id=sale[1],
|
|
|
total=sale[2],
|
|
total=sale[2],
|
|
|
fudo_id=sale[3],
|
|
fudo_id=sale[3],
|
|
|
- fecha=sale[4],
|
|
|
|
|
|
|
+ date=sale[4],
|
|
|
table=sale[5],
|
|
table=sale[5],
|
|
|
- user_name=sale[6],
|
|
|
|
|
|
|
+ username=sale[6],
|
|
|
user_email=sale[7]
|
|
user_email=sale[7]
|
|
|
) for sale in sales
|
|
) for sale in sales
|
|
|
]
|
|
]
|
|
@@ -925,7 +964,7 @@ class SalesDataService(BaseDataService):
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
try:
|
|
try:
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "UPDATE venta_productos SET cantidad = ? WHERE venta_id = ? AND producto_id = ?",
|
|
|
|
|
|
|
+ "UPDATE sale_products SET quantity = ? WHERE sale_id = ? AND product_id = ?",
|
|
|
(new_quantity, sale_id, product_id)
|
|
(new_quantity, sale_id, product_id)
|
|
|
)
|
|
)
|
|
|
conn.commit()
|
|
conn.commit()
|
|
@@ -944,7 +983,7 @@ class SalesDataService(BaseDataService):
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "SELECT cantidad FROM venta_productos WHERE venta_id = ? AND producto_id = ?",
|
|
|
|
|
|
|
+ "SELECT quantity FROM sale_products WHERE sale_id = ? AND product_id = ?",
|
|
|
(sale_id, product_id)
|
|
(sale_id, product_id)
|
|
|
)
|
|
)
|
|
|
result = cursor.fetchone()
|
|
result = cursor.fetchone()
|
|
@@ -971,7 +1010,7 @@ class SalesDataService(BaseDataService):
|
|
|
conn.close()
|
|
conn.close()
|
|
|
return False
|
|
return False
|
|
|
try:
|
|
try:
|
|
|
- cursor.execute(f"UPDATE ventas SET {', '.join(updates)} WHERE id = ?", (*params, sale_id))
|
|
|
|
|
|
|
+ cursor.execute(f"UPDATE sales SET {', '.join(updates)} WHERE id = ?", (*params, sale_id))
|
|
|
conn.commit()
|
|
conn.commit()
|
|
|
success = cursor.rowcount > 0
|
|
success = cursor.rowcount > 0
|
|
|
if success:
|
|
if success:
|
|
@@ -990,9 +1029,9 @@ class SalesDataService(BaseDataService):
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
try:
|
|
try:
|
|
|
# Delete sale-product relationships first
|
|
# Delete sale-product relationships first
|
|
|
- cursor.execute("DELETE FROM venta_productos WHERE venta_id = ?", (sale_id,))
|
|
|
|
|
|
|
+ cursor.execute("DELETE FROM sale_products WHERE sale_id = ?", (sale_id,))
|
|
|
# Delete the sale
|
|
# Delete the sale
|
|
|
- cursor.execute("DELETE FROM ventas WHERE id = ?", (sale_id,))
|
|
|
|
|
|
|
+ cursor.execute("DELETE FROM sales WHERE id = ?", (sale_id,))
|
|
|
conn.commit()
|
|
conn.commit()
|
|
|
success = cursor.rowcount > 0
|
|
success = cursor.rowcount > 0
|
|
|
if success:
|
|
if success:
|
|
@@ -1011,7 +1050,7 @@ class SalesDataService(BaseDataService):
|
|
|
conn = self._get_connection()
|
|
conn = self._get_connection()
|
|
|
cursor = conn.cursor()
|
|
cursor = conn.cursor()
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "DELETE FROM venta_productos WHERE venta_id = ? AND producto_id = ?",
|
|
|
|
|
|
|
+ "DELETE FROM sale_products WHERE sale_id = ? AND product_id = ?",
|
|
|
(sale_id, product_id)
|
|
(sale_id, product_id)
|
|
|
)
|
|
)
|
|
|
conn.commit()
|
|
conn.commit()
|
|
@@ -1030,7 +1069,7 @@ class SalesDataService(BaseDataService):
|
|
|
try:
|
|
try:
|
|
|
# Get current quantity
|
|
# Get current quantity
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "SELECT cantidad FROM venta_productos WHERE venta_id = ? AND producto_id = ?",
|
|
|
|
|
|
|
+ "SELECT quantity FROM sale_products WHERE sale_id = ? AND product_id = ?",
|
|
|
(sale_id, product_id)
|
|
(sale_id, product_id)
|
|
|
)
|
|
)
|
|
|
result = cursor.fetchone()
|
|
result = cursor.fetchone()
|
|
@@ -1043,14 +1082,14 @@ class SalesDataService(BaseDataService):
|
|
|
if new_quantity <= 0:
|
|
if new_quantity <= 0:
|
|
|
# Remove the product completely
|
|
# Remove the product completely
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "DELETE FROM venta_productos WHERE venta_id = ? AND producto_id = ?",
|
|
|
|
|
|
|
+ "DELETE FROM sale_products WHERE sale_id = ? AND product_id = ?",
|
|
|
(sale_id, product_id)
|
|
(sale_id, product_id)
|
|
|
)
|
|
)
|
|
|
logger.info(f"Product {product_id} removed from sale {sale_id} (quantity reached 0).")
|
|
logger.info(f"Product {product_id} removed from sale {sale_id} (quantity reached 0).")
|
|
|
else:
|
|
else:
|
|
|
# Update with new quantity
|
|
# Update with new quantity
|
|
|
cursor.execute(
|
|
cursor.execute(
|
|
|
- "UPDATE venta_productos SET cantidad = ? WHERE venta_id = ? AND producto_id = ?",
|
|
|
|
|
|
|
+ "UPDATE sale_products SET quantity = ? WHERE sale_id = ? AND product_id = ?",
|
|
|
(new_quantity, sale_id, product_id)
|
|
(new_quantity, sale_id, product_id)
|
|
|
)
|
|
)
|
|
|
logger.info(f"Product {product_id} quantity decreased to {new_quantity} in sale {sale_id}.")
|
|
logger.info(f"Product {product_id} quantity decreased to {new_quantity} in sale {sale_id}.")
|
|
@@ -1118,7 +1157,7 @@ def initialize_db():
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
email TEXT UNIQUE NOT NULL,
|
|
email TEXT UNIQUE NOT NULL,
|
|
|
- nombre TEXT NOT NULL,
|
|
|
|
|
|
|
+ name TEXT NOT NULL,
|
|
|
rut TEXT UNIQUE NOT NULL,
|
|
rut TEXT UNIQUE NOT NULL,
|
|
|
pin_hash TEXT NOT NULL,
|
|
pin_hash TEXT NOT NULL,
|
|
|
kleincoins TEXT NOT NULL,
|
|
kleincoins TEXT NOT NULL,
|
|
@@ -1127,9 +1166,9 @@ def initialize_db():
|
|
|
""")
|
|
""")
|
|
|
|
|
|
|
|
# Crear tabla de productos
|
|
# Crear tabla de productos
|
|
|
- logger.info("Creando tabla de productos...")
|
|
|
|
|
|
|
+ logger.info("Creando tabla de products...")
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- CREATE TABLE IF NOT EXISTS productos (
|
|
|
|
|
|
|
+ CREATE TABLE IF NOT EXISTS products (
|
|
|
id INTEGER PRIMARY KEY,
|
|
id INTEGER PRIMARY KEY,
|
|
|
name TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
|
type TEXT,
|
|
type TEXT,
|
|
@@ -1141,28 +1180,28 @@ def initialize_db():
|
|
|
""")
|
|
""")
|
|
|
|
|
|
|
|
# Crear tabla de ventas
|
|
# Crear tabla de ventas
|
|
|
- logger.info("Creando tabla de ventas...")
|
|
|
|
|
|
|
+ logger.info("Creando tabla de sales...")
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- CREATE TABLE IF NOT EXISTS ventas (
|
|
|
|
|
|
|
+ CREATE TABLE IF NOT EXISTS sales (
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
user_id INTEGER NOT NULL,
|
|
user_id INTEGER NOT NULL,
|
|
|
total REAL NOT NULL,
|
|
total REAL NOT NULL,
|
|
|
- fudo_id TEXT UNIQUE NOT NULL,
|
|
|
|
|
- fecha TEXT NOT NULL,
|
|
|
|
|
|
|
+ fudo_id TEXT NOT NULL,
|
|
|
|
|
+ date TEXT NOT NULL,
|
|
|
"table" INTEGER NOT NULL,
|
|
"table" INTEGER NOT NULL,
|
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
|
);
|
|
);
|
|
|
""")
|
|
""")
|
|
|
|
|
|
|
|
# Crear tabla intermedia para ventas y productos
|
|
# Crear tabla intermedia para ventas y productos
|
|
|
- logger.info("Creando tabla intermedia de venta_productos...")
|
|
|
|
|
|
|
+ logger.info("Creando tabla intermedia de sale_products...")
|
|
|
cursor.execute("""
|
|
cursor.execute("""
|
|
|
- CREATE TABLE IF NOT EXISTS venta_productos (
|
|
|
|
|
- venta_id INTEGER NOT NULL,
|
|
|
|
|
- producto_id INTEGER NOT NULL,
|
|
|
|
|
- cantidad INTEGER NOT NULL DEFAULT 1,
|
|
|
|
|
- FOREIGN KEY (venta_id) REFERENCES ventas(id),
|
|
|
|
|
- FOREIGN KEY (producto_id) REFERENCES productos(id)
|
|
|
|
|
|
|
+ CREATE TABLE IF NOT EXISTS sale_products (
|
|
|
|
|
+ sale_id INTEGER NOT NULL,
|
|
|
|
|
+ product_id INTEGER NOT NULL,
|
|
|
|
|
+ quantity INTEGER NOT NULL DEFAULT 1,
|
|
|
|
|
+ FOREIGN KEY (sale_id) REFERENCES sales(id),
|
|
|
|
|
+ FOREIGN KEY (product_id) REFERENCES products(id)
|
|
|
);
|
|
);
|
|
|
""")
|
|
""")
|
|
|
|
|
|