mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 23:00:34 +00:00
refactor: banking modules to nestjs
This commit is contained in:
@@ -1,16 +1,21 @@
|
|||||||
import { Constructor, Model, QueryBuilderType, TransactionOrKnex } from 'objection';
|
import { QueryBuilder } from 'objection';
|
||||||
|
import Objection, { Model, Page } from 'objection';
|
||||||
|
|
||||||
export class BaseModel extends Model {
|
interface PaginationResult<M extends Model> {
|
||||||
public readonly id: number;
|
results: M[];
|
||||||
public readonly tableName: string;
|
pagination: {
|
||||||
|
total: number;
|
||||||
static get QueryBuilder() {
|
page: number;
|
||||||
return PaginationQueryBuilder;
|
pageSize: number;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class PaginationQueryBuilder<M extends Model, R = M[]> extends Model.QueryBuilder<M, R> {
|
class PaginationQueryBuilder<
|
||||||
pagination(page: number, pageSize: number) {
|
M extends Model,
|
||||||
|
R = M[],
|
||||||
|
> extends Model.QueryBuilder<M, R> {
|
||||||
|
pagination(page: number, pageSize: number): QueryBuilder<M, PaginationResult<M>> {
|
||||||
|
// @ts-ignore
|
||||||
return super.page(page, pageSize).runAfter(({ results, total }) => {
|
return super.page(page, pageSize).runAfter(({ results, total }) => {
|
||||||
return {
|
return {
|
||||||
results,
|
results,
|
||||||
@@ -23,3 +28,11 @@ class PaginationQueryBuilder<M extends Model, R = M[]> extends Model.QueryBuilde
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class BaseModel extends Model {
|
||||||
|
public readonly id: number;
|
||||||
|
public readonly tableName: string;
|
||||||
|
|
||||||
|
QueryBuilderType!: PaginationQueryBuilder<this>;
|
||||||
|
static QueryBuilder = PaginationQueryBuilder;
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import { BankAccountsModule } from '../BankingAccounts/BankAccounts.module';
|
|||||||
import { BankingTransactionsExcludeModule } from '../BankingTransactionsExclude/BankingTransactionsExclude.module';
|
import { BankingTransactionsExcludeModule } from '../BankingTransactionsExclude/BankingTransactionsExclude.module';
|
||||||
import { BankingTransactionsRegonizeModule } from '../BankingTranasctionsRegonize/BankingTransactionsRegonize.module';
|
import { BankingTransactionsRegonizeModule } from '../BankingTranasctionsRegonize/BankingTransactionsRegonize.module';
|
||||||
import { BankingMatchingModule } from '../BankingMatching/BankingMatching.module';
|
import { BankingMatchingModule } from '../BankingMatching/BankingMatching.module';
|
||||||
|
import { BankingTransactionsModule } from '../BankingTransactions/BankingTransactions.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -141,7 +142,8 @@ import { BankingMatchingModule } from '../BankingMatching/BankingMatching.module
|
|||||||
BankRulesModule,
|
BankRulesModule,
|
||||||
BankingTransactionsExcludeModule,
|
BankingTransactionsExcludeModule,
|
||||||
BankingTransactionsRegonizeModule,
|
BankingTransactionsRegonizeModule,
|
||||||
// BankingMatchingModule
|
BankingMatchingModule,
|
||||||
|
BankingTransactionsModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class EditBankRuleService {
|
|||||||
* @param createDTO
|
* @param createDTO
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
private transformDTO(createDTO: IEditBankRuleDTO): Partial<BankRule> {
|
private transformDTO(createDTO: IEditBankRuleDTO) {
|
||||||
return {
|
return {
|
||||||
...createDTO,
|
...createDTO,
|
||||||
};
|
};
|
||||||
@@ -59,7 +59,6 @@ export class EditBankRuleService {
|
|||||||
...tranformDTO,
|
...tranformDTO,
|
||||||
id: ruleId,
|
id: ruleId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Triggers `onBankRuleEdited` event.
|
// Triggers `onBankRuleEdited` event.
|
||||||
await this.eventPublisher.emitAsync(events.bankRules.onEdited, {
|
await this.eventPublisher.emitAsync(events.bankRules.onEdited, {
|
||||||
oldBankRule,
|
oldBankRule,
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { BaseModel } from '@/models/Model';
|
import { BaseModel } from '@/models/Model';
|
||||||
|
import { BankRuleComparator } from '../types';
|
||||||
|
|
||||||
export class BankRuleCondition extends BaseModel {
|
export class BankRuleCondition extends BaseModel {
|
||||||
public id!: number;
|
public id!: number;
|
||||||
public bankRuleId!: number;
|
public bankRuleId!: number;
|
||||||
public field!: string;
|
public field!: string;
|
||||||
public comparator!: string;
|
public comparator!: BankRuleComparator;
|
||||||
public value!: string;
|
public value!: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export enum BankRuleConditionComparator {
|
|||||||
Contains = 'contains',
|
Contains = 'contains',
|
||||||
Equals = 'equals',
|
Equals = 'equals',
|
||||||
Equal = 'equal',
|
Equal = 'equal',
|
||||||
NotContain = 'not_contain',
|
NotContain = 'not_contains',
|
||||||
Bigger = 'bigger',
|
Bigger = 'bigger',
|
||||||
BiggerOrEqual = 'bigger_or_equal',
|
BiggerOrEqual = 'bigger_or_equal',
|
||||||
Smaller = 'smaller',
|
Smaller = 'smaller',
|
||||||
@@ -59,19 +59,21 @@ export enum BankRuleAssignCategory {
|
|||||||
OwnerDrawings = 'OwnerDrawings',
|
OwnerDrawings = 'OwnerDrawings',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BankRuleComparator =
|
||||||
|
| 'contains'
|
||||||
|
| 'equals'
|
||||||
|
| 'not_contains'
|
||||||
|
| 'equal'
|
||||||
|
| 'bigger'
|
||||||
|
| 'bigger_or_equal'
|
||||||
|
| 'smaller'
|
||||||
|
| 'smaller_or_equal';
|
||||||
|
|
||||||
export interface IBankRuleConditionDTO {
|
export interface IBankRuleConditionDTO {
|
||||||
id?: number;
|
id?: number;
|
||||||
field: string;
|
field: string;
|
||||||
comparator:
|
comparator: BankRuleComparator;
|
||||||
| 'contains'
|
value: string;
|
||||||
| 'equals'
|
|
||||||
| 'not_contains'
|
|
||||||
| 'equal'
|
|
||||||
| 'bigger'
|
|
||||||
| 'bigger_or_equal'
|
|
||||||
| 'smaller'
|
|
||||||
| 'smaller_or_equal';
|
|
||||||
value: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBankRuleCommonDTO {
|
export interface IBankRuleCommonDTO {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||||
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
|
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
|
||||||
|
import { BaseModel } from '@/models/Model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GetBankAccountSummary {
|
export class GetBankAccountSummary {
|
||||||
@@ -34,6 +35,10 @@ export class GetBankAccountSummary {
|
|||||||
q.modify('notCategorized');
|
q.modify('notCategorized');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface UncategorizedTransactionsCount {
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieves the uncategorized transactions count of the given bank account.
|
// Retrieves the uncategorized transactions count of the given bank account.
|
||||||
const uncategorizedTranasctionsCount =
|
const uncategorizedTranasctionsCount =
|
||||||
await this.uncategorizedBankTransactionModel.query().onBuild((q) => {
|
await this.uncategorizedBankTransactionModel.query().onBuild((q) => {
|
||||||
@@ -79,6 +84,7 @@ export class GetBankAccountSummary {
|
|||||||
q.count('uncategorized_cashflow_transactions.id as total');
|
q.count('uncategorized_cashflow_transactions.id as total');
|
||||||
q.first();
|
q.first();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Retrieves the pending transactions count.
|
// Retrieves the pending transactions count.
|
||||||
const pendingTransactionsCount =
|
const pendingTransactionsCount =
|
||||||
await this.uncategorizedBankTransactionModel.query().onBuild((q) => {
|
await this.uncategorizedBankTransactionModel.query().onBuild((q) => {
|
||||||
@@ -91,9 +97,13 @@ export class GetBankAccountSummary {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const totalUncategorizedTransactions =
|
const totalUncategorizedTransactions =
|
||||||
|
// @ts-ignore
|
||||||
uncategorizedTranasctionsCount?.total || 0;
|
uncategorizedTranasctionsCount?.total || 0;
|
||||||
|
// @ts-ignore
|
||||||
const totalRecognizedTransactions = recognizedTransactionsCount?.total || 0;
|
const totalRecognizedTransactions = recognizedTransactionsCount?.total || 0;
|
||||||
|
// @ts-ignore
|
||||||
const totalExcludedTransactions = excludedTransactionsCount?.total || 0;
|
const totalExcludedTransactions = excludedTransactionsCount?.total || 0;
|
||||||
|
// @ts-ignore
|
||||||
const totalPendingTransactions = pendingTransactionsCount?.total || 0;
|
const totalPendingTransactions = pendingTransactionsCount?.total || 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
import {
|
|
||||||
CategorizeTransactionAsExpenseDTO,
|
|
||||||
ICashflowTransactionCategorizedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { BankTransaction } from '@/modules/BankingTransactions/models/BankTransaction';
|
import { BankTransaction } from '@/modules/BankingTransactions/models/BankTransaction';
|
||||||
@@ -10,7 +6,10 @@ import { Inject } from '@nestjs/common';
|
|||||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { ICashflowTransactionUncategorizedPayload } from '../types/BankingCategorize.types';
|
import {
|
||||||
|
ICashflowTransactionCategorizedPayload,
|
||||||
|
ICategorizeCashflowTransactioDTO,
|
||||||
|
} from '../types/BankingCategorize.types';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CategorizeTransactionAsExpense {
|
export class CategorizeTransactionAsExpense {
|
||||||
@@ -30,7 +29,7 @@ export class CategorizeTransactionAsExpense {
|
|||||||
*/
|
*/
|
||||||
public async categorize(
|
public async categorize(
|
||||||
cashflowTransactionId: number,
|
cashflowTransactionId: number,
|
||||||
transactionDTO: CategorizeTransactionAsExpenseDTO,
|
transactionDTO: ICategorizeCashflowTransactioDTO,
|
||||||
) {
|
) {
|
||||||
const transaction = await this.bankTransactionModel
|
const transaction = await this.bankTransactionModel
|
||||||
.query()
|
.query()
|
||||||
@@ -46,7 +45,12 @@ export class CategorizeTransactionAsExpense {
|
|||||||
} as ICashflowTransactionCategorizedPayload,
|
} as ICashflowTransactionCategorizedPayload,
|
||||||
);
|
);
|
||||||
// Creates a new expense transaction.
|
// Creates a new expense transaction.
|
||||||
const expenseTransaction = await this.createExpenseService.newExpense({});
|
// TODO: the DTO is not complete, we need to add the missing properties.
|
||||||
|
// @ts-ignore
|
||||||
|
const expenseTransaction = await this.createExpenseService.newExpense({
|
||||||
|
// ...transactionDTO,
|
||||||
|
// publishedAt: transaction.publishedAt,
|
||||||
|
});
|
||||||
|
|
||||||
// Updates the item on the storage and fetches the updated once.
|
// Updates the item on the storage and fetches the updated once.
|
||||||
const cashflowTransaction = await this.bankTransactionModel
|
const cashflowTransaction = await this.bankTransactionModel
|
||||||
@@ -62,7 +66,7 @@ export class CategorizeTransactionAsExpense {
|
|||||||
{
|
{
|
||||||
cashflowTransaction,
|
cashflowTransaction,
|
||||||
trx,
|
trx,
|
||||||
} as ICashflowTransactionUncategorizedPayload,
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { BankTransaction } from "@/modules/BankingTransactions/models/BankTransaction";
|
||||||
import { UncategorizedBankTransaction } from "@/modules/BankingTransactions/models/UncategorizedBankTransaction";
|
import { UncategorizedBankTransaction } from "@/modules/BankingTransactions/models/UncategorizedBankTransaction";
|
||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
|
||||||
export interface ICashflowTransactionCategorizedPayload {
|
export interface ICashflowTransactionCategorizedPayload {
|
||||||
uncategorizedTransactions: Array<UncategorizedBankTransaction>;
|
uncategorizedTransactions: Array<UncategorizedBankTransaction>;
|
||||||
cashflowTransaction: UncategorizedBankTransaction;
|
cashflowTransaction: BankTransaction;
|
||||||
oldUncategorizedTransactions: Array<UncategorizedBankTransaction>;
|
oldUncategorizedTransactions: Array<UncategorizedBankTransaction>;
|
||||||
categorizeDTO: any;
|
categorizeDTO: any;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
|
||||||
|
import { BankingMatchingApplication } from './BankingMatchingApplication';
|
||||||
|
import { GetMatchedTransactionsFilter, IMatchTransactionDTO } from './types';
|
||||||
|
|
||||||
|
@Controller('banking/matching')
|
||||||
|
export class BankingMatchingController {
|
||||||
|
constructor(
|
||||||
|
private readonly bankingMatchingApplication: BankingMatchingApplication
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Get('matched/transactions')
|
||||||
|
async getMatchedTransactions(
|
||||||
|
@Query('uncategorizedTransactionIds') uncategorizedTransactionIds: number[],
|
||||||
|
@Query() filter: GetMatchedTransactionsFilter
|
||||||
|
) {
|
||||||
|
return this.bankingMatchingApplication.getMatchedTransactions(
|
||||||
|
uncategorizedTransactionIds,
|
||||||
|
filter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/match/:uncategorizedTransactionId')
|
||||||
|
async matchTransaction(
|
||||||
|
@Param('uncategorizedTransactionId') uncategorizedTransactionId: number | number[],
|
||||||
|
@Body() matchedTransactions: IMatchTransactionDTO[]
|
||||||
|
) {
|
||||||
|
return this.bankingMatchingApplication.matchTransaction(
|
||||||
|
uncategorizedTransactionId,
|
||||||
|
matchedTransactions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/unmatch/:uncategorizedTransactionId')
|
||||||
|
async unmatchMatchedTransaction(
|
||||||
|
@Param('uncategorizedTransactionId') uncategorizedTransactionId: number
|
||||||
|
) {
|
||||||
|
return this.bankingMatchingApplication.unmatchMatchedTransaction(
|
||||||
|
uncategorizedTransactionId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,10 +19,14 @@ import { BankingTransactionsModule } from '../BankingTransactions/BankingTransac
|
|||||||
import { PaymentsReceivedModule } from '../PaymentReceived/PaymentsReceived.module';
|
import { PaymentsReceivedModule } from '../PaymentReceived/PaymentsReceived.module';
|
||||||
import { MatchBankTransactions } from './commands/MatchTransactions';
|
import { MatchBankTransactions } from './commands/MatchTransactions';
|
||||||
import { MatchTransactionsTypes } from './commands/MatchTransactionsTypes';
|
import { MatchTransactionsTypes } from './commands/MatchTransactionsTypes';
|
||||||
|
import { GetMatchedTransactionsByManualJournals } from './queries/GetMatchedTransactionsByManualJournals.service';
|
||||||
|
import { ValidateTransactionMatched } from './commands/ValidateTransactionsMatched.service';
|
||||||
|
import { BankingMatchingController } from './BankingMatching.controller';
|
||||||
|
|
||||||
const models = [RegisterTenancyModel(MatchedBankTransaction)];
|
const models = [RegisterTenancyModel(MatchedBankTransaction)];
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
controllers: [BankingMatchingController],
|
||||||
imports: [
|
imports: [
|
||||||
BillPaymentsModule,
|
BillPaymentsModule,
|
||||||
BankingTransactionsModule,
|
BankingTransactionsModule,
|
||||||
@@ -30,12 +34,14 @@ const models = [RegisterTenancyModel(MatchedBankTransaction)];
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
...models,
|
...models,
|
||||||
|
ValidateTransactionMatched,
|
||||||
MatchBankTransactions,
|
MatchBankTransactions,
|
||||||
MatchTransactionsTypes,
|
MatchTransactionsTypes,
|
||||||
GetMatchedTransactionsByBills,
|
GetMatchedTransactionsByBills,
|
||||||
GetMatchedTransactionsByCashflow,
|
GetMatchedTransactionsByCashflow,
|
||||||
GetMatchedTransactionsByExpenses,
|
GetMatchedTransactionsByExpenses,
|
||||||
GetMatchedTransactionsByInvoices,
|
GetMatchedTransactionsByInvoices,
|
||||||
|
GetMatchedTransactionsByManualJournals,
|
||||||
BankingMatchingApplication,
|
BankingMatchingApplication,
|
||||||
GetMatchedTransactions,
|
GetMatchedTransactions,
|
||||||
UnmatchMatchedBankTransaction,
|
UnmatchMatchedBankTransaction,
|
||||||
|
|||||||
@@ -30,18 +30,15 @@ export class BankingMatchingApplication {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the given uncategorized transaction with the given system transaction.
|
* Matches the given uncategorized transaction with the given system transaction.
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {number} uncategorizedTransactionId
|
* @param {number} uncategorizedTransactionId
|
||||||
* @param {IMatchTransactionDTO} matchTransactionsDTO
|
* @param {IMatchTransactionDTO} matchTransactionsDTO
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public matchTransaction(
|
public matchTransaction(
|
||||||
tenantId: number,
|
|
||||||
uncategorizedTransactionId: number | Array<number>,
|
uncategorizedTransactionId: number | Array<number>,
|
||||||
matchedTransactions: Array<IMatchTransactionDTO>
|
matchedTransactions: Array<IMatchTransactionDTO>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.matchTransactionService.matchTransaction(
|
return this.matchTransactionService.matchTransaction(
|
||||||
tenantId,
|
|
||||||
uncategorizedTransactionId,
|
uncategorizedTransactionId,
|
||||||
matchedTransactions
|
matchedTransactions
|
||||||
);
|
);
|
||||||
@@ -49,16 +46,13 @@ export class BankingMatchingApplication {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmatch the given matched transaction.
|
* Unmatch the given matched transaction.
|
||||||
* @param {number} tenantId
|
* @param {number} uncategorizedTransactionId - Uncategorized transaction id.
|
||||||
* @param {number} uncategorizedTransactionId
|
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public unmatchMatchedTransaction(
|
public unmatchMatchedTransaction(
|
||||||
tenantId: number,
|
|
||||||
uncategorizedTransactionId: number
|
uncategorizedTransactionId: number
|
||||||
) {
|
) {
|
||||||
return this.unmatchMatchedTransactionService.unmatchMatchedTransaction(
|
return this.unmatchMatchedTransactionService.unmatchMatchedTransaction(
|
||||||
tenantId,
|
|
||||||
uncategorizedTransactionId
|
uncategorizedTransactionId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,6 @@ export class MatchBankTransactions {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public async matchTransaction(
|
public async matchTransaction(
|
||||||
tenantId: number,
|
|
||||||
uncategorizedTransactionId: number | Array<number>,
|
uncategorizedTransactionId: number | Array<number>,
|
||||||
matchedTransactions: Array<IMatchTransactionDTO>,
|
matchedTransactions: Array<IMatchTransactionDTO>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
|||||||
@@ -21,12 +21,10 @@ export class UnmatchMatchedBankTransaction {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public unmatchMatchedTransaction(
|
public unmatchMatchedTransaction(
|
||||||
tenantId: number,
|
|
||||||
uncategorizedTransactionId: number,
|
uncategorizedTransactionId: number,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.uow.withTransaction(async (trx) => {
|
return this.uow.withTransaction(async (trx) => {
|
||||||
await this.eventPublisher.emitAsync(events.bankMatch.onUnmatching, {
|
await this.eventPublisher.emitAsync(events.bankMatch.onUnmatching, {
|
||||||
tenantId,
|
|
||||||
uncategorizedTransactionId,
|
uncategorizedTransactionId,
|
||||||
trx,
|
trx,
|
||||||
} as IBankTransactionUnmatchingEventPayload);
|
} as IBankTransactionUnmatchingEventPayload);
|
||||||
@@ -37,7 +35,6 @@ export class UnmatchMatchedBankTransaction {
|
|||||||
.delete();
|
.delete();
|
||||||
|
|
||||||
await this.eventPublisher.emitAsync(events.bankMatch.onUnmatched, {
|
await this.eventPublisher.emitAsync(events.bankMatch.onUnmatched, {
|
||||||
tenantId,
|
|
||||||
uncategorizedTransactionId,
|
uncategorizedTransactionId,
|
||||||
trx,
|
trx,
|
||||||
} as IBankTransactionUnmatchingEventPayload);
|
} as IBankTransactionUnmatchingEventPayload);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
|
|||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { SystemPlaidItem } from '../models/SystemPlaidItem';
|
import { SystemPlaidItem } from '../models/SystemPlaidItem';
|
||||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||||
import { PlaidItemDTO } from '../types/BankingPlaid.types';
|
import { IPlaidItemCreatedEventPayload, PlaidItemDTO } from '../types/BankingPlaid.types';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PlaidItemService {
|
export class PlaidItemService {
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export class PlaidWebooks {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
switch (webhookCode) {
|
switch (webhookCode) {
|
||||||
case 'WEBHOOK_UPDATE_ACKNOWLEDGED':
|
case 'WEBHOOK_UPDATE_ACKNOWLEDGED':
|
||||||
this.serverLogAndEmitSocket('is updated', plaidItemId, error);
|
this.serverLogAndEmitSocket('is updated', webhookCode, plaidItemId);
|
||||||
break;
|
break;
|
||||||
case 'ERROR': {
|
case 'ERROR': {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -70,13 +70,15 @@ export class TriggerRecognizedTransactionsSubscriber {
|
|||||||
@OnEvent(events.import.onImportCommitted)
|
@OnEvent(events.import.onImportCommitted)
|
||||||
private async triggerRecognizeTransactionsOnImportCommitted({
|
private async triggerRecognizeTransactionsOnImportCommitted({
|
||||||
importId,
|
importId,
|
||||||
}: IImportFileCommitedEventPayload) {
|
|
||||||
const importFile = await Import.query().findOne({ importId });
|
|
||||||
const batch = importFile.paramsParsed.batch;
|
|
||||||
const payload = { transactionsCriteria: { batch } };
|
|
||||||
|
|
||||||
// Cannot continue if the imported resource is not bank account transactions.
|
// @ts-ignore
|
||||||
if (importFile.resource !== 'UncategorizedCashflowTransaction') return;
|
}: IImportFileCommitedEventPayload) {
|
||||||
|
// const importFile = await Import.query().findOne({ importId });
|
||||||
|
// const batch = importFile.paramsParsed.batch;
|
||||||
|
// const payload = { transactionsCriteria: { batch } };
|
||||||
|
|
||||||
|
// // Cannot continue if the imported resource is not bank account transactions.
|
||||||
|
// if (importFile.resource !== 'UncategorizedCashflowTransaction') return;
|
||||||
|
|
||||||
// await this.agenda.now('recognize-uncategorized-transactions-job', payload);
|
// await this.agenda.now('recognize-uncategorized-transactions-job', payload);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';
|
||||||
|
import { BankingTransactionsApplication } from './BankingTransactionsApplication.service';
|
||||||
|
import { ICashflowNewCommandDTO } from './types/BankingTransactions.types';
|
||||||
|
|
||||||
|
@Controller('banking/transactions')
|
||||||
|
export class BankingTransactionsController {
|
||||||
|
constructor(
|
||||||
|
private readonly bankingTransactionsApplication: BankingTransactionsApplication,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
async createTransaction(@Body() transactionDTO: ICashflowNewCommandDTO) {
|
||||||
|
return this.bankingTransactionsApplication.createTransaction(
|
||||||
|
transactionDTO,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
async deleteTransaction(@Param('id') transactionId: string) {
|
||||||
|
return this.bankingTransactionsApplication.deleteTransaction(
|
||||||
|
Number(transactionId),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
async getTransaction(@Param('id') transactionId: string) {
|
||||||
|
return this.bankingTransactionsApplication.getTransaction(
|
||||||
|
Number(transactionId),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import { CommandBankTransactionValidator } from './commands/CommandCasflowValida
|
|||||||
import { BranchTransactionDTOTransformer } from '../Branches/integrations/BranchTransactionDTOTransform';
|
import { BranchTransactionDTOTransformer } from '../Branches/integrations/BranchTransactionDTOTransform';
|
||||||
import { BranchesModule } from '../Branches/Branches.module';
|
import { BranchesModule } from '../Branches/Branches.module';
|
||||||
import { RemovePendingUncategorizedTransaction } from './commands/RemovePendingUncategorizedTransaction.service';
|
import { RemovePendingUncategorizedTransaction } from './commands/RemovePendingUncategorizedTransaction.service';
|
||||||
|
import { BankingTransactionsController } from './BankingTransactions.controller';
|
||||||
|
|
||||||
const models = [
|
const models = [
|
||||||
RegisterTenancyModel(UncategorizedBankTransaction),
|
RegisterTenancyModel(UncategorizedBankTransaction),
|
||||||
@@ -29,6 +30,7 @@ const models = [
|
|||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [AutoIncrementOrdersModule, LedgerModule, BranchesModule],
|
imports: [AutoIncrementOrdersModule, LedgerModule, BranchesModule],
|
||||||
|
controllers: [BankingTransactionsController],
|
||||||
providers: [
|
providers: [
|
||||||
BankTransactionAutoIncrement,
|
BankTransactionAutoIncrement,
|
||||||
BankTransactionGLEntriesService,
|
BankTransactionGLEntriesService,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { Model } from 'objection';
|
|||||||
// import { CASHFLOW_DIRECTION } from '@/services/Cashflow/constants';
|
// import { CASHFLOW_DIRECTION } from '@/services/Cashflow/constants';
|
||||||
// import { getCashflowTransactionFormattedType } from '@/utils/transactions-types';
|
// import { getCashflowTransactionFormattedType } from '@/utils/transactions-types';
|
||||||
import { BaseModel } from '@/models/Model';
|
import { BaseModel } from '@/models/Model';
|
||||||
import { getCashflowTransactionType } from '../utils';
|
import { getCashflowAccountTransactionsTypes, getCashflowTransactionType } from '../utils';
|
||||||
import { CASHFLOW_DIRECTION } from '../constants';
|
import { CASHFLOW_DIRECTION, CASHFLOW_TRANSACTION_TYPE } from '../constants';
|
||||||
import { BankTransactionLine } from './BankTransactionLine';
|
import { BankTransactionLine } from './BankTransactionLine';
|
||||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||||
|
|
||||||
@@ -27,9 +27,15 @@ export class BankTransaction extends BaseModel {
|
|||||||
cashflowAccountId: number;
|
cashflowAccountId: number;
|
||||||
creditAccountId: number;
|
creditAccountId: number;
|
||||||
|
|
||||||
|
categorizeRefType: string;
|
||||||
|
categorizeRefId: number;
|
||||||
|
uncategorized: boolean;
|
||||||
|
|
||||||
branchId: number;
|
branchId: number;
|
||||||
userId: number;
|
userId: number;
|
||||||
|
|
||||||
|
publishedAt: Date;
|
||||||
|
|
||||||
entries: BankTransactionLine[];
|
entries: BankTransactionLine[];
|
||||||
cashflowAccount: Account;
|
cashflowAccount: Account;
|
||||||
creditAccount: Account;
|
creditAccount: Account;
|
||||||
@@ -92,7 +98,9 @@ export class BankTransaction extends BaseModel {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
get typeMeta() {
|
get typeMeta() {
|
||||||
return getCashflowTransactionType(this.transactionType);
|
return getCashflowTransactionType(
|
||||||
|
this.transactionType as CASHFLOW_TRANSACTION_TYPE,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { BaseModel } from '@/models/Model';
|
|||||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||||
import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost';
|
import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost';
|
||||||
import { DiscountType } from '@/common/types/Discount';
|
import { DiscountType } from '@/common/types/Discount';
|
||||||
|
import { Knex } from 'knex';
|
||||||
|
|
||||||
export class Bill extends BaseModel {
|
export class Bill extends BaseModel {
|
||||||
public amount: number;
|
public amount: number;
|
||||||
@@ -615,7 +616,7 @@ export class Bill extends BaseModel {
|
|||||||
return notFoundBillsIds;
|
return notFoundBillsIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
static changePaymentAmount(billId, amount, trx) {
|
static changePaymentAmount(billId, amount, trx: Knex.Transaction) {
|
||||||
const changeMethod = amount > 0 ? 'increment' : 'decrement';
|
const changeMethod = amount > 0 ? 'increment' : 'decrement';
|
||||||
return this.query(trx)
|
return this.query(trx)
|
||||||
.where('id', billId)
|
.where('id', billId)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { defaultTo, omit, isEmpty } from 'lodash';
|
import { defaultTo, omit, isEmpty } from 'lodash';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Customer } from '../models/Customer';
|
|
||||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||||
import { ICustomerEditDTO, ICustomerNewDTO } from '../types/Customers.types';
|
import { ICustomerEditDTO, ICustomerNewDTO } from '../types/Customers.types';
|
||||||
import { ContactService } from '@/modules/Contacts/types/Contacts.types';
|
import { ContactService } from '@/modules/Contacts/types/Contacts.types';
|
||||||
@@ -20,7 +19,7 @@ export class CreateEditCustomerDTO {
|
|||||||
*/
|
*/
|
||||||
private transformCommonDTO = (
|
private transformCommonDTO = (
|
||||||
customerDTO: ICustomerNewDTO | ICustomerEditDTO,
|
customerDTO: ICustomerNewDTO | ICustomerEditDTO,
|
||||||
): Partial<Customer> => {
|
) => {
|
||||||
return {
|
return {
|
||||||
...omit(customerDTO, ['customerType']),
|
...omit(customerDTO, ['customerType']),
|
||||||
contactType: customerDTO.customerType,
|
contactType: customerDTO.customerType,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { PaymentReceived } from '../models/PaymentReceived';
|
|||||||
|
|
||||||
export interface IPaymentReceivedCreateDTO {
|
export interface IPaymentReceivedCreateDTO {
|
||||||
customerId: number;
|
customerId: number;
|
||||||
paymentDate: Date;
|
paymentDate: Date | string;
|
||||||
amount: number;
|
amount: number;
|
||||||
exchangeRate: number;
|
exchangeRate: number;
|
||||||
referenceNo: string;
|
referenceNo: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user