const db = require('../db/models'); const processFile = require('../middlewares/upload'); const ValidationError = require('../services/notifications/errors/validation'); const csv = require('csv-parser'); const stream = require('stream'); function createEntityService(DBApi, options = {}) { const entityName = options.entityName || 'Entity'; return class GenericService { static async create(data, currentUser) { const transaction = await db.sequelize.transaction(); try { const record = await DBApi.create(data, { currentUser, transaction }); await transaction.commit(); return record; } catch (error) { await transaction.rollback(); throw error; } } static async bulkImport(req, res) { const transaction = await db.sequelize.transaction(); try { await processFile(req, res); const bufferStream = new stream.PassThrough(); const results = []; await bufferStream.end(Buffer.from(req.file.buffer, 'utf-8')); await new Promise((resolve, reject) => { bufferStream .pipe(csv()) .on('data', (data) => results.push(data)) .on('end', () => resolve()) .on('error', (error) => reject(error)); }); await DBApi.bulkImport(results, { transaction, ignoreDuplicates: true, validate: true, currentUser: req.currentUser, }); await transaction.commit(); } catch (error) { await transaction.rollback(); throw error; } } static async update(data, id, currentUser) { const transaction = await db.sequelize.transaction(); try { const record = await DBApi.findBy({ id }, { transaction }); if (!record) { throw new ValidationError(`${entityName}NotFound`); } const updated = await DBApi.update(id, data, { currentUser, transaction }); await transaction.commit(); return updated; } catch (error) { await transaction.rollback(); throw error; } } static async deleteByIds(ids, currentUser) { const transaction = await db.sequelize.transaction(); try { await DBApi.deleteByIds(ids, { currentUser, transaction }); await transaction.commit(); } catch (error) { await transaction.rollback(); throw error; } } static async remove(id, currentUser) { const transaction = await db.sequelize.transaction(); try { await DBApi.remove(id, { currentUser, transaction }); await transaction.commit(); } catch (error) { await transaction.rollback(); throw error; } } }; } module.exports = { createEntityService };