From cd3304438c6fe7dbb63fb916c0ceac0d0067586d Mon Sep 17 00:00:00 2001 From: MrWaradana Date: Tue, 17 Dec 2024 14:25:10 +0700 Subject: [PATCH] refactor: equipment by id response --- src/__pycache__/models.cpython-311.pyc | Bin 5599 -> 5603 bytes .../__pycache__/model.cpython-311.pyc | Bin 1210 -> 4274 bytes .../__pycache__/router.cpython-311.pyc | Bin 4546 -> 4871 bytes .../__pycache__/schema.cpython-311.pyc | Bin 2799 -> 7393 bytes .../__pycache__/service.cpython-311.pyc | Bin 3325 -> 5342 bytes src/equipment/model.py | 69 ++++++++++++++++-- src/equipment/router.py | 43 ++++++++--- src/equipment/schema.py | 53 ++++++++++++-- src/equipment/service.py | 48 ++++++++++-- .../__pycache__/schema.cpython-311.pyc | Bin 2827 -> 2828 bytes src/equipment_master/schema.py | 4 +- .../__pycache__/schema.cpython-311.pyc | Bin 2472 -> 2473 bytes src/masterdata/schema.py | 4 +- src/models.py | 4 +- .../__pycache__/schema.cpython-311.pyc | Bin 2297 -> 2298 bytes src/yeardata/schema.py | 4 +- 16 files changed, 193 insertions(+), 36 deletions(-) diff --git a/src/__pycache__/models.cpython-311.pyc b/src/__pycache__/models.cpython-311.pyc index 0fb0d84e2939d4e1047d0445f7aef4bf22a5516a..ae4da66ca25f09f989402aa40ab59e557a0ce4a7 100644 GIT binary patch delta 79 zcmcbw{aBlKIWI340}$-yO-!%Y$h(-EmD?pXEphS|?jTknFpG<49;-B%mCGwW`7qBi X2yb&P?*Vp3&B=PAnvBwuBShN)r^6Rx delta 75 zcmaE?eP5e*IWI340}%Xu6Q5qTk#{jS3zti3+T^X=K`eqG1`p3X7AX*;kXL;2F`i{$ X&gMei1MG~FlZ`|*8Kox2h_(X&g?<+K diff --git a/src/equipment/__pycache__/model.cpython-311.pyc b/src/equipment/__pycache__/model.cpython-311.pyc index 88edd9a25a584007b7793866a58ee1f6e23eaacd..d2e34ceeef5262425b255d7cbd3b4a7872e1c3d2 100644 GIT binary patch literal 4274 zcmcJS%}?V<7Qmh0d?ye{NCKpj&^yqC2BaWJf9yhQmIfA0!|u-Xc1sbG<+dx}8QV#h zoy;<)9QM%KQ*M)Eq?KkFZ67%HpD;&T^1>Sq z>iJc@SN}{Tq7+=qG4|wTf};LI9N+FbJc=23AvE4O(HHN>e(meN#dRaYzkv@ zd(SvegEa$IWcPJTXi6|`Yg*(uMp77bC1H40W%qvcSz);)itH;99hE1nFvG~Kgc!z( zGK|#VTOz5)8Rm716$d22Fe+*9JmN7h2o6GFg;_;Gs@#$=`S4bf<=|zCK)wufhFFY= zokzu7Ls6|9$2J9(6&doxV8k^r&!~cgtQe0J_{@wb)RC2~!$;>>MFkIl5#SS~+G?$Y z#LB0Q7FHO{s^~}R1H6X%dHw0*<3Bw+Dm^{eKY0H6v(odI2S>-R&?*>$JytMxJT%2I zOcaT0%`*%Og|Z8>LX>|%(HZ`k>HD3-e@{%mX?N@WmNv1fPpldftDQfX**o2K@8lw& zWvhC&YGkV#opyxi9BJ7NJ-cCKH;Ayf&};Wk-UYPcwqD#eirX5UH>Yyl#a{M&Q=6*j zQx#*X()q$HeAcV?UtYAd!j@jxG74K7J!ht8yL-J&Xqc|(>57rAbPmZMzH>F|5vLw5 z@^LWxZKvk_{1{L30Y3OPbYrmwz_EfT#E0KTZa6)0ZFds!B*f|6`w*vhC&cO932}ON zGVVzxJW0}%OnQq&B+WX6-sdXhO$lJ_KcJW0Wm6g^4FlgxXP zyPo7Xp5!x6vfxP;J;^;!vgAq1o@CjR-1j6ao@AAeLTHFti9^^(5&qKNY!xd;!h?$K zpkQx+R!U+8h`KT>b7-(9D^>urf`Y#LEi3cP(ujt&tG&OpwN)Y;HEi2U!|*et*PI@}h}w+&f5+rtyEuN{@w@Fdyarbv+@MVb_0 zD6GhE3;z^_@H8O-l|60A)|i4`TMLP%ALnE(jMJ)PqG7k3UlNujG8Iw2%QlRo87V|X*RT+lRgm1O}h;h+%gSOFf_w81&$F$ z#}tRQFjdvgOu#Lm=hX}y5t+%Y=_Np@Hm(vHD}-2%k(+HRMJlW;gC{bQJWzUF2nmy; z*6sqWah~|P9p4M2R=O(4LQsw%^}3#)%tL;X%y;8vIAtam%tYEu|Jj_JzKjJYgYPLQ zK9Ztya9N;|ncHbheCo|!x7y#;;>&t`*@!Q9cFkz=&0;sxU(ljUdUVN%E_HUyWTqSJ zw$B4va!pUJ8OgQIftks7>%A9{?PNCe%!ZNK=={-~o9|Woix->P+#`MNkump3qjP4i z&cy^>f2`*p8~Mi?J>&j%S98vmdW-$c#ez2bP@jEh%s$lUtdn}y&s$n{Q_pT1*-esq z{_>V~l3It{v$&-fw~Qj>p7~$fJvGy<_7)*^O;z+%#Yj~;&)i+Xb(nVITRq>^((8J9 z-AJ!@4$blOn|k*}A8F$&`uK`5zS7xuAEc{Bm)@QI&c3tM$SNa;p{Vj&WJT^2NoP)c zfkc|J&o=gX2a^oj8voR2t$`&cFipbwVvQWIUcpIp4bC$NM@Zu+k=v&Y1(V}Bj*-GX zb(BbLbh-Z={+)9K+s0o4^}$ckp|~9L`Ftkzx%SI$le(vk-X?Wd8@)|xU30rHgAw2Q nC3U;#(p|BC_@0oDpK$JhZ}pP8U38!JR?ZXe3Hj)PZL|Lm3IfTn delta 398 zcmdm_xQml-IWI340}$9hj8AW7n#d=S9tGr0XGmd4Va#F3WsG9XWr||TWsYLbWr<>8 z1c@`{u;#Kwv4PplIqbO{Q5?CPQJjnnObqS}DJ(4vDXgh%sT`@C%UBs0Rs%5vL~*6C z1v6-}zXWkLStjmP*!WYAkx_H929pmjPikRlW;g#;3v7ur zkoAkh2B@qwC)KV<9>`^6FkoOP?gp|xFf%eTK437tKnP8i70_nnnCvN_%g4aUX!HR@ HfXxR0Mde$A diff --git a/src/equipment/__pycache__/router.cpython-311.pyc b/src/equipment/__pycache__/router.cpython-311.pyc index 5edb900045d476b9788fbd3adaa7ce9bf2489480..945ddd12b74a8f9eeb9311bc65e9efe444dc72fe 100644 GIT binary patch literal 4871 zcmbVP-ER}w6~FW0i9cf}PMpM!!?3WhhQ)zy+V0ZsLOxhF1WX99Eu&P{;JHbRJWlq` zm|eh;B6ihMsjB+a?PDrcTM$U)VJjiE4|(VxFj4(rjf8|$t<-&+73>R7J!i&t?1U_o zo9lDGe{;{hzjMybUn7wqf%NY;)x|$Y2>A~-nkmqzJpGy{)P0H%`UFiZNqU#krTZ1X+xC?LdQb`KAtj`Tm9QRBB5uD_>ei!5RF5e!y+`TM zdzD^2uEbs3u2P@guk`B)CE>RHr2&0V8FcG`(vY51l5Ra%O6kMOFh_Vog|A?%_nZ4B zN}8tEqpfCJMGMhk8XRi%JP3aUy4{DLm$V4&U*NUwFT`z#BfBC-0WtIgh_NroHmp6n zV)eWPtCtRHaVjr}THlTx?gi90ntHUCuFgNSLqzSTVJ$(E3z9al19=}H?{7zJ*0sS` z*zXXP0X^cP`?cf_^fv)L-b8FKUlkorBeetdfHr)QWYXUvV1~2Bvqi(q2zFq6c6x5P zVp3*DKDu;i_S9zux?&cW%eG{gs#!6<8FtE`Dl07I7m6il=Z$4%=2yJEP|!9ob@d`O3{VRip~(tk zpvPr{GHAvwnrc~7nKnm_mF2QQZ9JcD)@bGRW%w>^#{FagPotT-pz=BVo_-8shH&5# z%(ih;Xig+V^J$zZZncYCmHdVKJ@+}dja$OUBc?Y7U76hyGw^Ib&=j98G#MJ zc32+@KZp#+l290^fc*TOspIprXLIt@^y%qK<7eedznIR=U!_M%g@QV7u)=(6GxN-4 zPj=;o-HkWb8Zg*CfQljJ84&-4zcuo`pM-}W$Fo*^8uH(-fY>NjXbVl2VlTG9ta5yRUC=<0&7zY7v2nw-ck*Nn&pbVY6rEedBdZd z?QeD$S}qmlf6cRWMTROlxP^H38t= zr11}gPQ2Tk*$ihe!wfYhLQ&OU#*pV*@&&Lhv};o>mcWm6x5$%s=^897 zsbI)%J)#%Od8!uj*VR&m0+XR>&`($zzdZsXBe8C*`%p+A>|S(e`LUy8`P}(S`47)u z&P{owM`dApYuhY~YerEVMR5#-fe^BrJX%CLXu;mWVVw6j5FWX|IWbX>r|hX8M3Zg-aTxz8{EQh8-gU!W?KxZ<8C^SD6H|{9!*_!l!&V}}F`T7MiuhS62jkyWNTla&@D%73K!B$}ui$HVg^nIQOVphYic<;+jB0+SMVFB9%Vn>AW z_|%Kz$e|`dUHZ7BLDFwg#=~!;%mfTyfuHe55RDj;7Qe@~4wjwSY z#wI>)7``pwUx>mI)m4V?F@`~xg;Aipu)844TrU==XQJpeJWq{w$nZ$*K6qzlG4@|o z4VrCE$N!AnSF7FAF%JKWP}Yy@V%V=%%%#?v1a=3p+kGq>?rqtU_i}ZgsqO>M7T{^< z26kIqS%x|~eOp+mm<)}Z;dO0$EI#-D93U$t`T;u+qZkN{f51!65jc*klL4zU*U6Z* zdwxO=TQACW@=NPwxlZ1*UM)W%IqOBaP7Yd~xlZ1)I`hssPXfJnhJKs+U208&2Qlye zP4af~&V;pR)H*s@+cUM6+~iKxxKj=Kg!XB|5J=>6KEX186yPJpcdz literal 4546 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
  • &yDa&=CVsai-(%vtE%{y( zzsHi_XX4+s?QuMV}9hP|^q(I!JHAupr_)wIGNR3Kw zK+$@th(bgtg-_#6t?5(?@oHQ$!p`Or)ov2vOT$~D+#4t^@dny*Z|5q*+YPKCAyF|L zQo?WOMf%N4O~zw-58}I*)d|}2I?q+c!(E2s_#bFUf%sYeW0@Ph*O9m^^YNsTNGkl3 zXIdLRb5WO&!XavmWIRD3-qz2KdgN|sqXLe1Oo)Z3p>2^uI18o2)MzM;7VC!qq?tw& zY3CznoE1=0K5pj@OhbbX&WGWG17i?M+f)l&=&E8gy9u8>>tV4crtZ}NPk|$VaeC3J zs1V{~i8opc3UE4rmB>e9r%o>_;b3IA)gJ-2Z&Yf>;1LgI(oF>Y%;7-^&m2-0!Yu?Z zLMK8WLO;R)f)8O3VF+OuVFY0m;SRzW!d--W2=@`j5hf5GAWR}mAv{EwMwmgsH&Xfy z!YslZ!Xt!vgaw2}1V2ImVF_UwVFlqaLN|gNp$DP&4DdK4{~o$pa&+nHP1B4&H_p1I z)UK&~*VNw1``wiM0ZtrKP*gHi=)9fY&Wz_gtaDQBoXmGl?gidYr2-$|oG=MRC6k2? zcX}eznj@@ZLhYEycTDUpzHd)?KXfxP0YxPfmz-N3zki!{eE4(m+|oasNoKbW{j7gp z?Vr#0&+k1=Jx|kpo{@PdDw!_~-^~Vco}*Sayrd2<<%gFTX-^MiCJyc}0`ihdmI}Vn zY+F`26q#>P^)2Roi;T3T-ew&8P!-6FDp@QH-pP7%|j&?yjkK*YbDQ80k#E%{mUCTOhBgWUX*-GUq)cM+&>QuHIYE z-&<#-E91<0_n?vFt>y^@y;cfI1Y&4+R*xo^H>054srvIiQljl@9Yi zm!GkToFgY5ZLzUcb!;_1wrV5=k_T}{KweeJYT=ix%j3%gvYx|M=9yJJvw6?#-g;^v zJ+Xg>ky$7znZ42*c$Fq!AxY8gNhdQ~IX~-usCGZhcR$=)e*Zj0Kk$q^grbs%R~nqF zwC2lI8Fd<)FYdb~NeUY%@H)XXS20PUhhP<2!+Dx-QO~b!e6*K;ugW&|HE<&#;CJE# zb7RGgy+E9Mexn`8_`lk*t>^YOq;+sm{!w{~I)p_Oo*=jpP*qYH0R>(sDS%?9w;^{; ziD<(w9z>=Wv(-ebKrNi?t3lGec_a6KX#fO*i{&)5n|{QXQXA`?+ZP8k%2y%$Xq-{e;@jMU&G^(jUBp gNw9h|U_(LsxoE1l**xf^9MXeWy9aA8H|a~^e-oKDp8x;= delta 710 zcmZvY%}WA76u@V8CyDj5Xk9h?Afq%Aqz)EYL=;I-hb#y$73>&NX03Y8&Rvu_)TK*@ zf;xKa&@JdzmykUK{RJu1B?y|gBG%S?{CM*|=e^g-H`#Gzw@Zkx`;V=i6e&AA__;iM zfUV`Tgd$yv2;K18SV^bqN}x~&>%~zb&C^sRi6a6Iu@h0pc9tT2E(iD2+fsYk?Y!pX zGAj{Th6Gv{KnAmz%WImuaz`Gpr4O`LcB@RVT}28i@bmz@fL?&%(ht%=6K-~{cp9+- zJa#r50E@|c2y_4+2!jA4)e!sgdXM0JiYQ8A6(xmrL`6ze9OGKr#w7tHRpi|g-M(;G zNFQYAetwm1tGbX@bsKG}Hq+`#$fB7(Zh>mufF6M9XF-Ifk;aL@kQ?SG{@B%aTQOdY zAIGbm@*{!sWRMGu4uZUcbj(yT421{)5;uyQ>W+c|5MUR+h|QP=JXb<4_TpQP8uK;A zW~4COf2a6tk7crIVUNyeV>}S^n_FZ%-5Yb^NA%CBStLAFLw`|Ps)P2uW%996|JsOv W-8J+VrR6$k-&-b$UHiugwD1kqf{_~l diff --git a/src/equipment/__pycache__/service.cpython-311.pyc b/src/equipment/__pycache__/service.cpython-311.pyc index 571348ebab912ac970c3fa140002b4bba97e8cf4..2f0dee484ea4c12ed038e5a248a68ce910a63e23 100644 GIT binary patch literal 5342 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 diff --git a/src/equipment/model.py b/src/equipment/model.py index c097349..7b3559f 100644 --- a/src/equipment/model.py +++ b/src/equipment/model.py @@ -1,17 +1,74 @@ - -from sqlalchemy import Column, Float, Integer, String +from sqlalchemy import Column, Float, Integer, String, ForeignKey +from sqlalchemy.orm import relationship from src.database.core import Base from src.models import DefaultMixin, IdentityMixin - class Equipment(Base, DefaultMixin, IdentityMixin): __tablename__ = "lcc_ms_equipment_data" - - equipment_id = Column(String, nullable=False) + + assetnum = Column(String, nullable=False) acquisition_year = Column(Integer, nullable=False) acquisition_cost = Column(Float, nullable=False) capital_cost_record_time = Column(Integer, nullable=False) design_life = Column(Integer, nullable=False) forecasting_target_year = Column(Integer, nullable=False) - manhours_rate = Column(Float, nullable=False) \ No newline at end of file + manhours_rate = Column(Float, nullable=False) + + +class MasterRecords(Base, DefaultMixin, IdentityMixin): + __tablename__ = "lcc_tr_data" + + equipment = relationship( + "Equipment", + backref="maintenance_records", + lazy="raise", + primaryjoin="and_(MasterRecords.assetnum == foreign(Equipment.assetnum))", + viewonly=True, + ) + + # master_equipment = relationship( + # "MasterEquipment", + # lazy="raise", + # primaryjoin="and_(ScopeEquipment.assetnum == foreign(MasterEquipment.assetnum))", + # uselist=False # Add this if it's a one-to-one relationship + # ) + + assetnum = Column(String, nullable=False) + tahun = Column(String, nullable=False) + seq = Column(String, nullable=False) + is_actual = Column(String, nullable=False) + raw_cm_interval = Column(String, nullable=False) + raw_cm_material_cost = Column(String, nullable=False) + raw_cm_labor_time = Column(String, nullable=False) + raw_cm_labor_human = Column(String, nullable=False) + raw_pm_interval = Column(String, nullable=False) + raw_pm_material_cost = Column(String, nullable=False) + raw_pm_labor_time = Column(String, nullable=False) + raw_pm_labor_human = Column(String, nullable=False) + raw_predictive_labor_time = Column(String, nullable=False) + raw_predictive_labor_human = Column(String, nullable=False) + raw_oh_material_cost = Column(String, nullable=False) + raw_oh_labor_time = Column(String, nullable=False) + raw_oh_labor_human = Column(String, nullable=False) + raw_project_task_material_cost = Column(String, nullable=False) + raw_loss_output_MW = Column(String, nullable=False) + raw_loss_output_price = Column(String, nullable=False) + raw_operational_cost = Column(String, nullable=False) + raw_maintenance_cost = Column(String, nullable=False) + rc_cm_material_cost = Column(String, nullable=False) + rc_cm_labor_cost = Column(String, nullable=False) + rc_pm_material_cost = Column(String, nullable=False) + rc_pm_labor_cost = Column(String, nullable=False) + rc_predictive_labor_cost = Column(String, nullable=False) + rc_oh_material_cost = Column(String, nullable=False) + rc_oh_labor_cost = Column(String, nullable=False) + rc_project_material_cost = Column(String, nullable=False) + rc_lost_cost = Column(String, nullable=False) + rc_operation_cost = Column(String, nullable=False) + rc_maintenance_cost = Column(String, nullable=False) + rc_total_cost = Column(String, nullable=False) + eac_npv = Column(String, nullable=False) + eac_annual_mnt_cost = Column(String, nullable=False) + eac_annual_acq_cost = Column(String, nullable=False) + eac_eac = Column(String, nullable=False) diff --git a/src/equipment/router.py b/src/equipment/router.py index 51e56bc..4344069 100644 --- a/src/equipment/router.py +++ b/src/equipment/router.py @@ -1,7 +1,7 @@ - +from typing import List from fastapi import APIRouter, HTTPException, status -from .model import Equipment +from .model import Equipment, MasterRecords from .schema import EquipmentPagination, EquipmentRead, EquipmentCreate, EquipmentUpdate from .service import get, get_all, create, update, delete @@ -29,20 +29,33 @@ async def get_equipment_tree(): pass -@router.get("/{equipment_id}", response_model=StandardResponse[EquipmentRead]) -async def get_equipment(db_session: DbSession, equipment_id: str): - equipment = await get(db_session=db_session, equipment_id=equipment_id) - if not equipment: +@router.get("/{assetnum}", response_model=StandardResponse[EquipmentRead]) +async def get_equipment(db_session: DbSession, assetnum: str): + equipment_data, chart_data, min_eac_value, min_seq = await get( + db_session=db_session, assetnum=assetnum + ) + # raise Exception(equipment[0]) + if not chart_data: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="A data with this id does not exist.", ) - return StandardResponse(data=equipment, message="Data retrieved successfully") + return StandardResponse( + data=EquipmentRead( + equipment_data=equipment_data, + chart_data=chart_data, + min_eac_value=min_eac_value, + min_seq=min_seq, + ), + message="Data retrieved successfully", + ) @router.post("", response_model=StandardResponse[EquipmentRead]) -async def create_equipment(db_session: DbSession, equipment_in: EquipmentCreate, current_user: CurrentUser): +async def create_equipment( + db_session: DbSession, equipment_in: EquipmentCreate, current_user: CurrentUser +): equipment_in.created_by = current_user.name equipment = await create(db_session=db_session, equipment_in=equipment_in) @@ -50,7 +63,12 @@ async def create_equipment(db_session: DbSession, equipment_in: EquipmentCreate, @router.put("/{equipment_id}", response_model=StandardResponse[EquipmentRead]) -async def update_equipment(db_session: DbSession, equipment_id: str, equipment_in: EquipmentUpdate, current_user: CurrentUser): +async def update_equipment( + db_session: DbSession, + equipment_id: str, + equipment_in: EquipmentUpdate, + current_user: CurrentUser, +): equipment = await get(db_session=db_session, equipment_id=equipment_id) if not equipment: @@ -60,7 +78,12 @@ async def update_equipment(db_session: DbSession, equipment_id: str, equipment_i ) equipment_in.updated_by = current_user.name - return StandardResponse(data=await update(db_session=db_session, equipment=equipment, equipment_in=equipment_in), message="Data updated successfully") + return StandardResponse( + data=await update( + db_session=db_session, equipment=equipment, equipment_in=equipment_in + ), + message="Data updated successfully", + ) @router.delete("/{equipment_id}", response_model=StandardResponse[EquipmentRead]) diff --git a/src/equipment/schema.py b/src/equipment/schema.py index 1785b03..0f6705e 100644 --- a/src/equipment/schema.py +++ b/src/equipment/schema.py @@ -3,10 +3,10 @@ from typing import List, Optional from uuid import UUID from pydantic import Field -from src.models import DefultBase, Pagination +from src.models import DefaultBase, Pagination -class EquipmentBase(DefultBase): +class EquipmentBase(DefaultBase): acquisition_year: Optional[int] = Field(None, nullable=True) acquisition_cost: Optional[float] = Field(None, nullable=True) capital_cost_record_time: Optional[int] = Field(None, nullable=True) @@ -19,6 +19,47 @@ class EquipmentBase(DefultBase): updated_by: Optional[str] = Field(None, nullable=True) +class MasterBase(DefaultBase): + assetnum: Optional[str] = Field(None, nullable=True) + tahun: Optional[float] = Field(None, nullable=True) + seq: Optional[float] = Field(None, nullable=True) + is_actual: Optional[float] = Field(None, nullable=True) + raw_cm_interval: Optional[float] = Field(None, nullable=True) + raw_cm_material_cost: Optional[float] = Field(None, nullable=True) + raw_cm_labor_time: Optional[float] = Field(None, nullable=True) + raw_cm_labor_human: Optional[float] = Field(None, nullable=True) + raw_pm_interval: Optional[float] = Field(None, nullable=True) + raw_pm_material_cost: Optional[float] = Field(None, nullable=True) + raw_pm_labor_time: Optional[float] = Field(None, nullable=True) + raw_pm_labor_human: Optional[float] = Field(None, nullable=True) + raw_predictive_labor_time: Optional[float] = Field(None, nullable=True) + raw_predictive_labor_human: Optional[float] = Field(None, nullable=True) + raw_oh_material_cost: Optional[float] = Field(None, nullable=True) + raw_oh_labor_time: Optional[float] = Field(None, nullable=True) + raw_oh_labor_human: Optional[float] = Field(None, nullable=True) + raw_project_task_material_cost: Optional[float] = Field(None, nullable=True) + raw_loss_output_MW: Optional[float] = Field(None, nullable=True) + raw_loss_output_price: Optional[float] = Field(None, nullable=True) + raw_operational_cost: Optional[float] = Field(None, nullable=True) + raw_maintenance_cost: Optional[float] = Field(None, nullable=True) + rc_cm_material_cost: Optional[float] = Field(None, nullable=True) + rc_cm_labor_cost: Optional[float] = Field(None, nullable=True) + rc_pm_material_cost: Optional[float] = Field(None, nullable=True) + rc_pm_labor_cost: Optional[float] = Field(None, nullable=True) + rc_predictive_labor_cost: Optional[float] = Field(None, nullable=True) + rc_oh_material_cost: Optional[float] = Field(None, nullable=True) + rc_oh_labor_cost: Optional[float] = Field(None, nullable=True) + rc_project_material_cost: Optional[float] = Field(None, nullable=True) + rc_lost_cost: Optional[float] = Field(None, nullable=True) + rc_operation_cost: Optional[float] = Field(None, nullable=True) + rc_maintenance_cost: Optional[float] = Field(None, nullable=True) + rc_total_cost: Optional[float] = Field(None, nullable=True) + eac_npv: Optional[float] = Field(None, nullable=True) + eac_annual_mnt_cost: Optional[float] = Field(None, nullable=True) + eac_annual_acq_cost: Optional[float] = Field(None, nullable=True) + eac_eac: Optional[float] = Field(None, nullable=True) + + class EquipmentCreate(EquipmentBase): pass @@ -27,9 +68,11 @@ class EquipmentUpdate(EquipmentBase): pass -class EquipmentRead(EquipmentBase): - id: UUID - equipment_id: str +class EquipmentRead(DefaultBase): + equipment_data: EquipmentBase + chart_data: List[MasterBase] + min_eac_value: Optional[float] = Field(None, nullable=True) + min_seq: Optional[float] = Field(None, nullable=True) class EquipmentPagination(Pagination): diff --git a/src/equipment/service.py b/src/equipment/service.py index 51e7255..5a18acb 100644 --- a/src/equipment/service.py +++ b/src/equipment/service.py @@ -1,5 +1,6 @@ -from sqlalchemy import Select, Delete -from .model import Equipment +from sqlalchemy import Select, Delete, Float, func +from sqlalchemy.orm import selectinload +from .model import Equipment, MasterRecords from .schema import EquipmentCreate, EquipmentUpdate from typing import Optional @@ -7,11 +8,44 @@ from src.database.core import DbSession from src.auth.service import CurrentUser -async def get(*, db_session: DbSession, equipment_id: str) -> Optional[Equipment]: - """Returns a document based on the given document id.""" - query = Select(Equipment).filter(Equipment.equipment_id == equipment_id) - result = await db_session.execute(query) - return result.scalars().one_or_none() +async def get( + *, db_session: DbSession, assetnum: str +) -> tuple[list[MasterRecords], float | None]: + """Returns master records with equipment data based on asset number.""" + + # First query to get equipment record + equipment_query = Select(Equipment).filter(Equipment.assetnum == assetnum) + equipment_result = await db_session.execute(equipment_query) + equipment_record = equipment_result.scalars().one_or_none() + + # Second query to get master records + master_query = ( + Select(MasterRecords) + .join(MasterRecords.equipment) + .options(selectinload(MasterRecords.equipment)) + .filter(Equipment.assetnum == assetnum) + ) + master_result = await db_session.execute(master_query) + records = master_result.scalars().all() + + # Third query specifically for minimum eac_eac + min_query = ( + Select(func.min(func.cast(MasterRecords.eac_eac, Float)), MasterRecords.seq) + .join(MasterRecords.equipment) + .filter(Equipment.assetnum == assetnum) + .group_by(MasterRecords.seq) + .order_by(func.min(func.cast(MasterRecords.eac_eac, Float))) + .limit(1) + ) + min_result = await db_session.execute(min_query) + min_record = min_result.first() + min_eac_value = ( + float(min_record[0]) if min_record and min_record[0] is not None else None + ) + min_seq = min_record[1] if min_record else None + + return equipment_record, records, min_eac_value, min_seq + # return result.scalars().all() async def get_all(*, db_session: DbSession): diff --git a/src/equipment_master/__pycache__/schema.cpython-311.pyc b/src/equipment_master/__pycache__/schema.cpython-311.pyc index fc4160765f476abf00917c10ec9ddbc283e21a16..bdbe183051d38a3c870e7cca2225ff014c8fa2b8 100644 GIT binary patch delta 66 zcmeAc>k;E!&dbZi00f756VsP%o>6lWi(&dbZi00j0Ayi%BVIWI340}veJO-$$8$ZNsK%I%VxmblrIF^pYI?*aoBGM;ylh DIQJ79 delta 65 zcmZ1}yh50FIWI340}#A^5ueVpk=KHeh07&1ZL=3+7`vG61qLi=@-_|~#;D1UIgSAU DRj(7S diff --git a/src/masterdata/schema.py b/src/masterdata/schema.py index 1540b59..5f8191b 100644 --- a/src/masterdata/schema.py +++ b/src/masterdata/schema.py @@ -3,11 +3,11 @@ from typing import List, Optional from uuid import UUID from pydantic import Field -from src.models import DefultBase, Pagination +from src.models import DefaultBase, Pagination from src.auth.service import CurrentUser -class MasterdataBase(DefultBase): +class MasterdataBase(DefaultBase): # discount_rate: Optional[float] # inflation_rate: Optional[float] # manhours_rate: Optional[float] diff --git a/src/models.py b/src/models.py index ac00e67..69af726 100644 --- a/src/models.py +++ b/src/models.py @@ -62,7 +62,7 @@ class DefaultMixin(TimeStampMixin, UUIDMixin): # Pydantic Models -class DefultBase(BaseModel): +class DefaultBase(BaseModel): class Config: from_attributes = True validate_assignment = True @@ -76,7 +76,7 @@ class DefultBase(BaseModel): } -class Pagination(DefultBase): +class Pagination(DefaultBase): itemsPerPage: int page: int total: int diff --git a/src/yeardata/__pycache__/schema.cpython-311.pyc b/src/yeardata/__pycache__/schema.cpython-311.pyc index 75503c300e836bcabbf732a6a6fc12fbcf9d450b..bb00edc9bbe655e4f2f61c3ef85a10474af95931 100644 GIT binary patch delta 87 zcmew<_)Cy?IWI340}!0#O-xtc$g9K1%I%VxmblrL@hF?2-US9M=mQ%YqxA;{Ok#rd IWMhtF05vrjiU0rr delta 86 zcmew*_*0N~IWI340}wboj89kH$g9K1!sU{hw%LyHD4U_~1qLkW0~;Ho^#=w_VuICV H6OLm5DVi8( diff --git a/src/yeardata/schema.py b/src/yeardata/schema.py index 3627ac8..371eae8 100644 --- a/src/yeardata/schema.py +++ b/src/yeardata/schema.py @@ -4,10 +4,10 @@ from typing import List, Optional from uuid import UUID from pydantic import Field -from src.models import DefultBase, Pagination +from src.models import DefaultBase, Pagination -class YeardataBase(DefultBase): +class YeardataBase(DefaultBase): year: Optional[int] = Field(None, nullable=True) rp_per_kwh: Optional[float] = Field(None, nullable=True) created_at: Optional[datetime] = Field(None, nullable=True)