From b12980adfdd67d09bb3bbfc1d946548804400a20 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Thu, 9 Jan 2025 17:14:08 +0800 Subject: [PATCH] update dashboard excel --- .../modules/data/service/DashboardService.kt | 39 +++++++++++++----- .../web/models/ExportDashboardExcelRequest.kt | 4 +- ...shboard] Financial Summary for client.xlsx | Bin 12751 -> 12828 bytes 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt index 394d060..f7600e4 100644 --- a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt +++ b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt @@ -1060,9 +1060,9 @@ open class DashboardService( + " when coalesce(round(p.totalFee / (COALESCE(expenditure.cumulativeExpenditure,0)),3),0) < 1 then 'Negative'" + " end as projectedCashFlowStatus," + " case" - + " when p.totalFee - sum(i.issueAmount) >= 0 then coalesce(round(p.totalFee - sum(i.issueAmount),2),0)" - + " when p.totalFee - sum(i.issueAmount) < 0 then 0" - + " when p.totalFee - sum(i.issueAmount) is null then 0" + + " when p.totalFee - sum(coalesce(i.issueAmount, 0)) >= 0 then coalesce(round(p.totalFee - sum(coalesce(i.issueAmount, 0)),2),0)" + + " when p.totalFee - sum(coalesce(i.issueAmount, 0)) < 0 then 0" + + " when p.totalFee - sum(coalesce(i.issueAmount, 0)) is null then 0" + " end as totalUninvoiced" + " from team t" + " left join (" @@ -1319,9 +1319,9 @@ open class DashboardService( + " when coalesce(round(p.expectedTotalFee / (COALESCE(expenditure.cumulativeExpenditure,0)),3),0) < 1 then 'Negative'" + " end as projectedCashFlowStatus," + " case" - + " when p.expectedTotalFee - sum(i.issueAmount) >= 0 then coalesce(round(p.expectedTotalFee - sum(i.issueAmount),2),0)" - + " when p.expectedTotalFee - sum(i.issueAmount) < 0 then 0" - + " when p.expectedTotalFee - sum(i.issueAmount) is null then 0" + + " when p.expectedTotalFee - sum(coalesce(i.issueAmount, 0)) >= 0 then coalesce(round(p.expectedTotalFee - sum(coalesce(i.issueAmount, 0)),2),0)" + + " when p.expectedTotalFee - sum(coalesce(i.issueAmount, 0)) < 0 then 0" + + " when p.expectedTotalFee - sum(coalesce(i.issueAmount, 0)) is null then 0" + " end as totalUninvoiced" + " from team t" + " left join project p on t.teamLead = p.teamLead" @@ -3449,7 +3449,7 @@ open class DashboardService( } createCell(9).apply { - setCellValue(financialSummaryByClient.cumulativeExpenditure) + setCellValue(financialSummaryByClient.totalExpenditure) cellStyle.apply { setFont(normalFont) dataFormat = accountingStyle @@ -3457,8 +3457,9 @@ open class DashboardService( CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) } + createCell(10).apply { - setCellValue(financialSummaryByClient.totalInvoiced) + setCellValue(financialSummaryByClient.manhoursExpenditure) cellStyle.apply { setFont(normalFont) dataFormat = accountingStyle @@ -3467,7 +3468,7 @@ open class DashboardService( } createCell(11).apply { - cellFormula = "IF(H${rowIndex}-K${rowIndex}<0,0,H${rowIndex}-K${rowIndex})" + setCellValue(financialSummaryByClient.projectExpense) cellStyle.apply { setFont(normalFont) dataFormat = accountingStyle @@ -3476,6 +3477,24 @@ open class DashboardService( } createCell(12).apply { + setCellValue(financialSummaryByClient.totalInvoiced) + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(13).apply { + cellFormula = "IF(H${rowIndex}-M${rowIndex}<0,0,H${rowIndex}-M${rowIndex})" + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(14).apply { setCellValue(financialSummaryByClient.totalReceived) cellStyle.apply { setFont(normalFont) @@ -3903,7 +3922,7 @@ open class DashboardService( } createCell(14).apply { - cellFormula = "IF(I${rowIndex}-L${rowIndex}<0,0,I${rowIndex}-N${rowIndex})" + cellFormula = "IF(I${rowIndex}-N${rowIndex}<0,0,I${rowIndex}-N${rowIndex})" cellStyle.apply { setFont(normalFont) dataFormat = accountingStyle diff --git a/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt b/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt index 9b87a43..ba44282 100644 --- a/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt +++ b/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt @@ -8,7 +8,9 @@ data class FinancialSummaryByClient ( val projectNo: Double, val totalFee: Double, val totalBudget: Double, - val cumulativeExpenditure: Double, + val totalExpenditure: Double, + val manhoursExpenditure: Double, + val projectExpense: Double, val totalInvoiced: Double, val totalReceived: Double, ) diff --git a/src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx b/src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx index 7eb2f65ede65aeb9b01635824c18df75206c4f0d..5d18dd65bd990b7dc69d98b77ac8bab13f912e0c 100644 GIT binary patch delta 3232 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 NEXj9iQS86q{{YVK?cD$X delta 3171 zcmY+Gc{J3E8^*tbX*4mmNf`US?^$EA-fImPg(kbmzD2~?*OBE*vSdvn>kL9}w`3VFzS%^+L!2fJg}dGynhux=93h z`ncM8db)}Sy1P}FxqB8X(EbYjd=Bdlfb+LNuVbQV{W7x6GL|Qmg-n*1O7B1iCtm8* zPhN!Dzt#>pU=v=AG0noRW3XGDg`&r!+=qIspi`0Yu<(%Bwfq8niXT( z_|Y5N@2VtCDwA!SK06uMk4YTAx>9`!81r#p)V*Hou4gg~9}t-xW-h$^e)h#FnKn^R@+fGC(m>Hg#PT(}<}kfTfy9-s?^P_d#KT|L1iGUV zx5^=LS4FadHg6gfb8m0x4MFc^%pEWu_nNn3CBo1?HeQFG5ygbtW;jamV@nLAZU$7{ zmBh#)ujqR{wwtC%aryflL;;!sESqJ8MPXVrMc zi{w^6>S}CCt#||+yi>RP!pjvZ^S4?Dnj9Nopaw8`)cM~egdANWz zF*df>5@<2!tY_QL&oGNs5mJaFJ{xVb_ViAy5FbaP=jVk@9feFl9BA_}EUQ`t~EmGgy*ck%oiDouIYz z^JFeE8qJpR`BwT%)1;RHDT%PNOIg_Pvz51813HKs>`aQ^QBUfL8=^NnUb;@??<9D-8j3B}B_KX0Wlyb(ozK3e`EuJ;K| zbxPQrw4Iq{XP$Xqd}Hr3QMFcS1?ANd&|Y>py7W@{v0amJJGWm5?cKIRl%oU|D*2=c zXcjgN=a-YdMOmU!NF}aEBM|k22G^_#A8ej@rMz*!qW8LOqpbO6?+b?ltJT@&`L!^O zKKk0w!p0%v%wd&F9ehpKV)B{?sZtjZ_0XAe<+5gGivBQ>om}r#DwX$N+TXM|uUe+c zdsW6~HvfUneL31a-t?Ix`sl(Ln}or1pH?S1S=baZlC1&njD4F8Ybd<;5fDO-qGX;%k+)Pj(N1Hmlyx$ZTJaEj-rtLym>EUBW`vtu^L_JV|JlYvnw<4e z`^-8}3Aa-Ah17>M{{842l4CdpVIu;9ygr_s&ZU3 zJ^NLQjXqC?)W3~duLa9mGy8`~09Z(l1WP3lgmgF`8KUrKKgbIO0B!^TFah8dNfvBw zI>vKS5*f28uz}WmClC+Pl5v}giCLETtC!4FC3&|$pugWBR5$wT^oapI@l|;Ry%!G6 z-nO!+!fgE`ar%*yiMR1f%D1XMcXWCZGS`tRs)Iq7ebV`t5*CXbgo1407=2YN%VyML z6I5>-Vj)7DXyT*=DNrxca4I zTMiYt$0qcSD7L6`Tz{NR7(h!+1XEqEy`NRveRQJXxk@*g_HlPJsv}ikLPj1-vlRzd z<-dGrW$qOf%@NfjHkhvWq~UQ!k+m)Q^0~{8L%YZE!6Ty0KQVmrjR6evtNc4%f@=#T zXXysjtbzVUZr28zliF-OfrS&bL0htxgqD7yYe1y}Qzx<`Ra9?;k9|hVDRyS-IpMhy zvvRiRHPQQ~GAU81yTY2a1-$pMB%HPHv)w`lTwkX8jjV+?H6t*Kt3p`>Yty-Oq*`j- zt9N+)TNa4YmtowdyZ7Z{-Gw50g5S+LPie65OAFnzaPgm5Pr9dZVm&ySPGd}6rgRT}^m1r50?DKUK!^{%H?(lRLr(^@;EgHbe z9kT9h-~q_XKG)4V8c+9yDvsKI?%>pTnhkQ>f|(Z8y|s71_eYQu>vpJ|cTzYp9qIN} zC|)fDX=fEjBN#T`WPqixi`21nWsUY5ggvlvq0M=`WtFiJ*JXr@T+-kDl6U(0CPu9? zz;-ySQ)c(wMUB_OJsAbYbrJ&j{kBc3y*w2;x?4bHpQF2XQUL)Lw~|(+cGqgo z&tU*?aq;Ivy0~xyEj%J6X>V3XECW(8Kp{Srg|cvpi&otLi#Flr{J!rxAQjlV6`jXH zu#>`^gjP*9iFGTSL5nF69e%D@f&GI{drEOal;CuaVo(9?^9JjBakWRfImi%Xp-r-S z%}*EB%8tB(7X?Lgnra3eSrNSueSdr%!~8?H2^Kw~vg58w*_7aAVzUUW09pPhz)mi@ zm;Uq8X)y%r+WtArd1#JFFtVIsL$hayYxU>ojl1i%Ee#Kj9sogRE{y~9!C&{#B$gdV zj8aUzT8_1!Bn6P>SVcHc z@Ft3U6r6c|JO=;q%NfG0wdx-xe}lnc(?&cxC8@Nqd^@n=r%4^<4Yw#e$VX+5!Yllz zoC^{0Z<9jK2QQ&$!U6~C9rD-L9r*k+Y&D)Y$n2no+?utcEBlmUUD6D}qfluU^ec>RwzlT^`>qN)A7Xwp8aktzPRy6 zUhCwGG?Z@~dnbi4Vs!n;#ZL8GL5s^Ix?}NRzjn+zK1=SmFGW>G2znacx7l&Y+`{>7zbP8OLc1=m>a8!%j9%u%v4%dpYoCzvZk=Uz)VPqQcIPdfV+ZmSaSyF(0RI zG0l!=q1NIz)L%wQ(4)_|0vE{RY1DxLz%UuO#>R>r(e3)nKB1)fl-G}H{ox6?1`Xvz zjg)TcgjO)zG97)Utbmqc@kHiNS zh-&7*Z`wP(EQ3UZO3rerK-nS1cGWiX>v%bkce_Y?=={CMu;$W)(vT4QjM6qL_U;Kw zD%KCYi|e}`zx+XxR*os5DU&L~xEhjJt)3T@QJS9l!HWm!X+u}H>;X%q(kdP{$~Ma5 z4<>a4zf!m5`^Bx|Gn4xCDR-;S0TkLXUDx1Z{1BKPHh@{Lo4ar9AGk+7rj(dvh3)Q|*J3c!Z`JlFQRaZJc zXN5Axc@GrHLKt2pAL~>hEbjtPGX-(t(_5O_QZ?>KsGH__H2MxxM zP%6X^!D3vyIRE4dJEiG3)ifBV;nlHaYqhkk!6nVa=QZHFDeCohH}9v3>rD_#-c=_j z!@&I}(TH1;=4MJ-vfP4zm~h!1mzKn_+}*-vq-;hYsFA{0MdR+}Dk>+(Y9i<9)Q$*FJKYdRa;Y;if4mkdDZ0Jc8lz?B*FT70= z)zJ0DJETiX=hL=9EH*>V`S23|Bmklmf*>m@M}GO=unzi47(yO`of2ZG|E7XJec|6K z1L2Zd5OUB+@+Ng3)8EnF*YA;=qc6xMiDdo%ApijKU(H|5GdA!i8zaakNek{uvOpL> rgp?8FDrhaGg!+5Ke_oF@8354zN2CqbNvV