// @ts-nocheck import { QueryClient, UseMutationOptions, UseMutationResult, UseQueryOptions, UseQueryResult, useInfiniteQuery, useMutation, useQuery, useQueryClient, } from 'react-query'; import useApiRequest from '../useRequest'; import { transformToCamelCase } from '@/utils'; import t from './types'; import { BANK_QUERY_KEY } from '@/constants/query-keys/banking'; // Common cache invalidator. const commonInvalidateQueries = (query: QueryClient) => { query.invalidateQueries(BANK_QUERY_KEY.BANK_RULES); query.invalidateQueries(BANK_QUERY_KEY.RECOGNIZED_BANK_TRANSACTIONS_INFINITY); }; interface CreateBankRuleValues { value: any; } interface CreateBankRuleResponse {} /** * Creates a new bank rule. * @param {UseMutationOptions} options - * @returns {UseMutationResult}TCHES */ export function useCreateBankRule( options?: UseMutationOptions< CreateBankRuleValues, Error, CreateBankRuleValues >, ): UseMutationResult { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation( (values) => apiRequest.post(`/banking/rules`, values).then((res) => res.data), { ...options, onSuccess: () => { commonInvalidateQueries(queryClient); }, }, ); } interface DisconnectBankAccountRes {} interface DisconnectBankAccountValues { bankAccountId: number; } /** * Disconnects the given bank account. * @param {UseMutationOptions} options * @returns {UseMutationResult} */ export function useDisconnectBankAccount( options?: UseMutationOptions< DisconnectBankAccountRes, Error, DisconnectBankAccountValues >, ): UseMutationResult< DisconnectBankAccountRes, Error, DisconnectBankAccountValues > { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation< DisconnectBankAccountRes, Error, DisconnectBankAccountValues >( ({ bankAccountId }) => apiRequest.post(`/banking/bank_accounts/${bankAccountId}/disconnect`), { ...options, onSuccess: (res, values) => { queryClient.invalidateQueries([t.ACCOUNT, values.bankAccountId]); }, }, ); } interface UpdateBankAccountRes {} interface UpdateBankAccountValues { bankAccountId: number; } /** * Update the bank transactions of the bank account. * @param {UseMutationOptions} * @returns {UseMutationResult} */ export function useUpdateBankAccount( options?: UseMutationOptions< UpdateBankAccountRes, Error, UpdateBankAccountValues >, ): UseMutationResult { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation( ({ bankAccountId }) => apiRequest.post(`/banking/bank_accounts/${bankAccountId}/update`), { ...options, onSuccess: () => {}, }, ); } interface EditBankRuleValues { id: number; value: any; } interface EditBankRuleResponse {} /** * Edits the given bank rule. * @param {UseMutationOptions} options - * @returns */ export function useEditBankRule( options?: UseMutationOptions, ): UseMutationResult { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation( ({ id, value }) => apiRequest.post(`/banking/rules/${id}`, value), { ...options, onSuccess: () => { commonInvalidateQueries(queryClient); }, }, ); } interface DeleteBankRuleResponse {} type DeleteBankRuleValue = number; /** * Deletes the given bank rule. * @param {UseMutationOptions} options * @returns {UseMutationResult, ): UseMutationResult { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation( (id: number) => apiRequest.delete(`/banking/rules/${id}`), { onSuccess: (res, id) => { commonInvalidateQueries(queryClient); queryClient.invalidateQueries( BANK_QUERY_KEY.RECOGNIZED_BANK_TRANSACTIONS_INFINITY, ); queryClient.invalidateQueries([ t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY, ]); }, ...options, }, ); } interface BankRulesResponse {} /** * Retrieves all bank rules. * @param {UseQueryOptions} params - * @returns {UseQueryResult} */ export function useBankRules( options?: UseQueryOptions, ): UseQueryResult { const apiRequest = useApiRequest(); return useQuery( [BANK_QUERY_KEY.BANK_RULES], () => apiRequest.get('/banking/rules').then((res) => res.data.bank_rules), { ...options }, ); } interface GetBankRuleRes {} /** * Retrieve the given bank rule. * @param {number} bankRuleId - * @param {UseQueryOptions} options - * @returns {UseQueryResult} */ export function useBankRule( bankRuleId: number, options?: UseQueryOptions, ): UseQueryResult { const apiRequest = useApiRequest(); return useQuery( [BANK_QUERY_KEY.BANK_RULES, bankRuleId], () => apiRequest .get(`/banking/rules/${bankRuleId}`) .then((res) => res.data.bank_rule), { ...options }, ); } interface GetBankTransactionsMatchesValue { uncategorizeTransactionsIds: Array; } interface GetBankTransactionsMatchesResponse { perfectMatches: Array; possibleMatches: Array; totalPending: number; } /** * Retrieves the bank transactions matches. * @param {UseQueryOptions} params - * @returns {UseQueryResult} */ export function useGetBankTransactionsMatches( uncategorizeTransactionsIds: Array, options?: UseQueryOptions, ): UseQueryResult { const apiRequest = useApiRequest(); return useQuery( [BANK_QUERY_KEY.BANK_TRANSACTION_MATCHES, uncategorizeTransactionsIds], () => apiRequest .get(`/cashflow/transactions/matches`, { params: { uncategorizeTransactionsIds }, }) .then((res) => transformToCamelCase(res.data)), options, ); } const onValidateExcludeUncategorizedTransaction = (queryClient) => { // Invalidate queries. queryClient.invalidateQueries( BANK_QUERY_KEY.EXCLUDED_BANK_TRANSACTIONS_INFINITY, ); queryClient.invalidateQueries( t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY, ); // Invalidate accounts. queryClient.invalidateQueries(t.ACCOUNTS); queryClient.invalidateQueries(t.ACCOUNT); // invalidate bank account summary. queryClient.invalidateQueries(BANK_QUERY_KEY.BANK_ACCOUNT_SUMMARY_META); // Invalidate the recognized transactions. queryClient.invalidateQueries([ BANK_QUERY_KEY.RECOGNIZED_BANK_TRANSACTIONS_INFINITY, ]); }; type ExcludeUncategorizedTransactionValue = number; interface ExcludeUncategorizedTransactionRes {} /** * Excludes the given uncategorized transaction. * @param {UseMutationOptions} * @returns {UseMutationResult } */ export function useExcludeUncategorizedTransaction( options?: UseMutationOptions< ExcludeUncategorizedTransactionRes, Error, ExcludeUncategorizedTransactionValue >, ): UseMutationResult< ExcludeUncategorizedTransactionRes, Error, ExcludeUncategorizedTransactionValue > { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation< ExcludeUncategorizedTransactionRes, Error, ExcludeUncategorizedTransactionValue >( (uncategorizedTransactionId: number) => apiRequest.put( `/cashflow/transactions/${uncategorizedTransactionId}/exclude`, ), { onSuccess: (res, id) => { onValidateExcludeUncategorizedTransaction(queryClient); }, ...options, }, ); } type ExcludeBankTransactionValue = number; interface ExcludeBankTransactionResponse {} /** * Excludes the uncategorized bank transaction. * @param {UseMutationResult} options * @returns {UseMutationResult} */ export function useUnexcludeUncategorizedTransaction( options?: UseMutationOptions< ExcludeBankTransactionResponse, Error, ExcludeBankTransactionValue >, ): UseMutationResult< ExcludeBankTransactionResponse, Error, ExcludeBankTransactionValue > { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation< ExcludeBankTransactionResponse, Error, ExcludeBankTransactionValue >( (uncategorizedTransactionId: number) => apiRequest.put( `/cashflow/transactions/${uncategorizedTransactionId}/unexclude`, ), { onSuccess: (res, id) => { onValidateExcludeUncategorizedTransaction(queryClient); }, ...options, }, ); } type ExcludeBankTransactionsValue = { ids: Array }; interface ExcludeBankTransactionsResponse {} /** * Excludes the uncategorized bank transactions in bulk. * @param {UseMutationResult} options * @returns {UseMutationResult} */ export function useExcludeUncategorizedTransactions( options?: UseMutationOptions< ExcludeBankTransactionsResponse, Error, ExcludeBankTransactionsValue >, ): UseMutationResult< ExcludeBankTransactionsResponse, Error, ExcludeBankTransactionsValue > { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation< ExcludeBankTransactionsResponse, Error, ExcludeBankTransactionsValue >( (value: { ids: Array }) => apiRequest.put(`/cashflow/transactions/exclude`, { ids: value.ids }), { onSuccess: (res, id) => { onValidateExcludeUncategorizedTransaction(queryClient); }, ...options, }, ); } type UnexcludeBankTransactionsValue = { ids: Array }; interface UnexcludeBankTransactionsResponse {} /** * Excludes the uncategorized bank transactions in bulk. * @param {UseMutationResult} options * @returns {UseMutationResult} */ export function useUnexcludeUncategorizedTransactions( options?: UseMutationOptions< UnexcludeBankTransactionsResponse, Error, UnexcludeBankTransactionsValue >, ): UseMutationResult< UnexcludeBankTransactionsResponse, Error, UnexcludeBankTransactionsValue > { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation< UnexcludeBankTransactionsResponse, Error, UnexcludeBankTransactionsValue >( (value: { ids: Array }) => apiRequest.put(`/cashflow/transactions/unexclude`, { ids: value.ids }), { onSuccess: (res, id) => { onValidateExcludeUncategorizedTransaction(queryClient); }, ...options, }, ); } interface MatchUncategorizedTransactionValues { uncategorizedTransactions: Array; matchedTransactions: Array<{ reference_type: string; reference_id: number }>; } interface MatchUncategorizedTransactionRes {} /** * Matchess the given uncateogrized transaction. * @param props * @returns */ export function useMatchUncategorizedTransaction( props?: UseMutationOptions< MatchUncategorizedTransactionRes, Error, MatchUncategorizedTransactionValues >, ): UseMutationResult< MatchUncategorizedTransactionRes, Error, MatchUncategorizedTransactionValues > { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation< MatchUncategorizedTransactionRes, Error, MatchUncategorizedTransactionValues >((value) => apiRequest.post('/banking/matches/match', value), { onSuccess: (res, id) => { queryClient.invalidateQueries( t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY, ); queryClient.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY); // Invalidate accounts. queryClient.invalidateQueries(t.ACCOUNTS); queryClient.invalidateQueries(t.ACCOUNT); // Invalidate bank account summary. queryClient.invalidateQueries(BANK_QUERY_KEY.BANK_ACCOUNT_SUMMARY_META); }, ...props, }); } interface UnmatchUncategorizedTransactionValues { id: number; } interface UnmatchUncategorizedTransactionRes {} /** * Unmatch the given matched uncategorized transaction. * @param {UseMutationOptions} props * @returns {UseMutationResult} */ export function useUnmatchMatchedUncategorizedTransaction( props?: UseMutationOptions< UnmatchUncategorizedTransactionRes, Error, UnmatchUncategorizedTransactionValues >, ): UseMutationResult< UnmatchUncategorizedTransactionRes, Error, UnmatchUncategorizedTransactionValues > { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); return useMutation< UnmatchUncategorizedTransactionRes, Error, UnmatchUncategorizedTransactionValues >(({ id }) => apiRequest.post(`/banking/matches/unmatch/${id}`), { onSuccess: (res, id) => { queryClient.invalidateQueries( t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY, ); queryClient.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY); // Invalidate accounts. queryClient.invalidateQueries(t.ACCOUNTS); queryClient.invalidateQueries(t.ACCOUNT); // Invalidate bank account summary. queryClient.invalidateQueries(BANK_QUERY_KEY.BANK_ACCOUNT_SUMMARY_META); }, ...props, }); } interface GetRecognizedBankTransactionRes {} /** * REtrieves the given recognized bank transaction. * @param {number} uncategorizedTransactionId * @param {UseQueryOptions} options * @returns {UseQueryResult} */ export function useGetRecognizedBankTransaction( uncategorizedTransactionId: number, options?: UseQueryOptions, ): UseQueryResult { const apiRequest = useApiRequest(); return useQuery( [BANK_QUERY_KEY.RECOGNIZED_BANK_TRANSACTION, uncategorizedTransactionId], () => apiRequest .get(`/banking/recognized/transactions/${uncategorizedTransactionId}`) .then((res) => transformToCamelCase(res.data?.data)), options, ); } interface GetBankAccountSummaryMetaRes { name: string; totalUncategorizedTransactions: number; totalRecognizedTransactions: number; } /** * Get the given bank account meta summary. * @param {number} bankAccountId * @param {UseQueryOptions} options * @returns {UseQueryResult} */ export function useGetBankAccountSummaryMeta( bankAccountId: number, options?: UseQueryOptions, ): UseQueryResult { const apiRequest = useApiRequest(); return useQuery( [BANK_QUERY_KEY.BANK_ACCOUNT_SUMMARY_META, bankAccountId], () => apiRequest .get(`/banking/bank_accounts/${bankAccountId}/meta`) .then((res) => transformToCamelCase(res.data?.data)), { ...options }, ); } export interface GetAutofillCategorizeTransaction { accountId: number | null; amount: number; category: string | null; date: Date; formattedAmount: string; formattedDate: string; isRecognized: boolean; recognizedByRuleId: number | null; recognizedByRuleName: string | null; referenceNo: null | string; isDepositTransaction: boolean; isWithdrawalTransaction: boolean; } export function useGetAutofillCategorizeTransaction( uncategorizedTransactionIds: number[], options: any, ) { const apiRequest = useApiRequest(); return useQuery( [ BANK_QUERY_KEY.AUTOFILL_CATEGORIZE_BANK_TRANSACTION, uncategorizedTransactionIds, ], () => apiRequest .get(`/banking/categorize/autofill`, { params: { uncategorizedTransactionIds }, }) .then((res) => transformToCamelCase(res.data?.data)), { ...options }, ); } /** * @returns */ export function useRecognizedBankTransactionsInfinity( query, infinityProps, axios, ) { const apiRequest = useApiRequest(); return useInfiniteQuery( [BANK_QUERY_KEY.RECOGNIZED_BANK_TRANSACTIONS_INFINITY, query], async ({ pageParam = 1 }) => { const response = await apiRequest.http({ ...axios, method: 'get', url: `/api/banking/recognized`, params: { page: pageParam, ...query }, }); return response.data; }, { getPreviousPageParam: (firstPage) => firstPage.pagination.page - 1, getNextPageParam: (lastPage) => { const { pagination } = lastPage; return pagination.total > pagination.page_size * pagination.page ? lastPage.pagination.page + 1 : undefined; }, ...infinityProps, }, ); } export function useExcludedBankTransactionsInfinity( query, infinityProps, axios, ) { const apiRequest = useApiRequest(); return useInfiniteQuery( [BANK_QUERY_KEY.EXCLUDED_BANK_TRANSACTIONS_INFINITY, query], async ({ pageParam = 1 }) => { const response = await apiRequest.http({ ...axios, method: 'get', url: `/api/cashflow/excluded`, params: { page: pageParam, ...query }, }); return response.data; }, { getPreviousPageParam: (firstPage) => firstPage.pagination.page - 1, getNextPageParam: (lastPage) => { const { pagination } = lastPage; return pagination.total > pagination.page_size * pagination.page ? lastPage.pagination.page + 1 : undefined; }, ...infinityProps, }, ); }