Commit a33c21bf by Ooh-Ao

api

parent 32d21e32
# 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
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
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
async def get_all_equipment(db: AsyncSession):
result = await db.execute(select(Equipment))
return result.scalars().all()
async def get_equipment_by_id(equipmentId: UUID, db: AsyncSession):
result = await db.execute(select(Equipment).where(Equipment.equipmentId == equipmentId))
return result.scalar_one_or_none()
async def get_equipment_by_id(equipment_id: UUID, db: AsyncSession):
# ใช้ db.get เพื่อความสั้น
eq_db = await db.get(Equipment, equipment_id)
return eq_db
async def create_equipment(equipment_data: EquipmentCreate, db: AsyncSession):
# แปลง pydantic เป็น dict ถ้าต้องการ
# หรือจะสร้าง object ตรง ๆ ก็ได้
equipment = Equipment(
new_equipment = Equipment(
equipmentName=equipment_data.equipmentName,
description=equipment_data.description,
is_returnable=equipment_data.is_returnable,
is_returnable=equipment_data.is_returnable
)
db.add(equipment)
db.add(new_equipment)
try:
await db.commit()
await db.refresh(equipment)
return equipment
async def update_equipment(equipmentId: UUID, equipment_data: EquipmentUpdate, db: AsyncSession):
# หาอุปกรณ์ตาม PK
result = await db.execute(select(Equipment).where(Equipment.equipmentId == equipmentId))
eq_db = result.scalar_one_or_none()
await db.refresh(new_equipment)
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return new_equipment
async def update_equipment(equipment_id: UUID, equipment_data: EquipmentUpdate, db: AsyncSession):
eq_db = await db.get(Equipment, equipment_id)
if not eq_db:
raise HTTPException(status_code=404, detail="Equipment not found")
# อัปเดตเฉพาะฟิลด์ที่ส่งมา
if equipment_data.equipmentName is not None:
eq_db.equipmentName = equipment_data.equipmentName
if equipment_data.description is not None:
......@@ -45,16 +45,25 @@ async def update_equipment(equipmentId: UUID, equipment_data: EquipmentUpdate, d
if equipment_data.is_returnable is not None:
eq_db.is_returnable = equipment_data.is_returnable
try:
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
async def delete_equipment(equipmentId: UUID, db: AsyncSession):
eq_db = await db.get(Equipment, equipmentId)
async def delete_equipment(equipment_id: UUID, db: AsyncSession):
eq_db = await db.get(Equipment, equipment_id)
if not eq_db:
raise HTTPException(status_code=404, detail="Equipment not found")
try:
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"}
# 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.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 ..utils.file_handler import save_uploaded_file
from uuid import UUID
from ..schemas.member_schema import MemberUpdate
from ..schemas.member_schema import MemberCreate, MemberUpdate
async def get_users(db: AsyncSession):
result = await db.execute(select(Member))
return result.scalars().all()
async def get_user_by_id(id: UUID, db: AsyncSession):
result = await db.execute(select(Member).where(Member.memberId == id))
user = result.scalar_one_or_none()
async def get_user_by_id(member_id: UUID, db: AsyncSession):
user = await db.get(Member, member_id)
return user
async def create_user(user_data: dict, db: AsyncSession):
user_dict = user_data.dict() # แปลง Pydantic model เป็น dict
password = user_dict.pop('password') # ดึง password ออก
new_user = Member(**user_dict) # ใช้ dict ในการสร้าง Member instance
new_user.hash_password(password) # แฮชรหัสผ่าน
async def create_user(user_data: MemberCreate, db: AsyncSession):
# เช็คก่อนว่ามี username หรือ email ที่ซ้ำไหม (ถ้าระบบออกแบบว่าต้อง unique)
# ตัวอย่างเช็คซ้ำด้วย username:
result = await db.execute(select(Member).where(Member.username == user_data.username))
existing_member = result.scalar_one_or_none()
if existing_member:
raise HTTPException(status_code=400, detail="Username already taken")
# สร้าง User
try:
new_user = Member(
username=user_data.username,
firstName=user_data.firstName,
lastName=user_data.lastName,
email=user_data.email,
phoneNumber=user_data.phoneNumber,
role=user_data.role,
status=user_data.status
)
new_user.hash_password(user_data.password)
db.add(new_user)
await db.commit()
await db.refresh(new_user)
return new_user
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))
async def update_user(id: UUID, user_data: MemberUpdate, db: AsyncSession):
try:
# Fetch the user
result = await db.execute(select(Member).where(Member.memberId == id))
member = result.scalar_one_or_none()
async def update_user(member_id: UUID, user_data: MemberUpdate, db: AsyncSession):
member = await db.get(Member, member_id)
if not member:
raise HTTPException(status_code=404, detail="Member not found")
# Update member fields
if user_data.username:
# อัปเดตฟิลด์ทีละค่า (check None ก่อน)
if user_data.username is not None:
member.username = user_data.username
if user_data.password:
if user_data.password is not None and user_data.password != "":
member.hash_password(user_data.password)
if user_data.firstName:
if user_data.firstName is not None:
member.firstName = user_data.firstName
if user_data.lastName:
if user_data.lastName is not None:
member.lastName = user_data.lastName
if user_data.email:
if user_data.email is not None:
member.email = user_data.email
if user_data.phoneNumber:
if user_data.phoneNumber is not None:
member.phoneNumber = user_data.phoneNumber
if user_data.role:
if user_data.role is not None:
member.role = user_data.role
if user_data.status:
if user_data.status is not None:
member.status = user_data.status
if user_data.picture:
if user_data.picture is not None:
member.picture = user_data.picture
# Save changes
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
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
async def delete_user(memberId: UUID, db: AsyncSession):
# Retrieve the member by ID
member = await db.get(Member, memberId)
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")
# Delete the member instance
try:
await db.delete(member)
await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=500, detail=str(e))
return {
"actionStatus": "Success",
"message": "User deleted successfully",
"statusCode": 200,
}
# myproject/controllers/project_controller.py
from fastapi import HTTPException
from uuid import UUID
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select
from ..models.project import Project
from ..schemas.project_schema import (
ProjectCreate,
ProjectUpdate
)
from ..schemas.project_schema import ProjectCreate, ProjectUpdate
# CREATE
async def create_project(
db: AsyncSession,
project_in: ProjectCreate
):
async def create_project(db: AsyncSession, project_in: ProjectCreate):
new_project = Project(
project_name=project_in.project_name,
project_desc=project_in.project_desc,
start_date=project_in.start_date,
end_date=project_in.end_date
)
try:
db.add(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
# READ ALL
......@@ -33,31 +30,17 @@ async def get_all_projects(db: AsyncSession):
return result.scalars().all()
# READ ONE
async def get_project_by_id(
db: AsyncSession,
projectId: UUID
):
result = await db.execute(
select(Project).where(Project.projectId == projectId)
)
return result.scalar_one_or_none()
async def get_project_by_id(db: AsyncSession, project_id: UUID):
project_db = await db.get(Project, project_id)
return project_db
# UPDATE
async def update_project(
db: AsyncSession,
projectId: UUID,
project_in: ProjectUpdate
):
result = await db.execute(
select(Project).where(Project.projectId == projectId)
)
project_db = result.scalar_one_or_none()
async def update_project(db: AsyncSession, project_id: UUID, project_in: ProjectUpdate):
project_db = await db.get(Project, project_id)
if not project_db:
raise HTTPException(
status_code=404, detail="Project not found"
)
raise HTTPException(status_code=404, detail="Project not found")
# Update fields
if project_in.project_name is not None:
project_db.project_name = project_in.project_name
if project_in.project_desc is not None:
......@@ -65,20 +48,30 @@ async def update_project(
if project_in.start_date is not None:
project_db.start_date = project_in.start_date
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
try:
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
# DELETE
async def delete_project(db: AsyncSession, projectId: UUID):
project_db = await db.get(Project, projectId)
async def delete_project(db: AsyncSession, project_id: UUID):
project_db = await db.get(Project, project_id)
if not project_db:
raise HTTPException(
status_code=404, detail="Project not found"
)
raise HTTPException(status_code=404, detail="Project not found")
try:
await db.delete(project_db)
await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "Project deleted successfully"}
......@@ -3,27 +3,40 @@
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from uuid import UUID
from ..models.project_equipment import ProjectEquipment
from ..models.project import Project
from ..models.equipment import Equipment
from ..schemas.project_equipment_schema import (
ProjectEquipmentCreate,
ProjectEquipmentUpdate
ProjectEquipmentCreate
)
# CREATE
async def create_project_equipment(
db: AsyncSession,
pe_in: ProjectEquipmentCreate
):
async def create_project_equipment(db: AsyncSession, pe_in: ProjectEquipmentCreate):
# ถ้าต้องการตรวจสอบว่ามี project/equipment จริงหรือไม่
# 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(
projectId=pe_in.projectId,
equipmentId=pe_in.equipmentId,
quantity_in_project=pe_in.quantity_in_project
)
try:
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
# READ ALL
......@@ -32,32 +45,16 @@ async def get_all_project_equipments(db: AsyncSession):
return result.scalars().all()
# READ ONE
async def get_project_equipment_by_id(
db: AsyncSession,
peId: UUID
):
result = await db.execute(
select(ProjectEquipment).where(ProjectEquipment.peId == peId)
)
return result.scalar_one_or_none()
async def get_project_equipment_by_id(db: AsyncSession, pe_id: UUID):
pe_db = await db.get(ProjectEquipment, pe_id) # สั้นลง
return pe_db
# UPDATE
async def update_project_equipment(
db: AsyncSession,
peId: UUID,
pe_in: ProjectEquipmentUpdate
):
# หา record ตาม peId
result = await db.execute(
select(ProjectEquipment).where(ProjectEquipment.peId == peId)
)
pe_db = result.scalar_one_or_none()
async def update_project_equipment(db: AsyncSession, pe_id: UUID, pe_in: ProjectEquipmentCreate):
pe_db = await db.get(ProjectEquipment, pe_id)
if not pe_db:
raise HTTPException(
status_code=404, detail="ProjectEquipment not found"
)
raise HTTPException(status_code=404, detail="ProjectEquipment not found")
# อัปเดตฟิลด์
if pe_in.projectId is not None:
pe_db.projectId = pe_in.projectId
if pe_in.equipmentId is not None:
......@@ -65,20 +62,26 @@ async def update_project_equipment(
if pe_in.quantity_in_project is not None:
pe_db.quantity_in_project = pe_in.quantity_in_project
try:
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
# DELETE
async def delete_project_equipment(
db: AsyncSession,
peId: UUID
):
pe_db = await db.get(ProjectEquipment, peId)
async def delete_project_equipment(db: AsyncSession, pe_id: UUID):
pe_db = await db.get(ProjectEquipment, pe_id)
if not pe_db:
raise HTTPException(
status_code=404, detail="ProjectEquipment not found"
)
raise HTTPException(status_code=404, detail="ProjectEquipment not found")
try:
await db.delete(pe_db)
await db.commit()
except SQLAlchemyError as e:
await db.rollback()
raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "ProjectEquipment deleted successfully"}
......@@ -3,27 +3,26 @@
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from uuid import UUID
from ..models.project_member import ProjectMember
from ..schemas.project_member_schema import (
ProjectMemberCreate,
ProjectMemberUpdate
)
from ..schemas.project_member_schema import ProjectMemberCreate
# CREATE
async def create_project_member(
db: AsyncSession,
pm_in: ProjectMemberCreate
):
async def create_project_member(db: AsyncSession, pm_in: ProjectMemberCreate):
new_pm = ProjectMember(
memberId=pm_in.memberId,
projectId=pm_in.projectId,
role_in_project=pm_in.role_in_project
)
try:
db.add(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
# READ ALL
......@@ -32,24 +31,16 @@ async def get_all_project_members(db: AsyncSession):
return result.scalars().all()
# READ ONE
async def get_project_member_by_id(db: AsyncSession, pmId: UUID):
result = await db.execute(select(ProjectMember).where(ProjectMember.pmId == pmId))
return result.scalar_one_or_none()
async def get_project_member_by_id(db: AsyncSession, pm_id: UUID):
pm_db = await db.get(ProjectMember, pm_id)
return pm_db
# UPDATE
async def update_project_member(
db: AsyncSession,
pmId: UUID,
pm_in: ProjectMemberUpdate
):
# ค้นหาจาก pmId
result = await db.execute(select(ProjectMember).where(ProjectMember.pmId == pmId))
pm_db = result.scalar_one_or_none()
async def update_project_member(db: AsyncSession, pm_id: UUID, pm_in: ProjectMemberCreate):
pm_db = await db.get(ProjectMember, pm_id)
if not pm_db:
raise HTTPException(status_code=404, detail="ProjectMember not found")
# อัปเดตฟิลด์
if pm_in.memberId is not None:
pm_db.memberId = pm_in.memberId
if pm_in.projectId is not None:
......@@ -57,26 +48,32 @@ async def update_project_member(
if pm_in.role_in_project is not None:
pm_db.role_in_project = pm_in.role_in_project
try:
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
# DELETE
async def delete_project_member(db: AsyncSession, pmId: UUID):
pm_db = await db.get(ProjectMember, pmId)
async def delete_project_member(db: AsyncSession, pm_id: UUID):
pm_db = await db.get(ProjectMember, pm_id)
if not pm_db:
raise HTTPException(status_code=404, detail="ProjectMember not found")
try:
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"}
async def get_projects_by_member_id(db: AsyncSession, memberId: UUID):
"""
ดึงรายการ ProjectMember ทั้งหมดที่ memberId นี้สังกัดอยู่
"""
result = await db.execute(
select(ProjectMember).where(ProjectMember.memberId == memberId)
)
# READ Projects by MemberId
async def get_projects_by_member_id(db: AsyncSession, member_id: UUID):
stmt = select(ProjectMember).where(ProjectMember.memberId == member_id)
result = await db.execute(stmt)
return result.scalars().all()
......@@ -4,13 +4,14 @@ from .models.member import Base
import os
from fastapi.staticfiles import StaticFiles
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.project_routes import router as project_router
from .routes.project_member_routes import router as pm_router
from .routes.project_equipment_routes import router as pe_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
logging.basicConfig(level=logging.DEBUG)
app = FastAPI()
......@@ -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(member_routes.router, prefix="/members", tags=["Members"])
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(pm_router, prefix="/project-members", tags=["ProjectMembers"])
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
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 ..config.database import Base
from sqlalchemy.orm import relationship
class BorrowTransaction(Base):
__tablename__ = "borrow_transactions"
borrowId = Column(
UUID(as_uuid=True),
primary_key=True,
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)
borrowId = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
peId = Column(UUID(as_uuid=True), ForeignKey("project_equipment.peId"), nullable=False)
memberId = Column(UUID(as_uuid=True), ForeignKey("member.memberId"), nullable=False)
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)
created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
# updated_at ถ้าต้องการก็เพิ่มได้
created_at = Column(DateTime, nullable=False, server_default=func.now())
# ฟิลด์สำหรับการอนุมัติ
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
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.sql import func
from datetime import datetime
from sqlalchemy.orm import relationship
from ..config.database import Base
class Equipment(Base):
__tablename__ = 'equipment' # หรือ 'equipments' ตามที่คุณตั้ง
__tablename__ = 'equipment' # หรือ 'equipments' ตามต้องการ
equipmentId = Column(
UUID(as_uuid=True),
......@@ -19,6 +19,15 @@ class Equipment(Base):
equipmentName = Column(String(255), nullable=False)
description = Column(String, nullable=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())
# 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
import uuid
from sqlalchemy import Column, String, Text, Date
from sqlalchemy.dialects.postgresql import UUID
from ..config.database import Base
from sqlalchemy.orm import relationship
class Project(Base):
__tablename__ = 'projects' # ชื่อตารางใน DB
__tablename__ = 'project' # ชื่อตาราง
projectId = Column(
UUID(as_uuid=True),
......@@ -17,3 +17,15 @@ class Project(Base):
project_desc = Column(Text, nullable=True)
start_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
import uuid
from sqlalchemy import Column, Integer
from sqlalchemy import Column, Integer ,ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from ..config.database import Base
from sqlalchemy.orm import relationship
class ProjectEquipment(Base):
__tablename__ = "project_equipments"
__tablename__ = "project_equipment"
peId = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4
)
projectId = Column(UUID(as_uuid=True), nullable=False)
equipmentId = Column(UUID(as_uuid=True), nullable=False)
# Foreign Keys
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)
# 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
from sqlalchemy import Column, String, Text, ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from ..config.database import Base
from sqlalchemy.orm import relationship
class ProjectMember(Base):
__tablename__ = 'project_members'
__tablename__ = 'project_member'
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)
# 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 (
delete_borrow_transaction
)
from ..schemas.borrow_schema import (
BorrowCreate,
BorrowUpdate,
BorrowResponse
BorrowTransactionBase,
BorrowTransactionResponse,
)
router = APIRouter()
# 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(
borrow_in: BorrowCreate,
borrow_in: BorrowTransactionBase,
db: AsyncSession = Depends(get_db)
):
new_borrow = await create_borrow_transaction(db, borrow_in)
return new_borrow
# UPDATE (เช่น คืนอุปกรณ์)
@router.put("/{borrowId}", response_model=BorrowResponse)
@router.put("/{borrowId}", response_model=BorrowTransactionResponse)
async def update_borrow_endpoint(
borrowId: UUID,
borrow_up: BorrowUpdate,
borrow_up: BorrowTransactionBase,
db: AsyncSession = Depends(get_db)
):
updated_borrow = await update_borrow_transaction(db, borrowId, borrow_up)
return updated_borrow
# 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)):
return await get_all_borrow_transactions(db)
# GET BY ID
@router.get("/{borrowId}", response_model=BorrowResponse)
@router.get("/{borrowId}", response_model=BorrowTransactionResponse)
async def get_borrow_by_id_endpoint(
borrowId: UUID,
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 (
)
from ..schemas.project_equipment_schema import (
ProjectEquipmentCreate,
ProjectEquipmentUpdate,
ProjectEquipmentResponse
)
......@@ -51,7 +50,7 @@ async def read_pe_by_id_endpoint(
@router.put("/{peId}", response_model=ProjectEquipmentResponse)
async def update_pe_endpoint(
peId: UUID,
pe_in: ProjectEquipmentUpdate,
pe_in: ProjectEquipmentCreate,
db: AsyncSession = Depends(get_db)
):
updated_pe = await update_project_equipment(db, peId, pe_in)
......
......@@ -16,7 +16,6 @@ from ..controllers.project_member_controller import (
)
from ..schemas.project_member_schema import (
ProjectMemberCreate,
ProjectMemberUpdate,
ProjectMemberResponse
)
......@@ -52,7 +51,7 @@ async def read_pm_by_id(
@router.put("/{pmId}", response_model=ProjectMemberResponse)
async def update_pm_endpoint(
pmId: UUID,
pm_in: ProjectMemberUpdate,
pm_in: ProjectMemberCreate,
db: AsyncSession = Depends(get_db)
):
updated_pm = await update_project_member(db, pmId, pm_in)
......
......@@ -3,22 +3,20 @@ from uuid import UUID
from typing import Optional
from datetime import datetime
class BorrowCreate(BaseModel):
memberId: UUID
peId: UUID
class BorrowTransactionBase(BaseModel):
quantity_borrowed: int
status: Optional[str] = "borrowed"
status: str = "borrowed" # เช่น requested, borrowed, returned
returned_date: Optional[datetime] = None
class BorrowUpdate(BaseModel):
status: Optional[str] = None
class BorrowTransactionCreate(BorrowTransactionBase):
peId: UUID
memberId: UUID
class BorrowResponse(BaseModel):
class BorrowTransactionResponse(BorrowTransactionBase):
borrowId: UUID
created_at: datetime
peId: UUID
memberId: UUID
quantity_borrowed: int
status: str
returned_date: Optional[datetime] = None
class Config:
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,25 +9,12 @@ class EquipmentBase(BaseModel):
is_returnable: bool = True
class EquipmentCreate(EquipmentBase):
"""
Schema สำหรับรับข้อมูลเวลาสร้างอุปกรณ์ใหม่
"""
pass
class EquipmentUpdate(BaseModel):
"""
Schema สำหรับรับข้อมูลเวลาต้องอัปเดตบางฟิลด์
(แต่ละฟิลด์เป็น Optional เผื่อว่าไม่ต้องส่งทุกฟิลด์)
"""
equipmentName: Optional[str] = None
description: Optional[str] = None
is_returnable: Optional[bool] = None
class EquipmentUpdate(EquipmentBase):
pass
class EquipmentResponse(EquipmentBase):
"""
Schema สำหรับส่งคืนข้อมูล (Response) ไปยัง Client
โดยเพิ่ม equipmentId
"""
equipmentId: UUID
class Config:
......
# 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
from uuid import UUID
class ProjectEquipmentBase(BaseModel):
projectId: UUID
equipmentId: UUID
quantity_in_project: int = 0
class ProjectEquipmentCreate(ProjectEquipmentBase):
pass
class ProjectEquipmentUpdate(BaseModel):
projectId: Optional[UUID] = None
equipmentId: Optional[UUID] = None
quantity_in_project: Optional[int] = None
projectId: UUID
equipmentId: UUID
class ProjectEquipmentResponse(ProjectEquipmentBase):
peId: UUID
projectId: UUID
equipmentId: UUID
class Config:
orm_mode = True
......@@ -6,19 +6,17 @@ from uuid import UUID
class ProjectMemberBase(BaseModel):
memberId: UUID
projectId: UUID
role_in_project: Optional[str] = None
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):
pmId: UUID
projectId: UUID
class Config:
orm_mode = True
......@@ -12,13 +12,10 @@ class ProjectBase(BaseModel):
end_date: Optional[date] = None
class ProjectCreate(ProjectBase):
pass
pass # อาจจะไม่มีฟิลด์เพิ่มเติม
class ProjectUpdate(BaseModel):
project_name: Optional[str] = None
project_desc: Optional[str] = None
start_date: Optional[date] = None
end_date: Optional[date] = None
class ProjectUpdate(ProjectBase):
pass # ใช้สำหรับแก้ไข
class ProjectResponse(ProjectBase):
projectId: UUID
......
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