# 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