From baf05b10de36fda7a0b78cc06b8596715a03e586 Mon Sep 17 00:00:00 2001 From: MrWaradana Date: Tue, 23 Dec 2025 10:07:07 +0700 Subject: [PATCH] fix: correctly calculate remaining life and apply ordering using aliased column in EAC queries. --- .../__pycache__/service.cpython-311.pyc | Bin 27991 -> 28138 bytes src/equipment/service.py | 24 ++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/equipment/__pycache__/service.cpython-311.pyc b/src/equipment/__pycache__/service.cpython-311.pyc index 0ce524a131bf2f3d2df4774cee6460e0fa476b21..52128380ec84374df9c93915f1f9499edcc97374 100644 GIT binary patch delta 4254 zcmcgudu&_P8Taw4w&TQ!>o{rJByO5Cxk=+RZCIK%ZE5;|qo-J zt(e9i)2{5_{m%C~=X~F}-}&CO$oqdHB|k1M_SxY1!rhk`PMj>MBDyvc66&Zd?hv#DX~R4bmWJnOXC&cQ$b$lcjfWReVTrd#M%+C6Sx zHZQT!Yt`M|FjA|igKk~qtNk$ERxlo*Jy&X=oZsxIp5Cqw2){cD?F;7^x2r?Pobpb) zjqW@PbDdk5UET#ea`?J=2EG0)0Xh8hkKC)?K*Q=V-3oK`iCJ8Qo^gHrb4PLQZgmfB zR&Nq|xX#Gp%IDU(Ya#bKzEx;rk2=jg>#I1)O}z%0G9Js4%)P6 zGwxRRgM3hU&ac!#tFMqB0Qu0gP>{tEuU0q+3OA@kz4=ihv~Hop>aBB|E_CHlW5?X` zjY0B1_BiF6Pzc!=1I4{UF-}*HJ5?3NBVtU&cpS$2#CU>MtCTjv z9uEO;zu>_Zz$O9X1N;$}M11@?S7(vsP>i_cRH+fq{sWTaZiL*hMt;!KS=BB`fL#)? zTxQBtv?)h>bRBETKIvIch?ITD`zhJpglZCixbn&a)*i z+l|ip`J3ev;B0HSj>NKK;r;HtUC0+Rxsj?sL-%+>Gr_9z*Yj16YyBz2Nnu=FA36w^YZ(9;?t|9HAcpH^mYFR#7TRV<{F( z!kd*NJIv3t)O41j(34^+WwEhI_5eys5HJF)5&^?#ErAoEm?jhXXB+t^EfbY76gZRg z4pVB%N5@3{er~S$pdOdajv`DV+=*}(!rch>AWZWITKmYo{PouFk+1W^(RPUIqtO-Q z>Fo2-Z7zsb^qOTn)NwDlkDu;{RF0yJ*cSSp3j&7rwT>0!8UB99c1T6^n&V_d?C(pW zz`hBFk~6~vk@<7+^u=Q_r)sUC6KkE9eef*c>Ix+d+;eS3G#CJ@Cil^3hZLr-5>Q&uDx0Upoc}|JBxT$z6^q zXdP5?#D(g}3g%f*4at-Cvv7dVIe5{vpWDp_UVE){YNVW>zit!%!L~EgzX6N7_}!{`KVn)8K%zi$1{x4q$$3_d?Im!b5Y~}>}e$5;yZgM_=)YU)1UZk;o4kz z+xa!K_#=I5{~rnd z-Sn#%%hvz~*uCN51W{RLkXlGBo5i8{>=zR&Y8fV$T>@C1Pc&wiy#Zhp zrZ3dn;ywetkbyb;&W&Fwe-)LOzY@$}3FfZ^@)ro5pfjQR*^-7_Ndx8&G7Ioo75Daa zmz`cU6J9+VY|I54XT421Z_`zIfC}?c->*poKlCSvsCSZ`iJRa-T=Bw%@>u_7@+yD3 zzkUmTnv$m=hzn&uU&ZS|o-drMP%~c)urWA7p#t!212tvBbzuqM>47@(GUo$NK{4tX zys%DGmp_C3AhXbm!}6yYRTFVDrYni0@NaqWio&4;-wy8>lAxmBI#fem=XVe72SaIZV71!?!Jv=2Y+n-9I)%Xa=VPdnzC<<R zkQX0pb7Nz}B;Io{O^)#F!CL}&o8^6?-w(Et5#=Sf6#pfHg+N=@OSCL=o4bFcG?Hw68&%GK0mVkXU6*F=#ZNf^gKL zFoGZ&&{EV;GUlPELD}sI=!NUh(1+}JDmk8*V5|7M@ztcB`_%Mw0~(4l^)OPREAK!9 zXyN0g=%ZN_C2a_Y5JdVh)vONzGjCx>(4U%^fKIg;nR}4w)Dnitu7pWt`=ejQ2;59S6cV;A(8y*#-tKoY7kap3Dd-ylH CdM951 delta 3976 zcmbtW3v3j}8NRuf@BBJA8)N*&__bi4A3Tg5oA|-gU>idKvp|mZ?VNpN_s-1j0VWR@ zg%%P;70IAfZBmI!DGg2423^#WC?Qdh3aMyogDa$Mqo%6Vst`p)Nuf zhE}SV$z>pCs#)4%y<9E_Ia>{AOY{o4La&s^EA=Y5N;uEcs`VPVMwetsUn(yZy7}5N zy;iOja!{+&Lvl#SM5~wUA@LloL2r~Bg)T>H0(tqgyaMEvLeAAz>CJNUbidW|YUoF_ z7P-ag*x=w#kwVg%`W_i00}s(Q+D==e&PB+Rc<35+a~nu%0d>*#S-rXi+7HiZ_tK90 zJLfqHvVF2Z|pd$y?-BZx@X9?KhZ$I(| zbt}zP2WUIQ+KAEkC$7@cP3m@9qdp?Em_f;GPSY6_kM{_lom86c-2wfJ=J-9VlA~!3 z$J}{Ged;dAdo%RB*ULq#X8T0F>LA#+h{$$ME?Rh>eK**9(LS!qBE1J4_JBj5O4PkC z6A@+~?N=Y2p5EM0J~e#YD{mD(IQ6+Ux4Ivq4Ezt90=8{xKjaW~szcD&E*vAYBI;IE zXg?y_RJ5be-XYq-D6Z?lGAdA8Z0tqI6+%h#u|8+qySg1NI$4lF!p@K0CK_+7BgcoX3QL8xM9yZ z@6GMN(#O4rK*L7)t)&GpqIX$x9G6roXJR_}XjBn;5HNo>3}9s>;xwFK;W)fm4ytoe z?LLr*#VtQQn2e3;G;UgH3Bj_#veE2IFqN|K&=@<0O_yRs1Pd$=BOsMlTJ|tC71Ly5 zOR&}4S38`)4=wIEJz`2VHbo3O^zak4w<<w3sj{7-c+ zk*E2Sp+=bM&q77yeCleb(*u-su3W^cSA2tv^H*1t<%>lS6UNwv3!qH!`_YOb@&^C+ zif&ks&Xp(0PBHT@;fH+_`bcg&SBzwN4kjrZV}lsbZ3l!ELrVZA43vb$V#Sj>dy|(o zpM()!Z7w5`pMy)Elx8o-%y5=7rp~U$eWSev9oPkgFB!`}Jr?wS2V4{=wnmIM4(0LA zmR-QZcUwxx#ngqC%g&y6!ESle30mSYQJe|a*SmJpzYaiAX15bg< zKWMA#3WA5^wF$w{>>_~WjU;qE5ucMUZaW|w9-Eys%vjMhb|tmCJwys|cShhZ9^Cj) z#~n|@|Fcu6V{14`SIJMDXTk8Alke~N2RGIi@oSw;{68B8`1Q^+X80-49|b zZ2BRCAsgpBHXE1G4HwMHj3gO@QxnGHZ7-h(^wVtcW!=>z$$z|Qn7`Fs*KphCSeSo1 z!<&`;sRQ71gu9uJK<=}2BDZ2PyK*YK^3#CNpZ>W6;BJtg>S-%F)%HVas=RG7r|m|t z>sqjDGPrgsxOURNZpy!of7ny)Ep~X)|6ak))a@!!et{rZ{vn46|oZhXk{00EKK4MP!*>2QcQ+IJRk-_hsDp$mQv;&tvDc zVCQ78dn(vH>0dkLU;6-$aF8F`{5~neBXo|4Ix0DtsJbUGHQ1`K!ce@6d)vt+zNfch zji|uBIc&|;UAtPALl?UsF9vD)RN?LW7=@$6-{~!xFG9~fOZ?;Ba`HA0^!*fX)4ume z4II&w`U&Bui9Pr|F*@={U+jWn(8s#ef;jUKF z#q$Txc>}>+DwISTzd)%2;UK~Y!Vm)1A93efUL(OwsVc?1*rZD!gc`3munyU6a1My^H$F9-)k~x6wgt2pkFs5Dd*!{rgC;yimO#C=cm-s@g?Xds>^dI zi4WN(>;PZ75tHHfD62)NLx>`DAgn~#h=6Nv;WfG?F+2>nTMa4)Q0dlUhRN_##ojOH zQF;U6O$5Ae2UrV=R}g-Oa0B6w2x5canXnfh7fftWCQb+LiZ6U^KwMIzYgj2*;Rkh% zPtdm3EfbFa^OxEdeZt#cOoFdVw;k}h;=Z!`YCwn&!kQ8iywGyn0k4UH9TPjlQv>@& O>p|$?CHfUNru|<9QRiR) diff --git a/src/equipment/service.py b/src/equipment/service.py index c18b2f1..91bc657 100644 --- a/src/equipment/service.py +++ b/src/equipment/service.py @@ -2,7 +2,7 @@ import os import logging from typing import Optional, TypedDict, Any -from sqlalchemy import Select, Delete, Float, func, cast, String, text, case +from sqlalchemy import Select, Delete, Float, func, cast, String, text, case, asc, desc from sqlalchemy.orm import selectinload from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.ext.asyncio import AsyncSession @@ -395,13 +395,17 @@ async def get_top_10_economic_life(*, db_session: DbSession, common) -> list[Equ (current_year - Equipment.minimum_eac_year) >= 0, (current_year - Equipment.minimum_eac_year), ), - else_=0, - ).label("remaining_life") - ) - .filter(Equipment.minimum_eac_year != None) - .filter((Equipment.minimum_eac != None) & (Equipment.minimum_eac != 0)) + ( + (Equipment.minimum_eac_year - current_year) >= 0, + (Equipment.minimum_eac_year - current_year), + ), + else_=0, + ).label("remaining_life") + ) + .filter(Equipment.minimum_eac_year != None) + .filter((Equipment.minimum_eac != None) & (Equipment.minimum_eac != 0)) # .filter((current_year - Equipment.minimum_eac_year) >= 0) - .order_by((current_year - Equipment.minimum_eac_year).desc()) + .order_by(desc("remaining_life")) .order_by(func.abs(Equipment.minimum_eac).desc()) ) @@ -427,13 +431,17 @@ async def get_top_10_replacement_priorities(*, db_session: DbSession, common) -> (current_year - Equipment.minimum_eac_year) >= 0, (current_year - Equipment.minimum_eac_year), ), + ( + (Equipment.minimum_eac_year - current_year) >= 0, + (Equipment.minimum_eac_year - current_year), + ), else_=0, ).label("remaining_life") ) .filter(Equipment.minimum_eac_year != None) .filter((Equipment.minimum_eac != None) & (Equipment.minimum_eac != 0)) # .filter((current_year - Equipment.minimum_eac_year) >= 0) - .order_by((current_year - Equipment.minimum_eac_year).asc()) + .order_by(asc("remaining_life")) .order_by(func.abs(Equipment.minimum_eac).desc()) )