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() {
const router = Router();
router.get(
'/transactions',
[
query('account_id').optional().isInt().toInt(),
],
this.asyncMiddleware(this.accountTransactions.bind(this)),
this.catchServiceErrors,
);
router.post(
'/:id/activate',
[...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.
* @param {Error}

View File

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

View File

@@ -128,6 +128,7 @@ export default class AccountTransaction extends TenantModel {
*/
static get relationMappings() {
const Account = require('models/Account');
const Contact = require('models/Contact');
return {
account: {
@@ -138,6 +139,14 @@ export default class AccountTransaction extends TenantModel {
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() {
const Account = require('models/Account');
const Contact = require('models/Contact');
return {
account: {
@@ -31,6 +32,14 @@ export default class ManualJournalEntry extends TenantModel {
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,
IAccountsFilter,
IFilterMeta,
IAccountResponse
IAccountResponse,
IAccountsTransactionsFilter,
IAccountTransaction
} from 'interfaces';
import {
EventDispatcher,
@@ -317,7 +319,8 @@ export default class AccountsService {
* @param {number} accountId
*/
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.
*/

View File

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

View File

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