Commit a33c21bf by Ooh-Ao

api

parent 32d21e32
...@@ -5,127 +5,159 @@ from datetime import datetime ...@@ -5,127 +5,159 @@ from datetime import datetime
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from ..models.project_equipment import ProjectEquipment from ..models.project_equipment import ProjectEquipment
from ..models.project_member import ProjectMember from ..models.project_member import ProjectMember
from ..models.borrow_transaction import BorrowTransaction from ..models.borrow_transaction import BorrowTransaction
from ..models.project_equipment import ProjectEquipment from ..models.equipment import Equipment
from ..models.equipments import Equipment from ..schemas.borrow_schema import BorrowTransactionBase
from ..models.member import Member # ถ้าต้องเช็คว่ามี member นี้จริงไหม
from ..schemas.borrow_schema import BorrowCreate, BorrowUpdate
# CREATE # CREATE
# - ตรวจสอบ memberId มีจริงไหม (ถ้าต้องการ) async def create_borrow_transaction(db: AsyncSession, borrow_in: BorrowTransactionBase):
# - ตรวจสอบ project_equipment (peId) มีจริง + พอไหม """
# - ลดจำนวนใน project_equipment สมมติว่าตอนสร้างจะเป็นสถานะ requested ก่อน
# - สร้าง record borrow_transaction ยังไม่ตัดจำนวนใน project_equipment
async def create_borrow_transaction(db: AsyncSession, borrow_in: BorrowCreate): """
# 1) หา projectEquipment จาก peId pe_db = await db.get(ProjectEquipment, borrow_in.peId)
result_pe = await db.execute( if not pe_db:
select(ProjectEquipment).where(ProjectEquipment.peId == borrow_in.peId)
)
projectEquipment = result_pe.scalar_one_or_none()
if not projectEquipment:
raise HTTPException(status_code=404, detail="ProjectEquipment not found") raise HTTPException(status_code=404, detail="ProjectEquipment not found")
# 1.1) ตรวจสอบว่า memberId อยู่ใน projectId นี้หรือไม่ # ตรวจสอบ member อยู่ใน project หรือไม่
# (projectEquipment.projectId) + (borrow_in.memberId) result_pm = await db.execute(
check_pm = await db.execute(
select(ProjectMember).where( select(ProjectMember).where(
ProjectMember.memberId == borrow_in.memberId, ProjectMember.memberId == borrow_in.memberId,
ProjectMember.projectId == projectEquipment.projectId ProjectMember.projectId == pe_db.projectId
) )
) )
pm_record = check_pm.scalar_one_or_none() pm_db = result_pm.scalar_one_or_none()
if not pm_record: if not pm_db:
raise HTTPException( raise HTTPException(status_code=403, detail="Member is not in this project")
status_code=403,
detail="Member is not in this project, cannot borrow."
)
# 2) ตรวจสอบจำนวน # สร้าง BorrowTransaction (สถานะเริ่มต้นเป็น requested)
if projectEquipment.quantity_in_project < borrow_in.quantity_borrowed:
raise HTTPException(status_code=400, detail="Not enough equipment in project")
# 3) ลดจำนวน
projectEquipment.quantity_in_project -= borrow_in.quantity_borrowed
db.add(projectEquipment)
# 4) สร้าง BorrowTransaction
new_borrow = BorrowTransaction( new_borrow = BorrowTransaction(
memberId=borrow_in.memberId, memberId=borrow_in.memberId,
peId=borrow_in.peId, peId=borrow_in.peId,
quantity_borrowed=borrow_in.quantity_borrowed, quantity_borrowed=borrow_in.quantity_borrowed,
status=borrow_in.status or "borrowed" status=borrow_in.status or "requested" # ตั้งเป็น requested ถ้าไม่กำหนด
) )
db.add(new_borrow)
await db.commit() try:
await db.refresh(new_borrow) db.add(new_borrow)
await db.commit()
await db.refresh(new_borrow)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return new_borrow return new_borrow
# UPDATE (คืนอุปกรณ์, เปลี่ยนสถานะ)
async def update_borrow_transaction(db: AsyncSession, borrowId: UUID, borrow_up: BorrowUpdate): # UPDATE
# 1) หา borrow เดิม async def update_borrow_transaction(db: AsyncSession, borrow_id: UUID, borrow_up: BorrowTransactionBase):
result_bt = await db.execute( borrow_db = await db.get(BorrowTransaction, borrow_id)
select(BorrowTransaction).where(BorrowTransaction.borrowId == borrowId) if not borrow_db:
)
borrowTx = result_bt.scalar_one_or_none()
if not borrowTx:
raise HTTPException(status_code=404, detail="BorrowTransaction not found") raise HTTPException(status_code=404, detail="BorrowTransaction not found")
# ถ้า user ส่ง status มา try:
if borrow_up.status: # ถ้า user ส่ง status ใหม่มา
if borrow_up.status == "returned": if borrow_up.status:
# 2.1) หา ProjectEquipment # ------------------------------------------------------------------
result_pe = await db.execute( # 1) กรณี "approved"
select(ProjectEquipment).where(ProjectEquipment.peId == borrowTx.peId) # ------------------------------------------------------------------
) if borrow_up.status == "approved":
projectEquipment = result_pe.scalar_one_or_none() # ต้องเป็นคำขอที่ยังอยู่ในสถานะ requested ก่อน
if not projectEquipment: if borrow_db.status != "requested":
raise HTTPException(status_code=404, detail="ProjectEquipment not found") raise HTTPException(
status_code=400,
# 2.2) หา Equipment detail="Cannot approve a transaction that is not in 'requested' status."
result_eq = await db.execute( )
select(Equipment).where(Equipment.equipmentId == projectEquipment.equipmentId)
) # หา projectEquipment
equipment = result_eq.scalar_one_or_none() pe_db = await db.get(ProjectEquipment, borrow_db.peId)
if not equipment: if not pe_db:
raise HTTPException(status_code=404, detail="Equipment not found") raise HTTPException(status_code=404, detail="ProjectEquipment not found")
# ถ้าเป็นอุปกรณ์ต้องคืน => บวกจำนวนคืน # ตรวจสอบจำนวน
if equipment.is_returnable: if pe_db.quantity_in_project < borrow_db.quantity_borrowed:
projectEquipment.quantity_in_project += borrowTx.quantity_borrowed raise HTTPException(status_code=400, detail="Not enough equipment to approve")
db.add(projectEquipment)
# ตัดจำนวนใน project_equipment
borrowTx.status = "returned" pe_db.quantity_in_project -= borrow_db.quantity_borrowed
borrowTx.returned_date = datetime.utcnow() db.add(pe_db)
else:
# อัปเดตเป็นสถานะอื่น # เปลี่ยนสถานะเป็น approved
borrowTx.status = borrow_up.status borrow_db.status = "approved"
# หากต้องการเก็บว่าใครเป็นคน approved และเวลาใด
db.add(borrowTx) # borrow_db.approved_by = current_admin_id
await db.commit() # borrow_db.approved_at = datetime.utcnow()
await db.refresh(borrowTx)
return borrowTx # ------------------------------------------------------------------
# 2) กรณี "returned"
# ------------------------------------------------------------------
elif borrow_up.status == "returned":
# หา projectEquipment
pe_db = await db.get(ProjectEquipment, borrow_db.peId)
if not pe_db:
raise HTTPException(status_code=404, detail="ProjectEquipment not found")
# หาอุปกรณ์
result_eq = await db.execute(select(Equipment).where(Equipment.equipmentId == pe_db.equipmentId))
eq_db = result_eq.scalar_one_or_none()
if not eq_db:
raise HTTPException(status_code=404, detail="Equipment not found")
# ถ้าอุปกรณ์เป็นประเภทคืนได้ (is_returnable == True) ก็คืนจำนวน
if eq_db.is_returnable:
pe_db.quantity_in_project += borrow_db.quantity_borrowed
db.add(pe_db)
borrow_db.status = "returned"
borrow_db.returned_date = datetime.utcnow()
# ------------------------------------------------------------------
# 3) กรณีสถานะอื่น ๆ (เช่น rejected, borrowed, ฯลฯ)
# ------------------------------------------------------------------
else:
borrow_db.status = borrow_up.status
# ถ้ามีฟิลด์อื่น เช่น quantity_borrowed หรืออื่น ๆ ก็อัปเดตที่นี่
# if borrow_up.quantity_borrowed is not None:
# borrow_db.quantity_borrowed = borrow_up.quantity_borrowed
# ...
db.add(borrow_db)
await db.commit()
await db.refresh(borrow_db)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return borrow_db
# GET ALL # GET ALL
async def get_all_borrow_transactions(db: AsyncSession): async def get_all_borrow_transactions(db: AsyncSession):
result = await db.execute(select(BorrowTransaction)) result = await db.execute(select(BorrowTransaction))
return result.scalars().all() return result.scalars().all()
# GET BY ID # GET BY ID
async def get_borrow_transaction_by_id(db: AsyncSession, borrowId: UUID): async def get_borrow_transaction_by_id(db: AsyncSession, borrow_id: UUID):
result = await db.execute( return await db.get(BorrowTransaction, borrow_id)
select(BorrowTransaction).where(BorrowTransaction.borrowId == borrowId)
)
return result.scalar_one_or_none()
# DELETE # DELETE
async def delete_borrow_transaction(db: AsyncSession, borrowId: UUID): async def delete_borrow_transaction(db: AsyncSession, borrow_id: UUID):
borrowTx = await db.get(BorrowTransaction, borrowId) borrow_db = await db.get(BorrowTransaction, borrow_id)
if not borrowTx: if not borrow_db:
raise HTTPException(status_code=404, detail="BorrowTransaction not found") raise HTTPException(status_code=404, detail="BorrowTransaction not found")
await db.delete(borrowTx) try:
await db.commit() await db.delete(borrow_db)
return {"message": "BorrowTransaction deleted"} await db.commit()
\ No newline at end of file except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "BorrowTransaction deleted"}
# myproject/controllers/equipment_category_controller.py
from uuid import UUID
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from ..models.equipment_category import EquipmentCategory
from ..schemas.equipment_category_schema import EquipmentCategoryCreate
async def create_equipment_category(db: AsyncSession, cat_in: EquipmentCategoryCreate):
new_cat = EquipmentCategory(**cat_in.dict())
try:
db.add(new_cat)
await db.commit()
await db.refresh(new_cat)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e))
return new_cat
async def get_all_equipment_categories(db: AsyncSession):
result = await db.execute(select(EquipmentCategory))
return result.scalars().all()
async def get_equipment_category_by_id(db: AsyncSession, category_id: UUID):
return await db.get(EquipmentCategory, category_id)
# update, delete ตามต้องการ
...@@ -4,40 +4,40 @@ from uuid import UUID ...@@ -4,40 +4,40 @@ from uuid import UUID
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from ..models.equipments import Equipment from ..models.equipment import Equipment
from ..schemas.equipment_schema import EquipmentCreate, EquipmentUpdate from ..schemas.equipment_schema import EquipmentCreate, EquipmentUpdate
async def get_all_equipment(db: AsyncSession): async def get_all_equipment(db: AsyncSession):
result = await db.execute(select(Equipment)) result = await db.execute(select(Equipment))
return result.scalars().all() return result.scalars().all()
async def get_equipment_by_id(equipmentId: UUID, db: AsyncSession): async def get_equipment_by_id(equipment_id: UUID, db: AsyncSession):
result = await db.execute(select(Equipment).where(Equipment.equipmentId == equipmentId)) # ใช้ db.get เพื่อความสั้น
return result.scalar_one_or_none() eq_db = await db.get(Equipment, equipment_id)
return eq_db
async def create_equipment(equipment_data: EquipmentCreate, db: AsyncSession): async def create_equipment(equipment_data: EquipmentCreate, db: AsyncSession):
# แปลง pydantic เป็น dict ถ้าต้องการ new_equipment = Equipment(
# หรือจะสร้าง object ตรง ๆ ก็ได้
equipment = Equipment(
equipmentName=equipment_data.equipmentName, equipmentName=equipment_data.equipmentName,
description=equipment_data.description, description=equipment_data.description,
is_returnable=equipment_data.is_returnable, is_returnable=equipment_data.is_returnable
) )
db.add(equipment) db.add(new_equipment)
await db.commit() try:
await db.refresh(equipment) await db.commit()
return equipment await db.refresh(new_equipment)
except SQLAlchemyError as e:
async def update_equipment(equipmentId: UUID, equipment_data: EquipmentUpdate, db: AsyncSession): await db.rollback()
# หาอุปกรณ์ตาม PK raise HTTPException(status_code=400, detail=str(e.orig))
result = await db.execute(select(Equipment).where(Equipment.equipmentId == equipmentId)) return new_equipment
eq_db = result.scalar_one_or_none()
async def update_equipment(equipment_id: UUID, equipment_data: EquipmentUpdate, db: AsyncSession):
eq_db = await db.get(Equipment, equipment_id)
if not eq_db: if not eq_db:
raise HTTPException(status_code=404, detail="Equipment not found") raise HTTPException(status_code=404, detail="Equipment not found")
# อัปเดตเฉพาะฟิลด์ที่ส่งมา
if equipment_data.equipmentName is not None: if equipment_data.equipmentName is not None:
eq_db.equipmentName = equipment_data.equipmentName eq_db.equipmentName = equipment_data.equipmentName
if equipment_data.description is not None: if equipment_data.description is not None:
...@@ -45,16 +45,25 @@ async def update_equipment(equipmentId: UUID, equipment_data: EquipmentUpdate, d ...@@ -45,16 +45,25 @@ async def update_equipment(equipmentId: UUID, equipment_data: EquipmentUpdate, d
if equipment_data.is_returnable is not None: if equipment_data.is_returnable is not None:
eq_db.is_returnable = equipment_data.is_returnable eq_db.is_returnable = equipment_data.is_returnable
await db.commit() try:
await db.refresh(eq_db) await db.commit()
await db.refresh(eq_db)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return eq_db return eq_db
async def delete_equipment(equipmentId: UUID, db: AsyncSession): async def delete_equipment(equipment_id: UUID, db: AsyncSession):
eq_db = await db.get(Equipment, equipmentId) eq_db = await db.get(Equipment, equipment_id)
if not eq_db: if not eq_db:
raise HTTPException(status_code=404, detail="Equipment not found") raise HTTPException(status_code=404, detail="Equipment not found")
await db.delete(eq_db) try:
await db.commit() await db.delete(eq_db)
await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "Equipment deleted successfully"} return {"message": "Equipment deleted successfully"}
# myproject/controllers/inventory_lot_controller.py
from uuid import UUID
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from ..models.inventory_lot import InventoryLot
from ..models.equipment import Equipment
from ..schemas.inventory_lot_schema import InventoryLotCreate
from ..models.inventory_lot import InventoryAction
async def create_inventory_lot(db: AsyncSession, lot_in: InventoryLotCreate):
# 1) ตรวจสอบว่า equipmentId นี้มีอยู่จริงไหม
equipment_db = await db.get(Equipment, lot_in.equipmentId)
if not equipment_db:
raise HTTPException(status_code=400, detail="Invalid equipmentId")
new_lot = InventoryLot(**lot_in.dict())
try:
db.add(new_lot)
# ปรับปรุง quantity ของ equipment ถ้าต้องการ
if lot_in.action == InventoryAction.INBOUND:
equipment_db.quantity += lot_in.quantity
elif lot_in.action in [InventoryAction.OUTBOUND, InventoryAction.SCRAP, InventoryAction.MAINTENANCE_OUT]:
if equipment_db.quantity < lot_in.quantity:
raise HTTPException(status_code=400, detail="Not enough quantity in stock")
equipment_db.quantity -= lot_in.quantity
db.add(equipment_db)
await db.commit()
await db.refresh(new_lot)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e))
return new_lot
async def get_all_inventory_lots(db: AsyncSession):
result = await db.execute(select(InventoryLot))
return result.scalars().all()
async def get_inventory_lot_by_id(db: AsyncSession, lot_id: UUID):
return await db.get(InventoryLot, lot_id)
# ถ้าอยากมี update/delete ก็ทำได้เช่นเดียวกับ CRUD ทั่วไป
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select from sqlalchemy.future import select
from fastapi import HTTPException, UploadFile from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from fastapi import HTTPException
from uuid import UUID
from ..models.member import Member from ..models.member import Member
from ..utils.file_handler import save_uploaded_file from ..utils.file_handler import save_uploaded_file
from uuid import UUID from ..schemas.member_schema import MemberCreate, MemberUpdate
from ..schemas.member_schema import MemberUpdate
async def get_users(db: AsyncSession): async def get_users(db: AsyncSession):
result = await db.execute(select(Member)) result = await db.execute(select(Member))
return result.scalars().all() return result.scalars().all()
async def get_user_by_id(id: UUID, db: AsyncSession):
result = await db.execute(select(Member).where(Member.memberId == id)) async def get_user_by_id(member_id: UUID, db: AsyncSession):
user = result.scalar_one_or_none() user = await db.get(Member, member_id)
return user return user
async def create_user(user_data: dict, db: AsyncSession):
user_dict = user_data.dict() # แปลง Pydantic model เป็น dict async def create_user(user_data: MemberCreate, db: AsyncSession):
password = user_dict.pop('password') # ดึง password ออก # เช็คก่อนว่ามี username หรือ email ที่ซ้ำไหม (ถ้าระบบออกแบบว่าต้อง unique)
new_user = Member(**user_dict) # ใช้ dict ในการสร้าง Member instance # ตัวอย่างเช็คซ้ำด้วย username:
new_user.hash_password(password) # แฮชรหัสผ่าน result = await db.execute(select(Member).where(Member.username == user_data.username))
db.add(new_user) existing_member = result.scalar_one_or_none()
await db.commit() if existing_member:
await db.refresh(new_user) raise HTTPException(status_code=400, detail="Username already taken")
return new_user
# สร้าง User
async def update_user(id: UUID, user_data: MemberUpdate, db: AsyncSession):
try: try:
# Fetch the user new_user = Member(
result = await db.execute(select(Member).where(Member.memberId == id)) username=user_data.username,
member = result.scalar_one_or_none() firstName=user_data.firstName,
lastName=user_data.lastName,
if not member: email=user_data.email,
raise HTTPException(status_code=404, detail="Member not found") phoneNumber=user_data.phoneNumber,
role=user_data.role,
# Update member fields status=user_data.status
if user_data.username: )
member.username = user_data.username new_user.hash_password(user_data.password)
if user_data.password:
member.hash_password(user_data.password) db.add(new_user)
if user_data.firstName:
member.firstName = user_data.firstName
if user_data.lastName:
member.lastName = user_data.lastName
if user_data.email:
member.email = user_data.email
if user_data.phoneNumber:
member.phoneNumber = user_data.phoneNumber
if user_data.role:
member.role = user_data.role
if user_data.status:
member.status = user_data.status
if user_data.picture:
member.picture = user_data.picture
# Save changes
await db.commit() await db.commit()
await db.refresh(member) await db.refresh(new_user)
return member return new_user
except Exception as e: except IntegrityError as ie:
# ถ้ามี constraint อะไรซ้ำหรือผิดพลาด
await db.rollback()
raise HTTPException(status_code=400, detail=str(ie.orig))
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
async def delete_user(memberId: UUID, db: AsyncSession):
# Retrieve the member by ID async def update_user(member_id: UUID, user_data: MemberUpdate, db: AsyncSession):
member = await db.get(Member, memberId) member = await db.get(Member, member_id)
if not member: if not member:
raise HTTPException(status_code=404, detail="Member not found") raise HTTPException(status_code=404, detail="Member not found")
# Delete the member instance # อัปเดตฟิลด์ทีละค่า (check None ก่อน)
await db.delete(member) if user_data.username is not None:
await db.commit() member.username = user_data.username
if user_data.password is not None and user_data.password != "":
member.hash_password(user_data.password)
if user_data.firstName is not None:
member.firstName = user_data.firstName
if user_data.lastName is not None:
member.lastName = user_data.lastName
if user_data.email is not None:
member.email = user_data.email
if user_data.phoneNumber is not None:
member.phoneNumber = user_data.phoneNumber
if user_data.role is not None:
member.role = user_data.role
if user_data.status is not None:
member.status = user_data.status
if user_data.picture is not None:
member.picture = user_data.picture
try:
await db.commit()
await db.refresh(member)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=500, detail=str(e))
return member
async def delete_user(member_id: UUID, db: AsyncSession):
member = await db.get(Member, member_id)
if not member:
raise HTTPException(status_code=404, detail="Member not found")
try:
await db.delete(member)
await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=500, detail=str(e))
return { return {
"actionStatus": "Success", "actionStatus": "Success",
"message": "User deleted successfully", "message": "User deleted successfully",
"statusCode": 200, "statusCode": 200,
} }
# myproject/controllers/project_controller.py
from fastapi import HTTPException from fastapi import HTTPException
from uuid import UUID from uuid import UUID
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select from sqlalchemy import select
from ..models.project import Project from ..models.project import Project
from ..schemas.project_schema import ( from ..schemas.project_schema import ProjectCreate, ProjectUpdate
ProjectCreate,
ProjectUpdate
)
# CREATE # CREATE
async def create_project( async def create_project(db: AsyncSession, project_in: ProjectCreate):
db: AsyncSession,
project_in: ProjectCreate
):
new_project = Project( new_project = Project(
project_name=project_in.project_name, project_name=project_in.project_name,
project_desc=project_in.project_desc, project_desc=project_in.project_desc,
start_date=project_in.start_date, start_date=project_in.start_date,
end_date=project_in.end_date end_date=project_in.end_date
) )
db.add(new_project) try:
await db.commit() db.add(new_project)
await db.refresh(new_project) await db.commit()
await db.refresh(new_project)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return new_project return new_project
# READ ALL # READ ALL
...@@ -33,31 +30,17 @@ async def get_all_projects(db: AsyncSession): ...@@ -33,31 +30,17 @@ async def get_all_projects(db: AsyncSession):
return result.scalars().all() return result.scalars().all()
# READ ONE # READ ONE
async def get_project_by_id( async def get_project_by_id(db: AsyncSession, project_id: UUID):
db: AsyncSession, project_db = await db.get(Project, project_id)
projectId: UUID return project_db
):
result = await db.execute(
select(Project).where(Project.projectId == projectId)
)
return result.scalar_one_or_none()
# UPDATE # UPDATE
async def update_project( async def update_project(db: AsyncSession, project_id: UUID, project_in: ProjectUpdate):
db: AsyncSession, project_db = await db.get(Project, project_id)
projectId: UUID,
project_in: ProjectUpdate
):
result = await db.execute(
select(Project).where(Project.projectId == projectId)
)
project_db = result.scalar_one_or_none()
if not project_db: if not project_db:
raise HTTPException( raise HTTPException(status_code=404, detail="Project not found")
status_code=404, detail="Project not found"
)
# Update fields
if project_in.project_name is not None: if project_in.project_name is not None:
project_db.project_name = project_in.project_name project_db.project_name = project_in.project_name
if project_in.project_desc is not None: if project_in.project_desc is not None:
...@@ -65,20 +48,30 @@ async def update_project( ...@@ -65,20 +48,30 @@ async def update_project(
if project_in.start_date is not None: if project_in.start_date is not None:
project_db.start_date = project_in.start_date project_db.start_date = project_in.start_date
if project_in.end_date is not None: if project_in.end_date is not None:
# สมมติว่าต้องการเช็คไม่ให้ end_date < start_date
if project_in.start_date and project_in.end_date < project_in.start_date:
raise HTTPException(status_code=400, detail="end_date cannot be before start_date")
project_db.end_date = project_in.end_date project_db.end_date = project_in.end_date
await db.commit() try:
await db.refresh(project_db) await db.commit()
await db.refresh(project_db)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return project_db return project_db
# DELETE # DELETE
async def delete_project(db: AsyncSession, projectId: UUID): async def delete_project(db: AsyncSession, project_id: UUID):
project_db = await db.get(Project, projectId) project_db = await db.get(Project, project_id)
if not project_db: if not project_db:
raise HTTPException( raise HTTPException(status_code=404, detail="Project not found")
status_code=404, detail="Project not found"
) try:
await db.delete(project_db) await db.delete(project_db)
await db.commit() await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "Project deleted successfully"} return {"message": "Project deleted successfully"}
...@@ -3,27 +3,40 @@ ...@@ -3,27 +3,40 @@
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from uuid import UUID from uuid import UUID
from ..models.project_equipment import ProjectEquipment from ..models.project_equipment import ProjectEquipment
from ..models.project import Project
from ..models.equipment import Equipment
from ..schemas.project_equipment_schema import ( from ..schemas.project_equipment_schema import (
ProjectEquipmentCreate, ProjectEquipmentCreate
ProjectEquipmentUpdate
) )
# CREATE # CREATE
async def create_project_equipment( async def create_project_equipment(db: AsyncSession, pe_in: ProjectEquipmentCreate):
db: AsyncSession, # ถ้าต้องการตรวจสอบว่ามี project/equipment จริงหรือไม่
pe_in: ProjectEquipmentCreate # project = await db.get(Project, pe_in.projectId)
): # if not project:
# raise HTTPException(status_code=400, detail="Invalid projectId")
#
# equipment = await db.get(Equipment, pe_in.equipmentId)
# if not equipment:
# raise HTTPException(status_code=400, detail="Invalid equipmentId")
new_pe = ProjectEquipment( new_pe = ProjectEquipment(
projectId=pe_in.projectId, projectId=pe_in.projectId,
equipmentId=pe_in.equipmentId, equipmentId=pe_in.equipmentId,
quantity_in_project=pe_in.quantity_in_project quantity_in_project=pe_in.quantity_in_project
) )
db.add(new_pe)
await db.commit() try:
await db.refresh(new_pe) db.add(new_pe)
await db.commit()
await db.refresh(new_pe)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return new_pe return new_pe
# READ ALL # READ ALL
...@@ -32,32 +45,16 @@ async def get_all_project_equipments(db: AsyncSession): ...@@ -32,32 +45,16 @@ async def get_all_project_equipments(db: AsyncSession):
return result.scalars().all() return result.scalars().all()
# READ ONE # READ ONE
async def get_project_equipment_by_id( async def get_project_equipment_by_id(db: AsyncSession, pe_id: UUID):
db: AsyncSession, pe_db = await db.get(ProjectEquipment, pe_id) # สั้นลง
peId: UUID return pe_db
):
result = await db.execute(
select(ProjectEquipment).where(ProjectEquipment.peId == peId)
)
return result.scalar_one_or_none()
# UPDATE # UPDATE
async def update_project_equipment( async def update_project_equipment(db: AsyncSession, pe_id: UUID, pe_in: ProjectEquipmentCreate):
db: AsyncSession, pe_db = await db.get(ProjectEquipment, pe_id)
peId: UUID,
pe_in: ProjectEquipmentUpdate
):
# หา record ตาม peId
result = await db.execute(
select(ProjectEquipment).where(ProjectEquipment.peId == peId)
)
pe_db = result.scalar_one_or_none()
if not pe_db: if not pe_db:
raise HTTPException( raise HTTPException(status_code=404, detail="ProjectEquipment not found")
status_code=404, detail="ProjectEquipment not found"
)
# อัปเดตฟิลด์
if pe_in.projectId is not None: if pe_in.projectId is not None:
pe_db.projectId = pe_in.projectId pe_db.projectId = pe_in.projectId
if pe_in.equipmentId is not None: if pe_in.equipmentId is not None:
...@@ -65,20 +62,26 @@ async def update_project_equipment( ...@@ -65,20 +62,26 @@ async def update_project_equipment(
if pe_in.quantity_in_project is not None: if pe_in.quantity_in_project is not None:
pe_db.quantity_in_project = pe_in.quantity_in_project pe_db.quantity_in_project = pe_in.quantity_in_project
await db.commit() try:
await db.refresh(pe_db) await db.commit()
await db.refresh(pe_db)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return pe_db return pe_db
# DELETE # DELETE
async def delete_project_equipment( async def delete_project_equipment(db: AsyncSession, pe_id: UUID):
db: AsyncSession, pe_db = await db.get(ProjectEquipment, pe_id)
peId: UUID
):
pe_db = await db.get(ProjectEquipment, peId)
if not pe_db: if not pe_db:
raise HTTPException( raise HTTPException(status_code=404, detail="ProjectEquipment not found")
status_code=404, detail="ProjectEquipment not found"
) try:
await db.delete(pe_db) await db.delete(pe_db)
await db.commit() await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "ProjectEquipment deleted successfully"} return {"message": "ProjectEquipment deleted successfully"}
...@@ -3,27 +3,26 @@ ...@@ -3,27 +3,26 @@
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from uuid import UUID from uuid import UUID
from ..models.project_member import ProjectMember from ..models.project_member import ProjectMember
from ..schemas.project_member_schema import ( from ..schemas.project_member_schema import ProjectMemberCreate
ProjectMemberCreate,
ProjectMemberUpdate
)
# CREATE # CREATE
async def create_project_member( async def create_project_member(db: AsyncSession, pm_in: ProjectMemberCreate):
db: AsyncSession,
pm_in: ProjectMemberCreate
):
new_pm = ProjectMember( new_pm = ProjectMember(
memberId=pm_in.memberId, memberId=pm_in.memberId,
projectId=pm_in.projectId, projectId=pm_in.projectId,
role_in_project=pm_in.role_in_project role_in_project=pm_in.role_in_project
) )
db.add(new_pm) try:
await db.commit() db.add(new_pm)
await db.refresh(new_pm) await db.commit()
await db.refresh(new_pm)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return new_pm return new_pm
# READ ALL # READ ALL
...@@ -32,24 +31,16 @@ async def get_all_project_members(db: AsyncSession): ...@@ -32,24 +31,16 @@ async def get_all_project_members(db: AsyncSession):
return result.scalars().all() return result.scalars().all()
# READ ONE # READ ONE
async def get_project_member_by_id(db: AsyncSession, pmId: UUID): async def get_project_member_by_id(db: AsyncSession, pm_id: UUID):
result = await db.execute(select(ProjectMember).where(ProjectMember.pmId == pmId)) pm_db = await db.get(ProjectMember, pm_id)
return result.scalar_one_or_none() return pm_db
# UPDATE # UPDATE
async def update_project_member( async def update_project_member(db: AsyncSession, pm_id: UUID, pm_in: ProjectMemberCreate):
db: AsyncSession, pm_db = await db.get(ProjectMember, pm_id)
pmId: UUID,
pm_in: ProjectMemberUpdate
):
# ค้นหาจาก pmId
result = await db.execute(select(ProjectMember).where(ProjectMember.pmId == pmId))
pm_db = result.scalar_one_or_none()
if not pm_db: if not pm_db:
raise HTTPException(status_code=404, detail="ProjectMember not found") raise HTTPException(status_code=404, detail="ProjectMember not found")
# อัปเดตฟิลด์
if pm_in.memberId is not None: if pm_in.memberId is not None:
pm_db.memberId = pm_in.memberId pm_db.memberId = pm_in.memberId
if pm_in.projectId is not None: if pm_in.projectId is not None:
...@@ -57,26 +48,32 @@ async def update_project_member( ...@@ -57,26 +48,32 @@ async def update_project_member(
if pm_in.role_in_project is not None: if pm_in.role_in_project is not None:
pm_db.role_in_project = pm_in.role_in_project pm_db.role_in_project = pm_in.role_in_project
await db.commit() try:
await db.refresh(pm_db) await db.commit()
await db.refresh(pm_db)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return pm_db return pm_db
# DELETE # DELETE
async def delete_project_member(db: AsyncSession, pmId: UUID): async def delete_project_member(db: AsyncSession, pm_id: UUID):
pm_db = await db.get(ProjectMember, pmId) pm_db = await db.get(ProjectMember, pm_id)
if not pm_db: if not pm_db:
raise HTTPException(status_code=404, detail="ProjectMember not found") raise HTTPException(status_code=404, detail="ProjectMember not found")
await db.delete(pm_db) try:
await db.commit() await db.delete(pm_db)
await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "ProjectMember deleted successfully"} return {"message": "ProjectMember deleted successfully"}
async def get_projects_by_member_id(db: AsyncSession, memberId: UUID): # READ Projects by MemberId
""" async def get_projects_by_member_id(db: AsyncSession, member_id: UUID):
ดึงรายการ ProjectMember ทั้งหมดที่ memberId นี้สังกัดอยู่ stmt = select(ProjectMember).where(ProjectMember.memberId == member_id)
""" result = await db.execute(stmt)
result = await db.execute( return result.scalars().all()
select(ProjectMember).where(ProjectMember.memberId == memberId)
)
return result.scalars().all()
\ No newline at end of file
...@@ -4,13 +4,14 @@ from .models.member import Base ...@@ -4,13 +4,14 @@ from .models.member import Base
import os import os
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
import logging import logging
from .routes import member_routes,auth_routes,file_upload_router from .routes import member_routes,auth_routes,file_upload_router,inventory_lot_router
from .routes.equipment_routes import router as equipment_router from .routes.equipment_routes import router as equipment_router
from .routes.project_routes import router as project_router from .routes.project_routes import router as project_router
from .routes.project_member_routes import router as pm_router from .routes.project_member_routes import router as pm_router
from .routes.project_equipment_routes import router as pe_router from .routes.project_equipment_routes import router as pe_router
from .routes.borrow_routes import router as borrow_router from .routes.borrow_routes import router as borrow_router
from .routes.inventory_lot_router import router as inventory_lot_router
from .routes.equipment_category_router import router as equipment_category_router
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
app = FastAPI() app = FastAPI()
...@@ -40,6 +41,8 @@ app.mount("/images", StaticFiles(directory=UPLOAD_DIR), name="images") ...@@ -40,6 +41,8 @@ app.mount("/images", StaticFiles(directory=UPLOAD_DIR), name="images")
app.include_router(auth_routes.router, prefix="/auth", tags=["Authentication"]) app.include_router(auth_routes.router, prefix="/auth", tags=["Authentication"])
app.include_router(member_routes.router, prefix="/members", tags=["Members"]) app.include_router(member_routes.router, prefix="/members", tags=["Members"])
app.include_router(equipment_router, prefix="/equipments", tags=["Equipments"]) app.include_router(equipment_router, prefix="/equipments", tags=["Equipments"])
app.include_router(inventory_lot_router, prefix="/inventory-lots", tags=["InventoryLots"])
app.include_router(equipment_category_router, prefix="/equipment-categories", tags=["EquipmentsCategories"])
app.include_router(project_router, prefix="/projects", tags=["Projects"]) app.include_router(project_router, prefix="/projects", tags=["Projects"])
app.include_router(pm_router, prefix="/project-members", tags=["ProjectMembers"]) app.include_router(pm_router, prefix="/project-members", tags=["ProjectMembers"])
app.include_router(pe_router, prefix="/project-equipments", tags=["ProjectEquipments"]) app.include_router(pe_router, prefix="/project-equipments", tags=["ProjectEquipments"])
......
# myproject/models/borrow_transaction.py from sqlalchemy import Column, String, Integer, DateTime, ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from datetime import datetime
from uuid import uuid4
from sqlalchemy.orm import relationship
from ..config.database import Base
import uuid import uuid
from datetime import datetime from datetime import datetime
from sqlalchemy import Column, Integer, String, DateTime from sqlalchemy import Column, Integer, String, DateTime ,ForeignKey
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from ..config.database import Base from ..config.database import Base
from sqlalchemy.orm import relationship
class BorrowTransaction(Base): class BorrowTransaction(Base):
__tablename__ = "borrow_transactions" __tablename__ = "borrow_transactions"
borrowId = Column( borrowId = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
UUID(as_uuid=True), peId = Column(UUID(as_uuid=True), ForeignKey("project_equipment.peId"), nullable=False)
primary_key=True, memberId = Column(UUID(as_uuid=True), ForeignKey("member.memberId"), nullable=False)
default=uuid.uuid4
)
peId = Column(UUID(as_uuid=True), nullable=False) # FK -> project_equipments.peId
memberId = Column(UUID(as_uuid=True), nullable=False) # FK -> member.memberId (ตาม Model Member)
quantity_borrowed = Column(Integer, nullable=False, default=1) quantity_borrowed = Column(Integer, nullable=False, default=1)
status = Column(String(50), nullable=False, default="borrowed") status = Column(String(50), nullable=False, default="requested") # requested, approved, rejected, borrowed, returned
returned_date = Column(DateTime, nullable=True) returned_date = Column(DateTime, nullable=True)
created_at = Column(DateTime, nullable=False, default=datetime.utcnow) created_at = Column(DateTime, nullable=False, server_default=func.now())
# updated_at ถ้าต้องการก็เพิ่มได้
# ฟิลด์สำหรับการอนุมัติ
approved_by = Column(UUID(as_uuid=True), ForeignKey("member.memberId"), nullable=True)
approved_at = Column(DateTime, nullable=True)
rejected_reason = Column(String, nullable=True)
project_equipment = relationship("ProjectEquipment", back_populates="borrow_transactions")
\ No newline at end of file
# myproject/models/equipment.py # myproject/models/equipment.py
import uuid import uuid
from sqlalchemy import Column, String, Integer ,Boolean from sqlalchemy import Column, String, Integer ,Boolean,ForeignKey
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func from sqlalchemy.sql import func
from datetime import datetime from datetime import datetime
from sqlalchemy.orm import relationship
from ..config.database import Base from ..config.database import Base
class Equipment(Base): class Equipment(Base):
__tablename__ = 'equipment' # หรือ 'equipments' ตามที่คุณตั้ง __tablename__ = 'equipment' # หรือ 'equipments' ตามต้องการ
equipmentId = Column( equipmentId = Column(
UUID(as_uuid=True), UUID(as_uuid=True),
...@@ -19,6 +19,15 @@ class Equipment(Base): ...@@ -19,6 +19,15 @@ class Equipment(Base):
equipmentName = Column(String(255), nullable=False) equipmentName = Column(String(255), nullable=False)
description = Column(String, nullable=True) description = Column(String, nullable=True)
is_returnable = Column(Boolean, nullable=False, default=True) is_returnable = Column(Boolean, nullable=False, default=True)
# ถ้าต้องการวันเวลาสร้าง/แก้ไข สามารถเพิ่มได้ categoryId = Column(UUID(as_uuid=True), ForeignKey("equipment_category.categoryId"), nullable=True)
# ถ้าต้องการวันเวลาสร้าง/แก้ไข
# createdAt = Column(DateTime, nullable=False, server_default=func.now()) # createdAt = Column(DateTime, nullable=False, server_default=func.now())
# updatedAt = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now()) # updatedAt = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
# Relationship เชื่อมไปยัง ProjectEquipment
project_equipment = relationship(
"ProjectEquipment",
back_populates="equipment",
cascade="all, delete-orphan"
)
# myproject/models/equipment_category.py
from sqlalchemy import Column, String, Text
from sqlalchemy.dialects.postgresql import UUID
from uuid import uuid4
from ..config.database import Base
class EquipmentCategory(Base):
__tablename__ = "equipment_category"
categoryId = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
categoryName = Column(String(255), nullable=False, unique=True)
categoryDesc = Column(Text, nullable=True)
# myproject/models/inventory_lot.py
from sqlalchemy import Column, String, Integer, DateTime, ForeignKey, Enum
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from sqlalchemy.ext.declarative import declarative_base
from uuid import uuid4
from datetime import datetime
import enum
from ..config.database import Base # ปรับ path ให้ตรงกับโปรเจค
class InventoryAction(enum.Enum):
INBOUND = "INBOUND" # นำเข้า
OUTBOUND = "OUTBOUND" # ถอนออก
SCRAP = "SCRAP" # ทิ้ง/โละ
MAINTENANCE_OUT = "MAINTENANCE_OUT" # ส่งซ่อม
class InventoryLot(Base):
__tablename__ = "inventory_lot"
lotId = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
equipmentId = Column(UUID(as_uuid=True), ForeignKey("equipment.equipmentId"), nullable=False)
quantity = Column(Integer, nullable=False)
action = Column(Enum(InventoryAction), nullable=False)
remark = Column(String, nullable=True)
# ใครเป็นคนทำ Lot นี้ (สมมติ FK -> member.memberId)
created_by = Column(UUID(as_uuid=True), ForeignKey("member.memberId"), nullable=True)
# วันเวลาที่บันทึก
created_at = Column(DateTime, server_default=func.now(), nullable=False)
# myproject/models/project.py # myproject/models/project.py
import uuid import uuid
from sqlalchemy import Column, String, Text, Date from sqlalchemy import Column, String, Text, Date
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from ..config.database import Base from ..config.database import Base
from sqlalchemy.orm import relationship
class Project(Base): class Project(Base):
__tablename__ = 'projects' # ชื่อตารางใน DB __tablename__ = 'project' # ชื่อตาราง
projectId = Column( projectId = Column(
UUID(as_uuid=True), UUID(as_uuid=True),
...@@ -17,3 +17,15 @@ class Project(Base): ...@@ -17,3 +17,15 @@ class Project(Base):
project_desc = Column(Text, nullable=True) project_desc = Column(Text, nullable=True)
start_date = Column(Date, nullable=True) start_date = Column(Date, nullable=True)
end_date = Column(Date, nullable=True) end_date = Column(Date, nullable=True)
# Relationship เชื่อมไปยัง ProjectMember และ ProjectEquipment
project_member = relationship(
"ProjectMember",
back_populates="project",
cascade="all, delete-orphan"
)
project_equipment = relationship(
"ProjectEquipment",
back_populates="project",
cascade="all, delete-orphan"
)
# myproject/models/project_equipment.py # myproject/models/project_equipment.py
import uuid import uuid
from sqlalchemy import Column, Integer from sqlalchemy import Column, Integer ,ForeignKey
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from ..config.database import Base from ..config.database import Base
from sqlalchemy.orm import relationship
class ProjectEquipment(Base): class ProjectEquipment(Base):
__tablename__ = "project_equipments" __tablename__ = "project_equipment"
peId = Column( peId = Column(
UUID(as_uuid=True), UUID(as_uuid=True),
primary_key=True, primary_key=True,
default=uuid.uuid4 default=uuid.uuid4
) )
projectId = Column(UUID(as_uuid=True), nullable=False) # Foreign Keys
equipmentId = Column(UUID(as_uuid=True), nullable=False) projectId = Column(
UUID(as_uuid=True),
ForeignKey("project.projectId"),
nullable=False
)
equipmentId = Column(
UUID(as_uuid=True),
ForeignKey("equipment.equipmentId"),
nullable=False
)
quantity_in_project = Column(Integer, nullable=False, default=0) quantity_in_project = Column(Integer, nullable=False, default=0)
# Relationship กลับไปยัง Project และ Equipment
project = relationship("Project", back_populates="project_equipment")
equipment = relationship("Equipment", back_populates="project_equipment")
# เชื่อมโยงกับ BorrowTransaction
borrow_transactions = relationship(
"BorrowTransaction",
back_populates="project_equipment"
)
...@@ -4,11 +4,29 @@ import uuid ...@@ -4,11 +4,29 @@ import uuid
from sqlalchemy import Column, String, Text, ForeignKey from sqlalchemy import Column, String, Text, ForeignKey
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
from ..config.database import Base from ..config.database import Base
from sqlalchemy.orm import relationship
class ProjectMember(Base): class ProjectMember(Base):
__tablename__ = 'project_members' __tablename__ = 'project_member'
pmId = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) pmId = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
memberId = Column(UUID(as_uuid=True), nullable=False)
projectId = Column(UUID(as_uuid=True), nullable=False) # Foreign Keys
memberId = Column(
UUID(as_uuid=True),
ForeignKey("member.memberId"), # หรือ "users.userId" ตามตารางจริง
nullable=False
)
projectId = Column(
UUID(as_uuid=True),
ForeignKey("project.projectId"),
nullable=False
)
role_in_project = Column(String(100), nullable=True) role_in_project = Column(String(100), nullable=True)
# Relationship เชื่อมกลับไปยัง Project
project = relationship("Project", back_populates="project_member")
# ถ้ามี Model Member/User ก็สามารถประกาศ relationship ได้ เช่น
# member = relationship("Member", back_populates="project_members")
...@@ -14,39 +14,38 @@ from ..controllers.borrow_controller import ( ...@@ -14,39 +14,38 @@ from ..controllers.borrow_controller import (
delete_borrow_transaction delete_borrow_transaction
) )
from ..schemas.borrow_schema import ( from ..schemas.borrow_schema import (
BorrowCreate, BorrowTransactionBase,
BorrowUpdate, BorrowTransactionResponse,
BorrowResponse
) )
router = APIRouter() router = APIRouter()
# CREATE (พนักงานยืมอุปกรณ์) # CREATE (พนักงานยืมอุปกรณ์)
@router.post("/", response_model=BorrowResponse, status_code=status.HTTP_201_CREATED) @router.post("/", response_model=BorrowTransactionResponse, status_code=status.HTTP_201_CREATED)
async def create_borrow_endpoint( async def create_borrow_endpoint(
borrow_in: BorrowCreate, borrow_in: BorrowTransactionBase,
db: AsyncSession = Depends(get_db) db: AsyncSession = Depends(get_db)
): ):
new_borrow = await create_borrow_transaction(db, borrow_in) new_borrow = await create_borrow_transaction(db, borrow_in)
return new_borrow return new_borrow
# UPDATE (เช่น คืนอุปกรณ์) # UPDATE (เช่น คืนอุปกรณ์)
@router.put("/{borrowId}", response_model=BorrowResponse) @router.put("/{borrowId}", response_model=BorrowTransactionResponse)
async def update_borrow_endpoint( async def update_borrow_endpoint(
borrowId: UUID, borrowId: UUID,
borrow_up: BorrowUpdate, borrow_up: BorrowTransactionBase,
db: AsyncSession = Depends(get_db) db: AsyncSession = Depends(get_db)
): ):
updated_borrow = await update_borrow_transaction(db, borrowId, borrow_up) updated_borrow = await update_borrow_transaction(db, borrowId, borrow_up)
return updated_borrow return updated_borrow
# GET ALL # GET ALL
@router.get("/", response_model=List[BorrowResponse]) @router.get("/", response_model=List[BorrowTransactionResponse])
async def get_all_borrows_endpoint(db: AsyncSession = Depends(get_db)): async def get_all_borrows_endpoint(db: AsyncSession = Depends(get_db)):
return await get_all_borrow_transactions(db) return await get_all_borrow_transactions(db)
# GET BY ID # GET BY ID
@router.get("/{borrowId}", response_model=BorrowResponse) @router.get("/{borrowId}", response_model=BorrowTransactionResponse)
async def get_borrow_by_id_endpoint( async def get_borrow_by_id_endpoint(
borrowId: UUID, borrowId: UUID,
db: AsyncSession = Depends(get_db) db: AsyncSession = Depends(get_db)
......
# myproject/routers/equipment_category_router.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from uuid import UUID
from ..schemas.equipment_category_schema import (
EquipmentCategoryCreate,
EquipmentCategoryResponse,
)
from ..controllers.equipment_category_controller import (
create_equipment_category,
get_all_equipment_categories,
get_equipment_category_by_id,
)
from ..config.database import get_db
router = APIRouter(
prefix="/equipment-categories",
tags=["Equipment Categories"]
)
@router.post("/", response_model=EquipmentCategoryResponse)
async def create_category(
category_in: EquipmentCategoryCreate,
db: AsyncSession = Depends(get_db)
):
return await create_equipment_category(db, category_in)
@router.get("/", response_model=List[EquipmentCategoryResponse])
async def read_categories(db: AsyncSession = Depends(get_db)):
return await get_all_equipment_categories(db)
@router.get("/{category_id}", response_model=EquipmentCategoryResponse)
async def read_category(category_id: UUID, db: AsyncSession = Depends(get_db)):
category = await get_equipment_category_by_id(db, category_id)
if not category:
raise HTTPException(status_code=404, detail="EquipmentCategory not found")
return category
# @router.put("/{category_id}", response_model=EquipmentCategoryResponse)
# async def update_category(
# category_id: UUID,
# category_in: EquipmentCategoryCreate,
# db: AsyncSession = Depends(get_db)
# ):
# return await update_equipment_category(db, category_id, category_in)
# @router.delete("/{category_id}", response_model=dict)
# async def delete_category(category_id: UUID, db: AsyncSession = Depends(get_db)):
# return await delete_equipment_category(db, category_id)
# myproject/routers/inventory_lot_router.py
from fastapi import APIRouter, Depends, HTTPException
from uuid import UUID
from sqlalchemy.ext.asyncio import AsyncSession
from ..controllers.inventory_lot_controller import (
create_inventory_lot,
get_all_inventory_lots,
get_inventory_lot_by_id
)
from ..schemas.inventory_lot_schema import InventoryLotCreate, InventoryLotResponse
from ..config.database import get_db
router = APIRouter()
@router.post("/", response_model=InventoryLotResponse)
async def create_lot(lot_in: InventoryLotCreate, db: AsyncSession = Depends(get_db)):
return await create_inventory_lot(db, lot_in)
@router.get("/", response_model=list[InventoryLotResponse])
async def read_all_lots(db: AsyncSession = Depends(get_db)):
return await get_all_inventory_lots(db)
@router.get("/{lot_id}", response_model=InventoryLotResponse)
async def read_lot_by_id(lot_id: UUID, db: AsyncSession = Depends(get_db)):
lot = await get_inventory_lot_by_id(db, lot_id)
if not lot:
raise HTTPException(status_code=404, detail="InventoryLot not found")
return lot
...@@ -15,7 +15,6 @@ from ..controllers.project_equipment_controller import ( ...@@ -15,7 +15,6 @@ from ..controllers.project_equipment_controller import (
) )
from ..schemas.project_equipment_schema import ( from ..schemas.project_equipment_schema import (
ProjectEquipmentCreate, ProjectEquipmentCreate,
ProjectEquipmentUpdate,
ProjectEquipmentResponse ProjectEquipmentResponse
) )
...@@ -51,7 +50,7 @@ async def read_pe_by_id_endpoint( ...@@ -51,7 +50,7 @@ async def read_pe_by_id_endpoint(
@router.put("/{peId}", response_model=ProjectEquipmentResponse) @router.put("/{peId}", response_model=ProjectEquipmentResponse)
async def update_pe_endpoint( async def update_pe_endpoint(
peId: UUID, peId: UUID,
pe_in: ProjectEquipmentUpdate, pe_in: ProjectEquipmentCreate,
db: AsyncSession = Depends(get_db) db: AsyncSession = Depends(get_db)
): ):
updated_pe = await update_project_equipment(db, peId, pe_in) updated_pe = await update_project_equipment(db, peId, pe_in)
......
...@@ -16,7 +16,6 @@ from ..controllers.project_member_controller import ( ...@@ -16,7 +16,6 @@ from ..controllers.project_member_controller import (
) )
from ..schemas.project_member_schema import ( from ..schemas.project_member_schema import (
ProjectMemberCreate, ProjectMemberCreate,
ProjectMemberUpdate,
ProjectMemberResponse ProjectMemberResponse
) )
...@@ -52,7 +51,7 @@ async def read_pm_by_id( ...@@ -52,7 +51,7 @@ async def read_pm_by_id(
@router.put("/{pmId}", response_model=ProjectMemberResponse) @router.put("/{pmId}", response_model=ProjectMemberResponse)
async def update_pm_endpoint( async def update_pm_endpoint(
pmId: UUID, pmId: UUID,
pm_in: ProjectMemberUpdate, pm_in: ProjectMemberCreate,
db: AsyncSession = Depends(get_db) db: AsyncSession = Depends(get_db)
): ):
updated_pm = await update_project_member(db, pmId, pm_in) updated_pm = await update_project_member(db, pmId, pm_in)
......
...@@ -3,22 +3,20 @@ from uuid import UUID ...@@ -3,22 +3,20 @@ from uuid import UUID
from typing import Optional from typing import Optional
from datetime import datetime from datetime import datetime
class BorrowCreate(BaseModel): class BorrowTransactionBase(BaseModel):
memberId: UUID
peId: UUID
quantity_borrowed: int quantity_borrowed: int
status: Optional[str] = "borrowed" status: str = "borrowed" # เช่น requested, borrowed, returned
returned_date: Optional[datetime] = None
class BorrowUpdate(BaseModel): class BorrowTransactionCreate(BorrowTransactionBase):
status: Optional[str] = None peId: UUID
memberId: UUID
class BorrowResponse(BaseModel): class BorrowTransactionResponse(BorrowTransactionBase):
borrowId: UUID borrowId: UUID
created_at: datetime
peId: UUID peId: UUID
memberId: UUID memberId: UUID
quantity_borrowed: int
status: str
returned_date: Optional[datetime] = None
class Config: class Config:
orm_mode = True orm_mode = True
\ No newline at end of file
# myproject/schemas/equipment_category_schema.py
from pydantic import BaseModel
from uuid import UUID
from typing import Optional
class EquipmentCategoryBase(BaseModel):
categoryName: str
categoryDesc: Optional[str] = None
class EquipmentCategoryCreate(EquipmentCategoryBase):
pass
class EquipmentCategoryResponse(EquipmentCategoryBase):
categoryId: UUID
class Config:
orm_mode = True
...@@ -9,26 +9,13 @@ class EquipmentBase(BaseModel): ...@@ -9,26 +9,13 @@ class EquipmentBase(BaseModel):
is_returnable: bool = True is_returnable: bool = True
class EquipmentCreate(EquipmentBase): class EquipmentCreate(EquipmentBase):
"""
Schema สำหรับรับข้อมูลเวลาสร้างอุปกรณ์ใหม่
"""
pass pass
class EquipmentUpdate(BaseModel): class EquipmentUpdate(EquipmentBase):
""" pass
Schema สำหรับรับข้อมูลเวลาต้องอัปเดตบางฟิลด์
(แต่ละฟิลด์เป็น Optional เผื่อว่าไม่ต้องส่งทุกฟิลด์)
"""
equipmentName: Optional[str] = None
description: Optional[str] = None
is_returnable: Optional[bool] = None
class EquipmentResponse(EquipmentBase): class EquipmentResponse(EquipmentBase):
"""
Schema สำหรับส่งคืนข้อมูล (Response) ไปยัง Client
โดยเพิ่ม equipmentId
"""
equipmentId: UUID equipmentId: UUID
class Config: class Config:
orm_mode = True orm_mode = True
\ No newline at end of file
# myproject/schemas/inventory_lot_schema.py
from pydantic import BaseModel
from uuid import UUID
from datetime import datetime
from typing import Optional
import enum
class InventoryActionEnum(str, enum.Enum):
INBOUND = "INBOUND"
OUTBOUND = "OUTBOUND"
SCRAP = "SCRAP"
MAINTENANCE_OUT = "MAINTENANCE_OUT"
class InventoryLotBase(BaseModel):
equipmentId: UUID
quantity: int
action: InventoryActionEnum
remark: Optional[str] = None
created_by: Optional[UUID] = None
class InventoryLotCreate(InventoryLotBase):
pass
class InventoryLotResponse(InventoryLotBase):
lotId: UUID
created_at: datetime
class Config:
orm_mode = True
...@@ -4,20 +4,16 @@ from typing import Optional ...@@ -4,20 +4,16 @@ from typing import Optional
from uuid import UUID from uuid import UUID
class ProjectEquipmentBase(BaseModel): class ProjectEquipmentBase(BaseModel):
projectId: UUID
equipmentId: UUID
quantity_in_project: int = 0 quantity_in_project: int = 0
class ProjectEquipmentCreate(ProjectEquipmentBase): class ProjectEquipmentCreate(ProjectEquipmentBase):
pass projectId: UUID
equipmentId: UUID
class ProjectEquipmentUpdate(BaseModel):
projectId: Optional[UUID] = None
equipmentId: Optional[UUID] = None
quantity_in_project: Optional[int] = None
class ProjectEquipmentResponse(ProjectEquipmentBase): class ProjectEquipmentResponse(ProjectEquipmentBase):
peId: UUID peId: UUID
projectId: UUID
equipmentId: UUID
class Config: class Config:
orm_mode = True orm_mode = True
...@@ -6,19 +6,17 @@ from uuid import UUID ...@@ -6,19 +6,17 @@ from uuid import UUID
class ProjectMemberBase(BaseModel): class ProjectMemberBase(BaseModel):
memberId: UUID memberId: UUID
projectId: UUID
role_in_project: Optional[str] = None role_in_project: Optional[str] = None
class ProjectMemberCreate(ProjectMemberBase): class ProjectMemberCreate(ProjectMemberBase):
pass projectId: UUID
class ProjectMemberUpdate(BaseModel):
memberId: Optional[UUID] = None
projectId: Optional[UUID] = None
role_in_project: Optional[str] = None
class ProjectMemberResponse(ProjectMemberBase): class ProjectMemberResponse(ProjectMemberBase):
pmId: UUID pmId: UUID
projectId: UUID
class Config: class Config:
orm_mode = True orm_mode = True
...@@ -12,16 +12,13 @@ class ProjectBase(BaseModel): ...@@ -12,16 +12,13 @@ class ProjectBase(BaseModel):
end_date: Optional[date] = None end_date: Optional[date] = None
class ProjectCreate(ProjectBase): class ProjectCreate(ProjectBase):
pass pass # อาจจะไม่มีฟิลด์เพิ่มเติม
class ProjectUpdate(BaseModel): class ProjectUpdate(ProjectBase):
project_name: Optional[str] = None pass # ใช้สำหรับแก้ไข
project_desc: Optional[str] = None
start_date: Optional[date] = None
end_date: Optional[date] = None
class ProjectResponse(ProjectBase): class ProjectResponse(ProjectBase):
projectId: UUID projectId: UUID
class Config: class Config:
orm_mode = True orm_mode = True
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment