| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- from fastapi import APIRouter, Depends, HTTPException, Query
- from typing import List, Optional
- import db
- import schemas
- from dependencies import require_admin
- import services.event_hooks as event_hooks
- from services.audit_service import audit_service
- from services.warehouse_report_service import warehouse_report_service
- router = APIRouter(prefix="/admin/warehouse", tags=["warehouse"])
- @router.get("/report")
- async def generate_stock_report(
- admin: dict = Depends(require_admin)
- ):
- url = warehouse_report_service.generate_report()
- return {"url": url}
- @router.get("/stock", response_model=dict)
- async def get_warehouse_stock(
- page: int = Query(1, ge=1),
- size: int = Query(50, ge=1, le=100),
- material_id: Optional[int] = None,
- admin: dict = Depends(require_admin)
- ):
- offset = (page - 1) * size
-
- query = """
- SELECT w.*, m.name_en as material_name_en
- FROM warehouse_stock w
- JOIN materials m ON w.material_id = m.id
- """
- params = []
-
- if material_id:
- query += " WHERE w.material_id = %s"
- params.append(material_id)
-
- query += " ORDER BY w.created_at DESC LIMIT %s OFFSET %s"
- params.extend([size, offset])
-
- stock = db.execute_query(query, tuple(params))
-
- count_query = "SELECT COUNT(*) as total FROM warehouse_stock"
- if material_id:
- count_query += " WHERE material_id = %s"
- total_res = db.execute_query(count_query, (material_id,))
- else:
- total_res = db.execute_query(count_query)
-
- return {
- "stock": stock,
- "total": total_res[0]['total'] if total_res else 0,
- "page": page,
- "size": size
- }
- @router.post("/stock", response_model=dict)
- async def add_stock_item(
- data: schemas.WarehouseItemCreate,
- admin: dict = Depends(require_admin)
- ):
- query = """
- INSERT INTO warehouse_stock (material_id, color_name, quantity, unit_mass, units_count, notes, is_active)
- VALUES (%s, %s, %s, %s, %s, %s, %s)
- """
- params = (data.material_id, data.color_name, data.quantity, data.unit_mass, data.units_count, data.notes, data.is_active)
-
- item_id = db.execute_commit(query, params)
-
- if not item_id:
- raise HTTPException(status_code=500, detail="Failed to add stock item")
-
- await audit_service.log(
- user_id=admin['id'],
- action="warehouse_add_item",
- target_type="warehouse_stock",
- target_id=item_id,
- details={
- "material_id": data.material_id,
- "color": data.color_name,
- "quantity": data.quantity,
- "units_count": data.units_count
- }
- )
-
- return {"id": item_id, "message": "Stock item added successfully"}
- @router.patch("/stock/{item_id}", response_model=dict)
- async def update_stock_item(
- item_id: int,
- data: schemas.WarehouseItemUpdate,
- admin: dict = Depends(require_admin)
- ):
- update_fields = []
- params = []
-
- if data.quantity is not None:
- update_fields.append("quantity = %s")
- params.append(data.quantity)
- if data.unit_mass is not None:
- update_fields.append("unit_mass = %s")
- params.append(data.unit_mass)
- if data.units_count is not None:
- update_fields.append("units_count = %s")
- params.append(data.units_count)
-
- if data.notes is not None:
- update_fields.append("notes = %s")
- params.append(data.notes)
-
- if data.is_active is not None:
- update_fields.append("is_active = %s")
- params.append(data.is_active)
-
- if not update_fields:
- raise HTTPException(status_code=400, detail="No fields to update")
-
- query = f"UPDATE warehouse_stock SET {', '.join(update_fields)} WHERE id = %s"
- params.append(item_id)
-
- db.execute_commit(query, tuple(params))
- await audit_service.log(
- user_id=admin['id'],
- action="warehouse_update_item",
- target_type="warehouse_stock",
- target_id=item_id,
- details=data.model_dump(exclude_unset=True)
- )
-
- return {"message": "Stock item updated successfully"}
- @router.delete("/stock/{item_id}", response_model=dict)
- async def delete_stock_item(
- item_id: int,
- admin: dict = Depends(require_admin)
- ):
- # Fetch item before deleting for logs
- item = db.execute_query("SELECT material_id, color_name FROM warehouse_stock WHERE id = %s", (item_id,))
-
- query = "DELETE FROM warehouse_stock WHERE id = %s"
- db.execute_commit(query, (item_id,))
- if item:
- await audit_service.log(
- user_id=admin['id'],
- action="warehouse_delete_item",
- target_type="warehouse_stock",
- target_id=item_id,
- details=item[0]
- )
- return {"message": "Stock item deleted successfully"}
|