fix: specific account transactions.

fix: specific expense associated expense account graph.
fix: specific manual journal associated account and contact graph.
This commit is contained in:
a.bouhuolia
2021-04-25 23:41:54 +02:00
parent fcc95d9e01
commit c75109a975
7 changed files with 102 additions and 4 deletions

View File

@@ -23,6 +23,14 @@ export default class AccountsController extends BaseController {
router() { router() {
const router = Router(); const router = Router();
router.get(
'/transactions',
[
query('account_id').optional().isInt().toInt(),
],
this.asyncMiddleware(this.accountTransactions.bind(this)),
this.catchServiceErrors,
);
router.post( router.post(
'/:id/activate', '/:id/activate',
[...this.accountParamSchema], [...this.accountParamSchema],
@@ -329,6 +337,28 @@ export default class AccountsController extends BaseController {
} }
} }
/**
* Retrieve accounts transactions list.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
async accountTransactions(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const transactionsFilter = this.matchedQueryData(req);
try {
const { transactions } = await this.accountsService.getAccountsTransactions(
tenantId,
transactionsFilter
);
return res.status(200).send({ transactions });
} catch (error) {
next(error);
}
}
/** /**
* Transforms service errors to response. * Transforms service errors to response.
* @param {Error} * @param {Error}

View File

@@ -28,6 +28,13 @@ export interface IAccount {
accountParentType: string, accountParentType: string,
}; };
export interface IAccountsTransactionsFilter {
accountId?: number,
}
export interface IAccountTransaction {
}
export interface IAccountResponse extends IAccount { export interface IAccountResponse extends IAccount {
} }

View File

@@ -128,6 +128,7 @@ export default class AccountTransaction extends TenantModel {
*/ */
static get relationMappings() { static get relationMappings() {
const Account = require('models/Account'); const Account = require('models/Account');
const Contact = require('models/Contact');
return { return {
account: { account: {
@@ -138,6 +139,14 @@ export default class AccountTransaction extends TenantModel {
to: 'accounts.id', to: 'accounts.id',
}, },
}, },
contact: {
relation: Model.BelongsToOneRelation,
modelClass: Contact.default,
join: {
from: 'accounts_transactions.contactId',
to: 'contacts.id',
},
},
}; };
} }
} }

View File

@@ -21,6 +21,7 @@ export default class ManualJournalEntry extends TenantModel {
*/ */
static get relationMappings() { static get relationMappings() {
const Account = require('models/Account'); const Account = require('models/Account');
const Contact = require('models/Contact');
return { return {
account: { account: {
@@ -31,6 +32,14 @@ export default class ManualJournalEntry extends TenantModel {
to: 'accounts.id', to: 'accounts.id',
}, },
}, },
contact: {
relation: Model.BelongsToOneRelation,
modelClass: Contact.default,
join: {
from: 'manual_journals_entries.contactId',
to: 'contacts.id',
},
},
}; };
} }
} }

View File

@@ -8,7 +8,9 @@ import {
IAccount, IAccount,
IAccountsFilter, IAccountsFilter,
IFilterMeta, IFilterMeta,
IAccountResponse IAccountResponse,
IAccountsTransactionsFilter,
IAccountTransaction
} from 'interfaces'; } from 'interfaces';
import { import {
EventDispatcher, EventDispatcher,
@@ -317,7 +319,8 @@ export default class AccountsService {
* @param {number} accountId * @param {number} accountId
*/ */
public async getAccount(tenantId: number, accountId: number) { public async getAccount(tenantId: number, accountId: number) {
return this.getAccountOrThrowError(tenantId, accountId); const account = await this.getAccountOrThrowError(tenantId, accountId);
return this.transformAccountResponse(tenantId, account);
} }
/** /**
@@ -628,6 +631,45 @@ export default class AccountsService {
}; };
} }
/**
* Retrieve the accounts transactions.
* @param {number} tenantId -
* @param {IAccountsTransactionsFilter} filter -
*/
public async getAccountsTransactions(
tenantId: number,
filter: IAccountsTransactionsFilter,
): Promise<{ transactions: IAccountTransaction }> {
const { AccountTransaction } = this.tenancy.models(tenantId);
this.logger.info('[accounts] trying to get accounts transactions list.');
const transactions = await AccountTransaction.query().onBuild((query) => {
query.orderBy('date', 'DESC');
if (filter.accountId) {
query.where('account_id', filter.accountId);
}
query.withGraphFetched('account');
query.withGraphFetched('contact');
});
return { transactions };
}
/**
* Transformes the account model to specific account response.
*/
private transformAccountResponse(tenantId: number, account: IAccount) {
const settings = this.tenancy.settings(tenantId);
const baseCurrency = settings.get({
group: 'organization',
key: 'base_currency',
});
return {
...account,
currencyCode: baseCurrency,
};
}
/** /**
* Transformes the accounts models to accounts response. * Transformes the accounts models to accounts response.
*/ */

View File

@@ -641,7 +641,7 @@ export default class ExpensesService implements IExpensesService {
const expense = await expenseRepository.findOneById(expenseId, [ const expense = await expenseRepository.findOneById(expenseId, [
'paymentAccount', 'paymentAccount',
'categories', 'categories.expenseAccount',
]); ]);
if (!expense) { if (!expense) {
throw new ServiceError(ERRORS.EXPENSE_NOT_FOUND); throw new ServiceError(ERRORS.EXPENSE_NOT_FOUND);

View File

@@ -822,7 +822,8 @@ export default class ManualJournalsService implements IManualJournalsService {
); );
const manualJournal = await ManualJournal.query() const manualJournal = await ManualJournal.query()
.findById(manualJournalId) .findById(manualJournalId)
.withGraphFetched('entries') .withGraphFetched('entries.account')
.withGraphFetched('entries.contact')
.withGraphFetched('transactions') .withGraphFetched('transactions')
.withGraphFetched('media'); .withGraphFetched('media');