add acquisition data CRUD API
parent
7daf2c1d79
commit
9b02963d45
Binary file not shown.
@ -0,0 +1,95 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from fastapi import APIRouter, HTTPException, status, Query
|
||||||
|
|
||||||
|
from src.acquisition_cost.model import AcquisitionData
|
||||||
|
from src.acquisition_cost.schema import AcquisitionCostDataPagination, AcquisitionCostDataRead, AcquisitionCostDataCreate, AcquisitionCostDataUpdate
|
||||||
|
from src.acquisition_cost.service import get, get_all, create, update, delete
|
||||||
|
|
||||||
|
from src.database.service import CommonParameters, search_filter_sort_paginate
|
||||||
|
from src.database.core import DbSession
|
||||||
|
from src.auth.service import CurrentUser
|
||||||
|
from src.models import StandardResponse
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("", response_model=StandardResponse[AcquisitionCostDataPagination])
|
||||||
|
async def get_yeardatas(
|
||||||
|
db_session: DbSession,
|
||||||
|
common: CommonParameters,
|
||||||
|
items_per_page: Optional[int] = Query(5),
|
||||||
|
search: Optional[str] = Query(None),
|
||||||
|
):
|
||||||
|
"""Get all acquisition_cost_data pagination."""
|
||||||
|
get_acquisition_cost_data = await get_all(
|
||||||
|
db_session=db_session,
|
||||||
|
items_per_page=items_per_page,
|
||||||
|
search=search,
|
||||||
|
common=common,
|
||||||
|
)
|
||||||
|
# return
|
||||||
|
return StandardResponse(
|
||||||
|
data=get_acquisition_cost_data,
|
||||||
|
message="Data retrieved successfully",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{acquisition_cost_data_id}", response_model=StandardResponse[AcquisitionCostDataRead])
|
||||||
|
async def get_acquisition_cost_data(db_session: DbSession, acquisition_cost_data_id: str):
|
||||||
|
acquisition_cost_data = await get(db_session=db_session, acquisition_cost_data_id=acquisition_cost_data_id)
|
||||||
|
if not acquisition_cost_data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="A data with this id does not exist.",
|
||||||
|
)
|
||||||
|
|
||||||
|
return StandardResponse(data=acquisition_cost_data, message="Data retrieved successfully")
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("", response_model=StandardResponse[AcquisitionCostDataRead])
|
||||||
|
async def create_acquisition_cost_data(
|
||||||
|
db_session: DbSession, acquisition_cost_data_in: AcquisitionCostDataCreate, current_user: CurrentUser
|
||||||
|
):
|
||||||
|
acquisition_cost_data_in.created_by = current_user.name
|
||||||
|
acquisition_cost_data = await create(db_session=db_session, acquisition_data_in=acquisition_cost_data_in)
|
||||||
|
|
||||||
|
return StandardResponse(data=acquisition_cost_data, message="Data created successfully")
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/{acquisition_cost_data_id}", response_model=StandardResponse[AcquisitionCostDataRead])
|
||||||
|
async def update_acquisition_cost_data(
|
||||||
|
db_session: DbSession,
|
||||||
|
acquisition_cost_data_id: str,
|
||||||
|
acquisition_cost_data_in: AcquisitionCostDataUpdate,
|
||||||
|
current_user: CurrentUser,
|
||||||
|
):
|
||||||
|
acquisition_cost_data = await get(db_session=db_session, acquisition_cost_data_id=acquisition_cost_data_id)
|
||||||
|
|
||||||
|
if not acquisition_cost_data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="A data with this id does not exist.",
|
||||||
|
)
|
||||||
|
acquisition_cost_data_in.updated_by = current_user.name
|
||||||
|
|
||||||
|
return StandardResponse(
|
||||||
|
data=await update(
|
||||||
|
db_session=db_session, acquisition_data=acquisition_cost_data, acquisition_data_in=acquisition_cost_data_in
|
||||||
|
),
|
||||||
|
message="Data updated successfully",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/{acquisition_cost_data_id}", response_model=StandardResponse[AcquisitionCostDataRead])
|
||||||
|
async def delete_acquisition_cost_data(db_session: DbSession, acquisition_cost_data_id: str):
|
||||||
|
acquisition_cost_data = await get(db_session=db_session, acquisition_cost_data_id=acquisition_cost_data_id)
|
||||||
|
|
||||||
|
if not acquisition_cost_data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=[{"msg": "A data with this id does not exist."}],
|
||||||
|
)
|
||||||
|
|
||||||
|
await delete(db_session=db_session, acquisition_cost_data_id=acquisition_cost_data_id)
|
||||||
|
|
||||||
|
return StandardResponse(message="Data deleted successfully", data=acquisition_cost_data)
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from typing import List, Optional
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
from pydantic import Field
|
||||||
|
from src.models import DefaultBase, Pagination
|
||||||
|
|
||||||
|
|
||||||
|
class AcquisitionCostDataBase(DefaultBase):
|
||||||
|
category_no: Optional[str] = Field(None, nullable=True)
|
||||||
|
name: Optional[str] = Field(None, nullable=True)
|
||||||
|
cost_unit_3_n_4: Optional[float] = Field(None, nullable=True)
|
||||||
|
cost_unit_3: Optional[float] = Field(None, nullable=True)
|
||||||
|
created_at: Optional[datetime] = Field(None, nullable=True)
|
||||||
|
updated_at: Optional[datetime] = Field(None, nullable=True)
|
||||||
|
created_by: Optional[str] = Field(None, nullable=True)
|
||||||
|
updated_by: Optional[str] = Field(None, nullable=True)
|
||||||
|
|
||||||
|
|
||||||
|
class AcquisitionCostDataCreate(AcquisitionCostDataBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AcquisitionCostDataUpdate(AcquisitionCostDataBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AcquisitionCostDataRead(AcquisitionCostDataBase):
|
||||||
|
id: UUID
|
||||||
|
|
||||||
|
|
||||||
|
class AcquisitionCostDataPagination(Pagination):
|
||||||
|
items: List[AcquisitionCostDataRead] = []
|
||||||
@ -0,0 +1,119 @@
|
|||||||
|
from sqlalchemy import Select, Delete, cast, String
|
||||||
|
from src.acquisition_cost.model import AcquisitionData
|
||||||
|
from src.acquisition_cost.schema import AcquisitionCostDataCreate, AcquisitionCostDataUpdate
|
||||||
|
from src.database.service import search_filter_sort_paginate
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from src.database.core import DbSession
|
||||||
|
from src.auth.service import CurrentUser
|
||||||
|
from src.equipment.model import Equipment
|
||||||
|
|
||||||
|
|
||||||
|
def _calculate_cost_unit_3(cost_unit_3_n_4: Optional[float]) -> Optional[float]:
|
||||||
|
"""Derive cost_unit_3 by splitting the combined unit 3&4 cost evenly."""
|
||||||
|
if cost_unit_3_n_4 is None:
|
||||||
|
return None
|
||||||
|
return cost_unit_3_n_4 / 2
|
||||||
|
|
||||||
|
|
||||||
|
async def _sync_equipment_acquisition_costs(
|
||||||
|
*, db_session: DbSession, category_no: Optional[str], cost_unit_3: Optional[float]
|
||||||
|
):
|
||||||
|
"""Keep equipment acquisition cost in sync for the affected category."""
|
||||||
|
if not category_no or cost_unit_3 is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
equipment_query = Select(Equipment).filter(Equipment.category_no == category_no)
|
||||||
|
equipment_result = await db_session.execute(equipment_query)
|
||||||
|
equipments = equipment_result.scalars().all()
|
||||||
|
|
||||||
|
for equipment in equipments:
|
||||||
|
if equipment.proportion is None:
|
||||||
|
continue
|
||||||
|
equipment.acquisition_cost = (equipment.proportion * 0.01) * cost_unit_3
|
||||||
|
|
||||||
|
|
||||||
|
async def get(*, db_session: DbSession, acquisition_cost_data_id: str) -> Optional[AcquisitionData]:
|
||||||
|
"""Returns a document based on the given document id."""
|
||||||
|
query = Select(AcquisitionData).filter(AcquisitionData.id == acquisition_cost_data_id)
|
||||||
|
result = await db_session.execute(query)
|
||||||
|
return result.scalars().one_or_none()
|
||||||
|
|
||||||
|
|
||||||
|
async def get_all(
|
||||||
|
*,
|
||||||
|
db_session: DbSession,
|
||||||
|
items_per_page: Optional[int],
|
||||||
|
search: Optional[str] = None,
|
||||||
|
common,
|
||||||
|
):
|
||||||
|
"""Returns all documents."""
|
||||||
|
query = Select(AcquisitionData).order_by(AcquisitionData.name.asc())
|
||||||
|
if search:
|
||||||
|
query = query.filter(cast(AcquisitionData.name, String).ilike(f"%{search}%"))
|
||||||
|
|
||||||
|
common["items_per_page"] = items_per_page
|
||||||
|
results = await search_filter_sort_paginate(model=query, **common)
|
||||||
|
|
||||||
|
# return results.scalars().all()
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
async def create(*, db_session: DbSession, acquisition_data_in: AcquisitionCostDataCreate):
|
||||||
|
"""Creates a new document."""
|
||||||
|
data = acquisition_data_in.model_dump()
|
||||||
|
cost_unit_changed = False
|
||||||
|
|
||||||
|
if data.get("cost_unit_3_n_4") is not None:
|
||||||
|
derived_cost_unit = _calculate_cost_unit_3(data["cost_unit_3_n_4"])
|
||||||
|
data["cost_unit_3"] = derived_cost_unit
|
||||||
|
cost_unit_changed = derived_cost_unit is not None
|
||||||
|
|
||||||
|
acquisition_data = AcquisitionData(**data)
|
||||||
|
db_session.add(acquisition_data)
|
||||||
|
|
||||||
|
if cost_unit_changed:
|
||||||
|
await _sync_equipment_acquisition_costs(
|
||||||
|
db_session=db_session,
|
||||||
|
category_no=acquisition_data.category_no,
|
||||||
|
cost_unit_3=acquisition_data.cost_unit_3,
|
||||||
|
)
|
||||||
|
|
||||||
|
await db_session.commit()
|
||||||
|
return acquisition_data
|
||||||
|
|
||||||
|
|
||||||
|
async def update(
|
||||||
|
*, db_session: DbSession, acquisition_data: AcquisitionData, acquisition_data_in: AcquisitionCostDataUpdate
|
||||||
|
):
|
||||||
|
"""Updates a document."""
|
||||||
|
data = acquisition_data_in.model_dump()
|
||||||
|
update_data = acquisition_data_in.model_dump(exclude_defaults=True)
|
||||||
|
|
||||||
|
cost_unit_changed = False
|
||||||
|
if "cost_unit_3_n_4" in update_data:
|
||||||
|
derived_cost_unit = _calculate_cost_unit_3(update_data.get("cost_unit_3_n_4"))
|
||||||
|
update_data["cost_unit_3"] = derived_cost_unit
|
||||||
|
cost_unit_changed = derived_cost_unit is not None
|
||||||
|
|
||||||
|
for field in data:
|
||||||
|
if field in update_data:
|
||||||
|
setattr(acquisition_data, field, update_data[field])
|
||||||
|
|
||||||
|
if cost_unit_changed:
|
||||||
|
await _sync_equipment_acquisition_costs(
|
||||||
|
db_session=db_session,
|
||||||
|
category_no=acquisition_data.category_no,
|
||||||
|
cost_unit_3=acquisition_data.cost_unit_3,
|
||||||
|
)
|
||||||
|
|
||||||
|
await db_session.commit()
|
||||||
|
|
||||||
|
return acquisition_data
|
||||||
|
|
||||||
|
|
||||||
|
async def delete(*, db_session: DbSession, acquisition_cost_data_id: str):
|
||||||
|
"""Deletes a document."""
|
||||||
|
query = Delete(AcquisitionData).where(AcquisitionData.id == acquisition_cost_data_id)
|
||||||
|
await db_session.execute(query)
|
||||||
|
await db_session.commit()
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue