|
|
from fastapi import FastAPI, Request, Depends, HTTPException, Form |
|
|
from fastapi.responses import HTMLResponse, RedirectResponse |
|
|
from fastapi.staticfiles import StaticFiles |
|
|
from fastapi.templating import Jinja2Templates |
|
|
from sqlalchemy.orm import Session |
|
|
from typing import Optional |
|
|
from datetime import date |
|
|
from decimal import Decimal |
|
|
|
|
|
import models |
|
|
import schemas |
|
|
import crud |
|
|
from database import engine, get_db |
|
|
|
|
|
|
|
|
models.Base.metadata.create_all(bind=engine) |
|
|
|
|
|
app = FastAPI(title="Architecture PM System") |
|
|
|
|
|
|
|
|
app.mount("/static", StaticFiles(directory="static"), name="static") |
|
|
|
|
|
|
|
|
templates = Jinja2Templates(directory="templates") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/", response_class=HTMLResponse) |
|
|
async def home(request: Request, db: Session = Depends(get_db)): |
|
|
projects_count = db.query(models.Project).count() |
|
|
employees_count = db.query(models.Employee).count() |
|
|
timesheets_count = db.query(models.Timesheet).count() |
|
|
invoices_count = db.query(models.Invoice).count() |
|
|
|
|
|
return templates.TemplateResponse("index.html", { |
|
|
"request": request, |
|
|
"projects_count": projects_count, |
|
|
"employees_count": employees_count, |
|
|
"timesheets_count": timesheets_count, |
|
|
"invoices_count": invoices_count |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/projects", response_class=HTMLResponse) |
|
|
async def list_projects(request: Request, db: Session = Depends(get_db)): |
|
|
projects = crud.get_projects(db) |
|
|
return templates.TemplateResponse("projects.html", { |
|
|
"request": request, |
|
|
"projects": projects |
|
|
}) |
|
|
|
|
|
@app.get("/api/projects") |
|
|
async def api_list_projects(db: Session = Depends(get_db)): |
|
|
return crud.get_projects(db) |
|
|
|
|
|
@app.post("/projects/create") |
|
|
async def create_project( |
|
|
project_id: str = Form(...), |
|
|
project_name: str = Form(...), |
|
|
client_name: str = Form(...), |
|
|
contract_value_aed: float = Form(...), |
|
|
planned_cost_aed: float = Form(...), |
|
|
project_start_date: date = Form(...), |
|
|
project_end_date: date = Form(...), |
|
|
project_type: str = Form(...), |
|
|
project_status: str = Form(...), |
|
|
current_phase: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
project = schemas.ProjectCreate( |
|
|
project_id=project_id, |
|
|
project_name=project_name, |
|
|
client_name=client_name, |
|
|
contract_value_aed=Decimal(str(contract_value_aed)), |
|
|
planned_cost_aed=Decimal(str(planned_cost_aed)), |
|
|
project_start_date=project_start_date, |
|
|
project_end_date=project_end_date, |
|
|
project_type=project_type, |
|
|
project_status=project_status, |
|
|
current_phase=current_phase |
|
|
) |
|
|
crud.create_project(db, project) |
|
|
return RedirectResponse(url="/projects", status_code=303) |
|
|
|
|
|
@app.post("/projects/delete/{project_id}") |
|
|
async def delete_project(project_id: str, db: Session = Depends(get_db)): |
|
|
crud.delete_project(db, project_id) |
|
|
return RedirectResponse(url="/projects", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/employees", response_class=HTMLResponse) |
|
|
async def list_employees(request: Request, db: Session = Depends(get_db)): |
|
|
employees = crud.get_employees(db) |
|
|
return templates.TemplateResponse("employees.html", { |
|
|
"request": request, |
|
|
"employees": employees |
|
|
}) |
|
|
|
|
|
@app.get("/api/employees") |
|
|
async def api_list_employees(db: Session = Depends(get_db)): |
|
|
return crud.get_employees(db) |
|
|
|
|
|
@app.post("/employees/create") |
|
|
async def create_employee( |
|
|
employee_id: str = Form(...), |
|
|
employee_name: str = Form(...), |
|
|
department: str = Form(...), |
|
|
role: str = Form(...), |
|
|
hourly_rate_aed: float = Form(...), |
|
|
employment_type: str = Form(...), |
|
|
start_date: date = Form(...), |
|
|
cost_category: str = Form(...), |
|
|
email: Optional[str] = Form(None), |
|
|
phone: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
employee = schemas.EmployeeCreate( |
|
|
employee_id=employee_id, |
|
|
employee_name=employee_name, |
|
|
department=department, |
|
|
role=role, |
|
|
hourly_rate_aed=Decimal(str(hourly_rate_aed)), |
|
|
employment_type=employment_type, |
|
|
start_date=start_date, |
|
|
cost_category=cost_category, |
|
|
email=email, |
|
|
phone=phone |
|
|
) |
|
|
crud.create_employee(db, employee) |
|
|
return RedirectResponse(url="/employees", status_code=303) |
|
|
|
|
|
@app.post("/employees/delete/{employee_id}") |
|
|
async def delete_employee(employee_id: str, db: Session = Depends(get_db)): |
|
|
crud.delete_employee(db, employee_id) |
|
|
return RedirectResponse(url="/employees", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/timesheets", response_class=HTMLResponse) |
|
|
async def list_timesheets(request: Request, db: Session = Depends(get_db)): |
|
|
timesheets = crud.get_timesheets(db, limit=200) |
|
|
employees = crud.get_employees(db) |
|
|
projects = crud.get_projects(db) |
|
|
return templates.TemplateResponse("timesheets.html", { |
|
|
"request": request, |
|
|
"timesheets": timesheets, |
|
|
"employees": employees, |
|
|
"projects": projects |
|
|
}) |
|
|
|
|
|
@app.get("/api/timesheets") |
|
|
async def api_list_timesheets(db: Session = Depends(get_db)): |
|
|
return crud.get_timesheets(db, limit=200) |
|
|
|
|
|
@app.post("/timesheets/create") |
|
|
async def create_timesheet( |
|
|
record_id: str = Form(...), |
|
|
date: date = Form(...), |
|
|
employee_id: str = Form(...), |
|
|
project_id: str = Form(...), |
|
|
hours_worked: float = Form(...), |
|
|
billable_hours: float = Form(...), |
|
|
work_category: str = Form(...), |
|
|
task_description: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
timesheet = schemas.TimesheetCreate( |
|
|
record_id=record_id, |
|
|
date=date, |
|
|
employee_id=employee_id, |
|
|
project_id=project_id, |
|
|
hours_worked=Decimal(str(hours_worked)), |
|
|
billable_hours=Decimal(str(billable_hours)), |
|
|
work_category=work_category, |
|
|
task_description=task_description |
|
|
) |
|
|
crud.create_timesheet(db, timesheet) |
|
|
return RedirectResponse(url="/timesheets", status_code=303) |
|
|
|
|
|
@app.post("/timesheets/delete/{record_id}") |
|
|
async def delete_timesheet(record_id: str, db: Session = Depends(get_db)): |
|
|
crud.delete_timesheet(db, record_id) |
|
|
return RedirectResponse(url="/timesheets", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/milestones", response_class=HTMLResponse) |
|
|
async def list_milestones(request: Request, db: Session = Depends(get_db)): |
|
|
milestones = crud.get_milestones(db) |
|
|
projects = crud.get_projects(db) |
|
|
return templates.TemplateResponse("milestones.html", { |
|
|
"request": request, |
|
|
"milestones": milestones, |
|
|
"projects": projects |
|
|
}) |
|
|
|
|
|
@app.get("/api/milestones") |
|
|
async def api_list_milestones(db: Session = Depends(get_db)): |
|
|
return crud.get_milestones(db) |
|
|
|
|
|
@app.post("/milestones/create") |
|
|
async def create_milestone( |
|
|
project_id: str = Form(...), |
|
|
milestone_name: str = Form(...), |
|
|
milestone_order: int = Form(...), |
|
|
planned_date: date = Form(...), |
|
|
status: str = Form(...), |
|
|
completion_percentage: int = Form(0), |
|
|
actual_date: Optional[date] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
milestone = schemas.MilestoneCreate( |
|
|
project_id=project_id, |
|
|
milestone_name=milestone_name, |
|
|
milestone_order=milestone_order, |
|
|
planned_date=planned_date, |
|
|
actual_date=actual_date, |
|
|
status=status, |
|
|
completion_percentage=completion_percentage |
|
|
) |
|
|
crud.create_milestone(db, milestone) |
|
|
return RedirectResponse(url="/milestones", status_code=303) |
|
|
|
|
|
@app.post("/milestones/delete/{milestone_id}") |
|
|
async def delete_milestone(milestone_id: int, db: Session = Depends(get_db)): |
|
|
crud.delete_milestone(db, milestone_id) |
|
|
return RedirectResponse(url="/milestones", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/invoices", response_class=HTMLResponse) |
|
|
async def list_invoices(request: Request, db: Session = Depends(get_db)): |
|
|
invoices = crud.get_invoices(db) |
|
|
projects = crud.get_projects(db) |
|
|
return templates.TemplateResponse("invoices.html", { |
|
|
"request": request, |
|
|
"invoices": invoices, |
|
|
"projects": projects |
|
|
}) |
|
|
|
|
|
@app.get("/api/invoices") |
|
|
async def api_list_invoices(db: Session = Depends(get_db)): |
|
|
return crud.get_invoices(db) |
|
|
|
|
|
@app.post("/invoices/create") |
|
|
async def create_invoice( |
|
|
invoice_id: str = Form(...), |
|
|
project_id: str = Form(...), |
|
|
invoice_date: date = Form(...), |
|
|
invoice_amount_aed: float = Form(...), |
|
|
due_date: date = Form(...), |
|
|
payment_status: str = Form(...), |
|
|
payment_date: Optional[date] = Form(None), |
|
|
milestone_reference: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
invoice = schemas.InvoiceCreate( |
|
|
invoice_id=invoice_id, |
|
|
project_id=project_id, |
|
|
invoice_date=invoice_date, |
|
|
invoice_amount_aed=Decimal(str(invoice_amount_aed)), |
|
|
due_date=due_date, |
|
|
payment_date=payment_date, |
|
|
payment_status=payment_status, |
|
|
milestone_reference=milestone_reference |
|
|
) |
|
|
crud.create_invoice(db, invoice) |
|
|
return RedirectResponse(url="/invoices", status_code=303) |
|
|
|
|
|
@app.post("/invoices/delete/{invoice_id}") |
|
|
async def delete_invoice(invoice_id: str, db: Session = Depends(get_db)): |
|
|
crud.delete_invoice(db, invoice_id) |
|
|
return RedirectResponse(url="/invoices", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/subcontractors", response_class=HTMLResponse) |
|
|
async def list_subcontractors(request: Request, db: Session = Depends(get_db)): |
|
|
subcontractors = crud.get_subcontractors(db) |
|
|
projects = crud.get_projects(db) |
|
|
return templates.TemplateResponse("subcontractors.html", { |
|
|
"request": request, |
|
|
"subcontractors": subcontractors, |
|
|
"projects": projects |
|
|
}) |
|
|
|
|
|
@app.get("/api/subcontractors") |
|
|
async def api_list_subcontractors(db: Session = Depends(get_db)): |
|
|
return crud.get_subcontractors(db) |
|
|
|
|
|
@app.post("/subcontractors/create") |
|
|
async def create_subcontractor( |
|
|
project_id: str = Form(...), |
|
|
subcontractor_name: str = Form(...), |
|
|
service_type: str = Form(...), |
|
|
contract_amount_aed: float = Form(...), |
|
|
amount_invoiced_aed: float = Form(0), |
|
|
payment_status: str = Form(...), |
|
|
work_category: str = Form(...), |
|
|
contact_person: Optional[str] = Form(None), |
|
|
contact_email: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
subcontractor = schemas.SubcontractorCreate( |
|
|
project_id=project_id, |
|
|
subcontractor_name=subcontractor_name, |
|
|
service_type=service_type, |
|
|
contract_amount_aed=Decimal(str(contract_amount_aed)), |
|
|
amount_invoiced_aed=Decimal(str(amount_invoiced_aed)), |
|
|
payment_status=payment_status, |
|
|
work_category=work_category, |
|
|
contact_person=contact_person, |
|
|
contact_email=contact_email |
|
|
) |
|
|
crud.create_subcontractor(db, subcontractor) |
|
|
return RedirectResponse(url="/subcontractors", status_code=303) |
|
|
|
|
|
@app.post("/subcontractors/delete/{subcontractor_id}") |
|
|
async def delete_subcontractor(subcontractor_id: int, db: Session = Depends(get_db)): |
|
|
crud.delete_subcontractor(db, subcontractor_id) |
|
|
return RedirectResponse(url="/subcontractors", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/staff-allocation", response_class=HTMLResponse) |
|
|
async def list_staff_allocations(request: Request, db: Session = Depends(get_db)): |
|
|
allocations = crud.get_staff_allocations(db) |
|
|
projects = crud.get_projects(db) |
|
|
employees = crud.get_employees(db) |
|
|
milestones = crud.get_milestones(db) |
|
|
return templates.TemplateResponse("staff_allocation.html", { |
|
|
"request": request, |
|
|
"allocations": allocations, |
|
|
"projects": projects, |
|
|
"employees": employees, |
|
|
"milestones": milestones |
|
|
}) |
|
|
|
|
|
@app.get("/api/staff-allocation") |
|
|
async def api_list_staff_allocations(db: Session = Depends(get_db)): |
|
|
return crud.get_staff_allocations(db) |
|
|
|
|
|
@app.post("/staff-allocation/create") |
|
|
async def create_staff_allocation( |
|
|
project_id: str = Form(...), |
|
|
employee_id: str = Form(...), |
|
|
employee_name: str = Form(...), |
|
|
role: str = Form(...), |
|
|
hours_allocated: float = Form(...), |
|
|
hours_worked: float = Form(0), |
|
|
hourly_rate_aed: float = Form(...), |
|
|
start_date: date = Form(...), |
|
|
milestone_id: Optional[int] = Form(None), |
|
|
milestone_name: Optional[str] = Form(None), |
|
|
category: Optional[str] = Form(None), |
|
|
skill_match_score: Optional[int] = Form(None), |
|
|
availability_status: Optional[str] = Form(None), |
|
|
performance_rating: Optional[str] = Form(None), |
|
|
end_date: Optional[date] = Form(None), |
|
|
notes: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
allocation = schemas.StaffAllocationCreate( |
|
|
project_id=project_id, |
|
|
milestone_id=milestone_id, |
|
|
milestone_name=milestone_name, |
|
|
employee_id=employee_id, |
|
|
employee_name=employee_name, |
|
|
role=role, |
|
|
category=category, |
|
|
hours_allocated=Decimal(str(hours_allocated)), |
|
|
hours_worked=Decimal(str(hours_worked)), |
|
|
hourly_rate_aed=Decimal(str(hourly_rate_aed)), |
|
|
skill_match_score=skill_match_score, |
|
|
availability_status=availability_status, |
|
|
performance_rating=performance_rating, |
|
|
start_date=start_date, |
|
|
end_date=end_date, |
|
|
notes=notes |
|
|
) |
|
|
crud.create_staff_allocation(db, allocation) |
|
|
return RedirectResponse(url="/staff-allocation", status_code=303) |
|
|
|
|
|
@app.post("/staff-allocation/delete/{allocation_id}") |
|
|
async def delete_staff_allocation(allocation_id: int, db: Session = Depends(get_db)): |
|
|
crud.delete_staff_allocation(db, allocation_id) |
|
|
return RedirectResponse(url="/staff-allocation", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/projects/edit/{project_id}", response_class=HTMLResponse) |
|
|
async def edit_project_form(request: Request, project_id: str, db: Session = Depends(get_db)): |
|
|
project = crud.get_project(db, project_id) |
|
|
if not project: |
|
|
raise HTTPException(status_code=404, detail="Project not found") |
|
|
return templates.TemplateResponse("edit_project.html", { |
|
|
"request": request, |
|
|
"project": project |
|
|
}) |
|
|
|
|
|
@app.post("/projects/update/{project_id}") |
|
|
async def update_project( |
|
|
project_id: str, |
|
|
project_name: str = Form(...), |
|
|
client_name: str = Form(...), |
|
|
contract_value_aed: float = Form(...), |
|
|
planned_cost_aed: float = Form(...), |
|
|
project_start_date: date = Form(...), |
|
|
project_end_date: date = Form(...), |
|
|
project_type: str = Form(...), |
|
|
project_status: str = Form(...), |
|
|
current_phase: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
project = schemas.ProjectCreate( |
|
|
project_id=project_id, |
|
|
project_name=project_name, |
|
|
client_name=client_name, |
|
|
contract_value_aed=Decimal(str(contract_value_aed)), |
|
|
planned_cost_aed=Decimal(str(planned_cost_aed)), |
|
|
project_start_date=project_start_date, |
|
|
project_end_date=project_end_date, |
|
|
project_type=project_type, |
|
|
project_status=project_status, |
|
|
current_phase=current_phase |
|
|
) |
|
|
crud.update_project(db, project_id, project) |
|
|
return RedirectResponse(url="/projects", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/employees/update/{employee_id}") |
|
|
async def update_employee( |
|
|
employee_id: str, |
|
|
employee_name: str = Form(...), |
|
|
department: str = Form(...), |
|
|
role: str = Form(...), |
|
|
hourly_rate_aed: float = Form(...), |
|
|
employment_type: str = Form(...), |
|
|
start_date: date = Form(...), |
|
|
cost_category: str = Form(...), |
|
|
email: Optional[str] = Form(None), |
|
|
phone: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
employee = schemas.EmployeeCreate( |
|
|
employee_id=employee_id, |
|
|
employee_name=employee_name, |
|
|
department=department, |
|
|
role=role, |
|
|
hourly_rate_aed=Decimal(str(hourly_rate_aed)), |
|
|
employment_type=employment_type, |
|
|
start_date=start_date, |
|
|
cost_category=cost_category, |
|
|
email=email, |
|
|
phone=phone |
|
|
) |
|
|
crud.update_employee(db, employee_id, employee) |
|
|
return RedirectResponse(url="/employees", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/timesheets/update/{record_id}") |
|
|
async def update_timesheet( |
|
|
record_id: str, |
|
|
date: date = Form(...), |
|
|
employee_id: str = Form(...), |
|
|
project_id: str = Form(...), |
|
|
hours_worked: float = Form(...), |
|
|
billable_hours: float = Form(...), |
|
|
work_category: str = Form(...), |
|
|
task_description: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
timesheet = schemas.TimesheetCreate( |
|
|
record_id=record_id, |
|
|
date=date, |
|
|
employee_id=employee_id, |
|
|
project_id=project_id, |
|
|
hours_worked=Decimal(str(hours_worked)), |
|
|
billable_hours=Decimal(str(billable_hours)), |
|
|
work_category=work_category, |
|
|
task_description=task_description |
|
|
) |
|
|
crud.update_timesheet(db, record_id, timesheet) |
|
|
return RedirectResponse(url="/timesheets", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/milestones/update/{milestone_id}") |
|
|
async def update_milestone( |
|
|
milestone_id: int, |
|
|
project_id: str = Form(...), |
|
|
milestone_name: str = Form(...), |
|
|
milestone_order: int = Form(...), |
|
|
planned_date: date = Form(...), |
|
|
status: str = Form(...), |
|
|
completion_percentage: int = Form(0), |
|
|
actual_date: Optional[date] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
milestone = schemas.MilestoneCreate( |
|
|
project_id=project_id, |
|
|
milestone_name=milestone_name, |
|
|
milestone_order=milestone_order, |
|
|
planned_date=planned_date, |
|
|
actual_date=actual_date, |
|
|
status=status, |
|
|
completion_percentage=completion_percentage |
|
|
) |
|
|
crud.update_milestone(db, milestone_id, milestone) |
|
|
return RedirectResponse(url="/milestones", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/invoices/update/{invoice_id}") |
|
|
async def update_invoice( |
|
|
invoice_id: str, |
|
|
project_id: str = Form(...), |
|
|
invoice_date: date = Form(...), |
|
|
invoice_amount_aed: float = Form(...), |
|
|
due_date: date = Form(...), |
|
|
payment_status: str = Form(...), |
|
|
payment_date: Optional[date] = Form(None), |
|
|
milestone_reference: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
invoice = schemas.InvoiceCreate( |
|
|
invoice_id=invoice_id, |
|
|
project_id=project_id, |
|
|
invoice_date=invoice_date, |
|
|
invoice_amount_aed=Decimal(str(invoice_amount_aed)), |
|
|
due_date=due_date, |
|
|
payment_date=payment_date, |
|
|
payment_status=payment_status, |
|
|
milestone_reference=milestone_reference |
|
|
) |
|
|
crud.update_invoice(db, invoice_id, invoice) |
|
|
return RedirectResponse(url="/invoices", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/subcontractors/update/{subcontractor_id}") |
|
|
async def update_subcontractor( |
|
|
subcontractor_id: int, |
|
|
project_id: str = Form(...), |
|
|
subcontractor_name: str = Form(...), |
|
|
service_type: str = Form(...), |
|
|
contract_amount_aed: float = Form(...), |
|
|
amount_invoiced_aed: float = Form(0), |
|
|
payment_status: str = Form(...), |
|
|
work_category: str = Form(...), |
|
|
contact_person: Optional[str] = Form(None), |
|
|
contact_email: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
subcontractor = schemas.SubcontractorCreate( |
|
|
project_id=project_id, |
|
|
subcontractor_name=subcontractor_name, |
|
|
service_type=service_type, |
|
|
contract_amount_aed=Decimal(str(contract_amount_aed)), |
|
|
amount_invoiced_aed=Decimal(str(amount_invoiced_aed)), |
|
|
payment_status=payment_status, |
|
|
work_category=work_category, |
|
|
contact_person=contact_person, |
|
|
contact_email=contact_email |
|
|
) |
|
|
crud.update_subcontractor(db, subcontractor_id, subcontractor) |
|
|
return RedirectResponse(url="/subcontractors", status_code=303) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/staff-allocation/update/{allocation_id}") |
|
|
async def update_staff_allocation( |
|
|
allocation_id: int, |
|
|
project_id: str = Form(...), |
|
|
employee_id: str = Form(...), |
|
|
employee_name: str = Form(...), |
|
|
role: str = Form(...), |
|
|
hours_allocated: float = Form(...), |
|
|
hours_worked: float = Form(0), |
|
|
hourly_rate_aed: float = Form(...), |
|
|
start_date: date = Form(...), |
|
|
milestone_id: Optional[int] = Form(None), |
|
|
milestone_name: Optional[str] = Form(None), |
|
|
category: Optional[str] = Form(None), |
|
|
skill_match_score: Optional[int] = Form(None), |
|
|
availability_status: Optional[str] = Form(None), |
|
|
performance_rating: Optional[str] = Form(None), |
|
|
end_date: Optional[date] = Form(None), |
|
|
notes: Optional[str] = Form(None), |
|
|
db: Session = Depends(get_db) |
|
|
): |
|
|
allocation = schemas.StaffAllocationCreate( |
|
|
project_id=project_id, |
|
|
milestone_id=milestone_id, |
|
|
milestone_name=milestone_name, |
|
|
employee_id=employee_id, |
|
|
employee_name=employee_name, |
|
|
role=role, |
|
|
category=category, |
|
|
hours_allocated=Decimal(str(hours_allocated)), |
|
|
hours_worked=Decimal(str(hours_worked)), |
|
|
hourly_rate_aed=Decimal(str(hourly_rate_aed)), |
|
|
skill_match_score=skill_match_score, |
|
|
availability_status=availability_status, |
|
|
performance_rating=performance_rating, |
|
|
start_date=start_date, |
|
|
end_date=end_date, |
|
|
notes=notes |
|
|
) |
|
|
crud.update_staff_allocation(db, allocation_id, allocation) |
|
|
return RedirectResponse(url="/staff-allocation", status_code=303) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
import uvicorn |
|
|
uvicorn.run(app, host="0.0.0.0", port=8000) |