plugin-financials/repositories/TransactionRepository.js
2025-11-03 13:51:33 +02:00

182 lines
5 KiB
JavaScript

const BaseFinancialRepository = require('./BaseFinancialRepository');
const logger = require('../../../src/utils/logger');
/**
* Transaction Repository
*
* Manages financial transactions with double-entry bookkeeping support.
*/
class TransactionRepository extends BaseFinancialRepository {
constructor() {
super('pg_fn_transactions');
}
/**
* Find transactions for a site
* @param {string} siteId - Site ID
* @param {Object} options - Query options
* @returns {Promise<Array>} Array of transactions
*/
async findBySiteId(siteId, options = {}) {
try {
return await this.findAll({ site_id: siteId }, {
orderBy: 'transaction_date',
orderDirection: 'desc',
...options
});
} catch (error) {
logger.error('Error finding transactions by site:', error);
throw error;
}
}
/**
* Find transactions by type
* @param {string} siteId - Site ID
* @param {string} transactionType - Transaction type (income, expense, transfer)
* @returns {Promise<Array>} Array of transactions
*/
async findByType(siteId, transactionType) {
try {
return await this.findAll({ site_id: siteId, transaction_type: transactionType }, {
orderBy: 'transaction_date',
orderDirection: 'desc'
});
} catch (error) {
logger.error('Error finding transactions by type:', error);
throw error;
}
}
/**
* Find transactions by date range
* @param {string} siteId - Site ID
* @param {string} startDate - Start date
* @param {string} endDate - End date
* @returns {Promise<Array>} Array of transactions
*/
async findByDateRange(siteId, startDate, endDate) {
try {
return await this.findWhere({
site_id: { eq: siteId },
transaction_date: { gte: startDate, lte: endDate }
}, {
orderBy: 'transaction_date',
orderDirection: 'asc'
});
} catch (error) {
logger.error('Error finding transactions by date range:', error);
throw error;
}
}
/**
* Find transactions by status
* @param {string} siteId - Site ID
* @param {string} status - Transaction status
* @returns {Promise<Array>} Array of transactions
*/
async findByStatus(siteId, status) {
try {
return await this.findAll({ site_id: siteId, status }, {
orderBy: 'transaction_date',
orderDirection: 'desc'
});
} catch (error) {
logger.error('Error finding transactions by status:', error);
throw error;
}
}
/**
* Create transaction with validation
* @param {Object} transactionData - Transaction data
* @returns {Promise<Object>} Created transaction
*/
async createTransaction(transactionData) {
try {
// Validate required fields
if (!transactionData.site_id || !transactionData.transaction_date ||
!transactionData.description || !transactionData.transaction_type ||
!transactionData.amount) {
throw new Error('Missing required fields for transaction');
}
// Set defaults
const transaction = {
...transactionData,
status: transactionData.status || 'pending',
currency: transactionData.currency || 'USD',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
};
return await this.create(transaction);
} catch (error) {
logger.error('Error creating transaction:', error);
throw error;
}
}
/**
* Approve transaction
* @param {string} transactionId - Transaction ID
* @param {string} approvedBy - User ID who approved
* @returns {Promise<Object>} Updated transaction
*/
async approveTransaction(transactionId, approvedBy) {
try {
return await this.updateById(transactionId, {
status: 'approved',
approved_by: approvedBy,
approved_at: new Date().toISOString(),
updated_at: new Date().toISOString()
});
} catch (error) {
logger.error('Error approving transaction:', error);
throw error;
}
}
/**
* Find transactions by unit ID
* @param {string} unitId - Unit ID
* @returns {Promise<Array>} Array of transactions
*/
async findByUnitId(unitId) {
try {
return await this.findAll({ unit_id: unitId }, {
orderBy: 'transaction_date',
orderDirection: 'asc'
});
} catch (error) {
logger.error('Error finding transactions by unit:', error);
throw error;
}
}
/**
* Find transactions by unit ID and type
* @param {string} unitId - Unit ID
* @param {string} transactionType - Transaction type
* @returns {Promise<Array>} Array of transactions
*/
async findByUnitIdAndType(unitId, transactionType) {
try {
return await this.findAll({
unit_id: unitId,
transaction_type: transactionType
}, {
orderBy: 'transaction_date',
orderDirection: 'asc'
});
} catch (error) {
logger.error('Error finding transactions by unit and type:', error);
throw error;
}
}
}
module.exports = TransactionRepository;