248 lines
7.7 KiB
Python
248 lines
7.7 KiB
Python
# database/models/listed.py
|
|
import sqlite3
|
|
import time
|
|
from database.db import get_connection
|
|
|
|
class Listed:
|
|
@staticmethod
|
|
def all():
|
|
conn = get_connection()
|
|
conn.row_factory = sqlite3.Row
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT * FROM listed")
|
|
rows = cur.fetchall()
|
|
conn.close()
|
|
return [dict(row) for row in rows]
|
|
|
|
@staticmethod
|
|
def get_by_account_product(account_id, product_id):
|
|
conn = get_connection()
|
|
conn.row_factory = sqlite3.Row
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"SELECT * FROM listed WHERE account_id = ? AND product_id = ?",
|
|
(account_id, product_id)
|
|
)
|
|
row = cur.fetchone()
|
|
conn.close()
|
|
if row:
|
|
return dict(row)
|
|
return None
|
|
|
|
@staticmethod
|
|
def create(account_id, product_id):
|
|
existing = Listed.get_by_account_product(account_id, product_id)
|
|
if existing:
|
|
return existing
|
|
|
|
listed_at = int(time.time())
|
|
conn = get_connection()
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"INSERT INTO listed (account_id, product_id, listed_at) VALUES (?, ?, ?)",
|
|
(account_id, product_id, listed_at)
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
return Listed.get_by_account_product(account_id, product_id)
|
|
|
|
@staticmethod
|
|
def delete(listed_id):
|
|
conn = get_connection()
|
|
cur = conn.cursor()
|
|
cur.execute("DELETE FROM listed WHERE id = ?", (listed_id,))
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
@staticmethod
|
|
def get_paginated(offset, limit, filters=None, sort_by="id", sort_order="ASC"):
|
|
filters = filters or {}
|
|
params = []
|
|
|
|
base_query = """
|
|
SELECT
|
|
l.id AS id,
|
|
p.sku AS sku,
|
|
p.name AS product_name,
|
|
a.email AS account_email,
|
|
l.listed_at AS listed_at,
|
|
l.status AS status,
|
|
p.condition AS condition,
|
|
p.images AS images
|
|
FROM listed l
|
|
JOIN products p ON l.product_id = p.id
|
|
JOIN accounts a ON l.account_id = a.id
|
|
"""
|
|
|
|
where_clauses = []
|
|
|
|
# --- Filters ---
|
|
if "status" in filters and filters["status"]:
|
|
status_val = filters["status"]
|
|
if isinstance(status_val, list):
|
|
placeholders = ",".join(["?"] * len(status_val))
|
|
where_clauses.append(f"l.status IN ({placeholders})")
|
|
params.extend(status_val)
|
|
else:
|
|
where_clauses.append("l.status = ?")
|
|
params.append(status_val)
|
|
|
|
if "account_id" in filters and filters["account_id"]:
|
|
where_clauses.append("l.account_id = ?")
|
|
params.append(filters["account_id"])
|
|
|
|
if "sku" in filters and filters["sku"].strip():
|
|
where_clauses.append("p.sku LIKE ?")
|
|
params.append(f"%{filters['sku'].strip()}%")
|
|
|
|
if "product_name" in filters and filters["product_name"].strip():
|
|
where_clauses.append("p.name LIKE ?")
|
|
params.append(f"%{filters['product_name'].strip()}%")
|
|
|
|
if "account_email" in filters and filters["account_email"].strip():
|
|
where_clauses.append("a.email LIKE ?")
|
|
params.append(f"%{filters['account_email'].strip()}%")
|
|
|
|
if where_clauses:
|
|
base_query += " WHERE " + " AND ".join(where_clauses)
|
|
|
|
# --- Count ---
|
|
total_query = f"SELECT COUNT(*) FROM ({base_query}) AS total"
|
|
conn = get_connection()
|
|
cur = conn.cursor()
|
|
cur.execute(total_query, params)
|
|
total_count = cur.fetchone()[0]
|
|
|
|
# --- Sort + Paginate ---
|
|
sort_column_map = {
|
|
"id": "l.id",
|
|
"sku": "p.sku",
|
|
"product_name": "p.name",
|
|
"account_email": "a.email",
|
|
"listed_at": "l.listed_at",
|
|
"status": "l.status"
|
|
}
|
|
sort_col = sort_column_map.get(sort_by, "l.id")
|
|
sort_order = "DESC" if sort_order.upper() == "DESC" else "ASC"
|
|
|
|
base_query += f" ORDER BY {sort_col} {sort_order} LIMIT ? OFFSET ?"
|
|
params.extend([limit, offset])
|
|
|
|
cur.execute(base_query, params)
|
|
rows = cur.fetchall()
|
|
|
|
items = [
|
|
{
|
|
"id": r[0],
|
|
"sku": r[1],
|
|
"product_name": r[2],
|
|
"account_email": r[3],
|
|
"listed_at": r[4],
|
|
"status": r[5],
|
|
"condition": r[6],
|
|
"images": r[7]
|
|
}
|
|
for r in rows
|
|
]
|
|
|
|
conn.close()
|
|
return items, total_count
|
|
|
|
@staticmethod
|
|
def bulk_create(items):
|
|
"""
|
|
Thêm nhiều bản ghi listed cùng lúc.
|
|
items = list of dict, mỗi dict có 'account_id' và 'product_id'
|
|
Nếu đã tồn tại thì bỏ qua, trả về danh sách tất cả bản ghi (mới và đã tồn tại)
|
|
"""
|
|
results = []
|
|
|
|
conn = get_connection()
|
|
cur = conn.cursor()
|
|
|
|
for item in items:
|
|
account_id = item.get("account_id")
|
|
product_id = item.get("product_id")
|
|
if not account_id or not product_id:
|
|
continue
|
|
|
|
# Kiểm tra trùng
|
|
cur.execute(
|
|
"SELECT * FROM listed WHERE account_id = ? AND product_id = ?",
|
|
(account_id, product_id)
|
|
)
|
|
row = cur.fetchone()
|
|
if row:
|
|
results.append(dict(row))
|
|
continue
|
|
|
|
# Insert mới
|
|
listed_at = int(time.time())
|
|
cur.execute(
|
|
"INSERT INTO listed (account_id, product_id, listed_at) VALUES (?, ?, ?)",
|
|
(account_id, product_id, listed_at)
|
|
)
|
|
listed_id = cur.lastrowid
|
|
cur.execute("SELECT * FROM listed WHERE id = ?", (listed_id,))
|
|
results.append(dict(cur.fetchone()))
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
return results
|
|
|
|
@staticmethod
|
|
def bulk_delete(ids=None, items=None):
|
|
"""
|
|
Xóa nhiều bản ghi listed cùng lúc.
|
|
- ids: list các id của listed
|
|
- items: list dict {'account_id': ..., 'product_id': ...} để xóa theo cặp
|
|
"""
|
|
if not ids and not items:
|
|
return 0 # không có gì để xóa
|
|
|
|
conn = get_connection()
|
|
cur = conn.cursor()
|
|
|
|
deleted_count = 0
|
|
|
|
# Xóa theo id
|
|
if ids:
|
|
placeholders = ",".join("?" for _ in ids)
|
|
cur.execute(f"DELETE FROM listed WHERE id IN ({placeholders})", ids)
|
|
deleted_count += cur.rowcount
|
|
|
|
# Xóa theo account_id + product_id
|
|
if items:
|
|
for item in items:
|
|
account_id = item.get("account_id")
|
|
product_id = item.get("product_id")
|
|
if not account_id or not product_id:
|
|
continue
|
|
cur.execute(
|
|
"DELETE FROM listed WHERE account_id = ? AND product_id = ?",
|
|
(account_id, product_id)
|
|
)
|
|
deleted_count += cur.rowcount
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
return deleted_count
|
|
|
|
@staticmethod
|
|
def count_all():
|
|
conn = get_connection()
|
|
cursor = conn.cursor()
|
|
cursor.execute("SELECT COUNT(*) FROM listed")
|
|
total = cursor.fetchone()[0]
|
|
conn.close()
|
|
return total
|
|
|
|
@staticmethod
|
|
def count_by_status(status):
|
|
conn = get_connection()
|
|
cursor = conn.cursor()
|
|
cursor.execute("SELECT COUNT(*) FROM listed WHERE status=?", (status,))
|
|
count = cursor.fetchone()[0]
|
|
conn.close()
|
|
return count
|