Upload 16 files
Browse files- Dockerfile +21 -0
- app/__pycache__/main.cpython-313.pyc +0 -0
- app/database/__pycache__/database.cpython-313.pyc +0 -0
- app/database/database.py +63 -0
- app/main.py +34 -0
- app/models/__pycache__/models.cpython-313.pyc +0 -0
- app/models/models.py +40 -0
- app/routers/__pycache__/meeting_status.cpython-313.pyc +0 -0
- app/routers/__pycache__/person_to_meet.cpython-313.pyc +0 -0
- app/routers/__pycache__/visitor_log.cpython-313.pyc +0 -0
- app/routers/meeting_status.py +74 -0
- app/routers/person_to_meet.py +65 -0
- app/routers/visitor_log.py +76 -0
- app/schemas/__pycache__/schemas.cpython-313.pyc +0 -0
- app/schemas/schemas.py +68 -0
- run.py +4 -0
Dockerfile
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.9-slim
|
2 |
+
|
3 |
+
# Set working directory
|
4 |
+
WORKDIR /app
|
5 |
+
|
6 |
+
# Copy requirements file and install dependencies
|
7 |
+
COPY requirements.txt .
|
8 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
9 |
+
|
10 |
+
# Copy .env file into the container
|
11 |
+
COPY .env .
|
12 |
+
|
13 |
+
# Copy application code
|
14 |
+
COPY app/ app/
|
15 |
+
COPY run.py .
|
16 |
+
|
17 |
+
# Expose the port the app runs on
|
18 |
+
EXPOSE 8000
|
19 |
+
|
20 |
+
# Command to run the application
|
21 |
+
CMD ["python3", "run.py"]
|
app/__pycache__/main.cpython-313.pyc
ADDED
Binary file (1.4 kB). View file
|
|
app/database/__pycache__/database.cpython-313.pyc
ADDED
Binary file (2.7 kB). View file
|
|
app/database/database.py
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sqlalchemy import create_engine
|
2 |
+
from sqlalchemy.ext.declarative import declarative_base
|
3 |
+
from sqlalchemy.orm import sessionmaker
|
4 |
+
import os
|
5 |
+
from dotenv import load_dotenv
|
6 |
+
import logging
|
7 |
+
import urllib.parse
|
8 |
+
|
9 |
+
# Configure logging
|
10 |
+
logging.basicConfig(level=logging.INFO)
|
11 |
+
logger = logging.getLogger(__name__)
|
12 |
+
|
13 |
+
# Load environment variables
|
14 |
+
load_dotenv()
|
15 |
+
|
16 |
+
# Get database credentials from environment variables
|
17 |
+
DB_USER = os.getenv("DB_USER", "dev_cbs_admin")
|
18 |
+
DB_PASSWORD = os.getenv("DB_PASSWORD", "password")
|
19 |
+
DB_HOST = os.getenv("DB_HOST", "13.126.242.31")
|
20 |
+
DB_PORT = os.getenv("DB_PORT", "5432")
|
21 |
+
DB_NAME = os.getenv("DB_NAME", "vst")
|
22 |
+
|
23 |
+
# URL encode the password to handle special characters like @
|
24 |
+
encoded_password = urllib.parse.quote_plus(DB_PASSWORD)
|
25 |
+
|
26 |
+
# Log the connection parameters (without password)
|
27 |
+
logger.info(f"Attempting to connect to PostgreSQL database at {DB_HOST}:{DB_PORT}/{DB_NAME} as {DB_USER}")
|
28 |
+
|
29 |
+
# Create database URL for PostgreSQL with encoded password
|
30 |
+
SQLALCHEMY_DATABASE_URL = f"postgresql://{DB_USER}:{encoded_password}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
|
31 |
+
# Log the URL with password masked
|
32 |
+
masked_url = SQLALCHEMY_DATABASE_URL.replace(encoded_password, "****")
|
33 |
+
logger.info(f"Connection URL: {masked_url}")
|
34 |
+
|
35 |
+
try:
|
36 |
+
# Create engine
|
37 |
+
engine = create_engine(SQLALCHEMY_DATABASE_URL)
|
38 |
+
|
39 |
+
# Test connection
|
40 |
+
with engine.connect() as conn:
|
41 |
+
logger.info("Database connection successful")
|
42 |
+
except Exception as e:
|
43 |
+
logger.error(f"Database connection error: {e}")
|
44 |
+
# Create a SQLite engine as fallback for development/testing
|
45 |
+
logger.info("Using SQLite as fallback database")
|
46 |
+
SQLALCHEMY_DATABASE_URL = "sqlite:///./visitor_management.db"
|
47 |
+
engine = create_engine(
|
48 |
+
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
49 |
+
)
|
50 |
+
|
51 |
+
# Create session
|
52 |
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
53 |
+
|
54 |
+
# Create base class
|
55 |
+
Base = declarative_base()
|
56 |
+
|
57 |
+
# Dependency to get DB session
|
58 |
+
def get_db():
|
59 |
+
db = SessionLocal()
|
60 |
+
try:
|
61 |
+
yield db
|
62 |
+
finally:
|
63 |
+
db.close()
|
app/main.py
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI
|
2 |
+
from fastapi.middleware.cors import CORSMiddleware
|
3 |
+
|
4 |
+
from app.database.database import engine
|
5 |
+
from app.models.models import Base
|
6 |
+
from app.routers import visitor_log, meeting_status, person_to_meet
|
7 |
+
|
8 |
+
# Create database tables
|
9 |
+
Base.metadata.create_all(bind=engine)
|
10 |
+
|
11 |
+
# Initialize FastAPI app
|
12 |
+
app = FastAPI(
|
13 |
+
title="Visitor Management System API",
|
14 |
+
description="API for managing visitor logs and meeting statuses",
|
15 |
+
version="1.0.0"
|
16 |
+
)
|
17 |
+
|
18 |
+
# Add CORS middleware
|
19 |
+
app.add_middleware(
|
20 |
+
CORSMiddleware,
|
21 |
+
allow_origins=["*"], # In production, replace with specific origins
|
22 |
+
allow_credentials=True,
|
23 |
+
allow_methods=["*"],
|
24 |
+
allow_headers=["*"],
|
25 |
+
)
|
26 |
+
|
27 |
+
# Include routers
|
28 |
+
app.include_router(visitor_log.router)
|
29 |
+
app.include_router(meeting_status.router)
|
30 |
+
app.include_router(person_to_meet.router)
|
31 |
+
|
32 |
+
@app.get("/")
|
33 |
+
def read_root():
|
34 |
+
return {"message": "Welcome to Visitor Management System API"}
|
app/models/__pycache__/models.cpython-313.pyc
ADDED
Binary file (2.46 kB). View file
|
|
app/models/models.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey
|
2 |
+
from sqlalchemy.orm import relationship
|
3 |
+
from app.database.database import Base
|
4 |
+
|
5 |
+
class VisitorLog(Base):
|
6 |
+
__tablename__ = "visitor_log"
|
7 |
+
|
8 |
+
sl_no = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
9 |
+
full_name = Column(String(255), nullable=False)
|
10 |
+
email_address = Column(String(255), nullable=False)
|
11 |
+
phone_number = Column(String(20), nullable=False)
|
12 |
+
company_name = Column(String(255), nullable=True)
|
13 |
+
qid_id_number = Column(String(50), nullable=True)
|
14 |
+
purpose_of_visit = Column(String(500), nullable=False)
|
15 |
+
person_to_meet = Column(String(255), nullable=False)
|
16 |
+
preferred_datetime = Column(DateTime, nullable=False)
|
17 |
+
reference_number = Column(String(50), unique=True, nullable=False, index=True)
|
18 |
+
|
19 |
+
# Relationship with MeetingStatus
|
20 |
+
meeting_status = relationship("MeetingStatus", back_populates="visitor_log")
|
21 |
+
|
22 |
+
class MeetingStatus(Base):
|
23 |
+
__tablename__ = "meeting_status"
|
24 |
+
|
25 |
+
sl_no = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
26 |
+
reference_number = Column(String(50), ForeignKey("visitor_log.reference_number"), nullable=False, unique=True)
|
27 |
+
status = Column(String(50), nullable=False)
|
28 |
+
email_send = Column(String(10), nullable=True) # Assuming this is a Yes/No or similar status
|
29 |
+
|
30 |
+
# Relationship with VisitorLog
|
31 |
+
visitor_log = relationship("VisitorLog", back_populates="meeting_status")
|
32 |
+
|
33 |
+
class PersonToMeet(Base):
|
34 |
+
__tablename__ = "person_to_meet"
|
35 |
+
|
36 |
+
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
37 |
+
name = Column(String(255), nullable=False)
|
38 |
+
phone_number = Column(String(20), nullable=False, unique=True)
|
39 |
+
department = Column(String(255), nullable=False)
|
40 |
+
email_id = Column(String(255), nullable=False)
|
app/routers/__pycache__/meeting_status.cpython-313.pyc
ADDED
Binary file (4.69 kB). View file
|
|
app/routers/__pycache__/person_to_meet.cpython-313.pyc
ADDED
Binary file (3.99 kB). View file
|
|
app/routers/__pycache__/visitor_log.cpython-313.pyc
ADDED
Binary file (4.58 kB). View file
|
|
app/routers/meeting_status.py
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Depends, HTTPException, status
|
2 |
+
from sqlalchemy.orm import Session
|
3 |
+
from typing import List
|
4 |
+
|
5 |
+
from app.database.database import get_db
|
6 |
+
from app.models.models import MeetingStatus, VisitorLog
|
7 |
+
from app.schemas.schemas import MeetingStatusCreate, MeetingStatusUpdate, MeetingStatusResponse
|
8 |
+
|
9 |
+
router = APIRouter(
|
10 |
+
prefix="/meeting-status",
|
11 |
+
tags=["meeting-status"]
|
12 |
+
)
|
13 |
+
|
14 |
+
# Create meeting status
|
15 |
+
@router.post("/", response_model=MeetingStatusResponse, status_code=status.HTTP_201_CREATED)
|
16 |
+
def create_meeting_status(meeting_status: MeetingStatusCreate, db: Session = Depends(get_db)):
|
17 |
+
# Check if visitor log exists
|
18 |
+
visitor_log = db.query(VisitorLog).filter(VisitorLog.reference_number == meeting_status.reference_number).first()
|
19 |
+
if not visitor_log:
|
20 |
+
raise HTTPException(status_code=404, detail="Visitor log not found")
|
21 |
+
|
22 |
+
# Check if meeting status already exists
|
23 |
+
existing_status = db.query(MeetingStatus).filter(MeetingStatus.reference_number == meeting_status.reference_number).first()
|
24 |
+
if existing_status:
|
25 |
+
raise HTTPException(status_code=400, detail="Meeting status already exists for this reference number")
|
26 |
+
|
27 |
+
db_meeting_status = MeetingStatus(
|
28 |
+
reference_number=meeting_status.reference_number,
|
29 |
+
status=meeting_status.status,
|
30 |
+
email_send=meeting_status.email_send
|
31 |
+
)
|
32 |
+
db.add(db_meeting_status)
|
33 |
+
db.commit()
|
34 |
+
db.refresh(db_meeting_status)
|
35 |
+
return db_meeting_status
|
36 |
+
|
37 |
+
# Get all meeting statuses
|
38 |
+
@router.get("/", response_model=List[MeetingStatusResponse])
|
39 |
+
def get_all_meeting_statuses(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
40 |
+
return db.query(MeetingStatus).offset(skip).limit(limit).all()
|
41 |
+
|
42 |
+
# Get meeting status by reference number
|
43 |
+
@router.get("/{reference_number}", response_model=MeetingStatusResponse)
|
44 |
+
def get_meeting_status(reference_number: str, db: Session = Depends(get_db)):
|
45 |
+
db_meeting_status = db.query(MeetingStatus).filter(MeetingStatus.reference_number == reference_number).first()
|
46 |
+
if db_meeting_status is None:
|
47 |
+
raise HTTPException(status_code=404, detail="Meeting status not found")
|
48 |
+
return db_meeting_status
|
49 |
+
|
50 |
+
# Update meeting status
|
51 |
+
@router.put("/{reference_number}", response_model=MeetingStatusResponse)
|
52 |
+
def update_meeting_status(reference_number: str, meeting_status: MeetingStatusUpdate, db: Session = Depends(get_db)):
|
53 |
+
db_meeting_status = db.query(MeetingStatus).filter(MeetingStatus.reference_number == reference_number).first()
|
54 |
+
if db_meeting_status is None:
|
55 |
+
raise HTTPException(status_code=404, detail="Meeting status not found")
|
56 |
+
|
57 |
+
# Update meeting status fields
|
58 |
+
for key, value in meeting_status.dict().items():
|
59 |
+
setattr(db_meeting_status, key, value)
|
60 |
+
|
61 |
+
db.commit()
|
62 |
+
db.refresh(db_meeting_status)
|
63 |
+
return db_meeting_status
|
64 |
+
|
65 |
+
# Delete meeting status
|
66 |
+
@router.delete("/{reference_number}", status_code=status.HTTP_204_NO_CONTENT)
|
67 |
+
def delete_meeting_status(reference_number: str, db: Session = Depends(get_db)):
|
68 |
+
db_meeting_status = db.query(MeetingStatus).filter(MeetingStatus.reference_number == reference_number).first()
|
69 |
+
if db_meeting_status is None:
|
70 |
+
raise HTTPException(status_code=404, detail="Meeting status not found")
|
71 |
+
|
72 |
+
db.delete(db_meeting_status)
|
73 |
+
db.commit()
|
74 |
+
return None
|
app/routers/person_to_meet.py
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Depends, HTTPException, status
|
2 |
+
from sqlalchemy.orm import Session
|
3 |
+
from typing import List
|
4 |
+
|
5 |
+
from app.database.database import get_db
|
6 |
+
from app.models.models import PersonToMeet
|
7 |
+
from app.schemas.schemas import PersonToMeetCreate, PersonToMeetUpdate, PersonToMeetResponse
|
8 |
+
|
9 |
+
router = APIRouter(
|
10 |
+
prefix="/person-to-meet",
|
11 |
+
tags=["person-to-meet"]
|
12 |
+
)
|
13 |
+
|
14 |
+
# Create person to meet
|
15 |
+
@router.post("/", response_model=PersonToMeetResponse, status_code=status.HTTP_201_CREATED)
|
16 |
+
def create_person_to_meet(person: PersonToMeetCreate, db: Session = Depends(get_db)):
|
17 |
+
db_person = PersonToMeet(
|
18 |
+
name=person.name,
|
19 |
+
phone_number=person.phone_number,
|
20 |
+
department=person.department,
|
21 |
+
email_id=person.email_id
|
22 |
+
)
|
23 |
+
db.add(db_person)
|
24 |
+
db.commit()
|
25 |
+
db.refresh(db_person)
|
26 |
+
return db_person
|
27 |
+
|
28 |
+
# Get all persons to meet
|
29 |
+
@router.get("/", response_model=List[PersonToMeetResponse])
|
30 |
+
def get_all_persons_to_meet(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
31 |
+
return db.query(PersonToMeet).offset(skip).limit(limit).all()
|
32 |
+
|
33 |
+
# Get person to meet by ID
|
34 |
+
@router.get("/{person_id}", response_model=PersonToMeetResponse)
|
35 |
+
def get_person_to_meet(person_id: int, db: Session = Depends(get_db)):
|
36 |
+
db_person = db.query(PersonToMeet).filter(PersonToMeet.id == person_id).first()
|
37 |
+
if db_person is None:
|
38 |
+
raise HTTPException(status_code=404, detail="Person to meet not found")
|
39 |
+
return db_person
|
40 |
+
|
41 |
+
# Update person to meet
|
42 |
+
@router.put("/{person_id}", response_model=PersonToMeetResponse)
|
43 |
+
def update_person_to_meet(person_id: int, person: PersonToMeetUpdate, db: Session = Depends(get_db)):
|
44 |
+
db_person = db.query(PersonToMeet).filter(PersonToMeet.id == person_id).first()
|
45 |
+
if db_person is None:
|
46 |
+
raise HTTPException(status_code=404, detail="Person to meet not found")
|
47 |
+
|
48 |
+
# Update person fields
|
49 |
+
for key, value in person.dict().items():
|
50 |
+
setattr(db_person, key, value)
|
51 |
+
|
52 |
+
db.commit()
|
53 |
+
db.refresh(db_person)
|
54 |
+
return db_person
|
55 |
+
|
56 |
+
# Delete person to meet
|
57 |
+
@router.delete("/{person_id}", status_code=status.HTTP_204_NO_CONTENT)
|
58 |
+
def delete_person_to_meet(person_id: int, db: Session = Depends(get_db)):
|
59 |
+
db_person = db.query(PersonToMeet).filter(PersonToMeet.id == person_id).first()
|
60 |
+
if db_person is None:
|
61 |
+
raise HTTPException(status_code=404, detail="Person to meet not found")
|
62 |
+
|
63 |
+
db.delete(db_person)
|
64 |
+
db.commit()
|
65 |
+
return None
|
app/routers/visitor_log.py
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Depends, HTTPException, status
|
2 |
+
from sqlalchemy.orm import Session
|
3 |
+
from typing import List
|
4 |
+
import uuid
|
5 |
+
|
6 |
+
from app.database.database import get_db
|
7 |
+
from app.models.models import VisitorLog
|
8 |
+
from app.schemas.schemas import VisitorLogCreate, VisitorLogResponse, VisitorWithStatusResponse
|
9 |
+
|
10 |
+
router = APIRouter(
|
11 |
+
prefix="/visitor-log",
|
12 |
+
tags=["visitor-log"]
|
13 |
+
)
|
14 |
+
|
15 |
+
# Generate unique reference number
|
16 |
+
def generate_reference_number():
|
17 |
+
return f"VST-{uuid.uuid4().hex[:8].upper()}"
|
18 |
+
|
19 |
+
# Create visitor log
|
20 |
+
@router.post("/", response_model=VisitorLogResponse, status_code=status.HTTP_201_CREATED)
|
21 |
+
def create_visitor_log(visitor: VisitorLogCreate, db: Session = Depends(get_db)):
|
22 |
+
reference_number = generate_reference_number()
|
23 |
+
db_visitor = VisitorLog(
|
24 |
+
full_name=visitor.full_name,
|
25 |
+
email_address=visitor.email_address,
|
26 |
+
phone_number=visitor.phone_number,
|
27 |
+
company_name=visitor.company_name,
|
28 |
+
qid_id_number=visitor.qid_id_number,
|
29 |
+
purpose_of_visit=visitor.purpose_of_visit,
|
30 |
+
person_to_meet=visitor.person_to_meet,
|
31 |
+
preferred_datetime=visitor.preferred_datetime,
|
32 |
+
reference_number=reference_number
|
33 |
+
)
|
34 |
+
db.add(db_visitor)
|
35 |
+
db.commit()
|
36 |
+
db.refresh(db_visitor)
|
37 |
+
return db_visitor
|
38 |
+
|
39 |
+
# Get all visitor logs
|
40 |
+
@router.get("/", response_model=List[VisitorLogResponse])
|
41 |
+
def get_all_visitor_logs(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
42 |
+
return db.query(VisitorLog).offset(skip).limit(limit).all()
|
43 |
+
|
44 |
+
# Get visitor log by reference number
|
45 |
+
@router.get("/{reference_number}", response_model=VisitorWithStatusResponse)
|
46 |
+
def get_visitor_log(reference_number: str, db: Session = Depends(get_db)):
|
47 |
+
db_visitor = db.query(VisitorLog).filter(VisitorLog.reference_number == reference_number).first()
|
48 |
+
if db_visitor is None:
|
49 |
+
raise HTTPException(status_code=404, detail="Visitor log not found")
|
50 |
+
return db_visitor
|
51 |
+
|
52 |
+
# Update visitor log
|
53 |
+
@router.put("/{reference_number}", response_model=VisitorLogResponse)
|
54 |
+
def update_visitor_log(reference_number: str, visitor: VisitorLogCreate, db: Session = Depends(get_db)):
|
55 |
+
db_visitor = db.query(VisitorLog).filter(VisitorLog.reference_number == reference_number).first()
|
56 |
+
if db_visitor is None:
|
57 |
+
raise HTTPException(status_code=404, detail="Visitor log not found")
|
58 |
+
|
59 |
+
# Update visitor log fields
|
60 |
+
for key, value in visitor.dict().items():
|
61 |
+
setattr(db_visitor, key, value)
|
62 |
+
|
63 |
+
db.commit()
|
64 |
+
db.refresh(db_visitor)
|
65 |
+
return db_visitor
|
66 |
+
|
67 |
+
# Delete visitor log
|
68 |
+
@router.delete("/{reference_number}", status_code=status.HTTP_204_NO_CONTENT)
|
69 |
+
def delete_visitor_log(reference_number: str, db: Session = Depends(get_db)):
|
70 |
+
db_visitor = db.query(VisitorLog).filter(VisitorLog.reference_number == reference_number).first()
|
71 |
+
if db_visitor is None:
|
72 |
+
raise HTTPException(status_code=404, detail="Visitor log not found")
|
73 |
+
|
74 |
+
db.delete(db_visitor)
|
75 |
+
db.commit()
|
76 |
+
return None
|
app/schemas/__pycache__/schemas.cpython-313.pyc
ADDED
Binary file (4.13 kB). View file
|
|
app/schemas/schemas.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel, EmailStr, Field
|
2 |
+
from datetime import datetime
|
3 |
+
from typing import Optional
|
4 |
+
|
5 |
+
# VisitorLog Schemas
|
6 |
+
class VisitorLogBase(BaseModel):
|
7 |
+
full_name: str
|
8 |
+
email_address: EmailStr
|
9 |
+
phone_number: str
|
10 |
+
company_name: Optional[str] = None
|
11 |
+
qid_id_number: Optional[str] = None
|
12 |
+
purpose_of_visit: str
|
13 |
+
person_to_meet: str
|
14 |
+
preferred_datetime: datetime
|
15 |
+
|
16 |
+
class VisitorLogCreate(VisitorLogBase):
|
17 |
+
pass
|
18 |
+
|
19 |
+
class VisitorLogResponse(VisitorLogBase):
|
20 |
+
sl_no: int
|
21 |
+
reference_number: str
|
22 |
+
|
23 |
+
class Config:
|
24 |
+
from_attributes = True # Updated from orm_mode
|
25 |
+
|
26 |
+
# MeetingStatus Schemas
|
27 |
+
class MeetingStatusBase(BaseModel):
|
28 |
+
status: str
|
29 |
+
email_send: Optional[str] = None
|
30 |
+
|
31 |
+
class MeetingStatusCreate(MeetingStatusBase):
|
32 |
+
reference_number: str
|
33 |
+
|
34 |
+
class MeetingStatusUpdate(MeetingStatusBase):
|
35 |
+
pass
|
36 |
+
|
37 |
+
class MeetingStatusResponse(MeetingStatusBase):
|
38 |
+
sl_no: int
|
39 |
+
reference_number: str
|
40 |
+
|
41 |
+
class Config:
|
42 |
+
from_attributes = True # Updated from orm_mode
|
43 |
+
|
44 |
+
# Combined Response Schema
|
45 |
+
class VisitorWithStatusResponse(VisitorLogResponse):
|
46 |
+
meeting_status: Optional[MeetingStatusResponse] = None
|
47 |
+
|
48 |
+
class Config:
|
49 |
+
from_attributes = True # Updated from orm_mode
|
50 |
+
|
51 |
+
# PersonToMeet Schemas
|
52 |
+
class PersonToMeetBase(BaseModel):
|
53 |
+
name: str
|
54 |
+
phone_number: str
|
55 |
+
department: str
|
56 |
+
email_id: EmailStr
|
57 |
+
|
58 |
+
class PersonToMeetCreate(PersonToMeetBase):
|
59 |
+
pass
|
60 |
+
|
61 |
+
class PersonToMeetUpdate(PersonToMeetBase):
|
62 |
+
pass
|
63 |
+
|
64 |
+
class PersonToMeetResponse(PersonToMeetBase):
|
65 |
+
id: int
|
66 |
+
|
67 |
+
class Config:
|
68 |
+
from_attributes = True
|
run.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import uvicorn
|
2 |
+
|
3 |
+
if __name__ == "__main__":
|
4 |
+
uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)
|