const db = require('../models'); const FileDBApi = require('./file'); const crypto = require('crypto'); const Utils = require('../utils'); const Sequelize = db.Sequelize; const Op = Sequelize.Op; module.exports = class BusinessesDBApi { static async create(data, options) { const currentUser = (options && options.currentUser) || { id: null }; const transaction = (options && options.transaction) || undefined; const businesses = await db.businesses.create({ ...data, createdById: currentUser.id, updatedById: currentUser.id, }, { transaction }); await businesses.setOwner_user(data.owner_user || currentUser.id, { transaction }); return businesses; } static async findAll(filter, options) { const limit = filter.limit || 0; let offset = 0; let where = {}; const currentPage = +filter.page; offset = currentPage * limit; const currentUser = options?.currentUser; const transaction = (options && options.transaction) || undefined; // Data Isolation if (currentUser && currentUser.app_role) { const roleName = currentUser.app_role.name; const isAdmin = roleName === 'Administrator' || roleName === 'Platform Owner'; const isPublicOrConsumer = roleName === 'Public' || roleName === 'Consumer'; if (!isAdmin && !isPublicOrConsumer) { // This is a "client" (e.g. Verified Business Owner) // Show businesses they own OR their primary businessId where[Op.or] = [ { owner_userId: currentUser.id }, { id: currentUser.businessId || null } ]; } else if (isPublicOrConsumer) { where.is_active = true; } } else if (!currentUser) { // Public unauthenticated access where.is_active = true; } let include = [{ model: db.users, as: 'owner_user' }]; if (filter) { if (filter.id) where.id = Utils.uuid(filter.id); if (filter.name) where.name = { [Op.iLike]: `%${filter.name}%` }; } const queryOptions = { where, include, distinct: true, limit: options?.countOnly ? undefined : (limit ? Number(limit) : undefined), offset: options?.countOnly ? undefined : (offset ? Number(offset) : undefined), order: [['createdAt', 'desc']], transaction }; const { rows, count } = await db.businesses.findAndCountAll(queryOptions); return { rows: options?.countOnly ? [] : rows, count: count }; } static async findAllAutocomplete(query, limit, offset) { let where = {}; if (query) { where = { [Op.or]: [ { ['id']: Utils.uuid(query) }, { ['name']: { [Op.iLike]: `%${query}%` } }, ], }; } const records = await db.businesses.findAll({ attributes: ['id', 'name'], where, limit: limit ? Number(limit) : undefined, offset: offset ? Number(offset) : undefined, order: [['name', 'ASC']], }); return records.map((record) => ({ id: record.id, label: record.name, })); } static async findBy(where, options) { const transaction = (options && options.transaction) || undefined; const business = await db.businesses.findOne({ where, transaction, include: [ { model: db.business_photos, as: 'business_photos_business', include: [{ model: db.file, as: 'photos' }] }, { model: db.service_prices, as: 'service_prices_business' }, { model: db.business_badges, as: 'business_badges_business' }, { model: db.reviews, as: 'reviews_business', include: [{ model: db.users, as: 'user' }] }, { model: db.users, as: 'owner_user' } ] }); if (!business) return null; return business.get({plain: true}); } static async update(id, data, options) { const currentUser = (options && options.currentUser) || {id: null}; const transaction = (options && options.transaction) || undefined; const record = await db.businesses.findByPk(id, {transaction}); if (!record) return null; await record.update({ ...data, updatedById: currentUser.id }, {transaction}); if (data.owner_user) await record.setOwner_user(data.owner_user, { transaction }); return record; } static async remove(id, options) { const currentUser = (options && options.currentUser) || {id: null}; const transaction = (options && options.transaction) || undefined; const record = await db.businesses.findByPk(id, options); await record.update({ deletedBy: currentUser.id }, { transaction }); await record.destroy({ transaction }); return record; } static async deleteByIds(ids, options) { const currentUser = (options && options.currentUser) || { id: null }; const transaction = (options && options.transaction) || undefined; const records = await db.businesses.findAll({ where: { id: { [Op.in]: ids } }, transaction }); for (const record of records) { await record.update({deletedBy: currentUser.id}, {transaction}); await record.destroy({transaction}); } return records; } };