import sqlite3 from datetime import datetime, date from typing import List, Optional from src.models import StockMovement class BaseDAO: """Base DAO class with common database operations""" def __init__(self, db_manager): self.db_manager = db_manager class StockMovementDAO(BaseDAO): """Data access object for StockMovement model""" def create(self, movement: StockMovement) -> bool: """Create a new stock movement record""" if not self.db_manager.connect(): return False try: cursor = self.db_manager.connection.cursor() cursor.execute(''' INSERT INTO stock_movements (product_id, movement_type, quantity, reference_type, reference_id) VALUES (?, ?, ?, ?, ?) ''', (movement.product_id, movement.movement_type, movement.quantity, movement.reference_type, movement.reference_id)) movement.id = cursor.lastrowid self.db_manager.connection.commit() return True except Exception as e: print(f"Error creating stock movement: {e}") return False finally: self.db_manager.disconnect() def get_by_id(self, movement_id: int) -> Optional[StockMovement]: """Get stock movement by ID""" if not self.db_manager.connect(): return None try: cursor = self.db_manager.connection.cursor() cursor.execute('SELECT * FROM stock_movements WHERE id = ?', (movement_id,)) row = cursor.fetchone() if row: created_at = datetime.fromisoformat(row['created_at']) if row['created_at'] else None return StockMovement( id=row['id'], product_id=row['product_id'], movement_type=row['movement_type'], quantity=row['quantity'], reference_type=row['reference_type'], reference_id=row['reference_id'] ) return None except Exception as e: print(f"Error getting stock movement: {e}") return None finally: self.db_manager.disconnect() def get_by_product_id(self, product_id: int) -> List[StockMovement]: """Get all stock movements for a product""" if not self.db_manager.connect(): return [] try: cursor = self.db_manager.connection.cursor() cursor.execute('SELECT * FROM stock_movements WHERE product_id = ? ORDER BY created_at DESC', (product_id,)) rows = cursor.fetchall() movements = [] for row in rows: created_at = datetime.fromisoformat(row['created_at']) if row['created_at'] else None movements.append(StockMovement( id=row['id'], product_id=row['product_id'], movement_type=row['movement_type'], quantity=row['quantity'], reference_type=row['reference_type'], reference_id=row['reference_id'] )) return movements except Exception as e: print(f"Error getting stock movements: {e}") return [] finally: self.db_manager.disconnect() def get_all(self) -> List[StockMovement]: """Get all stock movements""" if not self.db_manager.connect(): return [] try: cursor = self.db_manager.connection.cursor() cursor.execute('SELECT * FROM stock_movements ORDER BY created_at DESC') rows = cursor.fetchall() movements = [] for row in rows: created_at = datetime.fromisoformat(row['created_at']) if row['created_at'] else None movements.append(StockMovement( id=row['id'], product_id=row['product_id'], movement_type=row['movement_type'], quantity=row['quantity'], reference_type=row['reference_type'], reference_id=row['reference_id'] )) return movements except Exception as e: print(f"Error getting stock movements: {e}") return [] finally: self.db_manager.disconnect() def get_by_date_range(self, start_date: date, end_date: date) -> List[StockMovement]: """Get stock movements within a date range""" if not self.db_manager.connect(): return [] try: cursor = self.db_manager.connection.cursor() cursor.execute(''' SELECT * FROM stock_movements WHERE DATE(created_at) BETWEEN ? AND ? ORDER BY created_at DESC ''', (start_date.isoformat(), end_date.isoformat())) rows = cursor.fetchall() movements = [] for row in rows: created_at = datetime.fromisoformat(row['created_at']) if row['created_at'] else None movements.append(StockMovement( id=row['id'], product_id=row['product_id'], movement_type=row['movement_type'], quantity=row['quantity'], reference_type=row['reference_type'], reference_id=row['reference_id'] )) return movements except Exception as e: print(f"Error getting stock movements by date range: {e}") return [] finally: self.db_manager.disconnect()