mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
refactor(nestjs): hook up new endpoints
This commit is contained in:
@@ -1,12 +1,25 @@
|
|||||||
import { Controller, Param, Post } from '@nestjs/common';
|
import { Controller, Get, Param, Post, Query } from '@nestjs/common';
|
||||||
import { BankAccountsApplication } from './BankAccountsApplication.service';
|
import { BankAccountsApplication } from './BankAccountsApplication.service';
|
||||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { ICashflowAccountsFilter } from './types/BankAccounts.types';
|
||||||
|
|
||||||
@Controller('banking/accounts')
|
@Controller('banking/accounts')
|
||||||
@ApiTags('banking-accounts')
|
@ApiTags('banking-accounts')
|
||||||
export class BankAccountsController {
|
export class BankAccountsController {
|
||||||
constructor(private bankAccountsApplication: BankAccountsApplication) {}
|
constructor(private bankAccountsApplication: BankAccountsApplication) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@ApiOperation({ summary: 'Retrieve the bank accounts.' })
|
||||||
|
getBankAccounts(@Query() filterDto: ICashflowAccountsFilter) {
|
||||||
|
return this.bankAccountsApplication.getBankAccounts(filterDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':bankAccountId/summary')
|
||||||
|
@ApiOperation({ summary: 'Retrieve the bank account summary.' })
|
||||||
|
getBankAccountSummary(@Param('bankAccountId') bankAccountId: number) {
|
||||||
|
return this.bankAccountsApplication.getBankAccountSumnmary(bankAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
@Post(':id/disconnect')
|
@Post(':id/disconnect')
|
||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
summary: 'Disconnect the bank connection of the given bank account.',
|
summary: 'Disconnect the bank connection of the given bank account.',
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import { PlaidModule } from '../Plaid/Plaid.module';
|
|||||||
import { BankRulesModule } from '../BankRules/BankRules.module';
|
import { BankRulesModule } from '../BankRules/BankRules.module';
|
||||||
import { BankingTransactionsRegonizeModule } from '../BankingTranasctionsRegonize/BankingTransactionsRegonize.module';
|
import { BankingTransactionsRegonizeModule } from '../BankingTranasctionsRegonize/BankingTransactionsRegonize.module';
|
||||||
import { BankingTransactionsModule } from '../BankingTransactions/BankingTransactions.module';
|
import { BankingTransactionsModule } from '../BankingTransactions/BankingTransactions.module';
|
||||||
|
import { GetBankAccountsService } from './queries/GetBankAccounts';
|
||||||
|
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
||||||
|
import { GetBankAccountSummary } from './queries/GetBankAccountSummary';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -20,6 +23,7 @@ import { BankingTransactionsModule } from '../BankingTransactions/BankingTransac
|
|||||||
BankRulesModule,
|
BankRulesModule,
|
||||||
BankingTransactionsRegonizeModule,
|
BankingTransactionsRegonizeModule,
|
||||||
BankingTransactionsModule,
|
BankingTransactionsModule,
|
||||||
|
DynamicListModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
DisconnectBankAccountService,
|
DisconnectBankAccountService,
|
||||||
@@ -29,6 +33,8 @@ import { BankingTransactionsModule } from '../BankingTransactions/BankingTransac
|
|||||||
DeleteUncategorizedTransactionsOnAccountDeleting,
|
DeleteUncategorizedTransactionsOnAccountDeleting,
|
||||||
DisconnectPlaidItemOnAccountDeleted,
|
DisconnectPlaidItemOnAccountDeleted,
|
||||||
BankAccountsApplication,
|
BankAccountsApplication,
|
||||||
|
GetBankAccountsService,
|
||||||
|
GetBankAccountSummary
|
||||||
],
|
],
|
||||||
exports: [BankAccountsApplication],
|
exports: [BankAccountsApplication],
|
||||||
controllers: [BankAccountsController],
|
controllers: [BankAccountsController],
|
||||||
|
|||||||
@@ -3,16 +3,39 @@ import { DisconnectBankAccountService } from './commands/DisconnectBankAccount.s
|
|||||||
import { RefreshBankAccountService } from './commands/RefreshBankAccount.service';
|
import { RefreshBankAccountService } from './commands/RefreshBankAccount.service';
|
||||||
import { ResumeBankAccountFeedsService } from './commands/ResumeBankAccountFeeds.service';
|
import { ResumeBankAccountFeedsService } from './commands/ResumeBankAccountFeeds.service';
|
||||||
import { PauseBankAccountFeeds } from './commands/PauseBankAccountFeeds.service';
|
import { PauseBankAccountFeeds } from './commands/PauseBankAccountFeeds.service';
|
||||||
|
import { GetBankAccountsService } from './queries/GetBankAccounts';
|
||||||
|
import { ICashflowAccountsFilter } from './types/BankAccounts.types';
|
||||||
|
import { GetBankAccountSummary } from './queries/GetBankAccountSummary';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BankAccountsApplication {
|
export class BankAccountsApplication {
|
||||||
constructor(
|
constructor(
|
||||||
private disconnectBankAccountService: DisconnectBankAccountService,
|
private readonly getBankAccountsService: GetBankAccountsService,
|
||||||
|
private readonly getBankAccountSummaryService: GetBankAccountSummary,
|
||||||
|
private readonly disconnectBankAccountService: DisconnectBankAccountService,
|
||||||
private readonly refreshBankAccountService: RefreshBankAccountService,
|
private readonly refreshBankAccountService: RefreshBankAccountService,
|
||||||
private readonly resumeBankAccountFeedsService: ResumeBankAccountFeedsService,
|
private readonly resumeBankAccountFeedsService: ResumeBankAccountFeedsService,
|
||||||
private readonly pauseBankAccountFeedsService: PauseBankAccountFeeds,
|
private readonly pauseBankAccountFeedsService: PauseBankAccountFeeds,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the bank accounts.
|
||||||
|
* @param {ICashflowAccountsFilter} filterDto -
|
||||||
|
*/
|
||||||
|
getBankAccounts(filterDto: ICashflowAccountsFilter) {
|
||||||
|
return this.getBankAccountsService.getCashflowAccounts(filterDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the given bank account summary.
|
||||||
|
* @param {number} bankAccountId
|
||||||
|
*/
|
||||||
|
getBankAccountSumnmary(bankAccountId: number) {
|
||||||
|
return this.getBankAccountSummaryService.getBankAccountSummary(
|
||||||
|
bankAccountId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects the given bank account.
|
* Disconnects the given bank account.
|
||||||
* @param {number} bankAccountId - Bank account identifier.
|
* @param {number} bankAccountId - Bank account identifier.
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import { ACCOUNT_TYPE } from '@/constants/accounts';
|
||||||
|
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||||
|
import { CashflowAccountTransformer } from '@/modules/BankingTransactions/queries/BankAccountTransformer';
|
||||||
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
|
import { ICashflowAccountsFilter } from '../types/BankAccounts.types';
|
||||||
|
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
|
||||||
|
import { DynamicListService } from '@/modules/DynamicListing/DynamicList.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetBankAccountsService {
|
||||||
|
constructor(
|
||||||
|
private readonly dynamicListService: DynamicListService,
|
||||||
|
private readonly transformer: TransformerInjectable,
|
||||||
|
|
||||||
|
@Inject(Account.name)
|
||||||
|
private readonly accountModel: TenantModelProxy<typeof Account>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the cash flow accounts.
|
||||||
|
* @param {ICashflowAccountsFilter} filterDTO - Filter DTO.
|
||||||
|
* @returns {ICashflowAccount[]}
|
||||||
|
*/
|
||||||
|
public async getCashflowAccounts(filterDTO: ICashflowAccountsFilter) {
|
||||||
|
const _filterDto = {
|
||||||
|
sortOrder: 'desc',
|
||||||
|
columnSortBy: 'created_at',
|
||||||
|
inactiveMode: false,
|
||||||
|
...filterDTO,
|
||||||
|
};
|
||||||
|
// Parsees accounts list filter DTO.
|
||||||
|
const filter = this.dynamicListService.parseStringifiedFilter(_filterDto);
|
||||||
|
|
||||||
|
// Dynamic list service.
|
||||||
|
const dynamicList = await this.dynamicListService.dynamicList(
|
||||||
|
this.accountModel(),
|
||||||
|
filter,
|
||||||
|
);
|
||||||
|
// Retrieve accounts model based on the given query.
|
||||||
|
const accounts = await this.accountModel()
|
||||||
|
.query()
|
||||||
|
.onBuild((builder) => {
|
||||||
|
dynamicList.buildQuery()(builder);
|
||||||
|
|
||||||
|
builder.whereIn('account_type', [
|
||||||
|
ACCOUNT_TYPE.BANK,
|
||||||
|
ACCOUNT_TYPE.CASH,
|
||||||
|
ACCOUNT_TYPE.CREDIT_CARD,
|
||||||
|
]);
|
||||||
|
builder.modify('inactiveMode', filter.inactiveMode);
|
||||||
|
});
|
||||||
|
// Retrieves the transformed accounts.
|
||||||
|
const transformed = await this.transformer.transform(
|
||||||
|
accounts,
|
||||||
|
new CashflowAccountTransformer(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return transformed;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
|
|
||||||
export interface IBankAccountDisconnectingEventPayload {
|
export interface IBankAccountDisconnectingEventPayload {
|
||||||
@@ -15,3 +16,11 @@ export const ERRORS = {
|
|||||||
BANK_ACCOUNT_FEEDS_ALREADY_PAUSED: 'BANK_ACCOUNT_FEEDS_ALREADY_PAUSED',
|
BANK_ACCOUNT_FEEDS_ALREADY_PAUSED: 'BANK_ACCOUNT_FEEDS_ALREADY_PAUSED',
|
||||||
BANK_ACCOUNT_FEEDS_ALREADY_RESUMED: 'BANK_ACCOUNT_FEEDS_ALREADY_RESUMED',
|
BANK_ACCOUNT_FEEDS_ALREADY_RESUMED: 'BANK_ACCOUNT_FEEDS_ALREADY_RESUMED',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export interface ICashflowAccountsFilter extends IDynamicListFilter{
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
inactiveMode: boolean;
|
||||||
|
viewSlug?: string;
|
||||||
|
}
|
||||||
@@ -9,7 +9,10 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { BankingTransactionsApplication } from './BankingTransactionsApplication.service';
|
import { BankingTransactionsApplication } from './BankingTransactionsApplication.service';
|
||||||
import { IBankAccountsFilter } from './types/BankingTransactions.types';
|
import {
|
||||||
|
IBankAccountsFilter,
|
||||||
|
ICashflowAccountTransactionsQuery,
|
||||||
|
} from './types/BankingTransactions.types';
|
||||||
import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto';
|
import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto';
|
||||||
|
|
||||||
@Controller('banking/transactions')
|
@Controller('banking/transactions')
|
||||||
@@ -19,9 +22,13 @@ export class BankingTransactionsController {
|
|||||||
private readonly bankingTransactionsApplication: BankingTransactionsApplication,
|
private readonly bankingTransactionsApplication: BankingTransactionsApplication,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get('')
|
@Get()
|
||||||
async getBankAccounts(@Query() filterDTO: IBankAccountsFilter) {
|
async getBankAccountTransactions(
|
||||||
return this.bankingTransactionsApplication.getBankAccounts(filterDTO);
|
@Query() query: ICashflowAccountTransactionsQuery,
|
||||||
|
) {
|
||||||
|
return this.bankingTransactionsApplication.getBankAccountTransactions(
|
||||||
|
query,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import { GetBankAccountsService } from './queries/GetBankAccounts.service';
|
|||||||
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
||||||
import { BankAccount } from './models/BankAccount';
|
import { BankAccount } from './models/BankAccount';
|
||||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||||
|
import { GetBankAccountTransactionsService } from './queries/GetBankAccountTransactions/GetBankAccountTransactions.service';
|
||||||
|
import { GetBankAccountTransactionsRepository } from './queries/GetBankAccountTransactions/GetBankAccountTransactionsRepo.service';
|
||||||
|
|
||||||
const models = [
|
const models = [
|
||||||
RegisterTenancyModel(UncategorizedBankTransaction),
|
RegisterTenancyModel(UncategorizedBankTransaction),
|
||||||
@@ -57,6 +59,8 @@ const models = [
|
|||||||
CommandBankTransactionValidator,
|
CommandBankTransactionValidator,
|
||||||
BranchTransactionDTOTransformer,
|
BranchTransactionDTOTransformer,
|
||||||
RemovePendingUncategorizedTransaction,
|
RemovePendingUncategorizedTransaction,
|
||||||
|
GetBankAccountTransactionsRepository,
|
||||||
|
GetBankAccountTransactionsService,
|
||||||
],
|
],
|
||||||
exports: [...models, RemovePendingUncategorizedTransaction],
|
exports: [...models, RemovePendingUncategorizedTransaction],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import { CreateBankTransactionService } from './commands/CreateBankTransaction.s
|
|||||||
import { GetBankTransactionService } from './queries/GetBankTransaction.service';
|
import { GetBankTransactionService } from './queries/GetBankTransaction.service';
|
||||||
import {
|
import {
|
||||||
IBankAccountsFilter,
|
IBankAccountsFilter,
|
||||||
|
ICashflowAccountTransactionsQuery,
|
||||||
} from './types/BankingTransactions.types';
|
} from './types/BankingTransactions.types';
|
||||||
import { GetBankAccountsService } from './queries/GetBankAccounts.service';
|
import { GetBankAccountsService } from './queries/GetBankAccounts.service';
|
||||||
import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto';
|
import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto';
|
||||||
|
import { GetBankAccountTransactionsService } from './queries/GetBankAccountTransactions/GetBankAccountTransactions.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BankingTransactionsApplication {
|
export class BankingTransactionsApplication {
|
||||||
@@ -15,6 +17,7 @@ export class BankingTransactionsApplication {
|
|||||||
private readonly deleteTransactionService: DeleteCashflowTransaction,
|
private readonly deleteTransactionService: DeleteCashflowTransaction,
|
||||||
private readonly getCashflowTransactionService: GetBankTransactionService,
|
private readonly getCashflowTransactionService: GetBankTransactionService,
|
||||||
private readonly getBankAccountsService: GetBankAccountsService,
|
private readonly getBankAccountsService: GetBankAccountsService,
|
||||||
|
private readonly getBankAccountTransactionsService: GetBankAccountTransactionsService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,6 +40,16 @@ export class BankingTransactionsApplication {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the bank transactions of the given bank id.
|
||||||
|
* @param {ICashflowAccountTransactionsQuery} query
|
||||||
|
*/
|
||||||
|
public getBankAccountTransactions(query: ICashflowAccountTransactionsQuery) {
|
||||||
|
return this.getBankAccountTransactionsService.bankAccountTransactions(
|
||||||
|
query,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves specific cashflow transaction.
|
* Retrieves specific cashflow transaction.
|
||||||
* @param {number} cashflowTransactionId
|
* @param {number} cashflowTransactionId
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { getBankAccountTransactionsDefaultQuery } from './_utils';
|
||||||
|
import { GetBankAccountTransactionsRepository } from './GetBankAccountTransactionsRepo.service';
|
||||||
|
import { GetBankAccountTransactions } from './GetBankAccountTransactions';
|
||||||
|
import { ICashflowAccountTransactionsQuery } from '../../types/BankingTransactions.types';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetBankAccountTransactionsService {
|
||||||
|
constructor(
|
||||||
|
private readonly getBankAccountTransactionsRepository: GetBankAccountTransactionsRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the cashflow account transactions report data.
|
||||||
|
* @param {ICashflowAccountTransactionsQuery} query -
|
||||||
|
* @return {Promise<IInvetoryItemDetailDOO>}
|
||||||
|
*/
|
||||||
|
public async bankAccountTransactions(
|
||||||
|
query: ICashflowAccountTransactionsQuery,
|
||||||
|
) {
|
||||||
|
const parsedQuery = {
|
||||||
|
...getBankAccountTransactionsDefaultQuery(),
|
||||||
|
...query,
|
||||||
|
};
|
||||||
|
this.getBankAccountTransactionsRepository.setQuery(parsedQuery);
|
||||||
|
|
||||||
|
await this.getBankAccountTransactionsRepository.asyncInit();
|
||||||
|
|
||||||
|
// Retrieve the computed report.
|
||||||
|
const report = new GetBankAccountTransactions(
|
||||||
|
this.getBankAccountTransactionsRepository,
|
||||||
|
parsedQuery,
|
||||||
|
);
|
||||||
|
const transactions = report.reportData();
|
||||||
|
const pagination = this.getBankAccountTransactionsRepository.pagination;
|
||||||
|
|
||||||
|
return { transactions, pagination };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import R from 'ramda';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { first, isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
ICashflowAccountTransaction,
|
||||||
|
ICashflowAccountTransactionsQuery,
|
||||||
|
} from '../../types/BankingTransactions.types';
|
||||||
|
import { BankTransactionStatus } from './_constants';
|
||||||
|
import { FinancialSheet } from '@/modules/FinancialStatements/common/FinancialSheet';
|
||||||
|
import { formatBankTransactionsStatus } from './_utils';
|
||||||
|
import { GetBankAccountTransactionsRepository } from './GetBankAccountTransactionsRepo.service';
|
||||||
|
import { runningBalance } from '@/utils/running-balance';
|
||||||
|
|
||||||
|
export class GetBankAccountTransactions extends FinancialSheet {
|
||||||
|
private runningBalance: any;
|
||||||
|
private query: ICashflowAccountTransactionsQuery;
|
||||||
|
private repo: GetBankAccountTransactionsRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
* @param {IAccountTransaction[]} transactions -
|
||||||
|
* @param {number} openingBalance -
|
||||||
|
* @param {ICashflowAccountTransactionsQuery} query -
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
repo: GetBankAccountTransactionsRepository,
|
||||||
|
query: ICashflowAccountTransactionsQuery,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.repo = repo;
|
||||||
|
this.query = query;
|
||||||
|
this.runningBalance = runningBalance(this.repo.openingBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the transaction status.
|
||||||
|
* @param {} transaction
|
||||||
|
* @returns {BankTransactionStatus}
|
||||||
|
*/
|
||||||
|
private getTransactionStatus(transaction: any): BankTransactionStatus {
|
||||||
|
const categorizedTrans = this.repo.uncategorizedTransactionsMapByRef.get(
|
||||||
|
`${transaction.referenceType}-${transaction.referenceId}`,
|
||||||
|
);
|
||||||
|
const matchedTrans = this.repo.matchedBankTransactionsMapByRef.get(
|
||||||
|
`${transaction.referenceType}-${transaction.referenceId}`,
|
||||||
|
);
|
||||||
|
if (!isEmpty(categorizedTrans)) {
|
||||||
|
return BankTransactionStatus.Categorized;
|
||||||
|
} else if (!isEmpty(matchedTrans)) {
|
||||||
|
return BankTransactionStatus.Matched;
|
||||||
|
} else {
|
||||||
|
return BankTransactionStatus.Manual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the uncategoized transaction id from the given transaction.
|
||||||
|
* @param transaction
|
||||||
|
* @returns {number|null}
|
||||||
|
*/
|
||||||
|
private getUncategorizedTransId(transaction: any): number {
|
||||||
|
// The given transaction would be categorized, matched or not, so we'd take a look at
|
||||||
|
// the categorized transaction first to get the id if not exist, then should look at the matched
|
||||||
|
// transaction if not exist too, so the given transaction has no uncategorized transaction id.
|
||||||
|
const categorizedTrans = this.repo.uncategorizedTransactionsMapByRef.get(
|
||||||
|
`${transaction.referenceType}-${transaction.referenceId}`,
|
||||||
|
);
|
||||||
|
const matchedTrans = this.repo.matchedBankTransactionsMapByRef.get(
|
||||||
|
`${transaction.referenceType}-${transaction.referenceId}`,
|
||||||
|
);
|
||||||
|
// Relation between the transaction and matching always been one-to-one.
|
||||||
|
const firstCategorizedTrans = first(categorizedTrans);
|
||||||
|
const firstMatchedTrans = first(matchedTrans);
|
||||||
|
|
||||||
|
return (
|
||||||
|
firstCategorizedTrans?.id ||
|
||||||
|
firstMatchedTrans?.uncategorizedTransactionId ||
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Transformes the account transaction to to cashflow transaction node.
|
||||||
|
* @param {IAccountTransaction} transaction
|
||||||
|
* @returns {ICashflowAccountTransaction}
|
||||||
|
*/
|
||||||
|
private transactionNode = (transaction: any): ICashflowAccountTransaction => {
|
||||||
|
const status = this.getTransactionStatus(transaction);
|
||||||
|
const uncategorizedTransactionId =
|
||||||
|
this.getUncategorizedTransId(transaction);
|
||||||
|
|
||||||
|
return {
|
||||||
|
date: transaction.date,
|
||||||
|
formattedDate: moment(transaction.date).format('YYYY-MM-DD'),
|
||||||
|
|
||||||
|
withdrawal: transaction.credit,
|
||||||
|
deposit: transaction.debit,
|
||||||
|
|
||||||
|
formattedDeposit: this.formatNumber(transaction.debit),
|
||||||
|
formattedWithdrawal: this.formatNumber(transaction.credit),
|
||||||
|
|
||||||
|
referenceId: transaction.referenceId,
|
||||||
|
referenceType: transaction.referenceType,
|
||||||
|
|
||||||
|
formattedTransactionType: transaction.referenceTypeFormatted,
|
||||||
|
|
||||||
|
transactionNumber: transaction.transactionNumber,
|
||||||
|
referenceNumber: transaction.referenceNumber,
|
||||||
|
|
||||||
|
runningBalance: this.runningBalance.amount(),
|
||||||
|
formattedRunningBalance: this.formatNumber(this.runningBalance.amount()),
|
||||||
|
|
||||||
|
balance: 0,
|
||||||
|
formattedBalance: '',
|
||||||
|
status,
|
||||||
|
formattedStatus: formatBankTransactionsStatus(status),
|
||||||
|
uncategorizedTransactionId,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associate cashflow transaction node with running balance attribute.
|
||||||
|
* @param {IAccountTransaction} transaction
|
||||||
|
* @returns {ICashflowAccountTransaction}
|
||||||
|
*/
|
||||||
|
private transactionRunningBalance = (
|
||||||
|
transaction: ICashflowAccountTransaction,
|
||||||
|
): ICashflowAccountTransaction => {
|
||||||
|
const amount = transaction.deposit - transaction.withdrawal;
|
||||||
|
|
||||||
|
const biggerThanZero = R.lt(0, amount);
|
||||||
|
const lowerThanZero = R.gt(0, amount);
|
||||||
|
|
||||||
|
const absAmount = Math.abs(amount);
|
||||||
|
|
||||||
|
R.when(R.always(biggerThanZero), this.runningBalance.decrement)(absAmount);
|
||||||
|
R.when(R.always(lowerThanZero), this.runningBalance.increment)(absAmount);
|
||||||
|
|
||||||
|
const runningBalance = this.runningBalance.amount();
|
||||||
|
|
||||||
|
return {
|
||||||
|
...transaction,
|
||||||
|
runningBalance,
|
||||||
|
formattedRunningBalance: this.formatNumber(runningBalance),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associate to balance attribute to cashflow transaction node.
|
||||||
|
* @param {ICashflowAccountTransaction} transaction
|
||||||
|
* @returns {ICashflowAccountTransaction}
|
||||||
|
*/
|
||||||
|
private transactionBalance = (
|
||||||
|
transaction: ICashflowAccountTransaction,
|
||||||
|
): ICashflowAccountTransaction => {
|
||||||
|
const balance =
|
||||||
|
transaction.runningBalance +
|
||||||
|
transaction.withdrawal * -1 +
|
||||||
|
transaction.deposit;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...transaction,
|
||||||
|
balance,
|
||||||
|
formattedBalance: this.formatNumber(balance),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transformes the given account transaction to cashflow report transaction.
|
||||||
|
* @param {ICashflowAccountTransaction} transaction
|
||||||
|
* @returns {ICashflowAccountTransaction}
|
||||||
|
*/
|
||||||
|
private transactionTransformer = (
|
||||||
|
transaction,
|
||||||
|
): ICashflowAccountTransaction => {
|
||||||
|
return R.compose(
|
||||||
|
this.transactionBalance,
|
||||||
|
this.transactionRunningBalance,
|
||||||
|
this.transactionNode,
|
||||||
|
)(transaction);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the report transactions node.
|
||||||
|
* @param {} transactions
|
||||||
|
* @returns {ICashflowAccountTransaction[]}
|
||||||
|
*/
|
||||||
|
private transactionsNode = (transactions): ICashflowAccountTransaction[] => {
|
||||||
|
return R.map(this.transactionTransformer)(transactions);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the reprot data node.
|
||||||
|
* @returns {ICashflowAccountTransaction[]}
|
||||||
|
*/
|
||||||
|
public reportData(): ICashflowAccountTransaction[] {
|
||||||
|
return this.transactionsNode(this.repo.transactions);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import { Injectable, Scope } from '@nestjs/common';
|
||||||
|
import { ICashflowAccountTransactionsQuery } from '../../types/BankingTransactions.types';
|
||||||
|
import {
|
||||||
|
groupMatchedBankTransactions,
|
||||||
|
groupUncategorizedTransactions,
|
||||||
|
} from './_utils';
|
||||||
|
|
||||||
|
@Injectable({ scope: Scope.REQUEST })
|
||||||
|
export class GetBankAccountTransactionsRepository {
|
||||||
|
private models: any;
|
||||||
|
public query: ICashflowAccountTransactionsQuery;
|
||||||
|
public transactions: any;
|
||||||
|
public uncategorizedTransactions: any;
|
||||||
|
public uncategorizedTransactionsMapByRef: Map<string, any>;
|
||||||
|
public matchedBankTransactions: any;
|
||||||
|
public matchedBankTransactionsMapByRef: Map<string, any>;
|
||||||
|
public pagination: any;
|
||||||
|
public openingBalance: any;
|
||||||
|
|
||||||
|
setQuery(query: ICashflowAccountTransactionsQuery) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Async initalize the resources.
|
||||||
|
*/
|
||||||
|
async asyncInit() {
|
||||||
|
await this.initCashflowAccountTransactions();
|
||||||
|
await this.initCashflowAccountOpeningBalance();
|
||||||
|
await this.initCategorizedTransactions();
|
||||||
|
await this.initMatchedTransactions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the cashflow account transactions.
|
||||||
|
* @param {number} tenantId -
|
||||||
|
* @param {ICashflowAccountTransactionsQuery} query -
|
||||||
|
*/
|
||||||
|
async initCashflowAccountTransactions() {
|
||||||
|
const { AccountTransaction } = this.models;
|
||||||
|
|
||||||
|
const { results, pagination } = await AccountTransaction.query()
|
||||||
|
.where('account_id', this.query.accountId)
|
||||||
|
.orderBy([
|
||||||
|
{ column: 'date', order: 'desc' },
|
||||||
|
{ column: 'created_at', order: 'desc' },
|
||||||
|
])
|
||||||
|
.pagination(this.query.page - 1, this.query.pageSize);
|
||||||
|
|
||||||
|
this.transactions = results;
|
||||||
|
this.pagination = pagination;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the cashflow account opening balance.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} accountId
|
||||||
|
* @param {IPaginationMeta} pagination
|
||||||
|
* @return {Promise<number>}
|
||||||
|
*/
|
||||||
|
async initCashflowAccountOpeningBalance(): Promise<void> {
|
||||||
|
const { AccountTransaction } = this.models;
|
||||||
|
|
||||||
|
// Retrieve the opening balance of credit and debit balances.
|
||||||
|
const openingBalancesSubquery = AccountTransaction.query()
|
||||||
|
.where('account_id', this.query.accountId)
|
||||||
|
.orderBy([
|
||||||
|
{ column: 'date', order: 'desc' },
|
||||||
|
{ column: 'created_at', order: 'desc' },
|
||||||
|
])
|
||||||
|
.limit(this.pagination.total)
|
||||||
|
.offset(this.pagination.pageSize * (this.pagination.page - 1));
|
||||||
|
|
||||||
|
// Sumation of credit and debit balance.
|
||||||
|
const openingBalances = await AccountTransaction.query()
|
||||||
|
.sum('credit as credit')
|
||||||
|
.sum('debit as debit')
|
||||||
|
.from(openingBalancesSubquery.as('T'))
|
||||||
|
.first();
|
||||||
|
|
||||||
|
const openingBalance = openingBalances.debit - openingBalances.credit;
|
||||||
|
|
||||||
|
this.openingBalance = openingBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the uncategorized transactions of the bank account.
|
||||||
|
*/
|
||||||
|
async initCategorizedTransactions() {
|
||||||
|
const { UncategorizedCashflowTransaction } = this.models;
|
||||||
|
const refs = this.transactions.map((t) => [t.referenceType, t.referenceId]);
|
||||||
|
|
||||||
|
const uncategorizedTransactions =
|
||||||
|
await UncategorizedCashflowTransaction.query().whereIn(
|
||||||
|
['categorizeRefType', 'categorizeRefId'],
|
||||||
|
refs,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.uncategorizedTransactions = uncategorizedTransactions;
|
||||||
|
this.uncategorizedTransactionsMapByRef = groupUncategorizedTransactions(
|
||||||
|
uncategorizedTransactions,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the matched bank transactions of the bank account.
|
||||||
|
*/
|
||||||
|
async initMatchedTransactions(): Promise<void> {
|
||||||
|
const { MatchedBankTransaction } = this.models;
|
||||||
|
const refs = this.transactions.map((t) => [t.referenceType, t.referenceId]);
|
||||||
|
|
||||||
|
const matchedBankTransactions =
|
||||||
|
await MatchedBankTransaction.query().whereIn(
|
||||||
|
['referenceType', 'referenceId'],
|
||||||
|
refs,
|
||||||
|
);
|
||||||
|
this.matchedBankTransactions = matchedBankTransactions;
|
||||||
|
this.matchedBankTransactionsMapByRef = groupMatchedBankTransactions(
|
||||||
|
matchedBankTransactions,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export const ERRORS = {
|
||||||
|
ACCOUNT_ID_HAS_INVALID_TYPE: 'ACCOUNT_ID_HAS_INVALID_TYPE',
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum BankTransactionStatus {
|
||||||
|
Categorized = 'categorized',
|
||||||
|
Matched = 'matched',
|
||||||
|
Manual = 'manual',
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import * as R from 'ramda';
|
||||||
|
|
||||||
|
export const groupUncategorizedTransactions = (
|
||||||
|
uncategorizedTransactions: any,
|
||||||
|
): Map<string, any> => {
|
||||||
|
return new Map(
|
||||||
|
R.toPairs(
|
||||||
|
R.groupBy(
|
||||||
|
(transaction: any) =>
|
||||||
|
`${transaction.categorizeRefType}-${transaction.categorizeRefId}`,
|
||||||
|
uncategorizedTransactions,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const groupMatchedBankTransactions = (
|
||||||
|
uncategorizedTransactions: any,
|
||||||
|
): Map<string, any> => {
|
||||||
|
return new Map(
|
||||||
|
R.toPairs(
|
||||||
|
R.groupBy(
|
||||||
|
(transaction: any) =>
|
||||||
|
`${transaction.referenceType}-${transaction.referenceId}`,
|
||||||
|
uncategorizedTransactions,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const formatBankTransactionsStatus = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'categorized':
|
||||||
|
return 'Categorized';
|
||||||
|
case 'matched':
|
||||||
|
return 'Matched';
|
||||||
|
case 'manual':
|
||||||
|
return 'Manual';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getBankAccountTransactionsDefaultQuery = () => {
|
||||||
|
return {
|
||||||
|
pageSize: 50,
|
||||||
|
page: 1,
|
||||||
|
numberFormat: {
|
||||||
|
precision: 2,
|
||||||
|
divideOn1000: false,
|
||||||
|
showZero: false,
|
||||||
|
formatMoney: 'total',
|
||||||
|
negativeFormat: 'mines',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -2,6 +2,7 @@ import { Knex } from 'knex';
|
|||||||
import { UncategorizedBankTransaction } from '../models/UncategorizedBankTransaction';
|
import { UncategorizedBankTransaction } from '../models/UncategorizedBankTransaction';
|
||||||
import { BankTransaction } from '../models/BankTransaction';
|
import { BankTransaction } from '../models/BankTransaction';
|
||||||
import { CreateBankTransactionDto } from '../dtos/CreateBankTransaction.dto';
|
import { CreateBankTransactionDto } from '../dtos/CreateBankTransaction.dto';
|
||||||
|
import { INumberFormatQuery } from '@/modules/FinancialStatements/types/Report.types';
|
||||||
|
|
||||||
export interface IPendingTransactionRemovingEventPayload {
|
export interface IPendingTransactionRemovingEventPayload {
|
||||||
uncategorizedTransactionId: number;
|
uncategorizedTransactionId: number;
|
||||||
@@ -128,3 +129,39 @@ export interface IGetUncategorizedTransactionsQuery {
|
|||||||
minAmount?: number;
|
minAmount?: number;
|
||||||
maxAmount?: number;
|
maxAmount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ICashflowAccountTransactionsQuery {
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
accountId: number;
|
||||||
|
numberFormat: INumberFormatQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ICashflowAccountTransaction {
|
||||||
|
withdrawal: number;
|
||||||
|
deposit: number;
|
||||||
|
runningBalance: number;
|
||||||
|
|
||||||
|
formattedWithdrawal: string;
|
||||||
|
formattedDeposit: string;
|
||||||
|
formattedRunningBalance: string;
|
||||||
|
|
||||||
|
transactionNumber: string;
|
||||||
|
referenceNumber: string;
|
||||||
|
|
||||||
|
referenceId: number;
|
||||||
|
referenceType: string;
|
||||||
|
|
||||||
|
formattedTransactionType: string;
|
||||||
|
|
||||||
|
balance: number;
|
||||||
|
formattedBalance: string;
|
||||||
|
|
||||||
|
date: Date;
|
||||||
|
formattedDate: string;
|
||||||
|
|
||||||
|
status: string;
|
||||||
|
formattedStatus: string;
|
||||||
|
|
||||||
|
uncategorizedTransactionId: number;
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import { Knex } from 'knex';
|
||||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||||
import { CommandItemCategoryValidatorService } from './CommandItemCategoryValidator.service';
|
import { CommandItemCategoryValidatorService } from './CommandItemCategoryValidator.service';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
@@ -7,13 +9,12 @@ import {
|
|||||||
IItemCategoryOTD,
|
IItemCategoryOTD,
|
||||||
} from '../ItemCategory.interfaces';
|
} from '../ItemCategory.interfaces';
|
||||||
import { SystemUser } from '@/modules/System/models/SystemUser';
|
import { SystemUser } from '@/modules/System/models/SystemUser';
|
||||||
import { Knex } from 'knex';
|
|
||||||
import { ItemCategory } from '../models/ItemCategory.model';
|
import { ItemCategory } from '../models/ItemCategory.model';
|
||||||
import { Inject } from '@nestjs/common';
|
|
||||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
import { EditItemCategoryDto } from '../dtos/ItemCategory.dto';
|
import { EditItemCategoryDto } from '../dtos/ItemCategory.dto';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class EditItemCategoryService {
|
export class EditItemCategoryService {
|
||||||
/**
|
/**
|
||||||
* @param {UnitOfWork} uow - Unit of work.
|
* @param {UnitOfWork} uow - Unit of work.
|
||||||
|
|||||||
@@ -17,14 +17,6 @@ class CommandItemCategoryDto {
|
|||||||
})
|
})
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({
|
|
||||||
example: 1,
|
|
||||||
description: 'The user ID',
|
|
||||||
})
|
|
||||||
userId: number;
|
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@ApiProperty({ example: 1, description: 'The cost account ID' })
|
@ApiProperty({ example: 1, description: 'The cost account ID' })
|
||||||
|
|||||||
15
packages/server/src/utils/running-balance.ts
Normal file
15
packages/server/src/utils/running-balance.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export const runningBalance = (amount: number) => {
|
||||||
|
let runningBalance = amount;
|
||||||
|
|
||||||
|
return {
|
||||||
|
decrement: (decrement: number) => {
|
||||||
|
runningBalance -= decrement;
|
||||||
|
},
|
||||||
|
increment: (increment: number) => {
|
||||||
|
runningBalance += increment;
|
||||||
|
},
|
||||||
|
amount: () => runningBalance,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -6,7 +6,7 @@ import t from './types';
|
|||||||
|
|
||||||
// Transform the account.
|
// Transform the account.
|
||||||
const transformAccount = (response) => {
|
const transformAccount = (response) => {
|
||||||
return response.data.account;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const commonInvalidateQueries = (query) => {
|
const commonInvalidateQueries = (query) => {
|
||||||
@@ -58,9 +58,9 @@ export function useAccount(id, props) {
|
|||||||
export function useAccountsTypes(props) {
|
export function useAccountsTypes(props) {
|
||||||
return useRequestQuery(
|
return useRequestQuery(
|
||||||
[t.ACCOUNTS_TYPES],
|
[t.ACCOUNTS_TYPES],
|
||||||
{ method: 'get', url: 'account_types' },
|
{ method: 'get', url: 'accounts/types' },
|
||||||
{
|
{
|
||||||
select: (res) => res.data.account_types,
|
select: (res) => res.data,
|
||||||
defaultData: [],
|
defaultData: [],
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function useCashflowAccounts(query, props) {
|
|||||||
[t.CASH_FLOW_ACCOUNTS, query],
|
[t.CASH_FLOW_ACCOUNTS, query],
|
||||||
{ method: 'get', url: 'banking/accounts', params: query },
|
{ method: 'get', url: 'banking/accounts', params: query },
|
||||||
{
|
{
|
||||||
select: (res) => res.data.cashflow_accounts,
|
select: (res) => res.data,
|
||||||
defaultData: [],
|
defaultData: [],
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export function useCustomer(id, props) {
|
|||||||
[t.CUSTOMER, id],
|
[t.CUSTOMER, id],
|
||||||
{ method: 'get', url: `customers/${id}` },
|
{ method: 'get', url: `customers/${id}` },
|
||||||
{
|
{
|
||||||
select: (res) => res.data.customer,
|
select: (res) => res.data,
|
||||||
defaultData: {},
|
defaultData: {},
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export function useEstimate(id, props) {
|
|||||||
[t.SALE_ESTIMATE, id],
|
[t.SALE_ESTIMATE, id],
|
||||||
{ method: 'get', url: `sale-estimates/${id}` },
|
{ method: 'get', url: `sale-estimates/${id}` },
|
||||||
{
|
{
|
||||||
select: (res) => res.data.estimate,
|
select: (res) => res.data,
|
||||||
defaultData: {},
|
defaultData: {},
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ export function useItem(id, props) {
|
|||||||
url: `items/${id}`,
|
url: `items/${id}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
select: (response) => response.data.item,
|
select: (response) => response.data,
|
||||||
defaultData: {},
|
defaultData: {},
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
@@ -179,10 +179,10 @@ export function useItemAssociatedInvoiceTransactions(id, props) {
|
|||||||
[t.ITEM_ASSOCIATED_WITH_INVOICES, id],
|
[t.ITEM_ASSOCIATED_WITH_INVOICES, id],
|
||||||
{
|
{
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: `items/${id}/transactions/invoices`,
|
url: `items/${id}/invoices`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
select: (res) => res.data.data,
|
select: (res) => res.data,
|
||||||
defaultData: [],
|
defaultData: [],
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
@@ -194,10 +194,10 @@ export function useItemAssociatedEstimateTransactions(id, props) {
|
|||||||
[t.ITEM_ASSOCIATED_WITH_ESTIMATES, id],
|
[t.ITEM_ASSOCIATED_WITH_ESTIMATES, id],
|
||||||
{
|
{
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: `items/${id}/transactions/estimates`,
|
url: `items/${id}/estimates`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
select: (res) => res.data.data,
|
select: (res) => res.data,
|
||||||
defaultData: [],
|
defaultData: [],
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
@@ -209,10 +209,10 @@ export function useItemAssociatedReceiptTransactions(id, props) {
|
|||||||
[t.ITEM_ASSOCIATED_WITH_RECEIPTS, id],
|
[t.ITEM_ASSOCIATED_WITH_RECEIPTS, id],
|
||||||
{
|
{
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: `items/${id}/transactions/receipts`,
|
url: `items/${id}/receipts`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
select: (res) => res.data.data,
|
select: (res) => res.data,
|
||||||
defaultData: [],
|
defaultData: [],
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
@@ -223,10 +223,10 @@ export function useItemAssociatedBillTransactions(id, props) {
|
|||||||
[t.ITEMS_ASSOCIATED_WITH_BILLS, id],
|
[t.ITEMS_ASSOCIATED_WITH_BILLS, id],
|
||||||
{
|
{
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: `items/${id}/transactions/bills`,
|
url: `items/${id}/bills`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
select: (res) => res.data.data,
|
select: (res) => res.data,
|
||||||
defaultData: [],
|
defaultData: [],
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
@@ -249,11 +249,11 @@ export function useItemWarehouseLocation(id, props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {*} id
|
* @param {*} id
|
||||||
* @param {*} query
|
* @param {*} query
|
||||||
* @param {*} props
|
* @param {*} props
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function useItemInventoryCost(query, props) {
|
export function useItemInventoryCost(query, props) {
|
||||||
return useRequestQuery(
|
return useRequestQuery(
|
||||||
@@ -268,5 +268,5 @@ export function useItemInventoryCost(query, props) {
|
|||||||
defaultData: [],
|
defaultData: [],
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export function useVendor(id, props) {
|
|||||||
[t.VENDOR, id],
|
[t.VENDOR, id],
|
||||||
{ method: 'get', url: `vendors/${id}` },
|
{ method: 'get', url: `vendors/${id}` },
|
||||||
{
|
{
|
||||||
select: (res) => res.data.vendor,
|
select: (res) => res.data,
|
||||||
defaultData: {},
|
defaultData: {},
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user