feat(server): move all cashflow under application service

This commit is contained in:
Ahmed Bouhuolia
2024-03-07 14:19:11 +02:00
parent d87d674aba
commit 62d3e386dd
8 changed files with 138 additions and 49 deletions

View File

@@ -3,14 +3,15 @@ import { Router, Request, Response, NextFunction } from 'express';
import { param } from 'express-validator';
import BaseController from '../BaseController';
import { ServiceError } from '@/exceptions';
import { DeleteCashflowTransaction } from '../../../services/Cashflow/DeleteCashflowTransactionService';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AbilitySubject, CashflowAction } from '@/interfaces';
import { CashflowApplication } from '@/services/Cashflow/CashflowApplication';
@Service()
export default class DeleteCashflowTransactionController extends BaseController {
@Inject()
private deleteCashflowService: DeleteCashflowTransaction;
private cashflowApplication: CashflowApplication;
/**
* Controller router.
@@ -44,7 +45,7 @@ export default class DeleteCashflowTransactionController extends BaseController
try {
const { oldCashflowTransaction } =
await this.deleteCashflowService.deleteCashflowTransaction(
await this.cashflowApplication.deleteTransaction(
tenantId,
transactionId
);

View File

@@ -7,14 +7,12 @@ import GetCashflowTransactionsService from '@/services/Cashflow/GetCashflowTrans
import { ServiceError } from '@/exceptions';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AbilitySubject, CashflowAction } from '@/interfaces';
import { CashflowApplication } from '@/services/Cashflow/CashflowApplication';
@Service()
export default class GetCashflowAccounts extends BaseController {
@Inject()
private getCashflowAccountsService: GetCashflowAccountsService;
@Inject()
private getCashflowTransactionsService: GetCashflowTransactionsService;
private cashflowApplication: CashflowApplication;
/**
* Controller router.
@@ -62,10 +60,7 @@ export default class GetCashflowAccounts extends BaseController {
try {
const cashflowAccounts =
await this.getCashflowAccountsService.getCashflowAccounts(
tenantId,
filter
);
await this.cashflowApplication.getCashflowAccounts(tenantId, filter);
return res.status(200).send({
cashflow_accounts: this.transfromToResponse(cashflowAccounts),

View File

@@ -6,11 +6,12 @@ import GetCashflowTransactionsService from '@/services/Cashflow/GetCashflowTrans
import { ServiceError } from '@/exceptions';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AbilitySubject, CashflowAction } from '@/interfaces';
import { CashflowApplication } from '@/services/Cashflow/CashflowApplication';
@Service()
export default class GetCashflowAccounts extends BaseController {
@Inject()
private getCashflowTransactionsService: GetCashflowTransactionsService;
private cashflowApplication: CashflowApplication;
/**
* Controller router.
@@ -43,11 +44,11 @@ export default class GetCashflowAccounts extends BaseController {
const { transactionId } = req.params;
try {
const cashflowTransaction =
await this.getCashflowTransactionsService.getCashflowTransaction(
tenantId,
transactionId
);
const cashflowTransaction = await this.cashflowApplication.getTransaction(
tenantId,
transactionId
);
return res.status(200).send({
cashflow_transaction: this.transfromToResponse(cashflowTransaction),

View File

@@ -1,18 +1,14 @@
import { Service, Inject } from 'typedi';
import { check, oneOf } from 'express-validator';
import { ValidationChain, check, param, query } from 'express-validator';
import { Router, Request, Response, NextFunction } from 'express';
import BaseController from '../BaseController';
import { ServiceError } from '@/exceptions';
import NewCashflowTransactionService from '@/services/Cashflow/NewCashflowTransactionService';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AbilitySubject, CashflowAction } from '@/interfaces';
import { CashflowApplication } from '@/services/Cashflow/CashflowApplication';
@Service()
export default class NewCashflowTransactionController extends BaseController {
@Inject()
private newCashflowTranscationService: NewCashflowTransactionService;
@Inject()
private cashflowApplication: CashflowApplication;
@@ -29,6 +25,8 @@ export default class NewCashflowTransactionController extends BaseController {
);
router.get(
'/transactions/:id/uncategorized',
this.getUncategorizedTransactionsValidationSchema,
this.validationResult,
this.asyncMiddleware(this.getUncategorizedCashflowTransactions),
this.catchServiceErrors
);
@@ -62,6 +60,18 @@ export default class NewCashflowTransactionController extends BaseController {
return router;
}
/**
* Getting uncategorized transactions validation schema.
* @returns {ValidationChain}
*/
public get getUncategorizedTransactionsValidationSchema() {
return [
param('id').exists().isNumeric().toInt(),
query('page').optional().isNumeric().toInt(),
query('page_size').optional().isNumeric().toInt(),
];
}
/**
* Categorize as expense validation schema.
*/
@@ -112,7 +122,7 @@ export default class NewCashflowTransactionController extends BaseController {
check('branch_id').optional({ nullable: true }).isNumeric().toInt(),
check('publish').default(false).isBoolean().toBoolean(),
];
}
}
/**
* Creates a new cashflow transaction.
@@ -130,7 +140,7 @@ export default class NewCashflowTransactionController extends BaseController {
try {
const cashflowTransaction =
await this.newCashflowTranscationService.newCashflowTransaction(
await this.cashflowApplication.createTransaction(
tenantId,
ownerContributionDTO,
userId
@@ -159,7 +169,7 @@ export default class NewCashflowTransactionController extends BaseController {
const { id: cashflowTransactionId } = req.params;
try {
const data= await this.cashflowApplication.uncategorizeTransaction(
const data = await this.cashflowApplication.uncategorizeTransaction(
tenantId,
cashflowTransactionId
);
@@ -229,9 +239,9 @@ export default class NewCashflowTransactionController extends BaseController {
/**
* Retrieves the uncategorized cashflow transactions.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
public getUncategorizedCashflowTransaction = async (
req: Request,
@@ -240,7 +250,7 @@ export default class NewCashflowTransactionController extends BaseController {
) => {
const { tenantId } = req;
const { id: transactionId } = req.params;
try {
const data = await this.cashflowApplication.getUncategorizedTransaction(
tenantId,
@@ -254,9 +264,9 @@ export default class NewCashflowTransactionController extends BaseController {
/**
* Retrieves the uncategorized cashflow transactions.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
public getUncategorizedCashflowTransactions = async (
req: Request,
@@ -265,11 +275,13 @@ export default class NewCashflowTransactionController extends BaseController {
) => {
const { tenantId } = req;
const { id: accountId } = req.params;
const query = this.matchedQueryData(req);
try {
const data = await this.cashflowApplication.getUncategorizedTransactions(
tenantId,
accountId
accountId,
query
);
return res.status(200).send(data);
@@ -337,9 +349,9 @@ export default class NewCashflowTransactionController extends BaseController {
errors: [
{
type: 'UNCATEGORIZED_TRANSACTION_TYPE_INVALID',
code: 4100,
}
]
code: 4100,
},
],
});
}
}

View File

@@ -156,3 +156,8 @@ export interface CategorizeTransactionAsExpenseDTO {
description: string;
branchId?: number;
}
export interface IGetUncategorizedTransactionsQuery {
page?: number;
pageSize?: number;
}

View File

@@ -5,19 +5,33 @@ import { CategorizeCashflowTransaction } from './CategorizeCashflowTransaction';
import {
CategorizeTransactionAsExpenseDTO,
CreateUncategorizedTransactionDTO,
ICashflowAccountsFilter,
ICashflowNewCommandDTO,
ICategorizeCashflowTransactioDTO,
IUncategorizedCashflowTransaction,
IGetUncategorizedTransactionsQuery,
} from '@/interfaces';
import { CategorizeTransactionAsExpense } from './CategorizeTransactionAsExpense';
import { GetUncategorizedTransactions } from './GetUncategorizedTransactions';
import { CreateUncategorizedTransaction } from './CreateUncategorizedTransaction';
import { GetUncategorizedTransaction } from './GetUncategorizedTransaction';
import NewCashflowTransactionService from './NewCashflowTransactionService';
import GetCashflowAccountsService from './GetCashflowAccountsService';
import { GetCashflowTransactionService } from './GetCashflowTransactionsService';
@Service()
export class CashflowApplication {
@Inject()
private createTransactionService: NewCashflowTransactionService;
@Inject()
private deleteTransactionService: DeleteCashflowTransaction;
@Inject()
private getCashflowAccountsService: GetCashflowAccountsService;
@Inject()
private getCashflowTransactionService: GetCashflowTransactionService;
@Inject()
private uncategorizeTransactionService: UncategorizeCashflowTransaction;
@@ -36,6 +50,25 @@ export class CashflowApplication {
@Inject()
private createUncategorizedTransactionService: CreateUncategorizedTransaction;
/**
* Creates a new cashflow transaction.
* @param {number} tenantId
* @param {ICashflowNewCommandDTO} transactionDTO
* @param {number} userId
* @returns
*/
public createTransaction(
tenantId: number,
transactionDTO: ICashflowNewCommandDTO,
userId?: number
) {
return this.createTransactionService.newCashflowTransaction(
tenantId,
transactionDTO,
userId
);
}
/**
* Deletes the given cashflow transaction.
* @param {number} tenantId
@@ -49,6 +82,35 @@ export class CashflowApplication {
);
}
/**
* Retrieves specific cashflow transaction.
* @param {number} tenantId
* @param {number} cashflowTransactionId
* @returns
*/
public getTransaction(tenantId: number, cashflowTransactionId: number) {
return this.getCashflowTransactionService.getCashflowTransaction(
tenantId,
cashflowTransactionId
);
}
/**
* Retrieves the cashflow accounts.
* @param {number} tenantId
* @param {ICashflowAccountsFilter} filterDTO
* @returns
*/
public getCashflowAccounts(
tenantId: number,
filterDTO: ICashflowAccountsFilter
) {
return this.getCashflowAccountsService.getCashflowAccounts(
tenantId,
filterDTO
);
}
/**
* Creates a new uncategorized cash transaction.
* @param {number} tenantId
@@ -105,7 +167,6 @@ export class CashflowApplication {
* @param {number} tenantId
* @param {number} cashflowTransactionId
* @param {CategorizeTransactionAsExpenseDTO} transactionDTO
* @returns
*/
public categorizeAsExpense(
tenantId: number,
@@ -122,20 +183,23 @@ export class CashflowApplication {
/**
* Retrieves the uncategorized cashflow transactions.
* @param {number} tenantId
* @returns {}
*/
public getUncategorizedTransactions(tenantId: number, accountId: number) {
public getUncategorizedTransactions(
tenantId: number,
accountId: number,
query: IGetUncategorizedTransactionsQuery
) {
return this.getUncategorizedTransactionsService.getTransactions(
tenantId,
accountId
accountId,
query
);
}
/**
*
* @param {number} tenantId
* @param {number} uncategorizedTransactionId
* @returns
* Retrieves specific uncategorized transaction.
* @param {number} tenantId
* @param {number} uncategorizedTransactionId
*/
public getUncategorizedTransaction(
tenantId: number,

View File

@@ -7,7 +7,7 @@ import { ServiceError } from '@/exceptions';
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
@Service()
export default class GetCashflowTransactionsService {
export class GetCashflowTransactionService {
@Inject()
private tenancy: HasTenancyService;

View File

@@ -2,6 +2,7 @@ import { Inject, Service } from 'typedi';
import HasTenancyService from '../Tenancy/TenancyService';
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
import { UncategorizedTransactionTransformer } from './UncategorizedTransactionTransformer';
import { IGetUncategorizedTransactionsQuery } from '@/interfaces';
@Service()
export class GetUncategorizedTransactions {
@@ -16,16 +17,26 @@ export class GetUncategorizedTransactions {
* @param {number} tenantId - Tenant id.
* @param {number} accountId - Account Id.
*/
public async getTransactions(tenantId: number, accountId: number) {
public async getTransactions(
tenantId: number,
accountId: number,
query: IGetUncategorizedTransactionsQuery
) {
const { UncategorizedCashflowTransaction } = this.tenancy.models(tenantId);
// Parsed query with default values.
const _query = {
page: 1,
pageSize: 20,
...query,
};
const { results, pagination } =
await UncategorizedCashflowTransaction.query()
.where('accountId', accountId)
.where('categorized', false)
.withGraphFetched('account')
.orderBy('date', 'DESC')
.pagination(0, 1000);
.pagination(_query.page - 1, _query.pageSize);
const data = await this.transformer.transform(
tenantId,