From aed6a5cffd95557c3211902945ba88537c8a9123 Mon Sep 17 00:00:00 2001 From: MrWaradana Date: Thu, 16 Jan 2025 09:55:43 +0700 Subject: [PATCH] feat: plant admin data APIs --- src/__pycache__/api.cpython-311.pyc | Bin 2588 -> 2994 bytes src/api.py | 13 +- src/plant_masterdata/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 169 bytes .../__pycache__/model.cpython-311.pyc | Bin 0 -> 2644 bytes .../__pycache__/router.cpython-311.pyc | Bin 0 -> 4679 bytes .../__pycache__/schema.cpython-311.pyc | Bin 0 -> 7381 bytes .../__pycache__/service.cpython-311.pyc | Bin 0 -> 3743 bytes src/plant_masterdata/model.py | 37 ++++++ src/plant_masterdata/router.py | 100 +++++++++++++++ src/plant_masterdata/schema.py | 85 +++++++++++++ src/plant_masterdata/service.py | 68 ++++++++++ src/plant_transaction_data/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 161 bytes .../__pycache__/model.cpython-311.pyc | Bin 0 -> 4248 bytes .../__pycache__/router.cpython-311.pyc | Bin 0 -> 4911 bytes .../__pycache__/schema.cpython-311.pyc | Bin 0 -> 7880 bytes .../__pycache__/service.cpython-311.pyc | Bin 0 -> 4014 bytes src/plant_transaction_data/model.py | 61 +++++++++ src/plant_transaction_data/router.py | 120 ++++++++++++++++++ src/plant_transaction_data/schema.py | 83 ++++++++++++ src/plant_transaction_data/service.py | 74 +++++++++++ 22 files changed, 640 insertions(+), 1 deletion(-) create mode 100644 src/plant_masterdata/__init__.py create mode 100644 src/plant_masterdata/__pycache__/__init__.cpython-311.pyc create mode 100644 src/plant_masterdata/__pycache__/model.cpython-311.pyc create mode 100644 src/plant_masterdata/__pycache__/router.cpython-311.pyc create mode 100644 src/plant_masterdata/__pycache__/schema.cpython-311.pyc create mode 100644 src/plant_masterdata/__pycache__/service.cpython-311.pyc create mode 100644 src/plant_masterdata/model.py create mode 100644 src/plant_masterdata/router.py create mode 100644 src/plant_masterdata/schema.py create mode 100644 src/plant_masterdata/service.py create mode 100644 src/plant_transaction_data/__init__.py create mode 100644 src/plant_transaction_data/__pycache__/__init__.cpython-311.pyc create mode 100644 src/plant_transaction_data/__pycache__/model.cpython-311.pyc create mode 100644 src/plant_transaction_data/__pycache__/router.cpython-311.pyc create mode 100644 src/plant_transaction_data/__pycache__/schema.cpython-311.pyc create mode 100644 src/plant_transaction_data/__pycache__/service.cpython-311.pyc create mode 100644 src/plant_transaction_data/model.py create mode 100644 src/plant_transaction_data/router.py create mode 100644 src/plant_transaction_data/schema.py create mode 100644 src/plant_transaction_data/service.py diff --git a/src/__pycache__/api.cpython-311.pyc b/src/__pycache__/api.cpython-311.pyc index bae70b2f41b0ba3752dbe54cdd8423aeaecc92d3..60daeeea58486b092b9a5bf793dbf7197a3483ea 100644 GIT binary patch delta 681 zcmbOuvPqn8IWI340}!lhZcqQgK9Ns?@!CZ7O0g7%6t*1ET;3=#Mg}lj9LScKI8T;Q za^fCodnqP{RF+is6z){1Oh%j}&m7h@yvvvv7*+!@1Vl-vN-vO^EXHWfC_6cb(VA5* zRc?X&DhfJNdFB30s0MI}XvdBuszC7Jnox?rVZ5T!`s@gVWZCs~6T z6(-BFP4<*7E=txzH&CxAzZ7U&kt)!Qw-ga7(9MCVQv<4-yq@g^mo1P1@>=oR$qU)r zl$tn(n2X?Sh7LZaP@c~TmASo4@5wk&h1MlR0oQjjTaAp7i-=C@V delta 375 zcmdlaK1YOaIWI340}w2o5&}@7&TG7vYv^-ogsz2g&~C_m2(+01H)<{hJYwh zupB2)jtfIhjENzYC6zseJ5?-`5huwrhjk6_GA5v@KnyiiJXL&w1dPWp*^7y5vLmAg zqvYf)Mr&57RH+5hlO36aC+}sHVTQ5aBiQl`sUj&7DU#`oYeZ3<%g6xJ3sfVNB9$VI zRgE~rd`Y0{WsE?F0WkzHGNi}^Gib_gW@1)gWE7aJ%yOPlWb$X0e~c=VKe2{Pp2HTz yC^Pvz+vLe-*q?J*0yTlO78g(6%h9$uoil}zgF#@1%!=q0zLQsTDNgp{&Hw;v(oLZN diff --git a/src/api.py b/src/api.py index 97c94ce..f49e7e4 100644 --- a/src/api.py +++ b/src/api.py @@ -8,6 +8,8 @@ from src.auth.service import JWTBearer from src.masterdata.router import router as masterdata_router +from src.plant_masterdata.router import router as plant_masterdata +from src.plant_transaction_data.router import router as plant_transaction_data from src.equipment.router import router as equipment_router from src.yeardata.router import router as yeardata_router from src.equipment_master.router import router as equipment_master_router @@ -48,7 +50,16 @@ authenticated_api_router.include_router( ) authenticated_api_router.include_router( -equipment_router, prefix="/equipment", tags=["equipment"] + plant_masterdata, prefix="/plant-masterdata", tags=["plant_masterdata"] +) +authenticated_api_router.include_router( + plant_transaction_data, + prefix="/plant-transaction-data", + tags=["plant_transaction_data"], +) + +authenticated_api_router.include_router( + equipment_router, prefix="/equipment", tags=["equipment"] ) authenticated_api_router.include_router( diff --git a/src/plant_masterdata/__init__.py b/src/plant_masterdata/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/plant_masterdata/__pycache__/__init__.cpython-311.pyc b/src/plant_masterdata/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4cf1c8e05a002e6b8b5f691f97174dabf42f1867 GIT binary patch literal 169 zcmZ3^%ge<81ojW((?RrO5CH>>P{wCAAY(d13PUi1CZpdK literal 0 HcmV?d00001 diff --git a/src/plant_masterdata/__pycache__/model.cpython-311.pyc b/src/plant_masterdata/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ef43f0cbbc4faf94e32c3b1535c99ee718997c0 GIT binary patch literal 2644 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 RHoA(FAtMag7~=22zX4d__V54z literal 0 HcmV?d00001 diff --git a/src/plant_masterdata/__pycache__/service.cpython-311.pyc b/src/plant_masterdata/__pycache__/service.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6dc83ec7dd9d5afa0f33eeaa73b1ecd187ee3967 GIT binary patch literal 3743 zcmcInO>7&-6`tk(@Mo7Ye-M584w+PgQc+^OXavnrF=U2|VJ0UT5mPS8j1L-$87)Q`A2PzCqQeGu6!sI<9bvd`xD2cPT+(dW0FaqWJr&HC>6(@$MaLS3EB)liA$$<+!j zRY|D=bygrzI&F+j6W^_4vPqR<)eYOC7mBSpAzOj7m&GhomZWLDU z;){l+sjC*zR%;YVrG3?|g4*wuHJq<)di*-J3AGOeie&)#7yO#&KOq!N{{Bi^$+${p zSIKph+~-%^^Ov8dI_C>*<+iKbZZ36`somskCpp`~?c@bFdBKSu&duvxIsV&)PZrwp zlq*l|%4a+B*|wZ@<*XxQpTT~p0EmXPkBG+{H<+44>Wk4zXa!OaKH(avt=NANe}8` zLny=8XWVZ%fUGovtk@6%YN4&k5!4K01Sl*2oSP*St)9RxX_~U4S=F&o_zTKP`%ois zI+U=hwrZ4Wr201ap^{d$Y)>p3<##Zlb^#L@$mlZc!aYf=nr5{^CTY(}AQs(?f-RjU zuK?=>0X8MoFvu*lCaAc%D>D!)@cExD;HyQ!s4YU!!@w^yH< z^w&-;yQ$@NY{iYO?1cjT$IF#TmR?)sAKCJuoMqn_YM z@~?W(fx(;rpn=~yIdJ&Y@l^18BRu2_8Y#Ue&>iQ*D;*EI&~5 zt03z|_Pv2ck26xNq_LnvEJ3p1`T;|Md|$oOt#suP)NM^bJiV_!RNL0CfebX=A4AHi zT{+W{Gi`a+m1moay~LT_M6Q#_Jy~=Txpv~3o4D4z*^5t5+n#3x3|Edlxar7e`iKk9 zf2kxNywMU{AAIqB_v{bb%ABjrIm+CBdoO^B-aaZcI2B9uifIJ659Ou3|M3d?|35yM zy}!WY!*B081xH{jIe0Moz)=8|(_0wWy7=A(CYU5>N0Jf-iakT8j|S$#4_P>b33!H* zAHeWcDAp#BJquS7`yoHuQL>-E=H@OvjdpUk+DgGy3J~(C_NF_L=|8NrBN;c6afD;? zi&*}^9Wcw!zT!o!cMa9hHn6!l2w(Igy>WQH*;qc4*V94h|fcp!0*-#yg;r(lLij!W1xMW?1!JM?d1ObA4Xn z5`8ozYz1g^^WR}3-T4Jp_r&ndYp!^@FAgR5=k#YpZn72bBdDCY+pIoJVsUP=7dzD# kq3%m4p6&-J7eeFNewcE|PtFP43|$hcCmB|KEn%wqAFkL`jQ{`u literal 0 HcmV?d00001 diff --git a/src/plant_masterdata/model.py b/src/plant_masterdata/model.py new file mode 100644 index 0000000..9e809f1 --- /dev/null +++ b/src/plant_masterdata/model.py @@ -0,0 +1,37 @@ +from sqlalchemy import Column, Float, String, UUID +from src.database.core import Base +from src.models import DefaultMixin, IdentityMixin + + +class PlantMasterData(Base, DefaultMixin, IdentityMixin): + __tablename__ = "lcc_plant_ms_data" + + id = Column(UUID(as_uuid=True), primary_key=True, index=True) + discount_rate = Column(Float, nullable=True) + total_project_cost = Column(Float, nullable=True) + umur_teknis = Column(Float, nullable=True) + interest_rate = Column(Float, nullable=True) + loan_portion = Column(Float, nullable=True) + equity_portion = Column(Float, nullable=True) + loan = Column(Float, nullable=True) + loan_tenor = Column(Float, nullable=True) + principal_interest_payment = Column(Float, nullable=True) + corporate_tax_rate = Column(Float, nullable=True) + wacc_on_project = Column(Float, nullable=True) + wacc_on_equity = Column(Float, nullable=True) + equity = Column(Float, nullable=True) + daya_mampu_netto = Column(Float, nullable=True) + auxiliary = Column(Float, nullable=True) + susut_trafo = Column(Float, nullable=True) + sfc = Column(Float, nullable=True) + electricity_price_a = Column(Float, nullable=True) + electricity_price_b = Column(Float, nullable=True) + electricity_price_c = Column(Float, nullable=True) + electricity_price_d = Column(Float, nullable=True) + harga_bahan_bakar = Column(Float, nullable=True) + calc_on_project_irr = Column(Float, nullable=True) + calc_on_project_npv = Column(Float, nullable=True) + calc_on_equity_irr = Column(Float, nullable=True) + calc_on_equity_npv = Column(Float, nullable=True) + calc_roa_all = Column(Float, nullable=True) + calc_roa_current = Column(Float, nullable=True) diff --git a/src/plant_masterdata/router.py b/src/plant_masterdata/router.py new file mode 100644 index 0000000..aa42c61 --- /dev/null +++ b/src/plant_masterdata/router.py @@ -0,0 +1,100 @@ +from typing import Optional +from fastapi import APIRouter, HTTPException, status, Query + +from .model import PlantMasterData +from .schema import ( + PlantMasterDataPagination, + PlantMasterDataRead, + PlantMasterDataCreate, + PlantMasterDataUpdate, +) +from .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[PlantMasterDataPagination]) +async def get_masterdatas( + db_session: DbSession, + common: CommonParameters, + items_per_page: Optional[int] = Query(5), + search: Optional[str] = Query(None), +): + """Get all documents.""" + # return + master_datas = await get_all( + db_session=db_session, + items_per_page=items_per_page, + search=search, + common=common, + ) + return StandardResponse( + data=master_datas, + message="Data retrieved successfully", + ) + + +@router.get("/{masterdata_id}", response_model=StandardResponse[PlantMasterDataRead]) +async def get_masterdata(db_session: DbSession, masterdata_id: str): + masterdata = await get(db_session=db_session, masterdata_id=masterdata_id) + if not masterdata: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="A data with this id does not exist.", + ) + + return StandardResponse(data=masterdata, message="Data retrieved successfully") + + +@router.post("", response_model=StandardResponse[PlantMasterDataRead]) +async def create_masterdata( + db_session: DbSession, masterdata_in: PlantMasterDataCreate, current_user: CurrentUser +): + masterdata_in.created_by = current_user.name + masterdata = await create(db_session=db_session, masterdata_in=masterdata_in) + + return StandardResponse(data=masterdata, message="Data created successfully") + + +@router.put("/{masterdata_id}", response_model=StandardResponse[PlantMasterDataRead]) +async def update_masterdata( + db_session: DbSession, + masterdata_id: str, + masterdata_in: PlantMasterDataUpdate, + current_user: CurrentUser, +): + masterdata = await get(db_session=db_session, masterdata_id=masterdata_id) + + if not masterdata: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="A data with this id does not exist.", + ) + masterdata_in.updated_by = current_user.name + + return StandardResponse( + data=await update( + db_session=db_session, masterdata=masterdata, masterdata_in=masterdata_in + ), + message="Data updated successfully", + ) + + +@router.delete("/{masterdata_id}", response_model=StandardResponse[PlantMasterDataRead]) +async def delete_masterdata(db_session: DbSession, masterdata_id: str): + masterdata = await get(db_session=db_session, masterdata_id=masterdata_id) + + if not masterdata: + 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, masterdata_id=masterdata_id) + + return StandardResponse(message="Data deleted successfully", data=masterdata) diff --git a/src/plant_masterdata/schema.py b/src/plant_masterdata/schema.py new file mode 100644 index 0000000..c164e76 --- /dev/null +++ b/src/plant_masterdata/schema.py @@ -0,0 +1,85 @@ +from datetime import datetime +from typing import List, Optional +from uuid import UUID + +from pydantic import Field +from src.models import DefaultBase, Pagination +from src.auth.service import CurrentUser + + +class PlantMasterdataBase(DefaultBase): + discount_rate: Optional[float] = Field(None, nullable=True) + total_project_cost: Optional[float] = Field(None, nullable=True) + umur_teknis: Optional[float] = Field(None, nullable=True) + interest_rate: Optional[float] = Field(None, nullable=True) + loan_portion: Optional[float] = Field(None, nullable=True) + equity_portion: Optional[float] = Field(None, nullable=True) + loan: Optional[float] = Field(None, nullable=True) + loan_tenor: Optional[float] = Field(None, nullable=True) + principal_interest_payment: Optional[float] = Field(None, nullable=True) + corporate_tax_rate: Optional[float] = Field(None, nullable=True) + wacc_on_project: Optional[float] = Field(None, nullable=True) + wacc_on_equity: Optional[float] = Field(None, nullable=True) + equity: Optional[float] = Field(None, nullable=True) + daya_mampu_netto: Optional[float] = Field(None, nullable=True) + auxiliary: Optional[float] = Field(None, nullable=True) + susut_trafo: Optional[float] = Field(None, nullable=True) + sfc: Optional[float] = Field(None, nullable=True) + electricity_price_a: Optional[float] = Field(None, nullable=True) + electricity_price_b: Optional[float] = Field(None, nullable=True) + electricity_price_c: Optional[float] = Field(None, nullable=True) + electricity_price_d: Optional[float] = Field(None, nullable=True) + harga_bahan_bakar: Optional[float] = Field(None, nullable=True) + calc_on_project_irr: Optional[float] = Field(None, nullable=True) + calc_on_project_npv: Optional[float] = Field(None, nullable=True) + calc_on_equity_irr: Optional[float] = Field(None, nullable=True) + calc_on_equity_npv: Optional[float] = Field(None, nullable=True) + calc_roa_all: Optional[float] = Field(None, nullable=True) + calc_roa_current: 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 PlantMasterDataCreate(PlantMasterdataBase): + discount_rate: float = Field(..., nullable=True) + total_project_cost: float = Field(..., nullable=True) + umur_teknis: float = Field(..., nullable=True) + interest_rate: float = Field(..., nullable=True) + loan_portion: float = Field(..., nullable=True) + equity_portion: float = Field(..., nullable=True) + loan: float = Field(..., nullable=True) + loan_tenor: float = Field(..., nullable=True) + principal_interest_payment: float = Field(..., nullable=True) + corporate_tax_rate: float = Field(..., nullable=True) + wacc_on_project: float = Field(..., nullable=True) + wacc_on_equity: float = Field(..., nullable=True) + equity: float = Field(..., nullable=True) + daya_mampu_netto: float = Field(..., nullable=True) + auxiliary: float = Field(..., nullable=True) + susut_trafo: float = Field(..., nullable=True) + sfc: float = Field(..., nullable=True) + electricity_price_a: float = Field(..., nullable=True) + electricity_price_b: float = Field(..., nullable=True) + electricity_price_c: float = Field(..., nullable=True) + electricity_price_d: float = Field(..., nullable=True) + harga_bahan_bakar: float = Field(..., nullable=True) + calc_on_project_irr: float = Field(..., nullable=True) + calc_on_project_npv: float = Field(..., nullable=True) + calc_on_equity_irr: float = Field(..., nullable=True) + calc_on_equity_npv: float = Field(..., nullable=True) + calc_roa_all: float = Field(..., nullable=True) + calc_roa_current: float = Field(..., nullable=True) + + +class PlantMasterDataUpdate(PlantMasterdataBase): + pass + + +class PlantMasterDataRead(PlantMasterdataBase): + id: UUID + + +class PlantMasterDataPagination(Pagination): + items: List[PlantMasterDataRead] = [] diff --git a/src/plant_masterdata/service.py b/src/plant_masterdata/service.py new file mode 100644 index 0000000..ba7b671 --- /dev/null +++ b/src/plant_masterdata/service.py @@ -0,0 +1,68 @@ +from sqlalchemy import Select, Delete + +from src.database.service import search_filter_sort_paginate +from .model import PlantMasterData +from .schema import PlantMasterDataCreate, PlantMasterDataUpdate +from typing import Optional + +from src.database.core import DbSession +from src.auth.service import CurrentUser + + +async def get( + *, db_session: DbSession, masterdata_id: str +) -> Optional[PlantMasterData]: + """Returns a document based on the given document id.""" + query = Select(PlantMasterData).filter(PlantMasterData.id == masterdata_id) + result = await db_session.execute(query) + return result.scalars().one_or_none() + + +async def get_all( + *, db_session: DbSession, items_per_page: int, search: str = None, common +) -> list[PlantMasterData]: + """Returns all documents.""" + query = Select(PlantMasterData) + + if search: + query = query.filter(PlantMasterData.total_project_cost.ilike(f"%{search}%")) + common["page"] = 1 + + common["items_per_page"] = items_per_page + result = await search_filter_sort_paginate(model=query, **common) + return result + + +async def create(*, db_session: DbSession, masterdata_in: PlantMasterDataCreate): + """Creates a new document.""" + masterdata = PlantMasterData(**masterdata_in.model_dump()) + db_session.add(masterdata) + await db_session.commit() + return masterdata + + +async def update( + *, + db_session: DbSession, + masterdata: PlantMasterData, + masterdata_in: PlantMasterDataUpdate, +): + """Updates a document.""" + data = masterdata_in.model_dump() + + update_data = masterdata_in.model_dump(exclude_defaults=True) + + for field in data: + if field in update_data: + setattr(masterdata, field, update_data[field]) + + await db_session.commit() + + return masterdata + + +async def delete(*, db_session: DbSession, masterdata_id: str): + """Deletes a document.""" + query = Delete(PlantMasterData).where(PlantMasterData.id == masterdata_id) + await db_session.execute(query) + await db_session.commit() diff --git a/src/plant_transaction_data/__init__.py b/src/plant_transaction_data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/plant_transaction_data/__pycache__/__init__.cpython-311.pyc b/src/plant_transaction_data/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45fd3a1a7436eb586cda32d1ab207254788973a8 GIT binary patch literal 161 zcmZ3^%ge<81P%}5(?RrO5CH>>P{wCAAY(d13PUi1CZpdGfy4)9Mn=XD3^1aI87Kw-b%rDM literal 0 HcmV?d00001 diff --git a/src/plant_transaction_data/__pycache__/model.cpython-311.pyc b/src/plant_transaction_data/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46923ac7e214c11001aaaf4b4a0d2fa040f44af5 GIT binary patch literal 4248 zcmbuC&u`mC7RM=xk}O$nBwIiH+pZI!Y)ZE z{Nct6EFdfvXwb{*Rsws`DOJ%PbnKro1b7hURA5hgOOZYGw2zeJBrOM6pfoAJd7tmh zJiehGM_-SOBsn<#`S&j#|2WKX|MnV#Bi=V&{TYm}IEj-&3a5t3AvIhMtC4a<<;%Pp zEk{Eh3o9`-UXJ^AL>W>O<%F6nCqrDA`;e3Pe{fP1$8iEDUqm_XTex~hd02{l%9Y~( z@tUP5jeSs4ELEe?W2GjTG=8F)_%YUL>{C;hwa1h{KR-Dtg(!b07`POssUut!EX8~% zKa({&aw1{Pl+7!@DfZ{^{|#n*^(9zeahNNIB(5BmLgh%9!#rG3Dg0gJMF^sUt9M9Y z@bNDq;Df7olw+PA$EE0Zu@_+=aP`R$lO&iV>62lY=jWrPm}G=W-eHm(Op<1j43ms9 z$rzJlnIy*~c_t|^$vBftFv%p7Ofktclgu#5ER)PJ$vl(1%Ond-a+67JG07s66q)2b zCixAMl$hkVOtQoz%S^JuB&$ra#w53ygpixtJVreuX8wdh~o-|_Mr#kPkF%6qY6zYNqZyi(xUejp=3sst~ z>oB2zL#U!#X6-ExbOTQcYgm7Lg$zN#22EEjtRS(b8J1f25zQme^k?`8Ayf($x zrbI^uTC-+Ch{-{-eo03MwxDSczWi4#(NVExm`Ff6h9rwvh4&^+^nG>p8Vll6OEzRb zni~TwYo7_KpwY3uL&9|(i?ZOWQhjGHjO!sUX{Ha}2x8cGiO9S0{_L>m1F4AKkS2X; zMM5=|rU!OiMOsZ$WqM63kca{8Ct}d_5;3sf7DZ7ZNGG}!6br-c35tl`N=43h$*_e1t%>Twm7nIk?}o=$6XiPeANbRQ z5nx@^ngt7z@;vJZS7cKX=y<;+=o)N=Pz6_OI);b$8KlnFd1m2lkx+%nea&zWXtg@* ztNfuh&~<39Wpkcv166g5;kh=RpsG^)9Mv=g8Tbr~ChZF(*$}-Lv4pB(^-aNqH^L_9 z2loe$SpUvvd+3*gV|dEUE86G39J|NA;a`y1B z7Ztn$B}2F{bn#+PH?B*HUqCLP0$^peex;{i6#pXzhEaiUa^w21n|-hG@Q1{W=lLez ztxB~wllfyPHq#v&=clbS&}R| z$)cMqg0L{tytHv!B83g7u;CUq2%imhj!iVT?Zx&jGPdT7t+``sjR(O(KSrx%lJv5Z zUUt*V5aX}$Wha}*_Evk7WN$m!+iv!D<6$>bXy)x`nUB-3}D>AUXqUBXXvXKvb$ zTK79gWageTbI+Z*NBGI$r!i<{<`(VC7Vb!7ZqJ$9bLaL5KOLCy*;{tCb>2B6v%Ajh zt~{8@gAMdOMH| z)Us7?>r;UryQ?BpdwmEXbOyg)%nUu@sl6ZZy`uJ!XZbTd1nZ}v{obzU_xdN$^nTYG z|ALQ~kx(eq<@U(`cXqi2^7h%~)=AL$GPV;s487!nKkd!dbo*~V`t-jHjUW8~00>aW A>;M1& literal 0 HcmV?d00001 diff --git a/src/plant_transaction_data/__pycache__/router.cpython-311.pyc b/src/plant_transaction_data/__pycache__/router.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7136018880a1f0529460ff4744ffdecd252014f GIT binary patch literal 4911 zcmbtX-ER}w6~FW8@5G6dII)x9ET7pfUkgIJ3#DZVECJSdA&_c>WDTC1#K>b?cgEWd z>y;3Ty0qGdeWI0Q33L-Ck>0i)?eX0h@57tOXk*Z4NZ4mInQ_q?4x6Klz*E8pS zoqO(?bAIRC>%T=JK>{Ux_q)}d!-V`BJIxYmG+zFLC*((>5sfPlol`gt+kAo71x3(B zMbsrl(q%=4aX}LcKHabQ-L_N+=s_i@hm?>WR>FEjiMZo(VMrfVhV`ft)kl;OeN-9M zV@k}G>nn`uKXW<^B=72!*lcTC)K`nsh%4Q%CHkcA2I;Y;#LjxF(!m*da0OEnX1DGGwh^6RhC=JuH*~Q&l)9WX3L(k z6h1PraN`O!4A2`oq0<${XwkfCPzK%T6;my0D$_1gqg*N))JC%mu|_Yemtf!L5?Cv3 z2elhn!xIGRxk}hWd6Vi!whY_Cjug!7s*)4YIgKJi{VlvN6(AP~2N}m~#ULS7Qst{c zmD}JR!m1~&mES@p`dYX~eiVKuej}PfLmE_7Q4==A?)U~oNVj%`xcq_ud4xx<+O z*s@Woye4i)-5h`=IsKUTyt)q<-|Re9zAq4o4&M^J$vbDdcj51W1+pb z9qqNGfgcB8V!Khs*dRQx4`J$kc#S^*X~4lxX6FD7){(Q0z|Vp^fxJTE5PtIQ#1h9G z8Ia%*Q3^gANCNO#l45#YTw<>m-4HFswS&%>fE79lI!!3InA#yX3_LN8A=5)VpZN0A%` zV&Lb2HyiGZdn@}QoP7jrCy-wQ;(62wlRY2Sb|16Ecujoo+04%EdH1y+d}hrZwvJ!3 zLd#D>%eBz5B`&+Z>PqBjE;nRr(AY-EidAvDAzKx0w!*v0XIpMIBcMv7m>m~GaK2dO z;gA3zJ!yfdGl6K*hTIqSzBI$AVZT7~0g(AdB%-HS2L!xRc@PBrJweV6;?iS4>|kRR zq5=;NHUgx1dSIS$cj$lyekMYri4AXkKQ@j7-+6eAe*tMk`{?$g9r3WGXm|Xb0Q^rV z`7Ab7kI&U-_SaKK9G^G_=>fIO}L$8r+ynA0a(jX`8 z1aS=i6U@s40XK^CF31i+tNX}^doufRbP`zCkp1sK{{K^B0FK5J*7PZB>{Bat`Yp#t zXypER>%=81n0Xq^)PfmH9Pj|ttX;pd&h{s)`MtJmu9x%0Rfb`2`&Lvql*@UB>7#x0 zGR$SRl~%7Vy;K4W1dm|tuk97$j1bJVl6d+~F#I>s+UOWR{`cRPSr zgd3_s4>Z|hI6sE-BVF^k5~B=nYjzaJ)rz^+S~G#eK^%6KGh8RyvUdTrg?!Pp1;b?S zh0i_aZLwT}0X!dUpfN;oK!@tONq{`k4$!=9f+#(%i-{palk?y468;lJQ; z10K2dH8iM;)7Ji9S|_j7_AfiY5{9c3&%;%U=N&oB$&WsE2vk2EajQ0Y;p<{^W>H@9 zPV(MmD|N^^yjV+}zny%_U8r#v96reXhI6&X#^%%!N5Tf^9h-H0Zj-brDtZwVZLD(= zThVl~VHT)2r@$;wgZRWz$A>LHZWO>4X_8L;aqJlGGIM99*B-;2_K1MikMa(|`lp;% PchXLw$kRFJ#>oEw3$SwC literal 0 HcmV?d00001 diff --git a/src/plant_transaction_data/__pycache__/schema.cpython-311.pyc b/src/plant_transaction_data/__pycache__/schema.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9401704dd3174a12554336653c50351a31f86824 GIT binary patch literal 7880 zcmchcOH3O{8pj(bgE0_D0tt^KJPnvP!9aMw%sWfS4D3d1q*miD63_aTb~_VhwHmK> zrOhD+4oKqz2OmbW9_=1{LU|5;KiXytchlJqzDWRHU? z%V!5)C9S&RtG0X&@KtfX8p~G=z8cPV!}8q#UoCZ9X|quP{zjtGL5V6IlII_Un}J6IlfNFH*ow-A%BPCZwdLk9DiHLH*$QvkZCXSzbE9|IsU$o@8I|cLcWvZTZMcV$F~W2C`EHKy z5b`}7-znsKIlfECyExt{!eygvO{J_1)rGs~!QWY&eXkQ%jaA|Gl|JycKwmqAT64N~pJ zu^dtSG-B2rMX6u*hJul3z)JMZN{zmz!6=oLOY`v3^j?~(S(9h=kPgu~@~7d~=B>P~ z1cMN{?<=aBx4fZO!CQO5{bGnf|wLq$P&70YCn9L)eF8f1~ zh*_Vl(rCn|!f?v36@QdM%!=PD7Ys#%Rpkrn6j)sjE63I_-?6I0nlI?}h2i>qeO_adacJHxgp?z=xy4jv9l=mo z(X&mB$sa?z#99#>laDk?VO>XF%18dtmvSg5!w7sqy}FqLRA0o4F;Z1N@*aH(G+_&F z;Pd^1C6?>?gRF~hoWd&8kIkH)Z#(CAcr^-}VpWDNIHFFur|AJWtqhi*|xcJ~n!j&J9W$gyKY%my# zuGJ!2hXVhgkhEJUw^8a*8c^<_+(l_b!55g;jM9Q~59L0}1C&;jHk5Xh4wO!mE)*w9 zH%bpmFNzDL52YVv0A&zm2xS;$1Z5QEA<7tv8)Y120%a2A5y}+GG|CJLzA?2qlzEf| zltq*!lx36^6#QR_=0RBnfj6SAX=`A8FMR-&eqQuUKi_@4)8^S+-`rbz+_v|d&7J3m zbkOhhD$gUD_c^?Kg1W3;?Q*e1-(tt7)KGv$B8A~d`h}^SFQtXqTOml18nIK7> zHM@;wce>df^Stdn8GAR#h#QJQ+?kG^gfmG}I_sD09!>0}JgjxfXq`&8PQ^CgzKNH; z`vW6WPz*AaX?hTEi0es}HH{ffW9g=`*vi|+lg@Yd85x6Okg-hvNOC+?e?eIPs?ooi z?q6l(ZoDz!JZohH>{WxTUK0#9<9r85KA7IYq%EnQ@3G!xqjx#oyUa-a$;){3G{gwl z%LZA_6vK46606Cs^Lo}bZ*CmIrZN@eXcM*B>< zea0Fa+qMz9!Up_m2HH=J~) z$hpq?JVu`<-REKCPTZboIDzEI~2IQc)|bi0LjOVAoKxA*r9M%(Y^;R?@B&MjB4uBy6WJ-C(a6WF^ztn;1{l zpA*(OXLQb`JLh8CCyjCEX)7b}OwAc&u9y{3%$s~av7t`H~v7M8R`2Oh=Mi!wMWHD3B=nae}S5sXV^=x3x7+6aWtTECUhq*h0Hvrgc z23aeroxz96{gnHniw&+DgX`(Rbw--vj}ohA@XUd|ZjklN&{&eDJQr>@v|$Wwq=z;b zX^w9s_Rk<@ur~~{QPkU}h*dl?p0cIXi#;~7WsGd4N46Nb7k`dt=(*3zV#@9T0A~r5_kEnhqWgxHJh*76Ruc^=FazJ z+B#gLZJ=zT?4Ve;*+uKKykOe%0TaW^{3Ju{F;A97?EejE-^zD)w9oODSHk!;)}d^n zv4>*Ch*bsm#f%M)515Qz4#hrv{X>abVr`X6VXItr{Z{!is;FkEPu+3Zt`1B&G^lN( zT#4-&)}dg11T*2wA&N;Edv$Chw(&>!#5S@)BYS<&nDKrZ^b6?#!lpKCG<(qUf=)cR zZf-BX8#8S_odzO1u8OO@c@E8K1jP#fx_!xC|eS$TsNvvXYXLjC7wBmWU3p(VT{81t;wAq3AF=kQOV?KrRONe#7uG)YBUb-(>9g~cb>;PF h4f?JMYn{YaYp~Uv4_X~Y^r|EdkQ_$xs>_<*{{Uc@((V8N literal 0 HcmV?d00001 diff --git a/src/plant_transaction_data/__pycache__/service.cpython-311.pyc b/src/plant_transaction_data/__pycache__/service.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3801315e1c591c0257f6d2e76c3b4243246aaf39 GIT binary patch literal 4014 zcmcIn-ESMm5#Qr|@Z*jWKO`%*B!`YFTTE=pR)SV>RT+U*If@6VjWRxHbQQX@-HZ2R@9u^$1SrGLB;Dc>5&imZU462-&0_)w_PjF{y5l=-HFdW6)0QwP8m56Dixv zWD_`aOVE?B!ZFtF!IGZ9VUX#CzP|RZAae}bFX+)Zl2vq-+U^aV$SIJf6rLoHhKL@k=CX5~x8Y1LBG0r$jF{g(+=VWA_(uCM4Y1}pZP zSS8wW?pEHgFv*!EV&zuUrF_vF4!yHNw^0oc4Nou5Vbg>rG~~-=LU7T#Zerp_^u?U% z4Y^5c?{qoXM9t-OS0dOdlcLtX=>RYSlsiy%{|)3S;z0Kn{mfRfs7xz8g8s*yvFg5& zwgf`^<$uVx`zzdSChcEgBTzwAy8oe63HT-N02+V9e}EqFKNU9k3SSiuO@WR_P#$*% zs#1sD$M|JH^MUp8_t~wODK({+v~mHiGqtFiSWlITDQg+0mh!8(xHp#9M>FXlp&v)6 z)wq(UH8%iP9K;`Etql4Onwn~;#B}9S5$8%ISA;q(kZw9HMyH7%mN8kQN-@iZWzvgC zL3;Ma^u>jDuVqrxvsY&4-?)~V|K4n7VG*A*G)-MFiMFsp(U&`@;01udYF@*mD{C&l zge}q!3(8Q;5|DqwZxj7Dgrdo<;wU5A%2-_)+d4n(oWEjUy;(nhv!>)6CAazA zMsjdFIb2T;S8*+Q)=8eVqX+ZmOhbQ*b$K4YEPUk9t-va$T?>~pXwIS$%3a|5%Fr&f&Cs58x z?k%MUb+IDkVeB*R7aZ7+)UhA2A_DG1>&H5{H;fLt&CzGvFrmtD1*WKzlobml9UGZH zqI6^*?n5P_gFYA6T+vdO%SBhvv8fSy3PKH(Pz!X$ypg|+2}NRB^59R`WC(C2tyCzK zisS_<8EjdCN#{{hNTtXLHUMzWsfIybhE@+0^DjVJkdFBweW9*g*czX4#;pM2-Z zDirwDlvzia{TCmINB)C=+!dP=I?;buy1V+buALXpZO+(oe@z&8+B0VN%s~De19`IQ zHSDgL19|fb%vX||88SdWOkM-G?|EmxSEe_>tl=|Y4qJmB$b;Ui9bXJWo#aO|)jspH z9o%&UfjQ`BIRqY=I<`Z}zv_N}408g2Cw{%pd+DejE#i+lh#Jk1Ay^JvA9I!w2Bn-{ zF08n`s>7p1A&|GyyoZffK-LYl@5Q8t>EJ-p*jq|2KqrNQ`2!#x4F1tQWOrYJT)n-0 zda{0cvUYmPIX&g|ZNAwMx<1YPICFmjbma&GwlL6$^lV4^>yiFiWYCEW+QJdJAtyKA zVVWZ6VJ8g=OY~43e^rNur=d!q%7zaT|J}j+^%ZhD_ooBz9(W&q8r>M&0Gq7{tBCYj zbnjLI%ZJ{IxEBXKg3-qv2@c&m3Hm%z^Zqk|KKZtP0DW?xPhmajMJM~;#nE|i=`sAV zW|VcD)A22pzFZm5-8ncDym{DCEsKybXtj-<-W*|C6)4hOxy*td7L>T+tvojLLk2H- zGGqegjzcl;0r3>w>_ST4wtT8CpQ_12jy$wEy^|Q+PK?wOBTv3zCq`3~9m zL$O3}n7(0mpzQt)$YG1!|2p`6`O*5>FaPz#QOwq#BaZUhx=yhXSWkN4u@4&=&^WyX z&(6hKJG@$4-M7OmT_Ut zd;i#XcHTJh68#=87Bs1pO5pDmBJ|&u+XErnC`CSvDMwpD8hZ|1$y!^1zZFEGa&e!W zR)Wi;(S;kM{c71-?#!hjh0B{@XEelf`Fzo0FC+7d%x2gPGPmn_FZzl;3r&LSEgN`> zOhc2t9p5@?Wm1osg5~j5O0SVBFF#rGn literal 0 HcmV?d00001 diff --git a/src/plant_transaction_data/model.py b/src/plant_transaction_data/model.py new file mode 100644 index 0000000..f2d69d4 --- /dev/null +++ b/src/plant_transaction_data/model.py @@ -0,0 +1,61 @@ +from sqlalchemy import Column, Float, Integer, String, UUID +from src.database.core import Base +from src.models import DefaultMixin, IdentityMixin + + +class PlantTransactionData(Base, DefaultMixin, IdentityMixin): + __tablename__ = "lcc_plant_tr_data" + + id = Column(UUID(as_uuid=True), primary_key=True, index=True) + tahun = Column(Integer, nullable=False) + is_actual = Column(Integer, nullable=False) + seq = Column(Integer, nullable=False) + net_capacity_factor = Column(Float, nullable=True) + eaf = Column(Float, nullable=True) + production_bruto = Column(Float, nullable=True) + production_netto = Column(Float, nullable=True) + energy_sales = Column(Float, nullable=True) + fuel_consumption = Column(Float, nullable=True) + revenue_a = Column(Float, nullable=True) + revenue_b = Column(Float, nullable=True) + revenue_c = Column(Float, nullable=True) + revenue_d = Column(Float, nullable=True) + revenue_total = Column(Float, nullable=True) + revenue_pv = Column(Float, nullable=True) + revenue_annualized = Column(Float, nullable=True) + cost_a_replacement = Column(Float, nullable=True) + cost_a_pm = Column(Float, nullable=True) + cost_a_acquisition = Column(Float, nullable=True) + cost_a_pinjaman = Column(Float, nullable=True) + cost_a_depreciation = Column(Float, nullable=True) + cost_a_total = Column(Float, nullable=True) + cost_a_pv = Column(Float, nullable=True) + cost_a_annualized = Column(Float, nullable=True) + cost_c_fuel = Column(Float, nullable=True) + cost_c_pv = Column(Float, nullable=True) + cost_c_annualized = Column(Float, nullable=True) + cost_bd_om = Column(Float, nullable=True) + cost_bd_pm_nonmi = Column(Float, nullable=True) + cost_bd_bd = Column(Float, nullable=True) + cost_bd_total = Column(Float, nullable=True) + cost_bd_pv = Column(Float, nullable=True) + cost_bd_annualized = Column(Float, nullable=True) + total_expense = Column(Float, nullable=True) + total_cost_eac = Column(Float, nullable=True) + total_profit_loss = Column(Float, nullable=True) + total_residual_value = Column(Float, nullable=True) + calc_depreciation = Column(Float, nullable=True) + calc_interest_payment = Column(Float, nullable=True) + calc_principal_payment = Column(Float, nullable=True) + calc_dept_amount = Column(Float, nullable=True) + calc2_ebitda = Column(Float, nullable=True) + calc2_earning_before_tax = Column(Float, nullable=True) + calc2_tax = Column(Float, nullable=True) + calc2_earning_after_tax = Column(Float, nullable=True) + calc2_nopat = Column(Float, nullable=True) + calc3_interest_after_tax = Column(Float, nullable=True) + calc3_free_cash_flow_on_project = Column(Float, nullable=True) + calc3_discounted_fcf_on_project = Column(Float, nullable=True) + calc4_principal_repayment = Column(Float, nullable=True) + calc4_free_cash_flow_on_equity = Column(Float, nullable=True) + calc4_discounted_fcf_on_equity = Column(Float, nullable=True) diff --git a/src/plant_transaction_data/router.py b/src/plant_transaction_data/router.py new file mode 100644 index 0000000..8d280f9 --- /dev/null +++ b/src/plant_transaction_data/router.py @@ -0,0 +1,120 @@ +from typing import Optional +from fastapi import APIRouter, HTTPException, status, Query + +from .model import PlantTransactionData +from .schema import ( + PlantTransactionDataPagination, + PlantTransactionDataRead, + PlantTransactionDataCreate, + PlantTransactionDataUpdate, +) +from .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[PlantTransactionDataPagination]) +async def get_transaction_datas( + db_session: DbSession, + common: CommonParameters, + items_per_page: Optional[int] = Query(5), + search: Optional[str] = Query(None), +): + """Get all transaction_data pagination.""" + year_data = await get_all( + db_session=db_session, + items_per_page=items_per_page, + search=search, + common=common, + ) + # return + return StandardResponse( + data=year_data, + message="Data retrieved successfully", + ) + + +@router.get( + "/{transaction_data_id}", response_model=StandardResponse[PlantTransactionDataRead] +) +async def get_transaction_data(db_session: DbSession, transaction_data_id: str): + transaction_data = await get( + db_session=db_session, transaction_data_id=transaction_data_id + ) + if not transaction_data: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="A data with this id does not exist.", + ) + + return StandardResponse( + data=transaction_data, message="Data retrieved successfully" + ) + + +@router.post("", response_model=StandardResponse[PlantTransactionDataRead]) +async def create_transaction_data( + db_session: DbSession, + transaction_data_in: PlantTransactionDataCreate, + current_user: CurrentUser, +): + transaction_data_in.created_by = current_user.name + transaction_data = await create( + db_session=db_session, transaction_data_in=transaction_data_in + ) + + return StandardResponse(data=transaction_data, message="Data created successfully") + + +@router.put( + "/{transaction_data_id}", response_model=StandardResponse[PlantTransactionDataRead] +) +async def update_transaction_data( + db_session: DbSession, + transaction_data_id: str, + transaction_data_in: PlantTransactionDataUpdate, + current_user: CurrentUser, +): + transaction_data = await get( + db_session=db_session, transaction_data_id=transaction_data_id + ) + + if not transaction_data: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="A data with this id does not exist.", + ) + transaction_data_in.updated_by = current_user.name + + return StandardResponse( + data=await update( + db_session=db_session, + transaction_data=transaction_data, + transaction_data_in=transaction_data_in, + ), + message="Data updated successfully", + ) + + +@router.delete( + "/{transaction_data_id}", response_model=StandardResponse[PlantTransactionDataRead] +) +async def delete_transaction_data(db_session: DbSession, transaction_data_id: str): + transaction_data = await get( + db_session=db_session, transaction_data_id=transaction_data_id + ) + + if not transaction_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, transaction_data_id=transaction_data_id) + + return StandardResponse(message="Data deleted successfully", data=transaction_data) diff --git a/src/plant_transaction_data/schema.py b/src/plant_transaction_data/schema.py new file mode 100644 index 0000000..b3b9a97 --- /dev/null +++ b/src/plant_transaction_data/schema.py @@ -0,0 +1,83 @@ +from datetime import datetime +from typing import List, Optional +from uuid import UUID + +from pydantic import Field +from src.models import DefaultBase, Pagination + + +class PlantTransactionDataBase(DefaultBase): + year: Optional[int] = Field(None, nullable=True) + rp_per_kwh: Optional[float] = Field(None, nullable=True) + tahun: Optional[int] = Field(None, nullable=True) + is_actual: Optional[int] = Field(None, nullable=True) + seq: Optional[int] = Field(None, nullable=True) + net_capacity_factor: Optional[float] = Field(None, nullable=True) + eaf: Optional[float] = Field(None, nullable=True) + production_bruto: Optional[float] = Field(None, nullable=True) + production_netto: Optional[float] = Field(None, nullable=True) + energy_sales: Optional[float] = Field(None, nullable=True) + fuel_consumption: Optional[float] = Field(None, nullable=True) + revenue_a: Optional[float] = Field(None, nullable=True) + revenue_b: Optional[float] = Field(None, nullable=True) + revenue_c: Optional[float] = Field(None, nullable=True) + revenue_d: Optional[float] = Field(None, nullable=True) + revenue_total: Optional[float] = Field(None, nullable=True) + revenue_pv: Optional[float] = Field(None, nullable=True) + revenue_annualized: Optional[float] = Field(None, nullable=True) + cost_a_replacement: Optional[float] = Field(None, nullable=True) + cost_a_pm: Optional[float] = Field(None, nullable=True) + cost_a_acquisition: Optional[float] = Field(None, nullable=True) + cost_a_pinjaman: Optional[float] = Field(None, nullable=True) + cost_a_depreciation: Optional[float] = Field(None, nullable=True) + cost_a_total: Optional[float] = Field(None, nullable=True) + cost_a_pv: Optional[float] = Field(None, nullable=True) + cost_a_annualized: Optional[float] = Field(None, nullable=True) + cost_c_fuel: Optional[float] = Field(None, nullable=True) + cost_c_pv: Optional[float] = Field(None, nullable=True) + cost_c_annualized: Optional[float] = Field(None, nullable=True) + cost_bd_om: Optional[float] = Field(None, nullable=True) + cost_bd_pm_nonmi: Optional[float] = Field(None, nullable=True) + cost_bd_bd: Optional[float] = Field(None, nullable=True) + cost_bd_total: Optional[float] = Field(None, nullable=True) + cost_bd_pv: Optional[float] = Field(None, nullable=True) + cost_bd_annualized: Optional[float] = Field(None, nullable=True) + total_expense: Optional[float] = Field(None, nullable=True) + total_cost_eac: Optional[float] = Field(None, nullable=True) + total_profit_loss: Optional[float] = Field(None, nullable=True) + total_residual_value: Optional[float] = Field(None, nullable=True) + calc_depreciation: Optional[float] = Field(None, nullable=True) + calc_interest_payment: Optional[float] = Field(None, nullable=True) + calc_principal_payment: Optional[float] = Field(None, nullable=True) + calc_dept_amount: Optional[float] = Field(None, nullable=True) + calc2_ebitda: Optional[float] = Field(None, nullable=True) + calc2_earning_before_tax: Optional[float] = Field(None, nullable=True) + calc2_tax: Optional[float] = Field(None, nullable=True) + calc2_earning_after_tax: Optional[float] = Field(None, nullable=True) + calc2_nopat: Optional[float] = Field(None, nullable=True) + calc3_interest_after_tax: Optional[float] = Field(None, nullable=True) + calc3_free_cash_flow_on_project: Optional[float] = Field(None, nullable=True) + calc3_discounted_fcf_on_project: Optional[float] = Field(None, nullable=True) + calc4_principal_repayment: Optional[float] = Field(None, nullable=True) + calc4_free_cash_flow_on_equity: Optional[float] = Field(None, nullable=True) + calc4_discounted_fcf_on_equity: 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 PlantTransactionDataCreate(PlantTransactionDataBase): + pass + + +class PlantTransactionDataUpdate(PlantTransactionDataBase): + pass + + +class PlantTransactionDataRead(PlantTransactionDataBase): + id: UUID + + +class PlantTransactionDataPagination(Pagination): + items: List[PlantTransactionDataRead] = [] diff --git a/src/plant_transaction_data/service.py b/src/plant_transaction_data/service.py new file mode 100644 index 0000000..a5c80c2 --- /dev/null +++ b/src/plant_transaction_data/service.py @@ -0,0 +1,74 @@ +from sqlalchemy import Select, Delete, cast, String +from .model import PlantTransactionData +from .schema import PlantTransactionDataCreate, PlantTransactionDataUpdate +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 + + +async def get( + *, db_session: DbSession, transaction_data_id: str +) -> Optional[PlantTransactionData]: + """Returns a document based on the given document id.""" + query = Select(PlantTransactionData).filter(PlantTransactionData.id == transaction_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(PlantTransactionData).order_by(PlantTransactionData.tahun.desc()) + if search: + query = query.filter( + cast(PlantTransactionData.tahun, String).ilike(f"%{search}%") + ) + common["page"] = 1 + + 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, yeardata_in: PlantTransactionDataCreate): + """Creates a new document.""" + yeardata = PlantTransactionData(**yeardata_in.model_dump()) + db_session.add(yeardata) + await db_session.commit() + return yeardata + + +async def update( + *, + db_session: DbSession, + yeardata: PlantTransactionData, + yeardata_in: PlantTransactionDataUpdate, +): + """Updates a document.""" + data = yeardata_in.model_dump() + + update_data = yeardata_in.model_dump(exclude_defaults=True) + + for field in data: + if field in update_data: + setattr(yeardata, field, update_data[field]) + + await db_session.commit() + + return yeardata + + +async def delete(*, db_session: DbSession, transaction_data_id: str): + """Deletes a document.""" + query = Delete(PlantTransactionData).where(PlantTransactionData.id == transaction_data_id) + await db_session.execute(query) + await db_session.commit()