from typing import List from sqlalchemy.orm import Session from app.crud.base import CRUDBase from app.models.inventory_transaction import InventoryTransaction, TransactionType from app.schemas.inventory_transaction import InventoryTransactionCreate, InventoryTransactionUpdate from datetime import datetime class CRUDInventoryTransaction(CRUDBase[InventoryTransaction, InventoryTransactionCreate, InventoryTransactionUpdate]): def create_with_product_update( self, db: Session, *, obj_in: InventoryTransactionCreate, current_user_id: int ) -> InventoryTransaction: # Create transaction with the current user db_obj = InventoryTransaction( transaction_type=obj_in.transaction_type, quantity=obj_in.quantity, unit_price=obj_in.unit_price, transaction_date=obj_in.transaction_date or datetime.utcnow(), notes=obj_in.notes, reference_number=obj_in.reference_number, product_id=obj_in.product_id, user_id=current_user_id, ) db.add(db_obj) # Update product quantity product = db.query(self.model).filter( self.model.product_id == obj_in.product_id ).first().product # Update quantity based on transaction type if obj_in.transaction_type == TransactionType.PURCHASE: product.quantity += obj_in.quantity elif obj_in.transaction_type == TransactionType.SALE: product.quantity -= obj_in.quantity elif obj_in.transaction_type == TransactionType.ADJUSTMENT: product.quantity += obj_in.quantity # Can be positive or negative elif obj_in.transaction_type == TransactionType.RETURN: if obj_in.notes and 'purchase' in obj_in.notes.lower(): # Return to supplier decreases quantity product.quantity -= obj_in.quantity else: # Customer return increases quantity product.quantity += obj_in.quantity db.add(product) db.commit() db.refresh(db_obj) return db_obj def get_by_product( self, db: Session, *, product_id: int, skip: int = 0, limit: int = 100 ) -> List[InventoryTransaction]: return ( db.query(InventoryTransaction) .filter(InventoryTransaction.product_id == product_id) .order_by(InventoryTransaction.transaction_date.desc()) .offset(skip) .limit(limit) .all() ) def get_by_user( self, db: Session, *, user_id: int, skip: int = 0, limit: int = 100 ) -> List[InventoryTransaction]: return ( db.query(InventoryTransaction) .filter(InventoryTransaction.user_id == user_id) .order_by(InventoryTransaction.transaction_date.desc()) .offset(skip) .limit(limit) .all() ) def get_by_type( self, db: Session, *, transaction_type: TransactionType, skip: int = 0, limit: int = 100 ) -> List[InventoryTransaction]: return ( db.query(InventoryTransaction) .filter(InventoryTransaction.transaction_type == transaction_type) .order_by(InventoryTransaction.transaction_date.desc()) .offset(skip) .limit(limit) .all() ) inventory_transaction = CRUDInventoryTransaction(InventoryTransaction)