11import { useMemo } from 'react' ;
22import { Transaction } from '@app/shared' ;
3- import { isInternalTransfer } from '../utils/transactionUtils' ;
3+ import { isInternalTransfer , isLoanCategory } from '../utils/transactionUtils' ;
44
55interface AnalyticsData {
66 totalIncome : number ;
@@ -73,6 +73,12 @@ function parseTransactionDate(dateValue: string): Date {
7373 return new Date ( dateValue ) ;
7474}
7575
76+ /** Exclude mortgage/loan category from analytics spending charts and related totals */
77+ function skipLoanExpense ( t : Transaction ) : boolean {
78+ const amount = t . chargedAmount || t . amount || 0 ;
79+ return amount < 0 && isLoanCategory ( t . category ) ;
80+ }
81+
7682export function useAnalytics ( transactions : Transaction [ ] , customCCKeywords : string [ ] = [ ] ) : AnalyticsData {
7783 return useMemo ( ( ) => {
7884 if ( ! transactions || transactions . length === 0 ) {
@@ -94,6 +100,7 @@ export function useAnalytics(transactions: Transaction[], customCCKeywords: stri
94100
95101 transactions . forEach ( t => {
96102 if ( isInternalTransfer ( t , customCCKeywords ) ) return ;
103+ if ( skipLoanExpense ( t ) ) return ;
97104 const amount = t . chargedAmount || t . amount || 0 ;
98105 if ( amount > 0 ) {
99106 totalIncome += amount ;
@@ -106,6 +113,7 @@ export function useAnalytics(transactions: Transaction[], customCCKeywords: stri
106113 const categoryMap = new Map < string , number > ( ) ;
107114 transactions . forEach ( t => {
108115 if ( isInternalTransfer ( t , customCCKeywords ) ) return ;
116+ if ( skipLoanExpense ( t ) ) return ;
109117 const category = t . category || 'אחר' ;
110118 const amount = Math . abs ( t . chargedAmount || t . amount || 0 ) ;
111119
@@ -138,7 +146,7 @@ export function useAnalytics(transactions: Transaction[], customCCKeywords: stri
138146 const entry = monthMap . get ( monthKey ) ! ;
139147 if ( amount > 0 ) {
140148 entry . income += amount ;
141- } else {
149+ } else if ( ! skipLoanExpense ( t ) ) {
142150 entry . expenses += Math . abs ( amount ) ;
143151 }
144152 } ) ;
@@ -155,6 +163,7 @@ export function useAnalytics(transactions: Transaction[], customCCKeywords: stri
155163 const weekdayMap = new Map < number , number > ( ) ;
156164 transactions . forEach ( t => {
157165 if ( isInternalTransfer ( t , customCCKeywords ) ) return ;
166+ if ( skipLoanExpense ( t ) ) return ;
158167 const amount = t . chargedAmount || t . amount || 0 ;
159168 if ( amount >= 0 ) return ;
160169
@@ -172,6 +181,7 @@ export function useAnalytics(transactions: Transaction[], customCCKeywords: stri
172181 const monthDayMap = new Map < number , number > ( ) ;
173182 transactions . forEach ( t => {
174183 if ( isInternalTransfer ( t , customCCKeywords ) ) return ;
184+ if ( skipLoanExpense ( t ) ) return ;
175185 const amount = t . chargedAmount || t . amount || 0 ;
176186 if ( amount >= 0 ) return ;
177187
@@ -191,6 +201,7 @@ export function useAnalytics(transactions: Transaction[], customCCKeywords: stri
191201 const merchantMap = new Map < string , { count : number ; total : number } > ( ) ;
192202 transactions . forEach ( t => {
193203 if ( isInternalTransfer ( t , customCCKeywords ) ) return ;
204+ if ( skipLoanExpense ( t ) ) return ;
194205 const desc = t . description ;
195206 if ( ! merchantMap . has ( desc ) ) {
196207 merchantMap . set ( desc , { count : 0 , total : 0 } ) ;
0 commit comments