/* eslint-disable global-require */ import * as R from 'ramda'; import { Model, ModelOptions, QueryContext, mixin } from 'objection'; import TenantModel from 'models/TenantModel'; import ModelSettings from './ModelSetting'; import Account from './Account'; import UncategorizedCashflowTransactionMeta from './UncategorizedCashflowTransaction.meta'; export default class UncategorizedCashflowTransaction extends mixin( TenantModel, [ModelSettings] ) { id!: number; amount!: number; categorized!: boolean; accountId!: number; /** * Table name. */ static get tableName() { return 'uncategorized_cashflow_transactions'; } /** * Timestamps columns. */ static get timestamps() { return ['createdAt', 'updatedAt']; } /** * Virtual attributes. */ static get virtualAttributes() { return [ 'withdrawal', 'deposit', 'isDepositTransaction', 'isWithdrawalTransaction', ]; } static get meta() { return UncategorizedCashflowTransactionMeta; } /** * Retrieves the withdrawal amount. * @returns {number} */ public get withdrawal() { return this.amount < 0 ? Math.abs(this.amount) : 0; } /** * Retrieves the deposit amount. * @returns {number} */ public get deposit(): number { return this.amount > 0 ? Math.abs(this.amount) : 0; } /** * Detarmines whether the transaction is deposit transaction. */ public get isDepositTransaction(): boolean { return 0 < this.deposit; } /** * Detarmines whether the transaction is withdrawal transaction. */ public get isWithdrawalTransaction(): boolean { return 0 < this.withdrawal; } /** * Relationship mapping. */ static get relationMappings() { const Account = require('models/Account'); return { /** * Transaction may has associated to account. */ account: { relation: Model.BelongsToOneRelation, modelClass: Account.default, join: { from: 'uncategorized_cashflow_transactions.accountId', to: 'accounts.id', }, }, }; } /** * Updates the count of uncategorized transactions for the associated account * based on the specified operation. * @param {QueryContext} queryContext - The query context for the transaction. * @param {boolean} increment - Indicates whether to increment or decrement the count. */ private async updateUncategorizedTransactionCount( queryContext: QueryContext, increment: boolean, amount: number = 1 ) { const operation = increment ? 'increment' : 'decrement'; await Account.query(queryContext.transaction) .findById(this.accountId) [operation]('uncategorized_transactions', amount); } /** * Runs after insert. * @param {QueryContext} queryContext */ public async $afterInsert(queryContext) { await super.$afterInsert(queryContext); await this.updateUncategorizedTransactionCount(queryContext, true); } /** * Runs after update. * @param {ModelOptions} opt * @param {QueryContext} queryContext */ public async $afterUpdate( opt: ModelOptions, queryContext: QueryContext ): Promise { await super.$afterUpdate(opt, queryContext); if (this.id && this.categorized) { await this.updateUncategorizedTransactionCount(queryContext, false); } } /** * Runs after delete. * @param {QueryContext} queryContext */ public async $afterDelete(queryContext: QueryContext) { await super.$afterDelete(queryContext); await this.updateUncategorizedTransactionCount(queryContext, false); } }