From 094c9daac2af1a36e8668450a090114a21432900 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 13 Mar 2026 15:34:13 +0000 Subject: [PATCH] Updated via schema editor on 2026-03-13 15:33 --- backend/src/db/api/test.js | 246 + backend/src/db/migrations/1773416015568.js | 83 + backend/src/db/models/test.js | 49 + .../db/seeders/20200430130760-user-roles.js | 3750 ++++----- .../db/seeders/20231127130745-sample-data.js | 6954 +++++------------ backend/src/db/seeders/20260313153335.js | 87 + backend/src/index.js | 235 +- backend/src/routes/test.js | 433 + backend/src/services/search.js | 538 +- backend/src/services/test.js | 114 + frontend/src/components/Test/CardTest.tsx | 105 + frontend/src/components/Test/ListTest.tsx | 87 + frontend/src/components/Test/TableTest.tsx | 481 ++ .../src/components/Test/configureTestCols.tsx | 74 + frontend/src/menuAside.ts | 130 +- frontend/src/pages/dashboard.tsx | 1426 ++-- frontend/src/pages/test/[testId].tsx | 122 + frontend/src/pages/test/test-edit.tsx | 120 + frontend/src/pages/test/test-list.tsx | 160 + frontend/src/pages/test/test-new.tsx | 96 + frontend/src/pages/test/test-table.tsx | 159 + frontend/src/pages/test/test-view.tsx | 81 + frontend/src/stores/store.ts | 80 +- frontend/src/stores/test/testSlice.ts | 236 + 24 files changed, 8118 insertions(+), 7728 deletions(-) create mode 100644 backend/src/db/api/test.js create mode 100644 backend/src/db/migrations/1773416015568.js create mode 100644 backend/src/db/models/test.js create mode 100644 backend/src/db/seeders/20260313153335.js create mode 100644 backend/src/routes/test.js create mode 100644 backend/src/services/test.js create mode 100644 frontend/src/components/Test/CardTest.tsx create mode 100644 frontend/src/components/Test/ListTest.tsx create mode 100644 frontend/src/components/Test/TableTest.tsx create mode 100644 frontend/src/components/Test/configureTestCols.tsx create mode 100644 frontend/src/pages/test/[testId].tsx create mode 100644 frontend/src/pages/test/test-edit.tsx create mode 100644 frontend/src/pages/test/test-list.tsx create mode 100644 frontend/src/pages/test/test-new.tsx create mode 100644 frontend/src/pages/test/test-table.tsx create mode 100644 frontend/src/pages/test/test-view.tsx create mode 100644 frontend/src/stores/test/testSlice.ts diff --git a/backend/src/db/api/test.js b/backend/src/db/api/test.js new file mode 100644 index 0000000..6c009ed --- /dev/null +++ b/backend/src/db/api/test.js @@ -0,0 +1,246 @@ +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 TestDBApi { + static async create(data, options) { + const currentUser = (options && options.currentUser) || { id: null }; + const transaction = (options && options.transaction) || undefined; + + const test = await db.test.create( + { + id: data.id || undefined, + + name: data.name || null, + importHash: data.importHash || null, + createdById: currentUser.id, + updatedById: currentUser.id, + }, + { transaction }, + ); + + return test; + } + + static async bulkImport(data, options) { + const currentUser = (options && options.currentUser) || { id: null }; + const transaction = (options && options.transaction) || undefined; + + // Prepare data - wrapping individual data transformations in a map() method + const testData = data.map((item, index) => ({ + id: item.id || undefined, + + name: item.name || null, + importHash: item.importHash || null, + createdById: currentUser.id, + updatedById: currentUser.id, + createdAt: new Date(Date.now() + index * 1000), + })); + + // Bulk create items + const test = await db.test.bulkCreate(testData, { transaction }); + + // For each item created, replace relation files + + return test; + } + + static async update(id, data, options) { + const currentUser = (options && options.currentUser) || { id: null }; + const transaction = (options && options.transaction) || undefined; + + const test = await db.test.findByPk(id, {}, { transaction }); + + const updatePayload = {}; + + if (data.name !== undefined) updatePayload.name = data.name; + + updatePayload.updatedById = currentUser.id; + + await test.update(updatePayload, { transaction }); + + return test; + } + + static async deleteByIds(ids, options) { + const currentUser = (options && options.currentUser) || { id: null }; + const transaction = (options && options.transaction) || undefined; + + const test = await db.test.findAll({ + where: { + id: { + [Op.in]: ids, + }, + }, + transaction, + }); + + await db.sequelize.transaction(async (transaction) => { + for (const record of test) { + await record.update({ deletedBy: currentUser.id }, { transaction }); + } + for (const record of test) { + await record.destroy({ transaction }); + } + }); + + return test; + } + + static async remove(id, options) { + const currentUser = (options && options.currentUser) || { id: null }; + const transaction = (options && options.transaction) || undefined; + + const test = await db.test.findByPk(id, options); + + await test.update( + { + deletedBy: currentUser.id, + }, + { + transaction, + }, + ); + + await test.destroy({ + transaction, + }); + + return test; + } + + static async findBy(where, options) { + const transaction = (options && options.transaction) || undefined; + + const test = await db.test.findOne({ where }, { transaction }); + + if (!test) { + return test; + } + + const output = test.get({ plain: true }); + + return output; + } + + static async findAll(filter, options) { + const limit = filter.limit || 0; + let offset = 0; + let where = {}; + const currentPage = +filter.page; + + offset = currentPage * limit; + + const orderBy = null; + + const transaction = (options && options.transaction) || undefined; + + let include = []; + + if (filter) { + if (filter.id) { + where = { + ...where, + ['id']: Utils.uuid(filter.id), + }; + } + + if (filter.name) { + where = { + ...where, + [Op.and]: Utils.ilike('test', 'name', filter.name), + }; + } + + if (filter.active !== undefined) { + where = { + ...where, + active: filter.active === true || filter.active === 'true', + }; + } + + if (filter.createdAtRange) { + const [start, end] = filter.createdAtRange; + + if (start !== undefined && start !== null && start !== '') { + where = { + ...where, + ['createdAt']: { + ...where.createdAt, + [Op.gte]: start, + }, + }; + } + + if (end !== undefined && end !== null && end !== '') { + where = { + ...where, + ['createdAt']: { + ...where.createdAt, + [Op.lte]: end, + }, + }; + } + } + } + + const queryOptions = { + where, + include, + distinct: true, + order: + filter.field && filter.sort + ? [[filter.field, filter.sort]] + : [['createdAt', 'desc']], + transaction: options?.transaction, + logging: console.log, + }; + + if (!options?.countOnly) { + queryOptions.limit = limit ? Number(limit) : undefined; + queryOptions.offset = offset ? Number(offset) : undefined; + } + + try { + const { rows, count } = await db.test.findAndCountAll(queryOptions); + + return { + rows: options?.countOnly ? [] : rows, + count: count, + }; + } catch (error) { + console.error('Error executing query:', error); + throw error; + } + } + + static async findAllAutocomplete(query, limit, offset) { + let where = {}; + + if (query) { + where = { + [Op.or]: [ + { ['id']: Utils.uuid(query) }, + Utils.ilike('test', 'id', query), + ], + }; + } + + const records = await db.test.findAll({ + attributes: ['id', 'id'], + where, + limit: limit ? Number(limit) : undefined, + offset: offset ? Number(offset) : undefined, + orderBy: [['id', 'ASC']], + }); + + return records.map((record) => ({ + id: record.id, + label: record.id, + })); + } +}; diff --git a/backend/src/db/migrations/1773416015568.js b/backend/src/db/migrations/1773416015568.js new file mode 100644 index 0000000..bb63bcf --- /dev/null +++ b/backend/src/db/migrations/1773416015568.js @@ -0,0 +1,83 @@ +module.exports = { + /** + * @param {QueryInterface} queryInterface + * @param {Sequelize} Sequelize + * @returns {Promise} + */ + async up(queryInterface, Sequelize) { + /** + * @type {Transaction} + */ + const transaction = await queryInterface.sequelize.transaction(); + try { + await queryInterface.createTable( + 'test', + { + id: { + type: Sequelize.DataTypes.UUID, + defaultValue: Sequelize.DataTypes.UUIDV4, + primaryKey: true, + }, + createdById: { + type: Sequelize.DataTypes.UUID, + references: { + key: 'id', + model: 'users', + }, + }, + updatedById: { + type: Sequelize.DataTypes.UUID, + references: { + key: 'id', + model: 'users', + }, + }, + createdAt: { type: Sequelize.DataTypes.DATE }, + updatedAt: { type: Sequelize.DataTypes.DATE }, + deletedAt: { type: Sequelize.DataTypes.DATE }, + importHash: { + type: Sequelize.DataTypes.STRING(255), + allowNull: true, + unique: true, + }, + }, + { transaction }, + ); + + await queryInterface.addColumn( + 'test', + 'name', + { + type: Sequelize.DataTypes.TEXT, + }, + { transaction }, + ); + + await transaction.commit(); + } catch (err) { + await transaction.rollback(); + throw err; + } + }, + /** + * @param {QueryInterface} queryInterface + * @param {Sequelize} Sequelize + * @returns {Promise} + */ + async down(queryInterface, Sequelize) { + /** + * @type {Transaction} + */ + const transaction = await queryInterface.sequelize.transaction(); + try { + await queryInterface.removeColumn('test', 'name', { transaction }); + + await queryInterface.dropTable('test', { transaction }); + + await transaction.commit(); + } catch (err) { + await transaction.rollback(); + throw err; + } + }, +}; diff --git a/backend/src/db/models/test.js b/backend/src/db/models/test.js new file mode 100644 index 0000000..30bb5c2 --- /dev/null +++ b/backend/src/db/models/test.js @@ -0,0 +1,49 @@ +const config = require('../../config'); +const providers = config.providers; +const crypto = require('crypto'); +const bcrypt = require('bcrypt'); +const moment = require('moment'); + +module.exports = function (sequelize, DataTypes) { + const test = sequelize.define( + 'test', + { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + + name: { + type: DataTypes.TEXT, + }, + + importHash: { + type: DataTypes.STRING(255), + allowNull: true, + unique: true, + }, + }, + { + timestamps: true, + paranoid: true, + freezeTableName: true, + }, + ); + + test.associate = (db) => { + /// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity + + //end loop + + db.test.belongsTo(db.users, { + as: 'createdBy', + }); + + db.test.belongsTo(db.users, { + as: 'updatedBy', + }); + }; + + return test; +}; diff --git a/backend/src/db/seeders/20200430130760-user-roles.js b/backend/src/db/seeders/20200430130760-user-roles.js index bba01d5..90f6d06 100644 --- a/backend/src/db/seeders/20200430130760-user-roles.js +++ b/backend/src/db/seeders/20200430130760-user-roles.js @@ -1,5 +1,4 @@ - -const { v4: uuid } = require("uuid"); +const { v4: uuid } = require('uuid'); module.exports = { /** @@ -26,26 +25,45 @@ module.exports = { return id; } - await queryInterface.bulkInsert("roles", [ - - - { id: getId("Administrator"), name: "Administrator", createdAt, updatedAt }, - - - - { id: getId("StoreOwner"), name: "Store Owner", createdAt, updatedAt }, - - { id: getId("OperationsManager"), name: "Operations Manager", createdAt, updatedAt }, - - { id: getId("FulfillmentSpecialist"), name: "Fulfillment Specialist", createdAt, updatedAt }, - - { id: getId("CatalogManager"), name: "Catalog Manager", createdAt, updatedAt }, - - { id: getId("CustomerSupport"), name: "Customer Support", createdAt, updatedAt }, - - - - { id: getId("Public"), name: "Public", createdAt, updatedAt }, + await queryInterface.bulkInsert('roles', [ + { + id: getId('Administrator'), + name: 'Administrator', + createdAt, + updatedAt, + }, + + { id: getId('StoreOwner'), name: 'Store Owner', createdAt, updatedAt }, + + { + id: getId('OperationsManager'), + name: 'Operations Manager', + createdAt, + updatedAt, + }, + + { + id: getId('FulfillmentSpecialist'), + name: 'Fulfillment Specialist', + createdAt, + updatedAt, + }, + + { + id: getId('CatalogManager'), + name: 'Catalog Manager', + createdAt, + updatedAt, + }, + + { + id: getId('CustomerSupport'), + name: 'Customer Support', + createdAt, + updatedAt, + }, + + { id: getId('Public'), name: 'Public', createdAt, updatedAt }, ]); /** @@ -53,22 +71,78 @@ module.exports = { */ function createPermissions(name) { return [ - { id: getId(`CREATE_${name.toUpperCase()}`), createdAt, updatedAt, name: `CREATE_${name.toUpperCase()}` }, - { id: getId(`READ_${name.toUpperCase()}`), createdAt, updatedAt, name: `READ_${name.toUpperCase()}` }, - { id: getId(`UPDATE_${name.toUpperCase()}`), createdAt, updatedAt, name: `UPDATE_${name.toUpperCase()}` }, - { id: getId(`DELETE_${name.toUpperCase()}`), createdAt, updatedAt, name: `DELETE_${name.toUpperCase()}` } + { + id: getId(`CREATE_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `CREATE_${name.toUpperCase()}`, + }, + { + id: getId(`READ_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `READ_${name.toUpperCase()}`, + }, + { + id: getId(`UPDATE_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `UPDATE_${name.toUpperCase()}`, + }, + { + id: getId(`DELETE_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `DELETE_${name.toUpperCase()}`, + }, ]; } const entities = [ - "users","roles","permissions","customers","addresses","product_categories","products","product_variants","inventory_locations","inventory_items","inventory_movements","orders","order_items","shipments","payments","refunds","discount_codes","order_status_events",, + 'users', + 'roles', + 'permissions', + 'customers', + 'addresses', + 'product_categories', + 'products', + 'product_variants', + 'inventory_locations', + 'inventory_items', + 'inventory_movements', + 'orders', + 'order_items', + 'shipments', + 'payments', + 'refunds', + 'discount_codes', + 'order_status_events', + 'test', + , ]; -await queryInterface.bulkInsert("permissions", entities.flatMap(createPermissions)); -await queryInterface.bulkInsert("permissions", [{ id: getId(`READ_API_DOCS`), createdAt, updatedAt, name: `READ_API_DOCS` }]); -await queryInterface.bulkInsert("permissions", [{ id: getId(`CREATE_SEARCH`), createdAt, updatedAt, name: `CREATE_SEARCH`}]); + await queryInterface.bulkInsert( + 'permissions', + entities.flatMap(createPermissions), + ); + await queryInterface.bulkInsert('permissions', [ + { + id: getId(`READ_API_DOCS`), + createdAt, + updatedAt, + name: `READ_API_DOCS`, + }, + ]); + await queryInterface.bulkInsert('permissions', [ + { + id: getId(`CREATE_SEARCH`), + createdAt, + updatedAt, + name: `CREATE_SEARCH`, + }, + ]); - -await queryInterface.sequelize.query(`create table "rolesPermissionsPermissions" + await queryInterface.sequelize + .query(`create table "rolesPermissionsPermissions" ( "createdAt" timestamp with time zone not null, "updatedAt" timestamp with time zone not null, @@ -77,1726 +151,1902 @@ await queryInterface.sequelize.query(`create table "rolesPermissionsPermissions" primary key ("roles_permissionsId", "permissionId") );`); + await queryInterface.bulkInsert('rolesPermissionsPermissions', [ + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_USERS'), + }, -await queryInterface.bulkInsert("rolesPermissionsPermissions", [ - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_USERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_USERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_USERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_USERS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_USERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_USERS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_USERS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_USERS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_USERS') }, - - - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_CUSTOMERS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_CUSTOMERS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_CUSTOMERS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_CUSTOMERS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('CREATE_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_CUSTOMERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_CUSTOMERS') }, - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_ADDRESSES') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_ADDRESSES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_ADDRESSES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_ADDRESSES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('CREATE_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_ADDRESSES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_ADDRESSES') }, - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_PRODUCT_CATEGORIES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_PRODUCT_CATEGORIES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_PRODUCT_CATEGORIES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_PRODUCT_CATEGORIES') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_PRODUCT_CATEGORIES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_PRODUCT_CATEGORIES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_PRODUCT_CATEGORIES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_PRODUCT_CATEGORIES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_PRODUCT_CATEGORIES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('UPDATE_PRODUCT_CATEGORIES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_PRODUCT_CATEGORIES') }, - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_PRODUCTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_PRODUCTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_PRODUCTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_PRODUCTS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_PRODUCTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_PRODUCTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_PRODUCTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_PRODUCTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_PRODUCTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('UPDATE_PRODUCTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_PRODUCTS') }, - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_PRODUCT_VARIANTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_PRODUCT_VARIANTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_PRODUCT_VARIANTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_PRODUCT_VARIANTS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_PRODUCT_VARIANTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_PRODUCT_VARIANTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_PRODUCT_VARIANTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_PRODUCT_VARIANTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_PRODUCT_VARIANTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('UPDATE_PRODUCT_VARIANTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_PRODUCT_VARIANTS') }, - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_INVENTORY_LOCATIONS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_INVENTORY_LOCATIONS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_INVENTORY_LOCATIONS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_INVENTORY_LOCATIONS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_INVENTORY_LOCATIONS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_INVENTORY_LOCATIONS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_INVENTORY_LOCATIONS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_INVENTORY_LOCATIONS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_INVENTORY_LOCATIONS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_INVENTORY_LOCATIONS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('UPDATE_INVENTORY_LOCATIONS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_INVENTORY_LOCATIONS') }, - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_INVENTORY_ITEMS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_INVENTORY_ITEMS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_INVENTORY_ITEMS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_INVENTORY_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('UPDATE_INVENTORY_ITEMS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_INVENTORY_ITEMS') }, - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_INVENTORY_MOVEMENTS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_INVENTORY_MOVEMENTS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('CREATE_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_INVENTORY_MOVEMENTS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_INVENTORY_MOVEMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('UPDATE_INVENTORY_MOVEMENTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_INVENTORY_MOVEMENTS') }, - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_ORDERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_ORDERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_ORDERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_ORDERS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_ORDERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_ORDERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_ORDERS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_ORDERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_ORDERS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_ORDERS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_ORDERS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_ORDERS') }, - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_ORDER_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_ORDER_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_ORDER_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_ORDER_ITEMS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_ORDER_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_ORDER_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_ORDER_ITEMS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_ORDER_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_ORDER_ITEMS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_ORDER_ITEMS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_ORDER_ITEMS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_ORDER_ITEMS') }, - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_SHIPMENTS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_SHIPMENTS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('CREATE_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_SHIPMENTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_SHIPMENTS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_SHIPMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_SHIPMENTS') }, - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_PAYMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_PAYMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_PAYMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_PAYMENTS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_PAYMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_PAYMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_PAYMENTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_PAYMENTS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_PAYMENTS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_PAYMENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_PAYMENTS') }, - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_REFUNDS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_REFUNDS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_REFUNDS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_REFUNDS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_REFUNDS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_REFUNDS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_REFUNDS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_REFUNDS') }, - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_REFUNDS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('CREATE_REFUNDS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_REFUNDS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_REFUNDS') }, - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_DISCOUNT_CODES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_DISCOUNT_CODES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_DISCOUNT_CODES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_DISCOUNT_CODES') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_DISCOUNT_CODES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_DISCOUNT_CODES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_DISCOUNT_CODES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_DISCOUNT_CODES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_DISCOUNT_CODES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_DISCOUNT_CODES') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('UPDATE_DISCOUNT_CODES') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_DISCOUNT_CODES') }, - - - - - - - - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('READ_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('UPDATE_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('DELETE_ORDER_STATUS_EVENTS') }, - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('READ_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('UPDATE_ORDER_STATUS_EVENTS') }, - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('CREATE_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('READ_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('UPDATE_ORDER_STATUS_EVENTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('READ_ORDER_STATUS_EVENTS') }, - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('CREATE_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('READ_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('UPDATE_ORDER_STATUS_EVENTS') }, - - - - - - - - - - - - - - - - { createdAt, updatedAt, roles_permissionsId: getId("StoreOwner"), permissionId: getId('CREATE_SEARCH') }, - - { createdAt, updatedAt, roles_permissionsId: getId("OperationsManager"), permissionId: getId('CREATE_SEARCH') }, - - { createdAt, updatedAt, roles_permissionsId: getId("FulfillmentSpecialist"), permissionId: getId('CREATE_SEARCH') }, - - { createdAt, updatedAt, roles_permissionsId: getId("CatalogManager"), permissionId: getId('CREATE_SEARCH') }, - - { createdAt, updatedAt, roles_permissionsId: getId("CustomerSupport"), permissionId: getId('CREATE_SEARCH') }, - - - - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_USERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_USERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_USERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_USERS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_ROLES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_ROLES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_ROLES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_ROLES') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_PERMISSIONS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_PERMISSIONS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_PERMISSIONS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_PERMISSIONS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_CUSTOMERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_CUSTOMERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_CUSTOMERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_CUSTOMERS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_ADDRESSES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_ADDRESSES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_ADDRESSES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_ADDRESSES') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_PRODUCT_CATEGORIES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_PRODUCT_CATEGORIES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_PRODUCT_CATEGORIES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_PRODUCT_CATEGORIES') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_PRODUCTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_PRODUCTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_PRODUCTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_PRODUCTS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_PRODUCT_VARIANTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_PRODUCT_VARIANTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_PRODUCT_VARIANTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_PRODUCT_VARIANTS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_INVENTORY_LOCATIONS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_INVENTORY_LOCATIONS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_INVENTORY_LOCATIONS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_INVENTORY_LOCATIONS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_INVENTORY_ITEMS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_INVENTORY_ITEMS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_INVENTORY_ITEMS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_INVENTORY_ITEMS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_INVENTORY_MOVEMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_INVENTORY_MOVEMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_INVENTORY_MOVEMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_INVENTORY_MOVEMENTS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_ORDERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_ORDERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_ORDERS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_ORDERS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_ORDER_ITEMS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_ORDER_ITEMS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_ORDER_ITEMS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_ORDER_ITEMS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_SHIPMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_SHIPMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_SHIPMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_SHIPMENTS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_PAYMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_PAYMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_PAYMENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_PAYMENTS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_REFUNDS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_REFUNDS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_REFUNDS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_REFUNDS') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_DISCOUNT_CODES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_DISCOUNT_CODES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_DISCOUNT_CODES') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_DISCOUNT_CODES') }, - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_ORDER_STATUS_EVENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_ORDER_STATUS_EVENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('UPDATE_ORDER_STATUS_EVENTS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('DELETE_ORDER_STATUS_EVENTS') }, - - - - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('READ_API_DOCS') }, - { createdAt, updatedAt, roles_permissionsId: getId("Administrator"), permissionId: getId('CREATE_SEARCH') }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('CREATE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('CREATE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('UPDATE_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('UPDATE_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('UPDATE_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('UPDATE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('UPDATE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('CREATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('UPDATE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('CREATE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('CREATE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('UPDATE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('READ_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('UPDATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('DELETE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('READ_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('UPDATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('CREATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('READ_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('UPDATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('READ_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('CREATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('READ_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('UPDATE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('StoreOwner'), + permissionId: getId('CREATE_SEARCH'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('OperationsManager'), + permissionId: getId('CREATE_SEARCH'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('FulfillmentSpecialist'), + permissionId: getId('CREATE_SEARCH'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CatalogManager'), + permissionId: getId('CREATE_SEARCH'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('CustomerSupport'), + permissionId: getId('CREATE_SEARCH'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_USERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_USERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_USERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_USERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_ROLES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_ROLES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_ROLES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_ROLES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_PERMISSIONS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_PERMISSIONS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_PERMISSIONS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_PERMISSIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_CUSTOMERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_CUSTOMERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_CUSTOMERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_CUSTOMERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_ADDRESSES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_ADDRESSES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_ADDRESSES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_ADDRESSES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_PRODUCT_CATEGORIES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_PRODUCT_CATEGORIES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_PRODUCT_CATEGORIES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_PRODUCT_CATEGORIES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_PRODUCTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_PRODUCTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_PRODUCTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_PRODUCTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_PRODUCT_VARIANTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_PRODUCT_VARIANTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_PRODUCT_VARIANTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_PRODUCT_VARIANTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_INVENTORY_LOCATIONS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_INVENTORY_LOCATIONS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_INVENTORY_LOCATIONS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_INVENTORY_LOCATIONS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_INVENTORY_ITEMS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_INVENTORY_ITEMS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_INVENTORY_ITEMS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_INVENTORY_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_INVENTORY_MOVEMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_INVENTORY_MOVEMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_INVENTORY_MOVEMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_INVENTORY_MOVEMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_ORDERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_ORDERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_ORDERS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_ORDERS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_ORDER_ITEMS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_ORDER_ITEMS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_ORDER_ITEMS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_ORDER_ITEMS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_SHIPMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_SHIPMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_SHIPMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_SHIPMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_PAYMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_PAYMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_PAYMENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_PAYMENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_REFUNDS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_REFUNDS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_REFUNDS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_REFUNDS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_DISCOUNT_CODES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_DISCOUNT_CODES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_DISCOUNT_CODES'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_DISCOUNT_CODES'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_ORDER_STATUS_EVENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_ORDER_STATUS_EVENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_ORDER_STATUS_EVENTS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_ORDER_STATUS_EVENTS'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_TEST'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_TEST'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('UPDATE_TEST'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('DELETE_TEST'), + }, + + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('READ_API_DOCS'), + }, + { + createdAt, + updatedAt, + roles_permissionsId: getId('Administrator'), + permissionId: getId('CREATE_SEARCH'), + }, ]); + await queryInterface.sequelize.query( + `UPDATE "users" SET "app_roleId"='${getId( + 'SuperAdmin', + )}' WHERE "email"='super_admin@flatlogic.com'`, + ); + await queryInterface.sequelize.query( + `UPDATE "users" SET "app_roleId"='${getId( + 'Administrator', + )}' WHERE "email"='admin@flatlogic.com'`, + ); - await queryInterface.sequelize.query(`UPDATE "users" SET "app_roleId"='${getId("SuperAdmin")}' WHERE "email"='super_admin@flatlogic.com'`); - await queryInterface.sequelize.query(`UPDATE "users" SET "app_roleId"='${getId("Administrator")}' WHERE "email"='admin@flatlogic.com'`); - - - - - - - await queryInterface.sequelize.query(`UPDATE "users" SET "app_roleId"='${getId("StoreOwner")}' WHERE "email"='client@hello.com'`); - await queryInterface.sequelize.query(`UPDATE "users" SET "app_roleId"='${getId("OperationsManager")}' WHERE "email"='john@doe.com'`); - - - - -} + await queryInterface.sequelize.query( + `UPDATE "users" SET "app_roleId"='${getId( + 'StoreOwner', + )}' WHERE "email"='client@hello.com'`, + ); + await queryInterface.sequelize.query( + `UPDATE "users" SET "app_roleId"='${getId( + 'OperationsManager', + )}' WHERE "email"='john@doe.com'`, + ); + }, }; - diff --git a/backend/src/db/seeders/20231127130745-sample-data.js b/backend/src/db/seeders/20231127130745-sample-data.js index 24f39a6..97496d0 100644 --- a/backend/src/db/seeders/20231127130745-sample-data.js +++ b/backend/src/db/seeders/20231127130745-sample-data.js @@ -1,33 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - const db = require('../models'); const Users = db.users; - - - - - const Customers = db.customers; const Addresses = db.addresses; @@ -58,4853 +31,2216 @@ const DiscountCodes = db.discount_codes; const OrderStatusEvents = db.order_status_events; - - - - - +const Test = db.test; const CustomersData = [ - - { - - - - - "full_name": "Morgan Reed", - - - - - - - "email": "morgan.reed@example.com", - - - - - - - "phone": "+14155550110", - - - - - - - "external_customer_ref": "CUST-10001", - - - - - - - "customer_status": "blocked", - - - - - - - "registered_at": new Date('2025-11-02T10:20:00Z'), - - - - - - - "notes": "Prefers email contact", - - - - }, - - { - - - - - "full_name": "Casey Brown", - - - - - - - "email": "casey.brown@example.com", - - - - - - - "phone": "+14155550111", - - - - - - - "external_customer_ref": "CUST-10002", - - - - - - - "customer_status": "active", - - - - - - - "registered_at": new Date('2025-12-14T16:05:00Z'), - - - - - - - "notes": "VIP frequent buyer", - - - - }, - - { - - - - - "full_name": "Jamie Park", - - - - - - - "email": "jamie.park@example.com", - - - - - - - "phone": "+14155550112", - - - - - - - "external_customer_ref": "CUST-10003", - - - - - - - "customer_status": "blocked", - - - - - - - "registered_at": new Date('2026-01-09T09:45:00Z'), - - - - - - - "notes": "Requests eco packaging when possible", - - - - }, - + { + full_name: 'Morgan Reed', + + email: 'morgan.reed@example.com', + + phone: '+14155550110', + + external_customer_ref: 'CUST-10001', + + customer_status: 'inactive', + + registered_at: new Date('2025-11-02T10:20:00Z'), + + notes: 'Prefers email contact', + }, + + { + full_name: 'Casey Brown', + + email: 'casey.brown@example.com', + + phone: '+14155550111', + + external_customer_ref: 'CUST-10002', + + customer_status: 'blocked', + + registered_at: new Date('2025-12-14T16:05:00Z'), + + notes: 'VIP frequent buyer', + }, + + { + full_name: 'Jamie Park', + + email: 'jamie.park@example.com', + + phone: '+14155550112', + + external_customer_ref: 'CUST-10003', + + customer_status: 'active', + + registered_at: new Date('2026-01-09T09:45:00Z'), + + notes: 'Requests eco packaging when possible', + }, + + { + full_name: 'Drew Wilson', + + email: 'drew.wilson@example.com', + + phone: '+14155550113', + + external_customer_ref: 'CUST-10004', + + customer_status: 'inactive', + + registered_at: new Date('2025-08-21T13:30:00Z'), + + notes: 'No orders in last 6 months', + }, ]; - - const AddressesData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - "address_type": "shipping", - - - - - - - "recipient_name": "Morgan Reed", - - - - - - - "line1": "123 Market St", - - - - - - - "line2": "Apt 7B", - - - - - - - "city": "San Francisco", - - - - - - - "region": "CA", - - - - - - - "postal_code": "94105", - - - - - - - "country": "US", - - - - - - - "phone": "+14155550110", - - - - - - - "is_default": true, - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "address_type": "shipping", - - - - - - - "recipient_name": "Morgan Reed", - - - - - - - "line1": "123 Market St", - - - - - - - "line2": "Apt 7B", - - - - - - - "city": "San Francisco", - - - - - - - "region": "CA", - - - - - - - "postal_code": "94105", - - - - - - - "country": "US", - - - - - - - "phone": "+14155550110", - - - - - - - "is_default": true, - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "address_type": "billing", - - - - - - - "recipient_name": "Casey Brown", - - - - - - - "line1": "88 Pine Ave", - - - - - - - "line2": "Suite 210", - - - - - - - "city": "Oakland", - - - - - - - "region": "CA", - - - - - - - "postal_code": "94607", - - - - - - - "country": "US", - - - - - - - "phone": "+14155550111", - - - - - - - "is_default": true, - - - - }, - + { + // type code here for "relation_one" field + + address_type: 'shipping', + + recipient_name: 'Morgan Reed', + + line1: '123 Market St', + + line2: 'Apt 7B', + + city: 'San Francisco', + + region: 'CA', + + postal_code: '94105', + + country: 'US', + + phone: '+14155550110', + + is_default: true, + }, + + { + // type code here for "relation_one" field + + address_type: 'billing', + + recipient_name: 'Morgan Reed', + + line1: '123 Market St', + + line2: 'Apt 7B', + + city: 'San Francisco', + + region: 'CA', + + postal_code: '94105', + + country: 'US', + + phone: '+14155550110', + + is_default: true, + }, + + { + // type code here for "relation_one" field + + address_type: 'billing', + + recipient_name: 'Casey Brown', + + line1: '88 Pine Ave', + + line2: 'Suite 210', + + city: 'Oakland', + + region: 'CA', + + postal_code: '94607', + + country: 'US', + + phone: '+14155550111', + + is_default: true, + }, + + { + // type code here for "relation_one" field + + address_type: 'shipping', + + recipient_name: 'Jamie Park', + + line1: '45 Elm Street', + + line2: 'Floor 2', + + city: 'San Jose', + + region: 'CA', + + postal_code: '95112', + + country: 'US', + + phone: '+14155550112', + + is_default: true, + }, ]; - - const ProductCategoriesData = [ - - { - - - - - "name": "Apparel", - - - - - - - "slug": "apparel", - - - - - - - "description": "Everyday clothing essentials", - - - - - - - // type code here for "relation_one" field - - - - - - - "is_active": true, - - - - }, - - { - - - - - "name": "Accessories", - - - - - - - "slug": "accessories", - - - - - - - "description": "Bags, hats, and add-ons", - - - - - - - // type code here for "relation_one" field - - - - - - - "is_active": true, - - - - }, - - { - - - - - "name": "Home Goods", - - - - - - - "slug": "home-goods", - - - - - - - "description": "Items for home and office", - - - - - - - // type code here for "relation_one" field - - - - - - - "is_active": true, - - - - }, - + { + name: 'Apparel', + + slug: 'apparel', + + description: 'Everyday clothing essentials', + + // type code here for "relation_one" field + + is_active: true, + }, + + { + name: 'Accessories', + + slug: 'accessories', + + description: 'Bags, hats, and add-ons', + + // type code here for "relation_one" field + + is_active: true, + }, + + { + name: 'Home Goods', + + slug: 'home-goods', + + description: 'Items for home and office', + + // type code here for "relation_one" field + + is_active: true, + }, + + { + name: 'Drinkware', + + slug: 'drinkware', + + description: 'Mugs, bottles, and tumblers', + + // type code here for "relation_one" field + + is_active: true, + }, ]; - - const ProductsData = [ - - { - - - - - "name": "Classic Tee", - - - - - - - "sku": "PROD-TEE-CLASSIC", - - - - - - - "barcode": "810000000101", - - - - - - - // type code here for "relation_one" field - - - - - - - "base_price": 24.0, - - - - - - - "compare_at_price": 30.0, - - - - - - - "reorder_point": 20, - - - - - - - "product_status": "draft", - - - - - - - "description": "Soft cotton tee for daily wear", - - - - - - - // type code here for "images" field - - - - - - - "track_inventory": true, - - - - - - - "is_taxable": true, - - - - }, - - { - - - - - "name": "Canvas Tote Bag", - - - - - - - "sku": "PROD-TOTE-CANVAS", - - - - - - - "barcode": "810000000102", - - - - - - - // type code here for "relation_one" field - - - - - - - "base_price": 18.0, - - - - - - - "compare_at_price": 22.0, - - - - - - - "reorder_point": 15, - - - - - - - "product_status": "active", - - - - - - - "description": "Durable canvas tote for groceries and errands", - - - - - - - // type code here for "images" field - - - - - - - "track_inventory": true, - - - - - - - "is_taxable": true, - - - - }, - - { - - - - - "name": "Insulated Water Bottle", - - - - - - - "sku": "PROD-BOTTLE-INSUL", - - - - - - - "barcode": "810000000103", - - - - - - - // type code here for "relation_one" field - - - - - - - "base_price": 32.0, - - - - - - - "compare_at_price": 38.0, - - - - - - - "reorder_point": 10, - - - - - - - "product_status": "archived", - - - - - - - "description": "Double-wall bottle keeps drinks cold or hot", - - - - - - - // type code here for "images" field - - - - - - - "track_inventory": true, - - - - - - - "is_taxable": true, - - - - }, - + { + name: 'Classic Tee', + + sku: 'PROD-TEE-CLASSIC', + + barcode: '810000000101', + + // type code here for "relation_one" field + + base_price: 24, + + compare_at_price: 30, + + reorder_point: 20, + + product_status: 'draft', + + description: 'Soft cotton tee for daily wear', + + // type code here for "images" field + + track_inventory: true, + + is_taxable: true, + }, + + { + name: 'Canvas Tote Bag', + + sku: 'PROD-TOTE-CANVAS', + + barcode: '810000000102', + + // type code here for "relation_one" field + + base_price: 18, + + compare_at_price: 22, + + reorder_point: 15, + + product_status: 'active', + + description: 'Durable canvas tote for groceries and errands', + + // type code here for "images" field + + track_inventory: true, + + is_taxable: true, + }, + + { + name: 'Insulated Water Bottle', + + sku: 'PROD-BOTTLE-INSUL', + + barcode: '810000000103', + + // type code here for "relation_one" field + + base_price: 32, + + compare_at_price: 38, + + reorder_point: 10, + + product_status: 'draft', + + description: 'Double-wall bottle keeps drinks cold or hot', + + // type code here for "images" field + + track_inventory: true, + + is_taxable: true, + }, + + { + name: 'Ceramic Mug', + + sku: 'PROD-MUG-CERAMIC', + + barcode: '810000000104', + + // type code here for "relation_one" field + + base_price: 14, + + compare_at_price: 16, + + reorder_point: 25, + + product_status: 'draft', + + description: '11 oz mug with glossy finish', + + // type code here for "images" field + + track_inventory: true, + + is_taxable: true, + }, ]; - - const ProductVariantsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - "variant_name": "Classic Tee - Small - Black", - - - - - - - "sku": "VAR-TEE-S-BLK", - - - - - - - "barcode": "820000000201", - - - - - - - "price": 24.0, - - - - - - - "cost": 9.5, - - - - - - - "weight_grams": 180, - - - - - - - "variant_status": "inactive", - - - - - - - // type code here for "images" field - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "variant_name": "Classic Tee - Medium - Black", - - - - - - - "sku": "VAR-TEE-M-BLK", - - - - - - - "barcode": "820000000202", - - - - - - - "price": 24.0, - - - - - - - "cost": 9.5, - - - - - - - "weight_grams": 190, - - - - - - - "variant_status": "active", - - - - - - - // type code here for "images" field - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "variant_name": "Canvas Tote - Natural", - - - - - - - "sku": "VAR-TOTE-NAT", - - - - - - - "barcode": "820000000203", - - - - - - - "price": 18.0, - - - - - - - "cost": 6.2, - - - - - - - "weight_grams": 220, - - - - - - - "variant_status": "inactive", - - - - - - - // type code here for "images" field - - - - }, - + { + // type code here for "relation_one" field + + variant_name: 'Classic Tee - Small - Black', + + sku: 'VAR-TEE-S-BLK', + + barcode: '820000000201', + + price: 24, + + cost: 9.5, + + weight_grams: 180, + + variant_status: 'inactive', + + // type code here for "images" field + }, + + { + // type code here for "relation_one" field + + variant_name: 'Classic Tee - Medium - Black', + + sku: 'VAR-TEE-M-BLK', + + barcode: '820000000202', + + price: 24, + + cost: 9.5, + + weight_grams: 190, + + variant_status: 'active', + + // type code here for "images" field + }, + + { + // type code here for "relation_one" field + + variant_name: 'Canvas Tote - Natural', + + sku: 'VAR-TOTE-NAT', + + barcode: '820000000203', + + price: 18, + + cost: 6.2, + + weight_grams: 220, + + variant_status: 'inactive', + + // type code here for "images" field + }, + + { + // type code here for "relation_one" field + + variant_name: 'Water Bottle - 24oz - Steel', + + sku: 'VAR-BOTTLE-24-STEEL', + + barcode: '820000000204', + + price: 32, + + cost: 12, + + weight_grams: 340, + + variant_status: 'active', + + // type code here for "images" field + }, ]; - - const InventoryLocationsData = [ - - { - - - - - "name": "Main Warehouse", - - - - - - - "code": "WH-MAIN", - - - - - - - "description": "Primary storage and pick area", - - - - - - - "is_active": true, - - - - }, - - { - - - - - "name": "Retail Backroom", - - - - - - - "code": "STORE-BR", - - - - - - - "description": "Backroom inventory for in-store needs", - - - - - - - "is_active": true, - - - - }, - - { - - - - - "name": "Overflow Storage", - - - - - - - "code": "WH-OVR", - - - - - - - "description": "Secondary overflow racks", - - - - - - - "is_active": true, - - - - }, - + { + name: 'Main Warehouse', + + code: 'WH-MAIN', + + description: 'Primary storage and pick area', + + is_active: true, + }, + + { + name: 'Retail Backroom', + + code: 'STORE-BR', + + description: 'Backroom inventory for in-store needs', + + is_active: true, + }, + + { + name: 'Overflow Storage', + + code: 'WH-OVR', + + description: 'Secondary overflow racks', + + is_active: true, + }, + + { + name: 'Returns Area', + + code: 'WH-RET', + + description: 'Quarantine for returns inspection', + + is_active: true, + }, ]; - - const InventoryItemsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "on_hand": 120, - - - - - - - "reserved": 6, - - - - - - - "safety_stock": 20, - - - - - - - "last_counted_at": new Date('2026-03-01T10:00:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "on_hand": 95, - - - - - - - "reserved": 4, - - - - - - - "safety_stock": 20, - - - - - - - "last_counted_at": new Date('2026-03-01T10:05:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "on_hand": 60, - - - - - - - "reserved": 2, - - - - - - - "safety_stock": 15, - - - - - - - "last_counted_at": new Date('2026-03-02T11:30:00Z'), - - - - }, - + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + on_hand: 120, + + reserved: 6, + + safety_stock: 20, + + last_counted_at: new Date('2026-03-01T10:00:00Z'), + }, + + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + on_hand: 95, + + reserved: 4, + + safety_stock: 20, + + last_counted_at: new Date('2026-03-01T10:05:00Z'), + }, + + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + on_hand: 60, + + reserved: 2, + + safety_stock: 15, + + last_counted_at: new Date('2026-03-02T11:30:00Z'), + }, + + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + on_hand: 45, + + reserved: 1, + + safety_stock: 10, + + last_counted_at: new Date('2026-03-03T09:20:00Z'), + }, ]; - - const InventoryMovementsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - "movement_type": "damaged", - - - - - - - "quantity_delta": 50, - - - - - - - "reason": "Supplier restock", - - - - - - - "reference": "PO-50021", - - - - - - - // type code here for "relation_one" field - - - - - - - "moved_at": new Date('2026-02-20T13:10:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "movement_type": "received", - - - - - - - "quantity_delta": -2, - - - - - - - "reason": "Allocated to order", - - - - - - - "reference": "ORD-10021", - - - - - - - // type code here for "relation_one" field - - - - - - - "moved_at": new Date('2026-03-10T10:05:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "movement_type": "released", - - - - - - - "quantity_delta": -1, - - - - - - - "reason": "Damaged during handling", - - - - - - - "reference": "ADJ-30009", - - - - - - - // type code here for "relation_one" field - - - - - - - "moved_at": new Date('2026-03-05T16:40:00Z'), - - - - }, - + { + // type code here for "relation_one" field + + movement_type: 'released', + + quantity_delta: 50, + + reason: 'Supplier restock', + + reference: 'PO-50021', + + // type code here for "relation_one" field + + moved_at: new Date('2026-02-20T13:10:00Z'), + }, + + { + // type code here for "relation_one" field + + movement_type: 'returned', + + quantity_delta: -2, + + reason: 'Allocated to order', + + reference: 'ORD-10021', + + // type code here for "relation_one" field + + moved_at: new Date('2026-03-10T10:05:00Z'), + }, + + { + // type code here for "relation_one" field + + movement_type: 'damaged', + + quantity_delta: -1, + + reason: 'Damaged during handling', + + reference: 'ADJ-30009', + + // type code here for "relation_one" field + + moved_at: new Date('2026-03-05T16:40:00Z'), + }, + + { + // type code here for "relation_one" field + + movement_type: 'shipped', + + quantity_delta: -1, + + reason: 'Shipped to customer', + + reference: 'ORD-10022', + + // type code here for "relation_one" field + + moved_at: new Date('2026-03-11T12:30:00Z'), + }, ]; - - const OrdersData = [ - - { - - - - - "order_number": "ORD-10021", - - - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "order_status": "pending_payment", - - - - - - - "fulfillment_status": "partial", - - - - - - - "payment_status": "partially_refunded", - - - - - - - "subtotal_amount": 56.0, - - - - - - - "discount_amount": 0.0, - - - - - - - "shipping_amount": 6.0, - - - - - - - "tax_amount": 5.04, - - - - - - - "total_amount": 67.04, - - - - - - - "currency": "USD", - - - - - - - "customer_note": "Please leave at front desk", - - - - - - - "internal_note": "Priority pack before 3pm", - - - - - - - "placed_at": new Date('2026-03-10T09:55:00Z'), - - - - - - - "fulfilled_at": new Date('2026-03-10T00:00:00Z'), - - - - }, - - { - - - - - "order_number": "ORD-10022", - - - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "order_status": "draft", - - - - - - - "fulfillment_status": "returned", - - - - - - - "payment_status": "unpaid", - - - - - - - "subtotal_amount": 32.0, - - - - - - - "discount_amount": 5.0, - - - - - - - "shipping_amount": 0.0, - - - - - - - "tax_amount": 2.43, - - - - - - - "total_amount": 29.43, - - - - - - - "currency": "USD", - - - - - - - "customer_note": "Gift wrap if available", - - - - - - - "internal_note": "Applied free shipping code", - - - - - - - "placed_at": new Date('2026-03-09T14:10:00Z'), - - - - - - - "fulfilled_at": new Date('2026-03-10T15:20:00Z'), - - - - }, - - { - - - - - "order_number": "ORD-10023", - - - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "order_status": "packed", - - - - - - - "fulfillment_status": "unfulfilled", - - - - - - - "payment_status": "paid", - - - - - - - "subtotal_amount": 38.0, - - - - - - - "discount_amount": 0.0, - - - - - - - "shipping_amount": 6.0, - - - - - - - "tax_amount": 3.15, - - - - - - - "total_amount": 47.15, - - - - - - - "currency": "USD", - - - - - - - "customer_note": "Eco packaging preferred", - - - - - - - "internal_note": "Awaiting second item restock", - - - - - - - "placed_at": new Date('2026-03-11T08:25:00Z'), - - - - - - - "fulfilled_at": new Date('2026-03-11T00:00:00Z'), - - - - }, - + { + order_number: 'ORD-10021', + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + order_status: 'refunded', + + fulfillment_status: 'partial', + + payment_status: 'failed', + + subtotal_amount: 56, + + discount_amount: 0, + + shipping_amount: 6, + + tax_amount: 5.04, + + total_amount: 67.04, + + currency: 'USD', + + customer_note: 'Please leave at front desk', + + internal_note: 'Priority pack before 3pm', + + placed_at: new Date('2026-03-10T09:55:00Z'), + + fulfilled_at: new Date('2026-03-10T00:00:00Z'), + }, + + { + order_number: 'ORD-10022', + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + order_status: 'draft', + + fulfillment_status: 'partial', + + payment_status: 'paid', + + subtotal_amount: 32, + + discount_amount: 5, + + shipping_amount: 0, + + tax_amount: 2.43, + + total_amount: 29.43, + + currency: 'USD', + + customer_note: 'Gift wrap if available', + + internal_note: 'Applied free shipping code', + + placed_at: new Date('2026-03-09T14:10:00Z'), + + fulfilled_at: new Date('2026-03-10T15:20:00Z'), + }, + + { + order_number: 'ORD-10023', + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + order_status: 'refunded', + + fulfillment_status: 'partial', + + payment_status: 'authorized', + + subtotal_amount: 38, + + discount_amount: 0, + + shipping_amount: 6, + + tax_amount: 3.15, + + total_amount: 47.15, + + currency: 'USD', + + customer_note: 'Eco packaging preferred', + + internal_note: 'Awaiting second item restock', + + placed_at: new Date('2026-03-11T08:25:00Z'), + + fulfilled_at: new Date('2026-03-11T00:00:00Z'), + }, + + { + order_number: 'ORD-10024', + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + // type code here for "relation_one" field + + order_status: 'delivered', + + fulfillment_status: 'returned', + + payment_status: 'failed', + + subtotal_amount: 24, + + discount_amount: 0, + + shipping_amount: 6, + + tax_amount: 2.52, + + total_amount: 32.52, + + currency: 'USD', + + customer_note: 'Call on arrival', + + internal_note: 'Payment failed twice', + + placed_at: new Date('2026-03-08T19:05:00Z'), + + fulfilled_at: new Date('2026-03-08T00:00:00Z'), + }, ]; - - const OrderItemsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "item_name": "Classic Tee - Small - Black", - - - - - - - "item_sku": "VAR-TEE-S-BLK", - - - - - - - "unit_price": 24.0, - - - - - - - "quantity": 2, - - - - - - - "discount_amount": 0.0, - - - - - - - "tax_amount": 3.6, - - - - - - - "line_total": 48.0, - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "item_name": "Ceramic Mug - White", - - - - - - - "item_sku": "VAR-MUG-WHT", - - - - - - - "unit_price": 14.0, - - - - - - - "quantity": 1, - - - - - - - "discount_amount": 0.0, - - - - - - - "tax_amount": 1.44, - - - - - - - "line_total": 14.0, - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - // type code here for "relation_one" field - - - - - - - "item_name": "Water Bottle - 24oz - Steel", - - - - - - - "item_sku": "VAR-BOTTLE-24-STEEL", - - - - - - - "unit_price": 32.0, - - - - - - - "quantity": 1, - - - - - - - "discount_amount": 5.0, - - - - - - - "tax_amount": 2.43, - - - - - - - "line_total": 27.0, - - - - }, - + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + item_name: 'Classic Tee - Small - Black', + + item_sku: 'VAR-TEE-S-BLK', + + unit_price: 24, + + quantity: 2, + + discount_amount: 0, + + tax_amount: 3.6, + + line_total: 48, + }, + + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + item_name: 'Ceramic Mug - White', + + item_sku: 'VAR-MUG-WHT', + + unit_price: 14, + + quantity: 1, + + discount_amount: 0, + + tax_amount: 1.44, + + line_total: 14, + }, + + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + item_name: 'Water Bottle - 24oz - Steel', + + item_sku: 'VAR-BOTTLE-24-STEEL', + + unit_price: 32, + + quantity: 1, + + discount_amount: 5, + + tax_amount: 2.43, + + line_total: 27, + }, + + { + // type code here for "relation_one" field + + // type code here for "relation_one" field + + item_name: 'Canvas Tote - Natural', + + item_sku: 'VAR-TOTE-NAT', + + unit_price: 18, + + quantity: 1, + + discount_amount: 0, + + tax_amount: 1.62, + + line_total: 18, + }, ]; - - const ShipmentsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - "shipment_status": "returned", - - - - - - - "carrier": "UPS", - - - - - - - "service_level": "Ground", - - - - - - - "tracking_number": "1Z999AA10123456784", - - - - - - - "packed_at": new Date('2026-03-10T14:50:00Z'), - - - - - - - "shipped_at": new Date('2026-03-10T18:15:00Z'), - - - - - - - "delivered_at": new Date('2026-03-12T16:40:00Z'), - - - - - - - "shipping_label_url": "https://labels.storeops.local/ship/ORD-10022.pdf", - - - - - - - "shipping_cost": 7.1, - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "shipment_status": "packed", - - - - - - - "carrier": "USPS", - - - - - - - "service_level": "Priority", - - - - - - - "tracking_number": "9405511202555123456781", - - - - - - - "packed_at": new Date('2026-03-10T15:05:00Z'), - - - - - - - "shipped_at": new Date('2026-03-11T00:00:00Z'), - - - - - - - "delivered_at": new Date('2026-03-13T00:00:00Z'), - - - - - - - "shipping_label_url": "https://labels.storeops.local/ship/ORD-10021.pdf", - - - - - - - "shipping_cost": 6.35, - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "shipment_status": "packed", - - - - - - - "carrier": "FedEx", - - - - - - - "service_level": "Home Delivery", - - - - - - - "tracking_number": "61299999999999999999", - - - - - - - "packed_at": new Date('2026-03-11T12:10:00Z'), - - - - - - - "shipped_at": new Date('2026-03-12T00:00:00Z'), - - - - - - - "delivered_at": new Date('2026-03-14T00:00:00Z'), - - - - - - - "shipping_label_url": "https://labels.storeops.local/ship/ORD-10023.pdf", - - - - - - - "shipping_cost": 8.25, - - - - }, - + { + // type code here for "relation_one" field + + shipment_status: 'delivered', + + carrier: 'UPS', + + service_level: 'Ground', + + tracking_number: '1Z999AA10123456784', + + packed_at: new Date('2026-03-10T14:50:00Z'), + + shipped_at: new Date('2026-03-10T18:15:00Z'), + + delivered_at: new Date('2026-03-12T16:40:00Z'), + + shipping_label_url: 'https://labels.storeops.local/ship/ORD-10022.pdf', + + shipping_cost: 7.1, + }, + + { + // type code here for "relation_one" field + + shipment_status: 'packed', + + carrier: 'USPS', + + service_level: 'Priority', + + tracking_number: '9405511202555123456781', + + packed_at: new Date('2026-03-10T15:05:00Z'), + + shipped_at: new Date('2026-03-11T00:00:00Z'), + + delivered_at: new Date('2026-03-13T00:00:00Z'), + + shipping_label_url: 'https://labels.storeops.local/ship/ORD-10021.pdf', + + shipping_cost: 6.35, + }, + + { + // type code here for "relation_one" field + + shipment_status: 'shipped', + + carrier: 'FedEx', + + service_level: 'Home Delivery', + + tracking_number: '61299999999999999999', + + packed_at: new Date('2026-03-11T12:10:00Z'), + + shipped_at: new Date('2026-03-12T00:00:00Z'), + + delivered_at: new Date('2026-03-14T00:00:00Z'), + + shipping_label_url: 'https://labels.storeops.local/ship/ORD-10023.pdf', + + shipping_cost: 8.25, + }, + + { + // type code here for "relation_one" field + + shipment_status: 'packed', + + carrier: 'USPS', + + service_level: 'First Class', + + tracking_number: '9400111202555987654321', + + packed_at: new Date('2026-03-06T09:20:00Z'), + + shipped_at: new Date('2026-03-06T12:00:00Z'), + + delivered_at: new Date('2026-03-08T15:35:00Z'), + + shipping_label_url: 'https://labels.storeops.local/ship/ORD-10025.pdf', + + shipping_cost: 5.1, + }, ]; - - const PaymentsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - "payment_method": "wallet", - - - - - - - "payment_status": "refunded", - - - - - - - "amount": 67.04, - - - - - - - "currency": "USD", - - - - - - - "provider": "Stripe", - - - - - - - "provider_payment_ref": "pi_3N8XxK2eZvKYlo2C10021", - - - - - - - "authorized_at": new Date('2026-03-10T09:56:00Z'), - - - - - - - "captured_at": new Date('2026-03-10T09:56:10Z'), - - - - - - - "refunded_at": new Date('2026-03-10T00:00:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "payment_method": "card", - - - - - - - "payment_status": "cancelled", - - - - - - - "amount": 29.43, - - - - - - - "currency": "USD", - - - - - - - "provider": "PayPal", - - - - - - - "provider_payment_ref": "PAYID-MOCK10022", - - - - - - - "authorized_at": new Date('2026-03-09T14:11:00Z'), - - - - - - - "captured_at": new Date('2026-03-09T14:11:15Z'), - - - - - - - "refunded_at": new Date('2026-03-09T00:00:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "payment_method": "bank_transfer", - - - - - - - "payment_status": "pending", - - - - - - - "amount": 47.15, - - - - - - - "currency": "USD", - - - - - - - "provider": "Stripe", - - - - - - - "provider_payment_ref": "pi_3N8XxK2eZvKYlo2C10023", - - - - - - - "authorized_at": new Date('2026-03-11T08:26:00Z'), - - - - - - - "captured_at": new Date('2026-03-11T00:00:00Z'), - - - - - - - "refunded_at": new Date('2026-03-11T00:00:00Z'), - - - - }, - + { + // type code here for "relation_one" field + + payment_method: 'manual', + + payment_status: 'cancelled', + + amount: 67.04, + + currency: 'USD', + + provider: 'Stripe', + + provider_payment_ref: 'pi_3N8XxK2eZvKYlo2C10021', + + authorized_at: new Date('2026-03-10T09:56:00Z'), + + captured_at: new Date('2026-03-10T09:56:10Z'), + + refunded_at: new Date('2026-03-10T00:00:00Z'), + }, + + { + // type code here for "relation_one" field + + payment_method: 'cash_on_delivery', + + payment_status: 'captured', + + amount: 29.43, + + currency: 'USD', + + provider: 'PayPal', + + provider_payment_ref: 'PAYID-MOCK10022', + + authorized_at: new Date('2026-03-09T14:11:00Z'), + + captured_at: new Date('2026-03-09T14:11:15Z'), + + refunded_at: new Date('2026-03-09T00:00:00Z'), + }, + + { + // type code here for "relation_one" field + + payment_method: 'card', + + payment_status: 'cancelled', + + amount: 47.15, + + currency: 'USD', + + provider: 'Stripe', + + provider_payment_ref: 'pi_3N8XxK2eZvKYlo2C10023', + + authorized_at: new Date('2026-03-11T08:26:00Z'), + + captured_at: new Date('2026-03-11T00:00:00Z'), + + refunded_at: new Date('2026-03-11T00:00:00Z'), + }, + + { + // type code here for "relation_one" field + + payment_method: 'cash_on_delivery', + + payment_status: 'captured', + + amount: 32.52, + + currency: 'USD', + + provider: 'Stripe', + + provider_payment_ref: 'pi_3N8XxK2eZvKYlo2C10024', + + authorized_at: new Date('2026-03-08T19:06:00Z'), + + captured_at: new Date('2026-03-08T00:00:00Z'), + + refunded_at: new Date('2026-03-08T00:00:00Z'), + }, ]; - - const RefundsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - "refund_status": "succeeded", - - - - - - - "amount": 21.8, - - - - - - - "currency": "USD", - - - - - - - "reason": "Returned item accepted", - - - - - - - "provider_refund_ref": "re_1MockRefund10025", - - - - - - - // type code here for "relation_one" field - - - - - - - "requested_at": new Date('2026-03-08T09:15:00Z'), - - - - - - - "processed_at": new Date('2026-03-09T10:00:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "refund_status": "cancelled", - - - - - - - "amount": 6.0, - - - - - - - "currency": "USD", - - - - - - - "reason": "Shipping fee goodwill refund", - - - - - - - "provider_refund_ref": "re_1MockRefund10021", - - - - - - - // type code here for "relation_one" field - - - - - - - "requested_at": new Date('2026-03-12T13:20:00Z'), - - - - - - - "processed_at": new Date('2026-03-12T00:00:00Z'), - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "refund_status": "pending", - - - - - - - "amount": 5.0, - - - - - - - "currency": "USD", - - - - - - - "reason": "Discount mismatch dispute", - - - - - - - "provider_refund_ref": "re_1MockRefund10022", - - - - - - - // type code here for "relation_one" field - - - - - - - "requested_at": new Date('2026-03-12T11:00:00Z'), - - - - - - - "processed_at": new Date('2026-03-12T11:30:00Z'), - - - - }, - + { + // type code here for "relation_one" field + + refund_status: 'pending', + + amount: 21.8, + + currency: 'USD', + + reason: 'Returned item accepted', + + provider_refund_ref: 're_1MockRefund10025', + + // type code here for "relation_one" field + + requested_at: new Date('2026-03-08T09:15:00Z'), + + processed_at: new Date('2026-03-09T10:00:00Z'), + }, + + { + // type code here for "relation_one" field + + refund_status: 'cancelled', + + amount: 6, + + currency: 'USD', + + reason: 'Shipping fee goodwill refund', + + provider_refund_ref: 're_1MockRefund10021', + + // type code here for "relation_one" field + + requested_at: new Date('2026-03-12T13:20:00Z'), + + processed_at: new Date('2026-03-12T00:00:00Z'), + }, + + { + // type code here for "relation_one" field + + refund_status: 'cancelled', + + amount: 5, + + currency: 'USD', + + reason: 'Discount mismatch dispute', + + provider_refund_ref: 're_1MockRefund10022', + + // type code here for "relation_one" field + + requested_at: new Date('2026-03-12T11:00:00Z'), + + processed_at: new Date('2026-03-12T11:30:00Z'), + }, + + { + // type code here for "relation_one" field + + refund_status: 'failed', + + amount: 32.52, + + currency: 'USD', + + reason: 'Payment never captured', + + provider_refund_ref: 're_1MockRefund10024', + + // type code here for "relation_one" field + + requested_at: new Date('2026-03-09T10:10:00Z'), + + processed_at: new Date('2026-03-09T10:20:00Z'), + }, ]; - - const DiscountCodesData = [ - - { - - - - - "code": "FREESHIP10", - - - - - - - "discount_type": "fixed_amount", - - - - - - - "value_amount": 0.0, - - - - - - - "currency": "USD", - - - - - - - "max_redemptions": 500, - - - - - - - "redeemed_count": 42, - - - - - - - "min_order_amount": 25.0, - - - - - - - "is_active": true, - - - - - - - "starts_at": new Date('2026-01-01T00:00:00Z'), - - - - - - - "ends_at": new Date('2026-12-31T23:59:00Z'), - - - - }, - - { - - - - - "code": "WELCOME5", - - - - - - - "discount_type": "free_shipping", - - - - - - - "value_amount": 5.0, - - - - - - - "currency": "USD", - - - - - - - "max_redemptions": 1000, - - - - - - - "redeemed_count": 188, - - - - - - - "min_order_amount": 20.0, - - - - - - - "is_active": true, - - - - - - - "starts_at": new Date('2025-10-01T00:00:00Z'), - - - - - - - "ends_at": new Date('2026-06-30T23:59:00Z'), - - - - }, - - { - - - - - "code": "SPRING15", - - - - - - - "discount_type": "fixed_amount", - - - - - - - "value_amount": 15.0, - - - - - - - "currency": "USD", - - - - - - - "max_redemptions": 300, - - - - - - - "redeemed_count": 27, - - - - - - - "min_order_amount": 30.0, - - - - - - - "is_active": true, - - - - - - - "starts_at": new Date('2026-03-01T00:00:00Z'), - - - - - - - "ends_at": new Date('2026-04-15T23:59:00Z'), - - - - }, - + { + code: 'FREESHIP10', + + discount_type: 'free_shipping', + + value_amount: 0, + + currency: 'USD', + + max_redemptions: 500, + + redeemed_count: 42, + + min_order_amount: 25, + + is_active: true, + + starts_at: new Date('2026-01-01T00:00:00Z'), + + ends_at: new Date('2026-12-31T23:59:00Z'), + }, + + { + code: 'WELCOME5', + + discount_type: 'fixed_amount', + + value_amount: 5, + + currency: 'USD', + + max_redemptions: 1000, + + redeemed_count: 188, + + min_order_amount: 20, + + is_active: true, + + starts_at: new Date('2025-10-01T00:00:00Z'), + + ends_at: new Date('2026-06-30T23:59:00Z'), + }, + + { + code: 'SPRING15', + + discount_type: 'percentage', + + value_amount: 15, + + currency: 'USD', + + max_redemptions: 300, + + redeemed_count: 27, + + min_order_amount: 30, + + is_active: true, + + starts_at: new Date('2026-03-01T00:00:00Z'), + + ends_at: new Date('2026-04-15T23:59:00Z'), + }, + + { + code: 'VIP20', + + discount_type: 'free_shipping', + + value_amount: 20, + + currency: 'USD', + + max_redemptions: 100, + + redeemed_count: 12, + + min_order_amount: 50, + + is_active: true, + + starts_at: new Date('2026-02-01T00:00:00Z'), + + ends_at: new Date('2026-12-31T23:59:00Z'), + }, ]; - - const OrderStatusEventsData = [ - - { - - - - - // type code here for "relation_one" field - - - - - - - "from_status": "paid", - - - - - - - "to_status": "packed", - - - - - - - // type code here for "relation_one" field - - - - - - - "changed_at": new Date('2026-03-10T09:56:15Z'), - - - - - - - "note": "Payment captured successfully", - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "from_status": "paid", - - - - - - - "to_status": "pending_payment", - - - - - - - // type code here for "relation_one" field - - - - - - - "changed_at": new Date('2026-03-10T14:50:00Z'), - - - - - - - "note": "Order packed and label printed", - - - - }, - - { - - - - - // type code here for "relation_one" field - - - - - - - "from_status": "refunded", - - - - - - - "to_status": "packed", - - - - - - - // type code here for "relation_one" field - - - - - - - "changed_at": new Date('2026-03-10T18:15:00Z'), - - - - - - - "note": "Handed to carrier pickup", - - - - }, - + { + // type code here for "relation_one" field + + from_status: 'pending_payment', + + to_status: 'cancelled', + + // type code here for "relation_one" field + + changed_at: new Date('2026-03-10T09:56:15Z'), + + note: 'Payment captured successfully', + }, + + { + // type code here for "relation_one" field + + from_status: 'pending_payment', + + to_status: 'delivered', + + // type code here for "relation_one" field + + changed_at: new Date('2026-03-10T14:50:00Z'), + + note: 'Order packed and label printed', + }, + + { + // type code here for "relation_one" field + + from_status: 'shipped', + + to_status: 'packed', + + // type code here for "relation_one" field + + changed_at: new Date('2026-03-10T18:15:00Z'), + + note: 'Handed to carrier pickup', + }, + + { + // type code here for "relation_one" field + + from_status: 'draft', + + to_status: 'draft', + + // type code here for "relation_one" field + + changed_at: new Date('2026-03-09T10:00:00Z'), + + note: 'Refund issued after return received', + }, ]; +const TestData = [ + { + name: 'Marie Curie', + }, + { + name: 'Rudolf Virchow', + }, + { + name: 'Ernst Mayr', + }, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Similar logic for "relation_many" - - + { + name: 'William Harvey', + }, +]; - - - - - - - - - - - - - - - - - - - +// Similar logic for "relation_many" - - - - - - async function associateAddressWithCustomer() { - - const relatedCustomer0 = await Customers.findOne({ - offset: Math.floor(Math.random() * (await Customers.count())), - }); - const Address0 = await Addresses.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Address0?.setCustomer) - { - await - Address0. - setCustomer(relatedCustomer0); - } - - const relatedCustomer1 = await Customers.findOne({ - offset: Math.floor(Math.random() * (await Customers.count())), - }); - const Address1 = await Addresses.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Address1?.setCustomer) - { - await - Address1. - setCustomer(relatedCustomer1); - } - - const relatedCustomer2 = await Customers.findOne({ - offset: Math.floor(Math.random() * (await Customers.count())), - }); - const Address2 = await Addresses.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Address2?.setCustomer) - { - await - Address2. - setCustomer(relatedCustomer2); - } - - } - - - - - - - - - - - - - - - - - - - - - - +async function associateAddressWithCustomer() { + const relatedCustomer0 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Address0 = await Addresses.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Address0?.setCustomer) { + await Address0.setCustomer(relatedCustomer0); + } - - - - - - - - - - - - async function associateProductCategoryWithParent_category() { - - const relatedParent_category0 = await ProductCategories.findOne({ - offset: Math.floor(Math.random() * (await ProductCategories.count())), - }); - const ProductCategory0 = await ProductCategories.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (ProductCategory0?.setParent_category) - { - await - ProductCategory0. - setParent_category(relatedParent_category0); - } - - const relatedParent_category1 = await ProductCategories.findOne({ - offset: Math.floor(Math.random() * (await ProductCategories.count())), - }); - const ProductCategory1 = await ProductCategories.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (ProductCategory1?.setParent_category) - { - await - ProductCategory1. - setParent_category(relatedParent_category1); - } - - const relatedParent_category2 = await ProductCategories.findOne({ - offset: Math.floor(Math.random() * (await ProductCategories.count())), - }); - const ProductCategory2 = await ProductCategories.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (ProductCategory2?.setParent_category) - { - await - ProductCategory2. - setParent_category(relatedParent_category2); - } - - } - - - - + const relatedCustomer1 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Address1 = await Addresses.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Address1?.setCustomer) { + await Address1.setCustomer(relatedCustomer1); + } - - - - - - - - - - - - async function associateProductWithCategory() { - - const relatedCategory0 = await ProductCategories.findOne({ - offset: Math.floor(Math.random() * (await ProductCategories.count())), - }); - const Product0 = await Products.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Product0?.setCategory) - { - await - Product0. - setCategory(relatedCategory0); - } - - const relatedCategory1 = await ProductCategories.findOne({ - offset: Math.floor(Math.random() * (await ProductCategories.count())), - }); - const Product1 = await Products.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Product1?.setCategory) - { - await - Product1. - setCategory(relatedCategory1); - } - - const relatedCategory2 = await ProductCategories.findOne({ - offset: Math.floor(Math.random() * (await ProductCategories.count())), - }); - const Product2 = await Products.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Product2?.setCategory) - { - await - Product2. - setCategory(relatedCategory2); - } - - } - - - - - - - - - - - - - - - - - - + const relatedCustomer2 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Address2 = await Addresses.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Address2?.setCustomer) { + await Address2.setCustomer(relatedCustomer2); + } - - - - - - async function associateProductVariantWithProduct() { - - const relatedProduct0 = await Products.findOne({ - offset: Math.floor(Math.random() * (await Products.count())), - }); - const ProductVariant0 = await ProductVariants.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (ProductVariant0?.setProduct) - { - await - ProductVariant0. - setProduct(relatedProduct0); - } - - const relatedProduct1 = await Products.findOne({ - offset: Math.floor(Math.random() * (await Products.count())), - }); - const ProductVariant1 = await ProductVariants.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (ProductVariant1?.setProduct) - { - await - ProductVariant1. - setProduct(relatedProduct1); - } - - const relatedProduct2 = await Products.findOne({ - offset: Math.floor(Math.random() * (await Products.count())), - }); - const ProductVariant2 = await ProductVariants.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (ProductVariant2?.setProduct) - { - await - ProductVariant2. - setProduct(relatedProduct2); - } - - } - - - - - - - - - - - - - - - - - - + const relatedCustomer3 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Address3 = await Addresses.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Address3?.setCustomer) { + await Address3.setCustomer(relatedCustomer3); + } +} - - - - - - - - - - - +async function associateProductCategoryWithParent_category() { + const relatedParent_category0 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const ProductCategory0 = await ProductCategories.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (ProductCategory0?.setParent_category) { + await ProductCategory0.setParent_category(relatedParent_category0); + } - - - - - - async function associateInventoryItemWithVariant() { - - const relatedVariant0 = await ProductVariants.findOne({ - offset: Math.floor(Math.random() * (await ProductVariants.count())), - }); - const InventoryItem0 = await InventoryItems.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (InventoryItem0?.setVariant) - { - await - InventoryItem0. - setVariant(relatedVariant0); - } - - const relatedVariant1 = await ProductVariants.findOne({ - offset: Math.floor(Math.random() * (await ProductVariants.count())), - }); - const InventoryItem1 = await InventoryItems.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (InventoryItem1?.setVariant) - { - await - InventoryItem1. - setVariant(relatedVariant1); - } - - const relatedVariant2 = await ProductVariants.findOne({ - offset: Math.floor(Math.random() * (await ProductVariants.count())), - }); - const InventoryItem2 = await InventoryItems.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (InventoryItem2?.setVariant) - { - await - InventoryItem2. - setVariant(relatedVariant2); - } - - } - - - - - async function associateInventoryItemWithLocation() { - - const relatedLocation0 = await InventoryLocations.findOne({ - offset: Math.floor(Math.random() * (await InventoryLocations.count())), - }); - const InventoryItem0 = await InventoryItems.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (InventoryItem0?.setLocation) - { - await - InventoryItem0. - setLocation(relatedLocation0); - } - - const relatedLocation1 = await InventoryLocations.findOne({ - offset: Math.floor(Math.random() * (await InventoryLocations.count())), - }); - const InventoryItem1 = await InventoryItems.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (InventoryItem1?.setLocation) - { - await - InventoryItem1. - setLocation(relatedLocation1); - } - - const relatedLocation2 = await InventoryLocations.findOne({ - offset: Math.floor(Math.random() * (await InventoryLocations.count())), - }); - const InventoryItem2 = await InventoryItems.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (InventoryItem2?.setLocation) - { - await - InventoryItem2. - setLocation(relatedLocation2); - } - - } - - - - - - - - - - + const relatedParent_category1 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const ProductCategory1 = await ProductCategories.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (ProductCategory1?.setParent_category) { + await ProductCategory1.setParent_category(relatedParent_category1); + } - - - - - - async function associateInventoryMovementWithInventory_item() { - - const relatedInventory_item0 = await InventoryItems.findOne({ - offset: Math.floor(Math.random() * (await InventoryItems.count())), - }); - const InventoryMovement0 = await InventoryMovements.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (InventoryMovement0?.setInventory_item) - { - await - InventoryMovement0. - setInventory_item(relatedInventory_item0); - } - - const relatedInventory_item1 = await InventoryItems.findOne({ - offset: Math.floor(Math.random() * (await InventoryItems.count())), - }); - const InventoryMovement1 = await InventoryMovements.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (InventoryMovement1?.setInventory_item) - { - await - InventoryMovement1. - setInventory_item(relatedInventory_item1); - } - - const relatedInventory_item2 = await InventoryItems.findOne({ - offset: Math.floor(Math.random() * (await InventoryItems.count())), - }); - const InventoryMovement2 = await InventoryMovements.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (InventoryMovement2?.setInventory_item) - { - await - InventoryMovement2. - setInventory_item(relatedInventory_item2); - } - - } - - - - - - - - - - - - - async function associateInventoryMovementWithPerformed_by() { - - const relatedPerformed_by0 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const InventoryMovement0 = await InventoryMovements.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (InventoryMovement0?.setPerformed_by) - { - await - InventoryMovement0. - setPerformed_by(relatedPerformed_by0); - } - - const relatedPerformed_by1 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const InventoryMovement1 = await InventoryMovements.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (InventoryMovement1?.setPerformed_by) - { - await - InventoryMovement1. - setPerformed_by(relatedPerformed_by1); - } - - const relatedPerformed_by2 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const InventoryMovement2 = await InventoryMovements.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (InventoryMovement2?.setPerformed_by) - { - await - InventoryMovement2. - setPerformed_by(relatedPerformed_by2); - } - - } - - - - + const relatedParent_category2 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const ProductCategory2 = await ProductCategories.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (ProductCategory2?.setParent_category) { + await ProductCategory2.setParent_category(relatedParent_category2); + } - - - - - - - - async function associateOrderWithCustomer() { - - const relatedCustomer0 = await Customers.findOne({ - offset: Math.floor(Math.random() * (await Customers.count())), - }); - const Order0 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Order0?.setCustomer) - { - await - Order0. - setCustomer(relatedCustomer0); - } - - const relatedCustomer1 = await Customers.findOne({ - offset: Math.floor(Math.random() * (await Customers.count())), - }); - const Order1 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Order1?.setCustomer) - { - await - Order1. - setCustomer(relatedCustomer1); - } - - const relatedCustomer2 = await Customers.findOne({ - offset: Math.floor(Math.random() * (await Customers.count())), - }); - const Order2 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Order2?.setCustomer) - { - await - Order2. - setCustomer(relatedCustomer2); - } - - } - - - - - async function associateOrderWithShipping_addres() { - - const relatedShipping_addres0 = await Addresses.findOne({ - offset: Math.floor(Math.random() * (await Addresses.count())), - }); - const Order0 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Order0?.setShipping_addres) - { - await - Order0. - setShipping_addres(relatedShipping_addres0); - } - - const relatedShipping_addres1 = await Addresses.findOne({ - offset: Math.floor(Math.random() * (await Addresses.count())), - }); - const Order1 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Order1?.setShipping_addres) - { - await - Order1. - setShipping_addres(relatedShipping_addres1); - } - - const relatedShipping_addres2 = await Addresses.findOne({ - offset: Math.floor(Math.random() * (await Addresses.count())), - }); - const Order2 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Order2?.setShipping_addres) - { - await - Order2. - setShipping_addres(relatedShipping_addres2); - } - - } - - - - - async function associateOrderWithBilling_addres() { - - const relatedBilling_addres0 = await Addresses.findOne({ - offset: Math.floor(Math.random() * (await Addresses.count())), - }); - const Order0 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Order0?.setBilling_addres) - { - await - Order0. - setBilling_addres(relatedBilling_addres0); - } - - const relatedBilling_addres1 = await Addresses.findOne({ - offset: Math.floor(Math.random() * (await Addresses.count())), - }); - const Order1 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Order1?.setBilling_addres) - { - await - Order1. - setBilling_addres(relatedBilling_addres1); - } - - const relatedBilling_addres2 = await Addresses.findOne({ - offset: Math.floor(Math.random() * (await Addresses.count())), - }); - const Order2 = await Orders.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Order2?.setBilling_addres) - { - await - Order2. - setBilling_addres(relatedBilling_addres2); - } - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - + const relatedParent_category3 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const ProductCategory3 = await ProductCategories.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (ProductCategory3?.setParent_category) { + await ProductCategory3.setParent_category(relatedParent_category3); + } +} - - - - - - async function associateOrderItemWithOrder() { - - const relatedOrder0 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const OrderItem0 = await OrderItems.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (OrderItem0?.setOrder) - { - await - OrderItem0. - setOrder(relatedOrder0); - } - - const relatedOrder1 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const OrderItem1 = await OrderItems.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (OrderItem1?.setOrder) - { - await - OrderItem1. - setOrder(relatedOrder1); - } - - const relatedOrder2 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const OrderItem2 = await OrderItems.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (OrderItem2?.setOrder) - { - await - OrderItem2. - setOrder(relatedOrder2); - } - - } - - - - - async function associateOrderItemWithVariant() { - - const relatedVariant0 = await ProductVariants.findOne({ - offset: Math.floor(Math.random() * (await ProductVariants.count())), - }); - const OrderItem0 = await OrderItems.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (OrderItem0?.setVariant) - { - await - OrderItem0. - setVariant(relatedVariant0); - } - - const relatedVariant1 = await ProductVariants.findOne({ - offset: Math.floor(Math.random() * (await ProductVariants.count())), - }); - const OrderItem1 = await OrderItems.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (OrderItem1?.setVariant) - { - await - OrderItem1. - setVariant(relatedVariant1); - } - - const relatedVariant2 = await ProductVariants.findOne({ - offset: Math.floor(Math.random() * (await ProductVariants.count())), - }); - const OrderItem2 = await OrderItems.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (OrderItem2?.setVariant) - { - await - OrderItem2. - setVariant(relatedVariant2); - } - - } - - - - - - - - - - - - - - - - +async function associateProductWithCategory() { + const relatedCategory0 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const Product0 = await Products.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Product0?.setCategory) { + await Product0.setCategory(relatedCategory0); + } - - - - - - async function associateShipmentWithOrder() { - - const relatedOrder0 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const Shipment0 = await Shipments.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Shipment0?.setOrder) - { - await - Shipment0. - setOrder(relatedOrder0); - } - - const relatedOrder1 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const Shipment1 = await Shipments.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Shipment1?.setOrder) - { - await - Shipment1. - setOrder(relatedOrder1); - } - - const relatedOrder2 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const Shipment2 = await Shipments.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Shipment2?.setOrder) - { - await - Shipment2. - setOrder(relatedOrder2); - } - - } - - - - - - - - - - - - - - - - - - - - + const relatedCategory1 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const Product1 = await Products.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Product1?.setCategory) { + await Product1.setCategory(relatedCategory1); + } - - - - - - async function associatePaymentWithOrder() { - - const relatedOrder0 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const Payment0 = await Payments.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Payment0?.setOrder) - { - await - Payment0. - setOrder(relatedOrder0); - } - - const relatedOrder1 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const Payment1 = await Payments.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Payment1?.setOrder) - { - await - Payment1. - setOrder(relatedOrder1); - } - - const relatedOrder2 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const Payment2 = await Payments.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Payment2?.setOrder) - { - await - Payment2. - setOrder(relatedOrder2); - } - - } - - - - - - - - - - - - - - - - - - - - + const relatedCategory2 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const Product2 = await Products.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Product2?.setCategory) { + await Product2.setCategory(relatedCategory2); + } - - - - - - async function associateRefundWithPayment() { - - const relatedPayment0 = await Payments.findOne({ - offset: Math.floor(Math.random() * (await Payments.count())), - }); - const Refund0 = await Refunds.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Refund0?.setPayment) - { - await - Refund0. - setPayment(relatedPayment0); - } - - const relatedPayment1 = await Payments.findOne({ - offset: Math.floor(Math.random() * (await Payments.count())), - }); - const Refund1 = await Refunds.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Refund1?.setPayment) - { - await - Refund1. - setPayment(relatedPayment1); - } - - const relatedPayment2 = await Payments.findOne({ - offset: Math.floor(Math.random() * (await Payments.count())), - }); - const Refund2 = await Refunds.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Refund2?.setPayment) - { - await - Refund2. - setPayment(relatedPayment2); - } - - } - - - - - - - - - - - - - - - async function associateRefundWithProcessed_by() { - - const relatedProcessed_by0 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const Refund0 = await Refunds.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (Refund0?.setProcessed_by) - { - await - Refund0. - setProcessed_by(relatedProcessed_by0); - } - - const relatedProcessed_by1 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const Refund1 = await Refunds.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (Refund1?.setProcessed_by) - { - await - Refund1. - setProcessed_by(relatedProcessed_by1); - } - - const relatedProcessed_by2 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const Refund2 = await Refunds.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (Refund2?.setProcessed_by) - { - await - Refund2. - setProcessed_by(relatedProcessed_by2); - } - - } - - - - - - + const relatedCategory3 = await ProductCategories.findOne({ + offset: Math.floor(Math.random() * (await ProductCategories.count())), + }); + const Product3 = await Products.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Product3?.setCategory) { + await Product3.setCategory(relatedCategory3); + } +} - - - - - - - - - - - - - - - - - - - - - - - +async function associateProductVariantWithProduct() { + const relatedProduct0 = await Products.findOne({ + offset: Math.floor(Math.random() * (await Products.count())), + }); + const ProductVariant0 = await ProductVariants.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (ProductVariant0?.setProduct) { + await ProductVariant0.setProduct(relatedProduct0); + } - - - - - - async function associateOrderStatusEventWithOrder() { - - const relatedOrder0 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const OrderStatusEvent0 = await OrderStatusEvents.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (OrderStatusEvent0?.setOrder) - { - await - OrderStatusEvent0. - setOrder(relatedOrder0); - } - - const relatedOrder1 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const OrderStatusEvent1 = await OrderStatusEvents.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (OrderStatusEvent1?.setOrder) - { - await - OrderStatusEvent1. - setOrder(relatedOrder1); - } - - const relatedOrder2 = await Orders.findOne({ - offset: Math.floor(Math.random() * (await Orders.count())), - }); - const OrderStatusEvent2 = await OrderStatusEvents.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (OrderStatusEvent2?.setOrder) - { - await - OrderStatusEvent2. - setOrder(relatedOrder2); - } - - } - - - - - - - - - async function associateOrderStatusEventWithChanged_by() { - - const relatedChanged_by0 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const OrderStatusEvent0 = await OrderStatusEvents.findOne({ - order: [['id', 'ASC']], - offset: 0 - }); - if (OrderStatusEvent0?.setChanged_by) - { - await - OrderStatusEvent0. - setChanged_by(relatedChanged_by0); - } - - const relatedChanged_by1 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const OrderStatusEvent1 = await OrderStatusEvents.findOne({ - order: [['id', 'ASC']], - offset: 1 - }); - if (OrderStatusEvent1?.setChanged_by) - { - await - OrderStatusEvent1. - setChanged_by(relatedChanged_by1); - } - - const relatedChanged_by2 = await Users.findOne({ - offset: Math.floor(Math.random() * (await Users.count())), - }); - const OrderStatusEvent2 = await OrderStatusEvents.findOne({ - order: [['id', 'ASC']], - offset: 2 - }); - if (OrderStatusEvent2?.setChanged_by) - { - await - OrderStatusEvent2. - setChanged_by(relatedChanged_by2); - } - - } - - - - - - + const relatedProduct1 = await Products.findOne({ + offset: Math.floor(Math.random() * (await Products.count())), + }); + const ProductVariant1 = await ProductVariants.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (ProductVariant1?.setProduct) { + await ProductVariant1.setProduct(relatedProduct1); + } + const relatedProduct2 = await Products.findOne({ + offset: Math.floor(Math.random() * (await Products.count())), + }); + const ProductVariant2 = await ProductVariants.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (ProductVariant2?.setProduct) { + await ProductVariant2.setProduct(relatedProduct2); + } + + const relatedProduct3 = await Products.findOne({ + offset: Math.floor(Math.random() * (await Products.count())), + }); + const ProductVariant3 = await ProductVariants.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (ProductVariant3?.setProduct) { + await ProductVariant3.setProduct(relatedProduct3); + } +} + +async function associateInventoryItemWithVariant() { + const relatedVariant0 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const InventoryItem0 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (InventoryItem0?.setVariant) { + await InventoryItem0.setVariant(relatedVariant0); + } + + const relatedVariant1 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const InventoryItem1 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (InventoryItem1?.setVariant) { + await InventoryItem1.setVariant(relatedVariant1); + } + + const relatedVariant2 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const InventoryItem2 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (InventoryItem2?.setVariant) { + await InventoryItem2.setVariant(relatedVariant2); + } + + const relatedVariant3 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const InventoryItem3 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (InventoryItem3?.setVariant) { + await InventoryItem3.setVariant(relatedVariant3); + } +} + +async function associateInventoryItemWithLocation() { + const relatedLocation0 = await InventoryLocations.findOne({ + offset: Math.floor(Math.random() * (await InventoryLocations.count())), + }); + const InventoryItem0 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (InventoryItem0?.setLocation) { + await InventoryItem0.setLocation(relatedLocation0); + } + + const relatedLocation1 = await InventoryLocations.findOne({ + offset: Math.floor(Math.random() * (await InventoryLocations.count())), + }); + const InventoryItem1 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (InventoryItem1?.setLocation) { + await InventoryItem1.setLocation(relatedLocation1); + } + + const relatedLocation2 = await InventoryLocations.findOne({ + offset: Math.floor(Math.random() * (await InventoryLocations.count())), + }); + const InventoryItem2 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (InventoryItem2?.setLocation) { + await InventoryItem2.setLocation(relatedLocation2); + } + + const relatedLocation3 = await InventoryLocations.findOne({ + offset: Math.floor(Math.random() * (await InventoryLocations.count())), + }); + const InventoryItem3 = await InventoryItems.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (InventoryItem3?.setLocation) { + await InventoryItem3.setLocation(relatedLocation3); + } +} + +async function associateInventoryMovementWithInventory_item() { + const relatedInventory_item0 = await InventoryItems.findOne({ + offset: Math.floor(Math.random() * (await InventoryItems.count())), + }); + const InventoryMovement0 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (InventoryMovement0?.setInventory_item) { + await InventoryMovement0.setInventory_item(relatedInventory_item0); + } + + const relatedInventory_item1 = await InventoryItems.findOne({ + offset: Math.floor(Math.random() * (await InventoryItems.count())), + }); + const InventoryMovement1 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (InventoryMovement1?.setInventory_item) { + await InventoryMovement1.setInventory_item(relatedInventory_item1); + } + + const relatedInventory_item2 = await InventoryItems.findOne({ + offset: Math.floor(Math.random() * (await InventoryItems.count())), + }); + const InventoryMovement2 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (InventoryMovement2?.setInventory_item) { + await InventoryMovement2.setInventory_item(relatedInventory_item2); + } + + const relatedInventory_item3 = await InventoryItems.findOne({ + offset: Math.floor(Math.random() * (await InventoryItems.count())), + }); + const InventoryMovement3 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (InventoryMovement3?.setInventory_item) { + await InventoryMovement3.setInventory_item(relatedInventory_item3); + } +} + +async function associateInventoryMovementWithPerformed_by() { + const relatedPerformed_by0 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const InventoryMovement0 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (InventoryMovement0?.setPerformed_by) { + await InventoryMovement0.setPerformed_by(relatedPerformed_by0); + } + + const relatedPerformed_by1 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const InventoryMovement1 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (InventoryMovement1?.setPerformed_by) { + await InventoryMovement1.setPerformed_by(relatedPerformed_by1); + } + + const relatedPerformed_by2 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const InventoryMovement2 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (InventoryMovement2?.setPerformed_by) { + await InventoryMovement2.setPerformed_by(relatedPerformed_by2); + } + + const relatedPerformed_by3 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const InventoryMovement3 = await InventoryMovements.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (InventoryMovement3?.setPerformed_by) { + await InventoryMovement3.setPerformed_by(relatedPerformed_by3); + } +} + +async function associateOrderWithCustomer() { + const relatedCustomer0 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Order0 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Order0?.setCustomer) { + await Order0.setCustomer(relatedCustomer0); + } + + const relatedCustomer1 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Order1 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Order1?.setCustomer) { + await Order1.setCustomer(relatedCustomer1); + } + + const relatedCustomer2 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Order2 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Order2?.setCustomer) { + await Order2.setCustomer(relatedCustomer2); + } + + const relatedCustomer3 = await Customers.findOne({ + offset: Math.floor(Math.random() * (await Customers.count())), + }); + const Order3 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Order3?.setCustomer) { + await Order3.setCustomer(relatedCustomer3); + } +} + +async function associateOrderWithShipping_address() { + const relatedShipping_address0 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order0 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Order0?.setShipping_address) { + await Order0.setShipping_address(relatedShipping_address0); + } + + const relatedShipping_address1 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order1 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Order1?.setShipping_address) { + await Order1.setShipping_address(relatedShipping_address1); + } + + const relatedShipping_address2 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order2 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Order2?.setShipping_address) { + await Order2.setShipping_address(relatedShipping_address2); + } + + const relatedShipping_address3 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order3 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Order3?.setShipping_address) { + await Order3.setShipping_address(relatedShipping_address3); + } +} + +async function associateOrderWithBilling_address() { + const relatedBilling_address0 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order0 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Order0?.setBilling_address) { + await Order0.setBilling_address(relatedBilling_address0); + } + + const relatedBilling_address1 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order1 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Order1?.setBilling_address) { + await Order1.setBilling_address(relatedBilling_address1); + } + + const relatedBilling_address2 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order2 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Order2?.setBilling_address) { + await Order2.setBilling_address(relatedBilling_address2); + } + + const relatedBilling_address3 = await Addresses.findOne({ + offset: Math.floor(Math.random() * (await Addresses.count())), + }); + const Order3 = await Orders.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Order3?.setBilling_address) { + await Order3.setBilling_address(relatedBilling_address3); + } +} + +async function associateOrderItemWithOrder() { + const relatedOrder0 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderItem0 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (OrderItem0?.setOrder) { + await OrderItem0.setOrder(relatedOrder0); + } + + const relatedOrder1 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderItem1 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (OrderItem1?.setOrder) { + await OrderItem1.setOrder(relatedOrder1); + } + + const relatedOrder2 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderItem2 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (OrderItem2?.setOrder) { + await OrderItem2.setOrder(relatedOrder2); + } + + const relatedOrder3 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderItem3 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (OrderItem3?.setOrder) { + await OrderItem3.setOrder(relatedOrder3); + } +} + +async function associateOrderItemWithVariant() { + const relatedVariant0 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const OrderItem0 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (OrderItem0?.setVariant) { + await OrderItem0.setVariant(relatedVariant0); + } + + const relatedVariant1 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const OrderItem1 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (OrderItem1?.setVariant) { + await OrderItem1.setVariant(relatedVariant1); + } + + const relatedVariant2 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const OrderItem2 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (OrderItem2?.setVariant) { + await OrderItem2.setVariant(relatedVariant2); + } + + const relatedVariant3 = await ProductVariants.findOne({ + offset: Math.floor(Math.random() * (await ProductVariants.count())), + }); + const OrderItem3 = await OrderItems.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (OrderItem3?.setVariant) { + await OrderItem3.setVariant(relatedVariant3); + } +} + +async function associateShipmentWithOrder() { + const relatedOrder0 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Shipment0 = await Shipments.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Shipment0?.setOrder) { + await Shipment0.setOrder(relatedOrder0); + } + + const relatedOrder1 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Shipment1 = await Shipments.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Shipment1?.setOrder) { + await Shipment1.setOrder(relatedOrder1); + } + + const relatedOrder2 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Shipment2 = await Shipments.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Shipment2?.setOrder) { + await Shipment2.setOrder(relatedOrder2); + } + + const relatedOrder3 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Shipment3 = await Shipments.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Shipment3?.setOrder) { + await Shipment3.setOrder(relatedOrder3); + } +} + +async function associatePaymentWithOrder() { + const relatedOrder0 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Payment0 = await Payments.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Payment0?.setOrder) { + await Payment0.setOrder(relatedOrder0); + } + + const relatedOrder1 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Payment1 = await Payments.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Payment1?.setOrder) { + await Payment1.setOrder(relatedOrder1); + } + + const relatedOrder2 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Payment2 = await Payments.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Payment2?.setOrder) { + await Payment2.setOrder(relatedOrder2); + } + + const relatedOrder3 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const Payment3 = await Payments.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Payment3?.setOrder) { + await Payment3.setOrder(relatedOrder3); + } +} + +async function associateRefundWithPayment() { + const relatedPayment0 = await Payments.findOne({ + offset: Math.floor(Math.random() * (await Payments.count())), + }); + const Refund0 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Refund0?.setPayment) { + await Refund0.setPayment(relatedPayment0); + } + + const relatedPayment1 = await Payments.findOne({ + offset: Math.floor(Math.random() * (await Payments.count())), + }); + const Refund1 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Refund1?.setPayment) { + await Refund1.setPayment(relatedPayment1); + } + + const relatedPayment2 = await Payments.findOne({ + offset: Math.floor(Math.random() * (await Payments.count())), + }); + const Refund2 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Refund2?.setPayment) { + await Refund2.setPayment(relatedPayment2); + } + + const relatedPayment3 = await Payments.findOne({ + offset: Math.floor(Math.random() * (await Payments.count())), + }); + const Refund3 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Refund3?.setPayment) { + await Refund3.setPayment(relatedPayment3); + } +} + +async function associateRefundWithProcessed_by() { + const relatedProcessed_by0 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const Refund0 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (Refund0?.setProcessed_by) { + await Refund0.setProcessed_by(relatedProcessed_by0); + } + + const relatedProcessed_by1 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const Refund1 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (Refund1?.setProcessed_by) { + await Refund1.setProcessed_by(relatedProcessed_by1); + } + + const relatedProcessed_by2 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const Refund2 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (Refund2?.setProcessed_by) { + await Refund2.setProcessed_by(relatedProcessed_by2); + } + + const relatedProcessed_by3 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const Refund3 = await Refunds.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (Refund3?.setProcessed_by) { + await Refund3.setProcessed_by(relatedProcessed_by3); + } +} + +async function associateOrderStatusEventWithOrder() { + const relatedOrder0 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderStatusEvent0 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (OrderStatusEvent0?.setOrder) { + await OrderStatusEvent0.setOrder(relatedOrder0); + } + + const relatedOrder1 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderStatusEvent1 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (OrderStatusEvent1?.setOrder) { + await OrderStatusEvent1.setOrder(relatedOrder1); + } + + const relatedOrder2 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderStatusEvent2 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (OrderStatusEvent2?.setOrder) { + await OrderStatusEvent2.setOrder(relatedOrder2); + } + + const relatedOrder3 = await Orders.findOne({ + offset: Math.floor(Math.random() * (await Orders.count())), + }); + const OrderStatusEvent3 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (OrderStatusEvent3?.setOrder) { + await OrderStatusEvent3.setOrder(relatedOrder3); + } +} + +async function associateOrderStatusEventWithChanged_by() { + const relatedChanged_by0 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const OrderStatusEvent0 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 0, + }); + if (OrderStatusEvent0?.setChanged_by) { + await OrderStatusEvent0.setChanged_by(relatedChanged_by0); + } + + const relatedChanged_by1 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const OrderStatusEvent1 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 1, + }); + if (OrderStatusEvent1?.setChanged_by) { + await OrderStatusEvent1.setChanged_by(relatedChanged_by1); + } + + const relatedChanged_by2 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const OrderStatusEvent2 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 2, + }); + if (OrderStatusEvent2?.setChanged_by) { + await OrderStatusEvent2.setChanged_by(relatedChanged_by2); + } + + const relatedChanged_by3 = await Users.findOne({ + offset: Math.floor(Math.random() * (await Users.count())), + }); + const OrderStatusEvent3 = await OrderStatusEvents.findOne({ + order: [['id', 'ASC']], + offset: 3, + }); + if (OrderStatusEvent3?.setChanged_by) { + await OrderStatusEvent3.setChanged_by(relatedChanged_by3); + } +} module.exports = { - up: async (queryInterface, Sequelize) => { - - - - - - - - await Customers.bulkCreate(CustomersData); - - - - - await Addresses.bulkCreate(AddressesData); - - - - - await ProductCategories.bulkCreate(ProductCategoriesData); - - - - - await Products.bulkCreate(ProductsData); - - - - - await ProductVariants.bulkCreate(ProductVariantsData); - - - - - await InventoryLocations.bulkCreate(InventoryLocationsData); - - - - - await InventoryItems.bulkCreate(InventoryItemsData); - - - - - await InventoryMovements.bulkCreate(InventoryMovementsData); - - - - - await Orders.bulkCreate(OrdersData); - - - - - await OrderItems.bulkCreate(OrderItemsData); - - - - - await Shipments.bulkCreate(ShipmentsData); - - - - - await Payments.bulkCreate(PaymentsData); - - - - - await Refunds.bulkCreate(RefundsData); - - - - - await DiscountCodes.bulkCreate(DiscountCodesData); - - - - - await OrderStatusEvents.bulkCreate(OrderStatusEventsData); - - - await Promise.all([ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Similar logic for "relation_many" - - - - - - - - - - - - - - - - - - - - - - - - - - - await associateAddressWithCustomer(), - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - await associateProductCategoryWithParent_category(), - - - - - - - - - - - - - - - - await associateProductWithCategory(), - - - - - - - - - - - - - - - - - - - - - - - - await associateProductVariantWithProduct(), - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - await associateInventoryItemWithVariant(), - - - - - await associateInventoryItemWithLocation(), - - - - - - - - - - - - - - - - await associateInventoryMovementWithInventory_item(), - - - - - - - - - - - - - await associateInventoryMovementWithPerformed_by(), - - - - - - - - - - - - await associateOrderWithCustomer(), - - - - - await associateOrderWithShipping_addres(), - - - - - await associateOrderWithBilling_addres(), - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - await associateOrderItemWithOrder(), - - - - - await associateOrderItemWithVariant(), - - - - - - - - - - - - - - - - - - - - - - await associateShipmentWithOrder(), - - - - - - - - - - - - - - - - - - - - - - - - - - await associatePaymentWithOrder(), - - - - - - - - - - - - - - - - - - - - - - - - - - await associateRefundWithPayment(), - - - - - - - - - - - - - - - await associateRefundWithProcessed_by(), - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - await associateOrderStatusEventWithOrder(), - - - - - - - - - await associateOrderStatusEventWithChanged_by(), - - - - - - - - ]); - - }, + up: async (queryInterface, Sequelize) => { + await Customers.bulkCreate(CustomersData); - down: async (queryInterface, Sequelize) => { - - - - - - - await queryInterface.bulkDelete('customers', null, {}); - - - await queryInterface.bulkDelete('addresses', null, {}); - - - await queryInterface.bulkDelete('product_categories', null, {}); - - - await queryInterface.bulkDelete('products', null, {}); - - - await queryInterface.bulkDelete('product_variants', null, {}); - - - await queryInterface.bulkDelete('inventory_locations', null, {}); - - - await queryInterface.bulkDelete('inventory_items', null, {}); - - - await queryInterface.bulkDelete('inventory_movements', null, {}); - - - await queryInterface.bulkDelete('orders', null, {}); - - - await queryInterface.bulkDelete('order_items', null, {}); - - - await queryInterface.bulkDelete('shipments', null, {}); - - - await queryInterface.bulkDelete('payments', null, {}); - - - await queryInterface.bulkDelete('refunds', null, {}); - - - await queryInterface.bulkDelete('discount_codes', null, {}); - - - await queryInterface.bulkDelete('order_status_events', null, {}); - - - }, -}; \ No newline at end of file + await Addresses.bulkCreate(AddressesData); + + await ProductCategories.bulkCreate(ProductCategoriesData); + + await Products.bulkCreate(ProductsData); + + await ProductVariants.bulkCreate(ProductVariantsData); + + await InventoryLocations.bulkCreate(InventoryLocationsData); + + await InventoryItems.bulkCreate(InventoryItemsData); + + await InventoryMovements.bulkCreate(InventoryMovementsData); + + await Orders.bulkCreate(OrdersData); + + await OrderItems.bulkCreate(OrderItemsData); + + await Shipments.bulkCreate(ShipmentsData); + + await Payments.bulkCreate(PaymentsData); + + await Refunds.bulkCreate(RefundsData); + + await DiscountCodes.bulkCreate(DiscountCodesData); + + await OrderStatusEvents.bulkCreate(OrderStatusEventsData); + + await Test.bulkCreate(TestData); + + await Promise.all([ + // Similar logic for "relation_many" + + await associateAddressWithCustomer(), + + await associateProductCategoryWithParent_category(), + + await associateProductWithCategory(), + + await associateProductVariantWithProduct(), + + await associateInventoryItemWithVariant(), + + await associateInventoryItemWithLocation(), + + await associateInventoryMovementWithInventory_item(), + + await associateInventoryMovementWithPerformed_by(), + + await associateOrderWithCustomer(), + + await associateOrderWithShipping_address(), + + await associateOrderWithBilling_address(), + + await associateOrderItemWithOrder(), + + await associateOrderItemWithVariant(), + + await associateShipmentWithOrder(), + + await associatePaymentWithOrder(), + + await associateRefundWithPayment(), + + await associateRefundWithProcessed_by(), + + await associateOrderStatusEventWithOrder(), + + await associateOrderStatusEventWithChanged_by(), + ]); + }, + + down: async (queryInterface, Sequelize) => { + await queryInterface.bulkDelete('customers', null, {}); + + await queryInterface.bulkDelete('addresses', null, {}); + + await queryInterface.bulkDelete('product_categories', null, {}); + + await queryInterface.bulkDelete('products', null, {}); + + await queryInterface.bulkDelete('product_variants', null, {}); + + await queryInterface.bulkDelete('inventory_locations', null, {}); + + await queryInterface.bulkDelete('inventory_items', null, {}); + + await queryInterface.bulkDelete('inventory_movements', null, {}); + + await queryInterface.bulkDelete('orders', null, {}); + + await queryInterface.bulkDelete('order_items', null, {}); + + await queryInterface.bulkDelete('shipments', null, {}); + + await queryInterface.bulkDelete('payments', null, {}); + + await queryInterface.bulkDelete('refunds', null, {}); + + await queryInterface.bulkDelete('discount_codes', null, {}); + + await queryInterface.bulkDelete('order_status_events', null, {}); + + await queryInterface.bulkDelete('test', null, {}); + }, +}; diff --git a/backend/src/db/seeders/20260313153335.js b/backend/src/db/seeders/20260313153335.js new file mode 100644 index 0000000..fe32966 --- /dev/null +++ b/backend/src/db/seeders/20260313153335.js @@ -0,0 +1,87 @@ +const { v4: uuid } = require('uuid'); +const db = require('../models'); +const Sequelize = require('sequelize'); +const config = require('../../config'); + +module.exports = { + /** + * @param{import("sequelize").QueryInterface} queryInterface + * @return {Promise} + */ + async up(queryInterface) { + const createdAt = new Date(); + const updatedAt = new Date(); + + /** @type {Map} */ + const idMap = new Map(); + + /** + * @param {string} key + * @return {string} + */ + function getId(key) { + if (idMap.has(key)) { + return idMap.get(key); + } + const id = uuid(); + idMap.set(key, id); + return id; + } + + /** + * @param {string} name + */ + function createPermissions(name) { + return [ + { + id: getId(`CREATE_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `CREATE_${name.toUpperCase()}`, + }, + { + id: getId(`READ_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `READ_${name.toUpperCase()}`, + }, + { + id: getId(`UPDATE_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `UPDATE_${name.toUpperCase()}`, + }, + { + id: getId(`DELETE_${name.toUpperCase()}`), + createdAt, + updatedAt, + name: `DELETE_${name.toUpperCase()}`, + }, + ]; + } + + const entities = ['test']; + + const createdPermissions = entities.flatMap(createPermissions); + + // Add permissions to database + await queryInterface.bulkInsert('permissions', createdPermissions); + // Get permissions ids + const permissionsIds = createdPermissions.map((p) => p.id); + // Get admin role + const adminRole = await db.roles.findOne({ + where: { name: config.roles.admin }, + }); + + if (adminRole) { + // Add permissions to admin role if it exists + await adminRole.addPermissions(permissionsIds); + } + }, + down: async (queryInterface, Sequelize) => { + await queryInterface.bulkDelete( + 'permissions', + entities.flatMap(createPermissions), + ); + }, +}; diff --git a/backend/src/index.js b/backend/src/index.js index 0052cf2..f921793 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -1,4 +1,3 @@ - const express = require('express'); const cors = require('cors'); const app = express(); @@ -14,13 +13,10 @@ const swaggerJsDoc = require('swagger-jsdoc'); const authRoutes = require('./routes/auth'); const fileRoutes = require('./routes/file'); const searchRoutes = require('./routes/search'); -const sqlRoutes = require('./routes/sql'); const pexelsRoutes = require('./routes/pexels'); const openaiRoutes = require('./routes/openai'); - - const usersRoutes = require('./routes/users'); const rolesRoutes = require('./routes/roles'); @@ -57,6 +53,7 @@ const discount_codesRoutes = require('./routes/discount_codes'); const order_status_eventsRoutes = require('./routes/order_status_events'); +const testRoutes = require('./routes/test'); const getBaseUrl = (url) => { if (!url) return ''; @@ -65,17 +62,18 @@ const getBaseUrl = (url) => { const options = { definition: { - openapi: "3.0.0", - info: { - version: "1.0.0", - title: "Store Ops Manager", - description: "Store Ops Manager Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.", - }, + openapi: '3.0.0', + info: { + version: '1.0.0', + title: 'Store Ops Manager', + description: + 'Store Ops Manager Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.', + }, servers: [ { url: getBaseUrl(process.env.NEXT_PUBLIC_BACK_API) || config.swaggerUrl, - description: "Development server", - } + description: 'Development server', + }, ], components: { securitySchemes: { @@ -83,28 +81,36 @@ const options = { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', - } + }, }, responses: { UnauthorizedError: { - description: "Access token is missing or invalid" - } - } + description: 'Access token is missing or invalid', + }, + }, }, - security: [{ - bearerAuth: [] - }] + security: [ + { + bearerAuth: [], + }, + ], }, - apis: ["./src/routes/*.js"], + apis: ['./src/routes/*.js'], }; const specs = swaggerJsDoc(options); -app.use('/api-docs', function (req, res, next) { - swaggerUI.host = getBaseUrl(process.env.NEXT_PUBLIC_BACK_API) || req.get('host'); - next() - }, swaggerUI.serve, swaggerUI.setup(specs)) +app.use( + '/api-docs', + function (req, res, next) { + swaggerUI.host = + getBaseUrl(process.env.NEXT_PUBLIC_BACK_API) || req.get('host'); + next(); + }, + swaggerUI.serve, + swaggerUI.setup(specs), +); -app.use(cors({origin: true})); +app.use(cors({ origin: true })); require('./auth/auth'); app.use(bodyParser.json()); @@ -114,83 +120,148 @@ app.use('/api/file', fileRoutes); app.use('/api/pexels', pexelsRoutes); app.enable('trust proxy'); - -app.use('/api/users', passport.authenticate('jwt', {session: false}), usersRoutes); - -app.use('/api/roles', passport.authenticate('jwt', {session: false}), rolesRoutes); - -app.use('/api/permissions', passport.authenticate('jwt', {session: false}), permissionsRoutes); - -app.use('/api/customers', passport.authenticate('jwt', {session: false}), customersRoutes); - -app.use('/api/addresses', passport.authenticate('jwt', {session: false}), addressesRoutes); - -app.use('/api/product_categories', passport.authenticate('jwt', {session: false}), product_categoriesRoutes); - -app.use('/api/products', passport.authenticate('jwt', {session: false}), productsRoutes); - -app.use('/api/product_variants', passport.authenticate('jwt', {session: false}), product_variantsRoutes); - -app.use('/api/inventory_locations', passport.authenticate('jwt', {session: false}), inventory_locationsRoutes); - -app.use('/api/inventory_items', passport.authenticate('jwt', {session: false}), inventory_itemsRoutes); - -app.use('/api/inventory_movements', passport.authenticate('jwt', {session: false}), inventory_movementsRoutes); - -app.use('/api/orders', passport.authenticate('jwt', {session: false}), ordersRoutes); - -app.use('/api/order_items', passport.authenticate('jwt', {session: false}), order_itemsRoutes); - -app.use('/api/shipments', passport.authenticate('jwt', {session: false}), shipmentsRoutes); - -app.use('/api/payments', passport.authenticate('jwt', {session: false}), paymentsRoutes); - -app.use('/api/refunds', passport.authenticate('jwt', {session: false}), refundsRoutes); - -app.use('/api/discount_codes', passport.authenticate('jwt', {session: false}), discount_codesRoutes); - -app.use('/api/order_status_events', passport.authenticate('jwt', {session: false}), order_status_eventsRoutes); - app.use( - '/api/openai', - passport.authenticate('jwt', { session: false }), - openaiRoutes, + '/api/users', + passport.authenticate('jwt', { session: false }), + usersRoutes, ); + app.use( - '/api/ai', - passport.authenticate('jwt', { session: false }), - openaiRoutes, + '/api/roles', + passport.authenticate('jwt', { session: false }), + rolesRoutes, +); + +app.use( + '/api/permissions', + passport.authenticate('jwt', { session: false }), + permissionsRoutes, +); + +app.use( + '/api/customers', + passport.authenticate('jwt', { session: false }), + customersRoutes, +); + +app.use( + '/api/addresses', + passport.authenticate('jwt', { session: false }), + addressesRoutes, +); + +app.use( + '/api/product_categories', + passport.authenticate('jwt', { session: false }), + product_categoriesRoutes, +); + +app.use( + '/api/products', + passport.authenticate('jwt', { session: false }), + productsRoutes, +); + +app.use( + '/api/product_variants', + passport.authenticate('jwt', { session: false }), + product_variantsRoutes, +); + +app.use( + '/api/inventory_locations', + passport.authenticate('jwt', { session: false }), + inventory_locationsRoutes, +); + +app.use( + '/api/inventory_items', + passport.authenticate('jwt', { session: false }), + inventory_itemsRoutes, +); + +app.use( + '/api/inventory_movements', + passport.authenticate('jwt', { session: false }), + inventory_movementsRoutes, +); + +app.use( + '/api/orders', + passport.authenticate('jwt', { session: false }), + ordersRoutes, +); + +app.use( + '/api/order_items', + passport.authenticate('jwt', { session: false }), + order_itemsRoutes, +); + +app.use( + '/api/shipments', + passport.authenticate('jwt', { session: false }), + shipmentsRoutes, +); + +app.use( + '/api/payments', + passport.authenticate('jwt', { session: false }), + paymentsRoutes, +); + +app.use( + '/api/refunds', + passport.authenticate('jwt', { session: false }), + refundsRoutes, +); + +app.use( + '/api/discount_codes', + passport.authenticate('jwt', { session: false }), + discount_codesRoutes, +); + +app.use( + '/api/order_status_events', + passport.authenticate('jwt', { session: false }), + order_status_eventsRoutes, +); + +app.use( + '/api/test', + passport.authenticate('jwt', { session: false }), + testRoutes, +); + +app.use( + '/api/openai', + passport.authenticate('jwt', { session: false }), + openaiRoutes, ); app.use( '/api/search', passport.authenticate('jwt', { session: false }), - searchRoutes); -app.use( - '/api/sql', - passport.authenticate('jwt', { session: false }), - sqlRoutes); - - -const publicDir = path.join( - __dirname, - '../public', + searchRoutes, ); +const publicDir = path.join(__dirname, '../public'); + if (fs.existsSync(publicDir)) { app.use('/', express.static(publicDir)); - app.get('*', function(request, response) { - response.sendFile( - path.resolve(publicDir, 'index.html'), - ); + app.get('*', function (request, response) { + response.sendFile(path.resolve(publicDir, 'index.html')); }); } const PORT = process.env.NODE_ENV === 'dev_stage' ? 3000 : 8080; +db.sequelize.sync().then(function () { app.listen(PORT, () => { console.log(`Listening on port ${PORT}`); }); +}); module.exports = app; diff --git a/backend/src/routes/test.js b/backend/src/routes/test.js new file mode 100644 index 0000000..948251c --- /dev/null +++ b/backend/src/routes/test.js @@ -0,0 +1,433 @@ +const express = require('express'); + +const TestService = require('../services/test'); +const TestDBApi = require('../db/api/test'); +const wrapAsync = require('../helpers').wrapAsync; + +const router = express.Router(); + +const { parse } = require('json2csv'); + +const { checkCrudPermissions } = require('../middlewares/check-permissions'); + +router.use(checkCrudPermissions('test')); + +/** + * @swagger + * components: + * schemas: + * Test: + * type: object + * properties: + + * name: + * type: string + * default: name + + */ + +/** + * @swagger + * tags: + * name: Test + * description: The Test managing API + */ + +/** + * @swagger + * /api/test: + * post: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Add new item + * description: Add new item + * requestBody: + * required: true + * content: + * application/json: + * schema: + * properties: + * data: + * description: Data of the updated item + * type: object + * $ref: "#/components/schemas/Test" + * responses: + * 200: + * description: The item was successfully added + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/Test" + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 405: + * description: Invalid input data + * 500: + * description: Some server error + */ +router.post( + '/', + wrapAsync(async (req, res) => { + const referer = + req.headers.referer || + `${req.protocol}://${req.hostname}${req.originalUrl}`; + const link = new URL(referer); + await TestService.create(req.body.data, req.currentUser, true, link.host); + const payload = true; + res.status(200).send(payload); + }), +); + +/** + * @swagger + * /api/budgets/bulk-import: + * post: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Bulk import items + * description: Bulk import items + * requestBody: + * required: true + * content: + * application/json: + * schema: + * properties: + * data: + * description: Data of the updated items + * type: array + * items: + * $ref: "#/components/schemas/Test" + * responses: + * 200: + * description: The items were successfully imported + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/Test" + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 405: + * description: Invalid input data + * 500: + * description: Some server error + * + */ +router.post( + '/bulk-import', + wrapAsync(async (req, res) => { + const referer = + req.headers.referer || + `${req.protocol}://${req.hostname}${req.originalUrl}`; + const link = new URL(referer); + await TestService.bulkImport(req, res, true, link.host); + const payload = true; + res.status(200).send(payload); + }), +); + +/** + * @swagger + * /api/test/{id}: + * put: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Update the data of the selected item + * description: Update the data of the selected item + * parameters: + * - in: path + * name: id + * description: Item ID to update + * required: true + * schema: + * type: string + * requestBody: + * description: Set new item data + * required: true + * content: + * application/json: + * schema: + * properties: + * id: + * description: ID of the updated item + * type: string + * data: + * description: Data of the updated item + * type: object + * $ref: "#/components/schemas/Test" + * required: + * - id + * responses: + * 200: + * description: The item data was successfully updated + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/Test" + * 400: + * description: Invalid ID supplied + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Item not found + * 500: + * description: Some server error + */ +router.put( + '/:id', + wrapAsync(async (req, res) => { + await TestService.update(req.body.data, req.body.id, req.currentUser); + const payload = true; + res.status(200).send(payload); + }), +); + +/** + * @swagger + * /api/test/{id}: + * delete: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Delete the selected item + * description: Delete the selected item + * parameters: + * - in: path + * name: id + * description: Item ID to delete + * required: true + * schema: + * type: string + * responses: + * 200: + * description: The item was successfully deleted + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/Test" + * 400: + * description: Invalid ID supplied + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Item not found + * 500: + * description: Some server error + */ +router.delete( + '/:id', + wrapAsync(async (req, res) => { + await TestService.remove(req.params.id, req.currentUser); + const payload = true; + res.status(200).send(payload); + }), +); + +/** + * @swagger + * /api/test/deleteByIds: + * post: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Delete the selected item list + * description: Delete the selected item list + * requestBody: + * required: true + * content: + * application/json: + * schema: + * properties: + * ids: + * description: IDs of the updated items + * type: array + * responses: + * 200: + * description: The items was successfully deleted + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/Test" + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Items not found + * 500: + * description: Some server error + */ +router.post( + '/deleteByIds', + wrapAsync(async (req, res) => { + await TestService.deleteByIds(req.body.data, req.currentUser); + const payload = true; + res.status(200).send(payload); + }), +); + +/** + * @swagger + * /api/test: + * get: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Get all test + * description: Get all test + * responses: + * 200: + * description: Test list successfully received + * content: + * application/json: + * schema: + * type: array + * items: + * $ref: "#/components/schemas/Test" + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Data not found + * 500: + * description: Some server error + */ +router.get( + '/', + wrapAsync(async (req, res) => { + const filetype = req.query.filetype; + + const currentUser = req.currentUser; + const payload = await TestDBApi.findAll(req.query, { currentUser }); + if (filetype && filetype === 'csv') { + const fields = ['id', 'name']; + const opts = { fields }; + try { + const csv = parse(payload.rows, opts); + res.status(200).attachment(csv); + res.send(csv); + } catch (err) { + console.error(err); + } + } else { + res.status(200).send(payload); + } + }), +); + +/** + * @swagger + * /api/test/count: + * get: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Count all test + * description: Count all test + * responses: + * 200: + * description: Test count successfully received + * content: + * application/json: + * schema: + * type: array + * items: + * $ref: "#/components/schemas/Test" + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Data not found + * 500: + * description: Some server error + */ +router.get( + '/count', + wrapAsync(async (req, res) => { + const currentUser = req.currentUser; + const payload = await TestDBApi.findAll(req.query, null, { + countOnly: true, + currentUser, + }); + + res.status(200).send(payload); + }), +); + +/** + * @swagger + * /api/test/autocomplete: + * get: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Find all test that match search criteria + * description: Find all test that match search criteria + * responses: + * 200: + * description: Test list successfully received + * content: + * application/json: + * schema: + * type: array + * items: + * $ref: "#/components/schemas/Test" + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Data not found + * 500: + * description: Some server error + */ +router.get('/autocomplete', async (req, res) => { + const payload = await TestDBApi.findAllAutocomplete( + req.query.query, + req.query.limit, + req.query.offset, + ); + + res.status(200).send(payload); +}); + +/** + * @swagger + * /api/test/{id}: + * get: + * security: + * - bearerAuth: [] + * tags: [Test] + * summary: Get selected item + * description: Get selected item + * parameters: + * - in: path + * name: id + * description: ID of item to get + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Selected item successfully received + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/Test" + * 400: + * description: Invalid ID supplied + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Item not found + * 500: + * description: Some server error + */ +router.get( + '/:id', + wrapAsync(async (req, res) => { + const payload = await TestDBApi.findBy({ id: req.params.id }); + + res.status(200).send(payload); + }), +); + +router.use('/', require('../helpers').commonErrorHandler); + +module.exports = router; diff --git a/backend/src/services/search.js b/backend/src/services/search.js index 0eaccb3..54243ae 100644 --- a/backend/src/services/search.js +++ b/backend/src/services/search.js @@ -9,7 +9,6 @@ const Op = Sequelize.Op; * @param {object} currentUser */ async function checkPermissions(permission, currentUser) { - if (!currentUser) { throw new ValidationError('auth.unauthorized'); } @@ -36,420 +35,126 @@ async function checkPermissions(permission, currentUser) { } module.exports = class SearchService { - static async search(searchQuery, currentUser ) { + static async search(searchQuery, currentUser) { try { if (!searchQuery) { throw new ValidationError('iam.errors.searchQueryRequired'); } const tableColumns = { - - - + users: ['firstName', 'lastName', 'phoneNumber', 'email'], - - "users": [ - - "firstName", - - "lastName", - - "phoneNumber", - - "email", - - ], - - - - - - + customers: [ + 'full_name', - - "customers": [ - - "full_name", - - "email", - - "phone", - - "external_customer_ref", - - "notes", - - ], - - - - + 'email', - - "addresses": [ - - "recipient_name", - - "line1", - - "line2", - - "city", - - "region", - - "postal_code", - - "country", - - "phone", - - ], - - - - + 'phone', - - "product_categories": [ - - "name", - - "slug", - - "description", - - ], - - - - + 'external_customer_ref', - - "products": [ - - "name", - - "sku", - - "barcode", - - "description", - - ], - - - - + 'notes', + ], - - "product_variants": [ - - "variant_name", - - "sku", - - "barcode", - - ], - - - - + addresses: [ + 'recipient_name', - - "inventory_locations": [ - - "name", - - "code", - - "description", - - ], - - - - + 'line1', - - - - + 'line2', - - "inventory_movements": [ - - "reason", - - "reference", - - ], - - - - + 'city', - - "orders": [ - - "order_number", - - "currency", - - "customer_note", - - "internal_note", - - ], - - - - + 'region', - - "order_items": [ - - "item_name", - - "item_sku", - - ], - - - - + 'postal_code', - - "shipments": [ - - "carrier", - - "service_level", - - "tracking_number", - - "shipping_label_url", - - ], - - - - + 'country', - - "payments": [ - - "currency", - - "provider", - - "provider_payment_ref", - - ], - - - - + 'phone', + ], - - "refunds": [ - - "currency", - - "reason", - - "provider_refund_ref", - - ], - - - - + product_categories: ['name', 'slug', 'description'], - - "discount_codes": [ - - "code", - - "currency", - - ], - - - - + products: ['name', 'sku', 'barcode', 'description'], - - "order_status_events": [ - - "note", - - ], - - + product_variants: ['variant_name', 'sku', 'barcode'], + + inventory_locations: ['name', 'code', 'description'], + + inventory_movements: ['reason', 'reference'], + + orders: ['order_number', 'currency', 'customer_note', 'internal_note'], + + order_items: ['item_name', 'item_sku'], + + shipments: [ + 'carrier', + + 'service_level', + + 'tracking_number', + + 'shipping_label_url', + ], + + payments: ['currency', 'provider', 'provider_payment_ref'], + + refunds: ['currency', 'reason', 'provider_refund_ref'], + + discount_codes: ['code', 'currency'], + + order_status_events: ['note'], + + test: ['name'], }; const columnsInt = { - - - - - - - - - - - - - - - - - - - - - - - "products": [ - - "base_price", - - "compare_at_price", - - "reorder_point", - - ], - - - - - - "product_variants": [ - - "price", - - "cost", - - "weight_grams", - - ], - - - - - - - - - - "inventory_items": [ - - "on_hand", - - "reserved", - - "safety_stock", - - ], - - - - - - "inventory_movements": [ - - "quantity_delta", - - ], - - - - - - "orders": [ - - "subtotal_amount", - - "discount_amount", - - "shipping_amount", - - "tax_amount", - - "total_amount", - - ], - - - - - - "order_items": [ - - "unit_price", - - "quantity", - - "discount_amount", - - "tax_amount", - - "line_total", - - ], - - - - - - "shipments": [ - - "shipping_cost", - - ], - - - - - - "payments": [ - - "amount", - - ], - - - - - - "refunds": [ - - "amount", - - ], - - - - - - "discount_codes": [ - - "value_amount", - - "max_redemptions", - - "redeemed_count", - - "min_order_amount", - - ], - - - - - - + products: ['base_price', 'compare_at_price', 'reorder_point'], + + product_variants: ['price', 'cost', 'weight_grams'], + + inventory_items: ['on_hand', 'reserved', 'safety_stock'], + + inventory_movements: ['quantity_delta'], + + orders: [ + 'subtotal_amount', + + 'discount_amount', + + 'shipping_amount', + + 'tax_amount', + + 'total_amount', + ], + + order_items: [ + 'unit_price', + + 'quantity', + + 'discount_amount', + + 'tax_amount', + + 'line_total', + ], + + shipments: ['shipping_cost'], + + payments: ['amount'], + + refunds: ['amount'], + + discount_codes: [ + 'value_amount', + + 'max_redemptions', + + 'redeemed_count', + + 'min_order_amount', + ], }; let allFoundRecords = []; @@ -460,48 +165,63 @@ module.exports = class SearchService { const attributesIntToSearch = columnsInt[tableName] || []; const whereCondition = { [Op.or]: [ - ...attributesToSearch.map(attribute => ({ + ...attributesToSearch.map((attribute) => ({ [attribute]: { - [Op.iLike] : `%${searchQuery}%`, + [Op.iLike]: `%${searchQuery}%`, }, })), - ...attributesIntToSearch.map(attribute => ( + ...attributesIntToSearch.map((attribute) => Sequelize.where( - Sequelize.cast(Sequelize.col(`${tableName}.${attribute}`), 'varchar'), - { [Op.iLike]: `%${searchQuery}%` } - ) - )), + Sequelize.cast( + Sequelize.col(`${tableName}.${attribute}`), + 'varchar', + ), + { [Op.iLike]: `%${searchQuery}%` }, + ), + ), ], }; - - - const hasPermission = await checkPermissions(`READ_${tableName.toUpperCase()}`, currentUser); + const hasPermission = await checkPermissions( + `READ_${tableName.toUpperCase()}`, + currentUser, + ); if (!hasPermission) { continue; } const foundRecords = await db[tableName].findAll({ where: whereCondition, - attributes: [...tableColumns[tableName], 'id', ...attributesIntToSearch], + attributes: [ + ...tableColumns[tableName], + 'id', + ...attributesIntToSearch, + ], }); - + const modifiedRecords = foundRecords.map((record) => { const matchAttribute = []; - + for (const attribute of attributesToSearch) { - if (record[attribute]?.toLowerCase()?.includes(searchQuery.toLowerCase())) { + if ( + record[attribute] + ?.toLowerCase() + ?.includes(searchQuery.toLowerCase()) + ) { matchAttribute.push(attribute); } } for (const attribute of attributesIntToSearch) { const castedValue = String(record[attribute]); - if (castedValue && castedValue.toLowerCase().includes(searchQuery.toLowerCase())) { + if ( + castedValue && + castedValue.toLowerCase().includes(searchQuery.toLowerCase()) + ) { matchAttribute.push(attribute); } } - + return { ...record.get(), matchAttribute, @@ -518,4 +238,4 @@ module.exports = class SearchService { throw error; } } -} \ No newline at end of file +}; diff --git a/backend/src/services/test.js b/backend/src/services/test.js new file mode 100644 index 0000000..7b0c74b --- /dev/null +++ b/backend/src/services/test.js @@ -0,0 +1,114 @@ +const db = require('../db/models'); +const TestDBApi = require('../db/api/test'); +const processFile = require('../middlewares/upload'); +const ValidationError = require('./notifications/errors/validation'); +const csv = require('csv-parser'); +const axios = require('axios'); +const config = require('../config'); +const stream = require('stream'); + +module.exports = class TestService { + static async create(data, currentUser) { + const transaction = await db.sequelize.transaction(); + try { + await TestDBApi.create(data, { + currentUser, + transaction, + }); + + await transaction.commit(); + } catch (error) { + await transaction.rollback(); + throw error; + } + } + + static async bulkImport(req, res, sendInvitationEmails = true, host) { + 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')); // convert Buffer to Stream + + await new Promise((resolve, reject) => { + bufferStream + .pipe(csv()) + .on('data', (data) => results.push(data)) + .on('end', async () => { + console.log('CSV results', results); + resolve(); + }) + .on('error', (error) => reject(error)); + }); + + await TestDBApi.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 { + let test = await TestDBApi.findBy({ id }, { transaction }); + + if (!test) { + throw new ValidationError('testNotFound'); + } + + const updatedTest = await TestDBApi.update(id, data, { + currentUser, + transaction, + }); + + await transaction.commit(); + return updatedTest; + } catch (error) { + await transaction.rollback(); + throw error; + } + } + + static async deleteByIds(ids, currentUser) { + const transaction = await db.sequelize.transaction(); + + try { + await TestDBApi.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 TestDBApi.remove(id, { + currentUser, + transaction, + }); + + await transaction.commit(); + } catch (error) { + await transaction.rollback(); + throw error; + } + } +}; diff --git a/frontend/src/components/Test/CardTest.tsx b/frontend/src/components/Test/CardTest.tsx new file mode 100644 index 0000000..04f2f38 --- /dev/null +++ b/frontend/src/components/Test/CardTest.tsx @@ -0,0 +1,105 @@ +import React from 'react'; +import ImageField from '../ImageField'; +import ListActionsPopover from '../ListActionsPopover'; +import { useAppSelector } from '../../stores/hooks'; +import dataFormatter from '../../helpers/dataFormatter'; +import { Pagination } from '../Pagination'; +import { saveFile } from '../../helpers/fileSaver'; +import LoadingSpinner from '../LoadingSpinner'; +import Link from 'next/link'; + +import { hasPermission } from '../../helpers/userPermissions'; + +type Props = { + test: any[]; + loading: boolean; + onDelete: (id: string) => void; + currentPage: number; + numPages: number; + onPageChange: (page: number) => void; +}; + +const CardTest = ({ + test, + loading, + onDelete, + currentPage, + numPages, + onPageChange, +}: Props) => { + const asideScrollbarsStyle = useAppSelector( + (state) => state.style.asideScrollbarsStyle, + ); + const bgColor = useAppSelector((state) => state.style.cardsColor); + const darkMode = useAppSelector((state) => state.style.darkMode); + const corners = useAppSelector((state) => state.style.corners); + const focusRing = useAppSelector((state) => state.style.focusRingColor); + + const currentUser = useAppSelector((state) => state.auth.currentUser); + const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_TEST'); + + return ( +
+ {loading && } +
    + {!loading && + test.map((item, index) => ( +
  • +
    + + {item.id} + + +
    + +
    +
    +
    +
    +
    Name
    +
    +
    {item.name}
    +
    +
    +
    +
  • + ))} + {!loading && test.length === 0 && ( +
    +

    No data to display

    +
    + )} +
+
+ +
+
+ ); +}; + +export default CardTest; diff --git a/frontend/src/components/Test/ListTest.tsx b/frontend/src/components/Test/ListTest.tsx new file mode 100644 index 0000000..51e23d7 --- /dev/null +++ b/frontend/src/components/Test/ListTest.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import CardBox from '../CardBox'; +import ImageField from '../ImageField'; +import dataFormatter from '../../helpers/dataFormatter'; +import { saveFile } from '../../helpers/fileSaver'; +import ListActionsPopover from '../ListActionsPopover'; +import { useAppSelector } from '../../stores/hooks'; +import { Pagination } from '../Pagination'; +import LoadingSpinner from '../LoadingSpinner'; +import Link from 'next/link'; + +import { hasPermission } from '../../helpers/userPermissions'; + +type Props = { + test: any[]; + loading: boolean; + onDelete: (id: string) => void; + currentPage: number; + numPages: number; + onPageChange: (page: number) => void; +}; + +const ListTest = ({ + test, + loading, + onDelete, + currentPage, + numPages, + onPageChange, +}: Props) => { + const currentUser = useAppSelector((state) => state.auth.currentUser); + const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_TEST'); + + const corners = useAppSelector((state) => state.style.corners); + const bgColor = useAppSelector((state) => state.style.cardsColor); + + return ( + <> +
+ {loading && } + {!loading && + test.map((item) => ( +
+ +
+ dark:divide-dark-700 overflow-x-auto' + } + > +
+

Name

+

{item.name}

+
+ + +
+
+
+ ))} + {!loading && test.length === 0 && ( +
+

No data to display

+
+ )} +
+
+ +
+ + ); +}; + +export default ListTest; diff --git a/frontend/src/components/Test/TableTest.tsx b/frontend/src/components/Test/TableTest.tsx new file mode 100644 index 0000000..9f0edec --- /dev/null +++ b/frontend/src/components/Test/TableTest.tsx @@ -0,0 +1,481 @@ +import React, { useEffect, useState, useMemo } from 'react'; +import { createPortal } from 'react-dom'; +import { ToastContainer, toast } from 'react-toastify'; +import BaseButton from '../BaseButton'; +import CardBoxModal from '../CardBoxModal'; +import CardBox from '../CardBox'; +import { + fetch, + update, + deleteItem, + setRefetch, + deleteItemsByIds, +} from '../../stores/test/testSlice'; +import { useAppDispatch, useAppSelector } from '../../stores/hooks'; +import { useRouter } from 'next/router'; +import { Field, Form, Formik } from 'formik'; +import { DataGrid, GridColDef } from '@mui/x-data-grid'; +import { loadColumns } from './configureTestCols'; +import _ from 'lodash'; +import dataFormatter from '../../helpers/dataFormatter'; +import { dataGridStyles } from '../../styles'; + +const perPage = 10; + +const TableSampleTest = ({ + filterItems, + setFilterItems, + filters, + showGrid, +}) => { + const notify = (type, msg) => toast(msg, { type, position: 'bottom-center' }); + + const dispatch = useAppDispatch(); + const router = useRouter(); + + const pagesList = []; + const [id, setId] = useState(null); + const [currentPage, setCurrentPage] = useState(0); + const [filterRequest, setFilterRequest] = React.useState(''); + const [columns, setColumns] = useState([]); + const [selectedRows, setSelectedRows] = useState([]); + const [sortModel, setSortModel] = useState([ + { + field: '', + sort: 'desc', + }, + ]); + + const { + test, + loading, + count, + notify: testNotify, + refetch, + } = useAppSelector((state) => state.test); + const { currentUser } = useAppSelector((state) => state.auth); + const focusRing = useAppSelector((state) => state.style.focusRingColor); + const bgColor = useAppSelector((state) => state.style.bgLayoutColor); + const corners = useAppSelector((state) => state.style.corners); + const numPages = + Math.floor(count / perPage) === 0 ? 1 : Math.ceil(count / perPage); + for (let i = 0; i < numPages; i++) { + pagesList.push(i); + } + + const loadData = async (page = currentPage, request = filterRequest) => { + if (page !== currentPage) setCurrentPage(page); + if (request !== filterRequest) setFilterRequest(request); + const { sort, field } = sortModel[0]; + + const query = `?page=${page}&limit=${perPage}${request}&sort=${sort}&field=${field}`; + dispatch(fetch({ limit: perPage, page, query })); + }; + + useEffect(() => { + if (testNotify.showNotification) { + notify(testNotify.typeNotification, testNotify.textNotification); + } + }, [testNotify.showNotification]); + + useEffect(() => { + if (!currentUser) return; + loadData(); + }, [sortModel, currentUser]); + + useEffect(() => { + if (refetch) { + loadData(0); + dispatch(setRefetch(false)); + } + }, [refetch, dispatch]); + + const [isModalInfoActive, setIsModalInfoActive] = useState(false); + const [isModalTrashActive, setIsModalTrashActive] = useState(false); + + const handleModalAction = () => { + setIsModalInfoActive(false); + setIsModalTrashActive(false); + }; + + const handleDeleteModalAction = (id: string) => { + setId(id); + setIsModalTrashActive(true); + }; + const handleDeleteAction = async () => { + if (id) { + await dispatch(deleteItem(id)); + await loadData(0); + setIsModalTrashActive(false); + } + }; + + const generateFilterRequests = useMemo(() => { + let request = '&'; + filterItems.forEach((item) => { + const isRangeFilter = filters.find( + (filter) => + filter.title === item.fields.selectedField && + (filter.number || filter.date), + ); + + if (isRangeFilter) { + const from = item.fields.filterValueFrom; + const to = item.fields.filterValueTo; + if (from) { + request += `${item.fields.selectedField}Range=${from}&`; + } + if (to) { + request += `${item.fields.selectedField}Range=${to}&`; + } + } else { + const value = item.fields.filterValue; + if (value) { + request += `${item.fields.selectedField}=${value}&`; + } + } + }); + return request; + }, [filterItems, filters]); + + const deleteFilter = (value) => { + const newItems = filterItems.filter((item) => item.id !== value); + + if (newItems.length) { + setFilterItems(newItems); + } else { + loadData(0, ''); + + setFilterItems(newItems); + } + }; + + const handleSubmit = () => { + loadData(0, generateFilterRequests); + }; + + const handleChange = (id) => (e) => { + const value = e.target.value; + const name = e.target.name; + + setFilterItems( + filterItems.map((item) => { + if (item.id !== id) return item; + if (name === 'selectedField') return { id, fields: { [name]: value } }; + + return { id, fields: { ...item.fields, [name]: value } }; + }), + ); + }; + + const handleReset = () => { + setFilterItems([]); + loadData(0, ''); + }; + + const onPageChange = (page: number) => { + loadData(page); + setCurrentPage(page); + }; + + useEffect(() => { + if (!currentUser) return; + + loadColumns(handleDeleteModalAction, `test`, currentUser).then((newCols) => + setColumns(newCols), + ); + }, [currentUser]); + + const handleTableSubmit = async (id: string, data) => { + if (!_.isEmpty(data)) { + await dispatch(update({ id, data })) + .unwrap() + .then((res) => res) + .catch((err) => { + throw new Error(err); + }); + } + }; + + const onDeleteRows = async (selectedRows) => { + await dispatch(deleteItemsByIds(selectedRows)); + await loadData(0); + }; + + const controlClasses = + 'w-full py-2 px-2 my-2 rounded dark:placeholder-gray-400 ' + + ` ${bgColor} ${focusRing} ${corners} ` + + 'dark:bg-slate-800 border'; + + const dataGrid = ( +
+ `datagrid--row`} + rows={test ?? []} + columns={columns} + initialState={{ + pagination: { + paginationModel: { + pageSize: 10, + }, + }, + }} + disableRowSelectionOnClick + onProcessRowUpdateError={(params) => { + console.log('Error', params); + }} + processRowUpdate={async (newRow, oldRow) => { + const data = dataFormatter.dataGridEditFormatter(newRow); + + try { + await handleTableSubmit(newRow.id, data); + return newRow; + } catch { + return oldRow; + } + }} + sortingMode={'server'} + checkboxSelection + onRowSelectionModelChange={(ids) => { + setSelectedRows(ids); + }} + onSortModelChange={(params) => { + params.length + ? setSortModel(params) + : setSortModel([{ field: '', sort: 'desc' }]); + }} + rowCount={count} + pageSizeOptions={[10]} + paginationMode={'server'} + loading={loading} + onPaginationModelChange={(params) => { + onPageChange(params.page); + }} + /> +
+ ); + + return ( + <> + {filterItems && Array.isArray(filterItems) && filterItems.length ? ( + + null} + > +
+ <> + {filterItems && + filterItems.map((filterItem) => { + return ( +
+
+
+ Filter +
+ + {filters.map((selectOption) => ( + + ))} + +
+ {filters.find( + (filter) => + filter.title === filterItem?.fields?.selectedField, + )?.type === 'enum' ? ( +
+
Value
+ + + {filters + .find( + (filter) => + filter.title === + filterItem?.fields?.selectedField, + ) + ?.options?.map((option) => ( + + ))} + +
+ ) : filters.find( + (filter) => + filter.title === + filterItem?.fields?.selectedField, + )?.number ? ( +
+
+
+ From +
+ +
+
+
+ To +
+ +
+
+ ) : filters.find( + (filter) => + filter.title === + filterItem?.fields?.selectedField, + )?.date ? ( +
+
+
+ From +
+ +
+
+
+ To +
+ +
+
+ ) : ( +
+
+ Contains +
+ +
+ )} +
+
+ Action +
+ { + deleteFilter(filterItem.id); + }} + /> +
+
+ ); + })} +
+ + +
+ +
+
+
+ ) : null} + +

Are you sure you want to delete this item?

+
+ + {dataGrid} + + {selectedRows.length > 0 && + createPortal( + onDeleteRows(selectedRows)} + />, + document.getElementById('delete-rows-button'), + )} + + + ); +}; + +export default TableSampleTest; diff --git a/frontend/src/components/Test/configureTestCols.tsx b/frontend/src/components/Test/configureTestCols.tsx new file mode 100644 index 0000000..7e64d77 --- /dev/null +++ b/frontend/src/components/Test/configureTestCols.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import BaseIcon from '../BaseIcon'; +import { mdiEye, mdiTrashCan, mdiPencilOutline } from '@mdi/js'; +import axios from 'axios'; +import { + GridActionsCellItem, + GridRowParams, + GridValueGetterParams, +} from '@mui/x-data-grid'; +import ImageField from '../ImageField'; +import { saveFile } from '../../helpers/fileSaver'; +import dataFormatter from '../../helpers/dataFormatter'; +import DataGridMultiSelect from '../DataGridMultiSelect'; +import ListActionsPopover from '../ListActionsPopover'; + +import { hasPermission } from '../../helpers/userPermissions'; + +type Params = (id: string) => void; + +export const loadColumns = async ( + onDelete: Params, + entityName: string, + + user, +) => { + async function callOptionsApi(entityName: string) { + if (!hasPermission(user, 'READ_' + entityName.toUpperCase())) return []; + + try { + const data = await axios(`/${entityName}/autocomplete?limit=100`); + return data.data; + } catch (error) { + console.log(error); + return []; + } + } + + const hasUpdatePermission = hasPermission(user, 'UPDATE_TEST'); + + return [ + { + field: 'name', + headerName: 'Name', + flex: 1, + minWidth: 120, + filterable: false, + headerClassName: 'datagrid--header', + cellClassName: 'datagrid--cell', + + editable: hasUpdatePermission, + }, + + { + field: 'actions', + type: 'actions', + minWidth: 30, + headerClassName: 'datagrid--header', + cellClassName: 'datagrid--cell', + getActions: (params: GridRowParams) => { + return [ +
+ +
, + ]; + }, + }, + ]; +}; diff --git a/frontend/src/menuAside.ts b/frontend/src/menuAside.ts index 23638dd..251cc91 100644 --- a/frontend/src/menuAside.ts +++ b/frontend/src/menuAside.ts @@ -1,5 +1,5 @@ import * as icon from '@mdi/js'; -import { MenuAsideItem } from './interfaces' +import { MenuAsideItem } from './interfaces'; const menuAside: MenuAsideItem[] = [ { @@ -7,14 +7,14 @@ const menuAside: MenuAsideItem[] = [ icon: icon.mdiViewDashboardOutline, label: 'Dashboard', }, - + { href: '/users/users-list', label: 'Users', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: icon.mdiAccountGroup ?? icon.mdiTable, - permissions: 'READ_USERS' + permissions: 'READ_USERS', }, { href: '/roles/roles-list', @@ -22,7 +22,7 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: icon.mdiShieldAccountVariantOutline ?? icon.mdiTable, - permissions: 'READ_ROLES' + permissions: 'READ_ROLES', }, { href: '/permissions/permissions-list', @@ -30,127 +30,180 @@ const menuAside: MenuAsideItem[] = [ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore icon: icon.mdiShieldAccountOutline ?? icon.mdiTable, - permissions: 'READ_PERMISSIONS' + permissions: 'READ_PERMISSIONS', }, { href: '/customers/customers-list', label: 'Customers', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiAccountGroup' in icon ? icon['mdiAccountGroup' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_CUSTOMERS' + icon: + 'mdiAccountGroup' in icon + ? icon['mdiAccountGroup' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_CUSTOMERS', }, { href: '/addresses/addresses-list', label: 'Addresses', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiMapMarker' in icon ? icon['mdiMapMarker' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_ADDRESSES' + icon: + 'mdiMapMarker' in icon + ? icon['mdiMapMarker' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_ADDRESSES', }, { href: '/product_categories/product_categories-list', label: 'Product categories', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiShape' in icon ? icon['mdiShape' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_PRODUCT_CATEGORIES' + icon: + 'mdiShape' in icon + ? icon['mdiShape' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_PRODUCT_CATEGORIES', }, { href: '/products/products-list', label: 'Products', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiPackageVariantClosed' in icon ? icon['mdiPackageVariantClosed' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_PRODUCTS' + icon: + 'mdiPackageVariantClosed' in icon + ? icon['mdiPackageVariantClosed' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_PRODUCTS', }, { href: '/product_variants/product_variants-list', label: 'Product variants', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiPackageVariant' in icon ? icon['mdiPackageVariant' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_PRODUCT_VARIANTS' + icon: + 'mdiPackageVariant' in icon + ? icon['mdiPackageVariant' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_PRODUCT_VARIANTS', }, { href: '/inventory_locations/inventory_locations-list', label: 'Inventory locations', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiWarehouse' in icon ? icon['mdiWarehouse' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_INVENTORY_LOCATIONS' + icon: + 'mdiWarehouse' in icon + ? icon['mdiWarehouse' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_INVENTORY_LOCATIONS', }, { href: '/inventory_items/inventory_items-list', label: 'Inventory items', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiClipboardList' in icon ? icon['mdiClipboardList' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_INVENTORY_ITEMS' + icon: + 'mdiClipboardList' in icon + ? icon['mdiClipboardList' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_INVENTORY_ITEMS', }, { href: '/inventory_movements/inventory_movements-list', label: 'Inventory movements', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiSwapVertical' in icon ? icon['mdiSwapVertical' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_INVENTORY_MOVEMENTS' + icon: + 'mdiSwapVertical' in icon + ? icon['mdiSwapVertical' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_INVENTORY_MOVEMENTS', }, { href: '/orders/orders-list', label: 'Orders', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiCart' in icon ? icon['mdiCart' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_ORDERS' + icon: + 'mdiCart' in icon + ? icon['mdiCart' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_ORDERS', }, { href: '/order_items/order_items-list', label: 'Order items', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiFormatListBulleted' in icon ? icon['mdiFormatListBulleted' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_ORDER_ITEMS' + icon: + 'mdiFormatListBulleted' in icon + ? icon['mdiFormatListBulleted' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_ORDER_ITEMS', }, { href: '/shipments/shipments-list', label: 'Shipments', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiTruckFast' in icon ? icon['mdiTruckFast' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_SHIPMENTS' + icon: + 'mdiTruckFast' in icon + ? icon['mdiTruckFast' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_SHIPMENTS', }, { href: '/payments/payments-list', label: 'Payments', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiCreditCardOutline' in icon ? icon['mdiCreditCardOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_PAYMENTS' + icon: + 'mdiCreditCardOutline' in icon + ? icon['mdiCreditCardOutline' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_PAYMENTS', }, { href: '/refunds/refunds-list', label: 'Refunds', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiCashRefund' in icon ? icon['mdiCashRefund' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_REFUNDS' + icon: + 'mdiCashRefund' in icon + ? icon['mdiCashRefund' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_REFUNDS', }, { href: '/discount_codes/discount_codes-list', label: 'Discount codes', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiTicketPercent' in icon ? icon['mdiTicketPercent' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_DISCOUNT_CODES' + icon: + 'mdiTicketPercent' in icon + ? icon['mdiTicketPercent' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_DISCOUNT_CODES', }, { href: '/order_status_events/order_status_events-list', label: 'Order status events', // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - icon: 'mdiTimelineTextOutline' in icon ? icon['mdiTimelineTextOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable, - permissions: 'READ_ORDER_STATUS_EVENTS' + icon: + 'mdiTimelineTextOutline' in icon + ? icon['mdiTimelineTextOutline' as keyof typeof icon] + : icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_ORDER_STATUS_EVENTS', + }, + { + href: '/test/test-list', + label: 'Test', + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + icon: icon.mdiTable ?? icon.mdiTable, + permissions: 'READ_TEST', }, { href: '/profile', @@ -158,14 +211,13 @@ const menuAside: MenuAsideItem[] = [ icon: icon.mdiAccountCircle, }, - { href: '/api-docs', target: '_blank', label: 'Swagger API', icon: icon.mdiFileCode, - permissions: 'READ_API_DOCS' + permissions: 'READ_API_DOCS', }, -] +]; -export default menuAside +export default menuAside; diff --git a/frontend/src/pages/dashboard.tsx b/frontend/src/pages/dashboard.tsx index 04ac8c9..db5b778 100644 --- a/frontend/src/pages/dashboard.tsx +++ b/frontend/src/pages/dashboard.tsx @@ -1,671 +1,897 @@ import * as icon from '@mdi/js'; -import Head from 'next/head' -import React from 'react' +import Head from 'next/head'; +import React from 'react'; import axios from 'axios'; -import type { ReactElement } from 'react' -import LayoutAuthenticated from '../layouts/Authenticated' -import SectionMain from '../components/SectionMain' -import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton' -import BaseIcon from "../components/BaseIcon"; -import { getPageTitle } from '../config' -import Link from "next/link"; +import type { ReactElement } from 'react'; +import LayoutAuthenticated from '../layouts/Authenticated'; +import SectionMain from '../components/SectionMain'; +import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton'; +import BaseIcon from '../components/BaseIcon'; +import { getPageTitle } from '../config'; +import Link from 'next/link'; +import { useTranslation } from 'next-i18next'; -import { hasPermission } from "../helpers/userPermissions"; +import { hasPermission } from '../helpers/userPermissions'; import { fetchWidgets } from '../stores/roles/rolesSlice'; import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator'; import { SmartWidget } from '../components/SmartWidget/SmartWidget'; import { useAppDispatch, useAppSelector } from '../stores/hooks'; const Dashboard = () => { - const dispatch = useAppDispatch(); - const iconsColor = useAppSelector((state) => state.style.iconsColor); - const corners = useAppSelector((state) => state.style.corners); - const cardsStyle = useAppSelector((state) => state.style.cardsStyle); + const { t } = useTranslation('common'); + const dispatch = useAppDispatch(); + const iconsColor = useAppSelector((state) => state.style.iconsColor); + const corners = useAppSelector((state) => state.style.corners); + const cardsStyle = useAppSelector((state) => state.style.cardsStyle); - const loadingMessage = 'Loading...'; + const loadingMessage = t('pages.dashboard.loading', { + defaultValue: 'Loading...', + }); - - const [users, setUsers] = React.useState(loadingMessage); - const [roles, setRoles] = React.useState(loadingMessage); - const [permissions, setPermissions] = React.useState(loadingMessage); - const [customers, setCustomers] = React.useState(loadingMessage); - const [addresses, setAddresses] = React.useState(loadingMessage); - const [product_categories, setProduct_categories] = React.useState(loadingMessage); - const [products, setProducts] = React.useState(loadingMessage); - const [product_variants, setProduct_variants] = React.useState(loadingMessage); - const [inventory_locations, setInventory_locations] = React.useState(loadingMessage); - const [inventory_items, setInventory_items] = React.useState(loadingMessage); - const [inventory_movements, setInventory_movements] = React.useState(loadingMessage); - const [orders, setOrders] = React.useState(loadingMessage); - const [order_items, setOrder_items] = React.useState(loadingMessage); - const [shipments, setShipments] = React.useState(loadingMessage); - const [payments, setPayments] = React.useState(loadingMessage); - const [refunds, setRefunds] = React.useState(loadingMessage); - const [discount_codes, setDiscount_codes] = React.useState(loadingMessage); - const [order_status_events, setOrder_status_events] = React.useState(loadingMessage); + const [users, setUsers] = React.useState(loadingMessage); + const [roles, setRoles] = React.useState(loadingMessage); + const [permissions, setPermissions] = React.useState(loadingMessage); + const [customers, setCustomers] = React.useState(loadingMessage); + const [addresses, setAddresses] = React.useState(loadingMessage); + const [product_categories, setProduct_categories] = + React.useState(loadingMessage); + const [products, setProducts] = React.useState(loadingMessage); + const [product_variants, setProduct_variants] = + React.useState(loadingMessage); + const [inventory_locations, setInventory_locations] = + React.useState(loadingMessage); + const [inventory_items, setInventory_items] = React.useState(loadingMessage); + const [inventory_movements, setInventory_movements] = + React.useState(loadingMessage); + const [orders, setOrders] = React.useState(loadingMessage); + const [order_items, setOrder_items] = React.useState(loadingMessage); + const [shipments, setShipments] = React.useState(loadingMessage); + const [payments, setPayments] = React.useState(loadingMessage); + const [refunds, setRefunds] = React.useState(loadingMessage); + const [discount_codes, setDiscount_codes] = React.useState(loadingMessage); + const [order_status_events, setOrder_status_events] = + React.useState(loadingMessage); + const [test, setTest] = React.useState(loadingMessage); - - const [widgetsRole, setWidgetsRole] = React.useState({ - role: { value: '', label: '' }, + const [widgetsRole, setWidgetsRole] = React.useState({ + role: { value: '', label: '' }, + }); + const { currentUser } = useAppSelector((state) => state.auth); + const { isFetchingQuery } = useAppSelector((state) => state.openAi); + + const { rolesWidgets, loading } = useAppSelector((state) => state.roles); + + async function loadData() { + const entities = [ + 'users', + 'roles', + 'permissions', + 'customers', + 'addresses', + 'product_categories', + 'products', + 'product_variants', + 'inventory_locations', + 'inventory_items', + 'inventory_movements', + 'orders', + 'order_items', + 'shipments', + 'payments', + 'refunds', + 'discount_codes', + 'order_status_events', + 'test', + ]; + const fns = [ + setUsers, + setRoles, + setPermissions, + setCustomers, + setAddresses, + setProduct_categories, + setProducts, + setProduct_variants, + setInventory_locations, + setInventory_items, + setInventory_movements, + setOrders, + setOrder_items, + setShipments, + setPayments, + setRefunds, + setDiscount_codes, + setOrder_status_events, + setTest, + ]; + + const requests = entities.map((entity, index) => { + if (hasPermission(currentUser, `READ_${entity.toUpperCase()}`)) { + return axios.get(`/${entity.toLowerCase()}/count`); + } else { + fns[index](null); + return Promise.resolve({ data: { count: null } }); + } }); - const { currentUser } = useAppSelector((state) => state.auth); - const { isFetchingQuery } = useAppSelector((state) => state.openAi); - - const { rolesWidgets, loading } = useAppSelector((state) => state.roles); - - - async function loadData() { - const entities = ['users','roles','permissions','customers','addresses','product_categories','products','product_variants','inventory_locations','inventory_items','inventory_movements','orders','order_items','shipments','payments','refunds','discount_codes','order_status_events',]; - const fns = [setUsers,setRoles,setPermissions,setCustomers,setAddresses,setProduct_categories,setProducts,setProduct_variants,setInventory_locations,setInventory_items,setInventory_movements,setOrders,setOrder_items,setShipments,setPayments,setRefunds,setDiscount_codes,setOrder_status_events,]; - const requests = entities.map((entity, index) => { - - if(hasPermission(currentUser, `READ_${entity.toUpperCase()}`)) { - return axios.get(`/${entity.toLowerCase()}/count`); - } else { - fns[index](null); - return Promise.resolve({data: {count: null}}); - } - - }); + Promise.allSettled(requests).then((results) => { + results.forEach((result, i) => { + if (result.status === 'fulfilled') { + fns[i](result.value.data.count); + } else { + fns[i](result.reason.message); + } + }); + }); + } - Promise.allSettled(requests).then((results) => { - results.forEach((result, i) => { - if (result.status === 'fulfilled') { - fns[i](result.value.data.count); - } else { - fns[i](result.reason.message); - } - }); - }); - } - - async function getWidgets(roleId) { - await dispatch(fetchWidgets(roleId)); - } - React.useEffect(() => { - if (!currentUser) return; - loadData().then(); - setWidgetsRole({ role: { value: currentUser?.app_role?.id, label: currentUser?.app_role?.name } }); - }, [currentUser]); + async function getWidgets(roleId) { + await dispatch(fetchWidgets(roleId)); + } + React.useEffect(() => { + if (!currentUser) return; + loadData().then(); + setWidgetsRole({ + role: { + value: currentUser?.app_role?.id, + label: currentUser?.app_role?.name, + }, + }); + }, [currentUser]); + + React.useEffect(() => { + if (!currentUser || !widgetsRole?.role?.value) return; + getWidgets(widgetsRole?.role?.value || '').then(); + }, [widgetsRole?.role?.value]); - React.useEffect(() => { - if (!currentUser || !widgetsRole?.role?.value) return; - getWidgets(widgetsRole?.role?.value || '').then(); - }, [widgetsRole?.role?.value]); - return ( <> - {getPageTitle('Overview')} + {getPageTitle( + t('pages.dashboard.pageTitle', { defaultValue: 'Overview' }), + )} + icon={icon.mdiChartTimelineVariant} + title={t('pages.dashboard.overview', { defaultValue: 'Overview' })} + main + > {''} - - {hasPermission(currentUser, 'CREATE_ROLES') && } + /> + )} {!!rolesWidgets.length && - hasPermission(currentUser, 'CREATE_ROLES') && ( -

- {`${widgetsRole?.role?.label || 'Users'}'s widgets`} -

- )} + hasPermission(currentUser, 'CREATE_ROLES') && ( +

+ {`${widgetsRole?.role?.label || 'Users'}'s widgets`} +

+ )}
- {(isFetchingQuery || loading) && ( -
- {' '} - Loading widgets... -
- )} + {(isFetchingQuery || loading) && ( +
+ {' '} + {t('pages.dashboard.loadingWidgets', { + defaultValue: 'Loading widgets...', + })} +
+ )} - { rolesWidgets && - rolesWidgets.map((widget) => ( - + {rolesWidgets && + rolesWidgets.map((widget) => ( + ))}
{!!rolesWidgets.length &&
} - -
- - - {hasPermission(currentUser, 'READ_USERS') && -
-
-
-
- Users -
-
- {users} -
-
-
- -
+ +
+ {hasPermission(currentUser, 'READ_USERS') && ( + +
+
+
+
+ Users
-
- } - - {hasPermission(currentUser, 'READ_ROLES') && -
-
-
-
- Roles -
-
- {roles} -
-
-
- -
+
+ {users}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_PERMISSIONS') && -
-
-
-
- Permissions -
-
- {permissions} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_ROLES') && ( + +
+
+
+
+ Roles
-
- } - - {hasPermission(currentUser, 'READ_CUSTOMERS') && -
-
-
-
- Customers -
-
- {customers} -
-
-
- -
+
+ {roles}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_ADDRESSES') && -
-
-
-
- Addresses -
-
- {addresses} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_PERMISSIONS') && ( + +
+
+
+
+ Permissions
-
- } - - {hasPermission(currentUser, 'READ_PRODUCT_CATEGORIES') && -
-
-
-
- Product categories -
-
- {product_categories} -
-
-
- -
+
+ {permissions}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_PRODUCTS') && -
-
-
-
- Products -
-
- {products} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_CUSTOMERS') && ( + +
+
+
+
+ Customers
-
- } - - {hasPermission(currentUser, 'READ_PRODUCT_VARIANTS') && -
-
-
-
- Product variants -
-
- {product_variants} -
-
-
- -
+
+ {customers}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_INVENTORY_LOCATIONS') && -
-
-
-
- Inventory locations -
-
- {inventory_locations} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_ADDRESSES') && ( + +
+
+
+
+ Addresses
-
- } - - {hasPermission(currentUser, 'READ_INVENTORY_ITEMS') && -
-
-
-
- Inventory items -
-
- {inventory_items} -
-
-
- -
+
+ {addresses}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_INVENTORY_MOVEMENTS') && -
-
-
-
- Inventory movements -
-
- {inventory_movements} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_PRODUCT_CATEGORIES') && ( + +
+
+
+
+ Product categories
-
- } - - {hasPermission(currentUser, 'READ_ORDERS') && -
-
-
-
- Orders -
-
- {orders} -
-
-
- -
+
+ {product_categories}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_ORDER_ITEMS') && -
-
-
-
- Order items -
-
- {order_items} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_PRODUCTS') && ( + +
+
+
+
+ Products
-
- } - - {hasPermission(currentUser, 'READ_SHIPMENTS') && -
-
-
-
- Shipments -
-
- {shipments} -
-
-
- -
+
+ {products}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_PAYMENTS') && -
-
-
-
- Payments -
-
- {payments} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_PRODUCT_VARIANTS') && ( + +
+
+
+
+ Product variants
-
- } - - {hasPermission(currentUser, 'READ_REFUNDS') && -
-
-
-
- Refunds -
-
- {refunds} -
-
-
- -
+
+ {product_variants}
+
+
+ +
- } - - {hasPermission(currentUser, 'READ_DISCOUNT_CODES') && -
-
-
-
- Discount codes -
-
- {discount_codes} -
-
-
- -
+
+ + )} + + {hasPermission(currentUser, 'READ_INVENTORY_LOCATIONS') && ( + +
+
+
+
+ Inventory locations
-
- } - - {hasPermission(currentUser, 'READ_ORDER_STATUS_EVENTS') && -
-
-
-
- Order status events -
-
- {order_status_events} -
-
-
- -
+
+ {inventory_locations}
+
+
+ +
- } - - +
+ + )} + + {hasPermission(currentUser, 'READ_INVENTORY_ITEMS') && ( + +
+
+
+
+ Inventory items +
+
+ {inventory_items} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_INVENTORY_MOVEMENTS') && ( + +
+
+
+
+ Inventory movements +
+
+ {inventory_movements} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_ORDERS') && ( + +
+
+
+
+ Orders +
+
+ {orders} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_ORDER_ITEMS') && ( + +
+
+
+
+ Order items +
+
+ {order_items} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_SHIPMENTS') && ( + +
+
+
+
+ Shipments +
+
+ {shipments} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_PAYMENTS') && ( + +
+
+
+
+ Payments +
+
+ {payments} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_REFUNDS') && ( + +
+
+
+
+ Refunds +
+
+ {refunds} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_DISCOUNT_CODES') && ( + +
+
+
+
+ Discount codes +
+
+ {discount_codes} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_ORDER_STATUS_EVENTS') && ( + +
+
+
+
+ Order status events +
+
+ {order_status_events} +
+
+
+ +
+
+
+ + )} + + {hasPermission(currentUser, 'READ_TEST') && ( + +
+
+
+
+ Test +
+
+ {test} +
+
+
+ +
+
+
+ + )}
- ) -} + ); +}; Dashboard.getLayout = function getLayout(page: ReactElement) { - return {page} -} + return {page}; +}; -export default Dashboard +export default Dashboard; diff --git a/frontend/src/pages/test/[testId].tsx b/frontend/src/pages/test/[testId].tsx new file mode 100644 index 0000000..90ce308 --- /dev/null +++ b/frontend/src/pages/test/[testId].tsx @@ -0,0 +1,122 @@ +import { mdiChartTimelineVariant, mdiUpload } from '@mdi/js'; +import Head from 'next/head'; +import React, { ReactElement, useEffect, useState } from 'react'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import dayjs from 'dayjs'; + +import CardBox from '../../components/CardBox'; +import LayoutAuthenticated from '../../layouts/Authenticated'; +import SectionMain from '../../components/SectionMain'; +import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; +import { getPageTitle } from '../../config'; + +import { Field, Form, Formik } from 'formik'; +import FormField from '../../components/FormField'; +import BaseDivider from '../../components/BaseDivider'; +import BaseButtons from '../../components/BaseButtons'; +import BaseButton from '../../components/BaseButton'; +import FormCheckRadio from '../../components/FormCheckRadio'; +import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'; +import FormFilePicker from '../../components/FormFilePicker'; +import FormImagePicker from '../../components/FormImagePicker'; +import { SelectField } from '../../components/SelectField'; +import { SelectFieldMany } from '../../components/SelectFieldMany'; +import { SwitchField } from '../../components/SwitchField'; +import { RichTextField } from '../../components/RichTextField'; + +import { update, fetch } from '../../stores/test/testSlice'; +import { useAppDispatch, useAppSelector } from '../../stores/hooks'; +import { useRouter } from 'next/router'; +import { saveFile } from '../../helpers/fileSaver'; +import dataFormatter from '../../helpers/dataFormatter'; +import ImageField from '../../components/ImageField'; + +const EditTest = () => { + const router = useRouter(); + const dispatch = useAppDispatch(); + const initVals = { + name: '', + }; + const [initialValues, setInitialValues] = useState(initVals); + + const { test } = useAppSelector((state) => state.test); + + const { testId } = router.query; + + useEffect(() => { + dispatch(fetch({ id: testId })); + }, [testId]); + + useEffect(() => { + if (typeof test === 'object') { + setInitialValues(test); + } + }, [test]); + + useEffect(() => { + if (typeof test === 'object') { + const newInitialVal = { ...initVals }; + + Object.keys(initVals).forEach((el) => (newInitialVal[el] = test[el])); + + setInitialValues(newInitialVal); + } + }, [test]); + + const handleSubmit = async (data) => { + await dispatch(update({ id: testId, data })); + await router.push('/test/test-list'); + }; + + return ( + <> + + {getPageTitle('Edit test')} + + + + {''} + + + handleSubmit(values)} + > +
+ + + + + + + + + router.push('/test/test-list')} + /> + + +
+
+
+ + ); +}; + +EditTest.getLayout = function getLayout(page: ReactElement) { + return ( + {page} + ); +}; + +export default EditTest; diff --git a/frontend/src/pages/test/test-edit.tsx b/frontend/src/pages/test/test-edit.tsx new file mode 100644 index 0000000..c01f8b8 --- /dev/null +++ b/frontend/src/pages/test/test-edit.tsx @@ -0,0 +1,120 @@ +import { mdiChartTimelineVariant, mdiUpload } from '@mdi/js'; +import Head from 'next/head'; +import React, { ReactElement, useEffect, useState } from 'react'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import dayjs from 'dayjs'; + +import CardBox from '../../components/CardBox'; +import LayoutAuthenticated from '../../layouts/Authenticated'; +import SectionMain from '../../components/SectionMain'; +import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; +import { getPageTitle } from '../../config'; + +import { Field, Form, Formik } from 'formik'; +import FormField from '../../components/FormField'; +import BaseDivider from '../../components/BaseDivider'; +import BaseButtons from '../../components/BaseButtons'; +import BaseButton from '../../components/BaseButton'; +import FormCheckRadio from '../../components/FormCheckRadio'; +import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'; +import FormFilePicker from '../../components/FormFilePicker'; +import FormImagePicker from '../../components/FormImagePicker'; +import { SelectField } from '../../components/SelectField'; +import { SelectFieldMany } from '../../components/SelectFieldMany'; +import { SwitchField } from '../../components/SwitchField'; +import { RichTextField } from '../../components/RichTextField'; + +import { update, fetch } from '../../stores/test/testSlice'; +import { useAppDispatch, useAppSelector } from '../../stores/hooks'; +import { useRouter } from 'next/router'; +import { saveFile } from '../../helpers/fileSaver'; +import dataFormatter from '../../helpers/dataFormatter'; +import ImageField from '../../components/ImageField'; + +const EditTestPage = () => { + const router = useRouter(); + const dispatch = useAppDispatch(); + const initVals = { + name: '', + }; + const [initialValues, setInitialValues] = useState(initVals); + + const { test } = useAppSelector((state) => state.test); + + const { id } = router.query; + + useEffect(() => { + dispatch(fetch({ id: id })); + }, [id]); + + useEffect(() => { + if (typeof test === 'object') { + setInitialValues(test); + } + }, [test]); + + useEffect(() => { + if (typeof test === 'object') { + const newInitialVal = { ...initVals }; + Object.keys(initVals).forEach((el) => (newInitialVal[el] = test[el])); + setInitialValues(newInitialVal); + } + }, [test]); + + const handleSubmit = async (data) => { + await dispatch(update({ id: id, data })); + await router.push('/test/test-list'); + }; + + return ( + <> + + {getPageTitle('Edit test')} + + + + {''} + + + handleSubmit(values)} + > +
+ + + + + + + + + router.push('/test/test-list')} + /> + + +
+
+
+ + ); +}; + +EditTestPage.getLayout = function getLayout(page: ReactElement) { + return ( + {page} + ); +}; + +export default EditTestPage; diff --git a/frontend/src/pages/test/test-list.tsx b/frontend/src/pages/test/test-list.tsx new file mode 100644 index 0000000..b421b53 --- /dev/null +++ b/frontend/src/pages/test/test-list.tsx @@ -0,0 +1,160 @@ +import { mdiChartTimelineVariant } from '@mdi/js'; +import Head from 'next/head'; +import { uniqueId } from 'lodash'; +import React, { ReactElement, useState } from 'react'; +import CardBox from '../../components/CardBox'; +import LayoutAuthenticated from '../../layouts/Authenticated'; +import SectionMain from '../../components/SectionMain'; +import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; +import { getPageTitle } from '../../config'; +import TableTest from '../../components/Test/TableTest'; +import BaseButton from '../../components/BaseButton'; +import axios from 'axios'; +import Link from 'next/link'; +import { useAppDispatch, useAppSelector } from '../../stores/hooks'; +import CardBoxModal from '../../components/CardBoxModal'; +import DragDropFilePicker from '../../components/DragDropFilePicker'; +import { setRefetch, uploadCsv } from '../../stores/test/testSlice'; + +import { hasPermission } from '../../helpers/userPermissions'; + +const TestTablesPage = () => { + const [filterItems, setFilterItems] = useState([]); + const [csvFile, setCsvFile] = useState(null); + const [isModalActive, setIsModalActive] = useState(false); + const [showTableView, setShowTableView] = useState(false); + + const { currentUser } = useAppSelector((state) => state.auth); + + const dispatch = useAppDispatch(); + + const [filters] = useState([{ label: 'Name', title: 'name' }]); + + const hasCreatePermission = + currentUser && hasPermission(currentUser, 'CREATE_TEST'); + + const addFilter = () => { + const newItem = { + id: uniqueId(), + fields: { + filterValue: '', + filterValueFrom: '', + filterValueTo: '', + selectedField: '', + }, + }; + newItem.fields.selectedField = filters[0].title; + setFilterItems([...filterItems, newItem]); + }; + + const getTestCSV = async () => { + const response = await axios({ + url: '/test?filetype=csv', + method: 'GET', + responseType: 'blob', + }); + const type = response.headers['content-type']; + const blob = new Blob([response.data], { type: type }); + const link = document.createElement('a'); + link.href = window.URL.createObjectURL(blob); + link.download = 'testCSV.csv'; + link.click(); + }; + + const onModalConfirm = async () => { + if (!csvFile) return; + await dispatch(uploadCsv(csvFile)); + dispatch(setRefetch(true)); + setCsvFile(null); + setIsModalActive(false); + }; + + const onModalCancel = () => { + setCsvFile(null); + setIsModalActive(false); + }; + + return ( + <> + + {getPageTitle('Test')} + + + + {''} + + + {hasCreatePermission && ( + + )} + + + + + {hasCreatePermission && ( + setIsModalActive(true)} + /> + )} + +
+
+
+
+ + + + +
+ + + + + ); +}; + +TestTablesPage.getLayout = function getLayout(page: ReactElement) { + return ( + {page} + ); +}; + +export default TestTablesPage; diff --git a/frontend/src/pages/test/test-new.tsx b/frontend/src/pages/test/test-new.tsx new file mode 100644 index 0000000..077eb84 --- /dev/null +++ b/frontend/src/pages/test/test-new.tsx @@ -0,0 +1,96 @@ +import { + mdiAccount, + mdiChartTimelineVariant, + mdiMail, + mdiUpload, +} from '@mdi/js'; +import Head from 'next/head'; +import React, { ReactElement } from 'react'; +import CardBox from '../../components/CardBox'; +import LayoutAuthenticated from '../../layouts/Authenticated'; +import SectionMain from '../../components/SectionMain'; +import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; +import { getPageTitle } from '../../config'; + +import { Field, Form, Formik } from 'formik'; +import FormField from '../../components/FormField'; +import BaseDivider from '../../components/BaseDivider'; +import BaseButtons from '../../components/BaseButtons'; +import BaseButton from '../../components/BaseButton'; +import FormCheckRadio from '../../components/FormCheckRadio'; +import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'; +import FormFilePicker from '../../components/FormFilePicker'; +import FormImagePicker from '../../components/FormImagePicker'; +import { SwitchField } from '../../components/SwitchField'; + +import { SelectField } from '../../components/SelectField'; +import { SelectFieldMany } from '../../components/SelectFieldMany'; +import { RichTextField } from '../../components/RichTextField'; + +import { create } from '../../stores/test/testSlice'; +import { useAppDispatch } from '../../stores/hooks'; +import { useRouter } from 'next/router'; +import moment from 'moment'; + +const initialValues = { + name: '', +}; + +const TestNew = () => { + const router = useRouter(); + const dispatch = useAppDispatch(); + + const handleSubmit = async (data) => { + await dispatch(create(data)); + await router.push('/test/test-list'); + }; + return ( + <> + + {getPageTitle('New Item')} + + + + {''} + + + handleSubmit(values)} + > +
+ + + + + + + + + router.push('/test/test-list')} + /> + + +
+
+
+ + ); +}; + +TestNew.getLayout = function getLayout(page: ReactElement) { + return ( + {page} + ); +}; + +export default TestNew; diff --git a/frontend/src/pages/test/test-table.tsx b/frontend/src/pages/test/test-table.tsx new file mode 100644 index 0000000..4773a3c --- /dev/null +++ b/frontend/src/pages/test/test-table.tsx @@ -0,0 +1,159 @@ +import { mdiChartTimelineVariant } from '@mdi/js'; +import Head from 'next/head'; +import { uniqueId } from 'lodash'; +import React, { ReactElement, useState } from 'react'; +import CardBox from '../../components/CardBox'; +import LayoutAuthenticated from '../../layouts/Authenticated'; +import SectionMain from '../../components/SectionMain'; +import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; +import { getPageTitle } from '../../config'; +import TableTest from '../../components/Test/TableTest'; +import BaseButton from '../../components/BaseButton'; +import axios from 'axios'; +import Link from 'next/link'; +import { useAppDispatch, useAppSelector } from '../../stores/hooks'; +import CardBoxModal from '../../components/CardBoxModal'; +import DragDropFilePicker from '../../components/DragDropFilePicker'; +import { setRefetch, uploadCsv } from '../../stores/test/testSlice'; + +import { hasPermission } from '../../helpers/userPermissions'; + +const TestTablesPage = () => { + const [filterItems, setFilterItems] = useState([]); + const [csvFile, setCsvFile] = useState(null); + const [isModalActive, setIsModalActive] = useState(false); + const [showTableView, setShowTableView] = useState(false); + + const { currentUser } = useAppSelector((state) => state.auth); + + const dispatch = useAppDispatch(); + + const [filters] = useState([{ label: 'Name', title: 'name' }]); + + const hasCreatePermission = + currentUser && hasPermission(currentUser, 'CREATE_TEST'); + + const addFilter = () => { + const newItem = { + id: uniqueId(), + fields: { + filterValue: '', + filterValueFrom: '', + filterValueTo: '', + selectedField: '', + }, + }; + newItem.fields.selectedField = filters[0].title; + setFilterItems([...filterItems, newItem]); + }; + + const getTestCSV = async () => { + const response = await axios({ + url: '/test?filetype=csv', + method: 'GET', + responseType: 'blob', + }); + const type = response.headers['content-type']; + const blob = new Blob([response.data], { type: type }); + const link = document.createElement('a'); + link.href = window.URL.createObjectURL(blob); + link.download = 'testCSV.csv'; + link.click(); + }; + + const onModalConfirm = async () => { + if (!csvFile) return; + await dispatch(uploadCsv(csvFile)); + dispatch(setRefetch(true)); + setCsvFile(null); + setIsModalActive(false); + }; + + const onModalCancel = () => { + setCsvFile(null); + setIsModalActive(false); + }; + + return ( + <> + + {getPageTitle('Test')} + + + + {''} + + + {hasCreatePermission && ( + + )} + + + + + {hasCreatePermission && ( + setIsModalActive(true)} + /> + )} + +
+
+
+
+ + + +
+ + + + + ); +}; + +TestTablesPage.getLayout = function getLayout(page: ReactElement) { + return ( + {page} + ); +}; + +export default TestTablesPage; diff --git a/frontend/src/pages/test/test-view.tsx b/frontend/src/pages/test/test-view.tsx new file mode 100644 index 0000000..235f6db --- /dev/null +++ b/frontend/src/pages/test/test-view.tsx @@ -0,0 +1,81 @@ +import React, { ReactElement, useEffect } from 'react'; +import Head from 'next/head'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import dayjs from 'dayjs'; +import { useAppDispatch, useAppSelector } from '../../stores/hooks'; +import { useRouter } from 'next/router'; +import { fetch } from '../../stores/test/testSlice'; +import { saveFile } from '../../helpers/fileSaver'; +import dataFormatter from '../../helpers/dataFormatter'; +import ImageField from '../../components/ImageField'; +import LayoutAuthenticated from '../../layouts/Authenticated'; +import { getPageTitle } from '../../config'; +import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; +import SectionMain from '../../components/SectionMain'; +import CardBox from '../../components/CardBox'; +import BaseButton from '../../components/BaseButton'; +import BaseDivider from '../../components/BaseDivider'; +import { mdiChartTimelineVariant } from '@mdi/js'; +import { SwitchField } from '../../components/SwitchField'; +import FormField from '../../components/FormField'; + +const TestView = () => { + const router = useRouter(); + const dispatch = useAppDispatch(); + const { test } = useAppSelector((state) => state.test); + + const { id } = router.query; + + function removeLastCharacter(str) { + console.log(str, `str`); + return str.slice(0, -1); + } + + useEffect(() => { + dispatch(fetch({ id })); + }, [dispatch, id]); + + return ( + <> + + {getPageTitle('View test')} + + + + + + +
+

Name

+

{test?.name}

+
+ + + + router.push('/test/test-list')} + /> +
+
+ + ); +}; + +TestView.getLayout = function getLayout(page: ReactElement) { + return ( + {page} + ); +}; + +export default TestView; diff --git a/frontend/src/stores/store.ts b/frontend/src/stores/store.ts index 2642934..36e2ee1 100644 --- a/frontend/src/stores/store.ts +++ b/frontend/src/stores/store.ts @@ -4,24 +4,25 @@ import mainReducer from './mainSlice'; import authSlice from './authSlice'; import openAiSlice from './openAiSlice'; -import usersSlice from "./users/usersSlice"; -import rolesSlice from "./roles/rolesSlice"; -import permissionsSlice from "./permissions/permissionsSlice"; -import customersSlice from "./customers/customersSlice"; -import addressesSlice from "./addresses/addressesSlice"; -import product_categoriesSlice from "./product_categories/product_categoriesSlice"; -import productsSlice from "./products/productsSlice"; -import product_variantsSlice from "./product_variants/product_variantsSlice"; -import inventory_locationsSlice from "./inventory_locations/inventory_locationsSlice"; -import inventory_itemsSlice from "./inventory_items/inventory_itemsSlice"; -import inventory_movementsSlice from "./inventory_movements/inventory_movementsSlice"; -import ordersSlice from "./orders/ordersSlice"; -import order_itemsSlice from "./order_items/order_itemsSlice"; -import shipmentsSlice from "./shipments/shipmentsSlice"; -import paymentsSlice from "./payments/paymentsSlice"; -import refundsSlice from "./refunds/refundsSlice"; -import discount_codesSlice from "./discount_codes/discount_codesSlice"; -import order_status_eventsSlice from "./order_status_events/order_status_eventsSlice"; +import usersSlice from './users/usersSlice'; +import rolesSlice from './roles/rolesSlice'; +import permissionsSlice from './permissions/permissionsSlice'; +import customersSlice from './customers/customersSlice'; +import addressesSlice from './addresses/addressesSlice'; +import product_categoriesSlice from './product_categories/product_categoriesSlice'; +import productsSlice from './products/productsSlice'; +import product_variantsSlice from './product_variants/product_variantsSlice'; +import inventory_locationsSlice from './inventory_locations/inventory_locationsSlice'; +import inventory_itemsSlice from './inventory_items/inventory_itemsSlice'; +import inventory_movementsSlice from './inventory_movements/inventory_movementsSlice'; +import ordersSlice from './orders/ordersSlice'; +import order_itemsSlice from './order_items/order_itemsSlice'; +import shipmentsSlice from './shipments/shipmentsSlice'; +import paymentsSlice from './payments/paymentsSlice'; +import refundsSlice from './refunds/refundsSlice'; +import discount_codesSlice from './discount_codes/discount_codesSlice'; +import order_status_eventsSlice from './order_status_events/order_status_eventsSlice'; +import testSlice from './test/testSlice'; export const store = configureStore({ reducer: { @@ -30,28 +31,29 @@ export const store = configureStore({ auth: authSlice, openAi: openAiSlice, -users: usersSlice, -roles: rolesSlice, -permissions: permissionsSlice, -customers: customersSlice, -addresses: addressesSlice, -product_categories: product_categoriesSlice, -products: productsSlice, -product_variants: product_variantsSlice, -inventory_locations: inventory_locationsSlice, -inventory_items: inventory_itemsSlice, -inventory_movements: inventory_movementsSlice, -orders: ordersSlice, -order_items: order_itemsSlice, -shipments: shipmentsSlice, -payments: paymentsSlice, -refunds: refundsSlice, -discount_codes: discount_codesSlice, -order_status_events: order_status_eventsSlice, + users: usersSlice, + roles: rolesSlice, + permissions: permissionsSlice, + customers: customersSlice, + addresses: addressesSlice, + product_categories: product_categoriesSlice, + products: productsSlice, + product_variants: product_variantsSlice, + inventory_locations: inventory_locationsSlice, + inventory_items: inventory_itemsSlice, + inventory_movements: inventory_movementsSlice, + orders: ordersSlice, + order_items: order_itemsSlice, + shipments: shipmentsSlice, + payments: paymentsSlice, + refunds: refundsSlice, + discount_codes: discount_codesSlice, + order_status_events: order_status_eventsSlice, + test: testSlice, }, -}) +}); // Infer the `RootState` and `AppDispatch` types from the store itself -export type RootState = ReturnType +export type RootState = ReturnType; // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} -export type AppDispatch = typeof store.dispatch +export type AppDispatch = typeof store.dispatch; diff --git a/frontend/src/stores/test/testSlice.ts b/frontend/src/stores/test/testSlice.ts new file mode 100644 index 0000000..409b828 --- /dev/null +++ b/frontend/src/stores/test/testSlice.ts @@ -0,0 +1,236 @@ +import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'; +import axios from 'axios'; +import { + fulfilledNotify, + rejectNotify, + resetNotify, +} from '../../helpers/notifyStateHandler'; + +interface MainState { + test: any; + loading: boolean; + count: number; + refetch: boolean; + rolesWidgets: any[]; + notify: { + showNotification: boolean; + textNotification: string; + typeNotification: string; + }; +} + +const initialState: MainState = { + test: [], + loading: false, + count: 0, + refetch: false, + rolesWidgets: [], + notify: { + showNotification: false, + textNotification: '', + typeNotification: 'warn', + }, +}; + +export const fetch = createAsyncThunk('test/fetch', async (data: any) => { + const { id, query } = data; + const result = await axios.get(`test${query || (id ? `/${id}` : '')}`); + return id + ? result.data + : { rows: result.data.rows, count: result.data.count }; +}); + +export const deleteItemsByIds = createAsyncThunk( + 'test/deleteByIds', + async (data: any, { rejectWithValue }) => { + try { + await axios.post('test/deleteByIds', { data }); + } catch (error) { + if (!error.response) { + throw error; + } + + return rejectWithValue(error.response.data); + } + }, +); + +export const deleteItem = createAsyncThunk( + 'test/deleteTest', + async (id: string, { rejectWithValue }) => { + try { + await axios.delete(`test/${id}`); + } catch (error) { + if (!error.response) { + throw error; + } + + return rejectWithValue(error.response.data); + } + }, +); + +export const create = createAsyncThunk( + 'test/createTest', + async (data: any, { rejectWithValue }) => { + try { + const result = await axios.post('test', { data }); + return result.data; + } catch (error) { + if (!error.response) { + throw error; + } + + return rejectWithValue(error.response.data); + } + }, +); + +export const uploadCsv = createAsyncThunk( + 'test/uploadCsv', + async (file: File, { rejectWithValue }) => { + try { + const data = new FormData(); + data.append('file', file); + data.append('filename', file.name); + + const result = await axios.post('test/bulk-import', data, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }); + + return result.data; + } catch (error) { + if (!error.response) { + throw error; + } + + return rejectWithValue(error.response.data); + } + }, +); + +export const update = createAsyncThunk( + 'test/updateTest', + async (payload: any, { rejectWithValue }) => { + try { + const result = await axios.put(`test/${payload.id}`, { + id: payload.id, + data: payload.data, + }); + return result.data; + } catch (error) { + if (!error.response) { + throw error; + } + + return rejectWithValue(error.response.data); + } + }, +); + +export const testSlice = createSlice({ + name: 'test', + initialState, + reducers: { + setRefetch: (state, action: PayloadAction) => { + state.refetch = action.payload; + }, + }, + extraReducers: (builder) => { + builder.addCase(fetch.pending, (state) => { + state.loading = true; + resetNotify(state); + }); + builder.addCase(fetch.rejected, (state, action) => { + state.loading = false; + rejectNotify(state, action); + }); + + builder.addCase(fetch.fulfilled, (state, action) => { + if (action.payload.rows && action.payload.count >= 0) { + state.test = action.payload.rows; + state.count = action.payload.count; + } else { + state.test = action.payload; + } + state.loading = false; + }); + + builder.addCase(deleteItemsByIds.pending, (state) => { + state.loading = true; + resetNotify(state); + }); + + builder.addCase(deleteItemsByIds.fulfilled, (state) => { + state.loading = false; + fulfilledNotify(state, 'Test has been deleted'); + }); + + builder.addCase(deleteItemsByIds.rejected, (state, action) => { + state.loading = false; + rejectNotify(state, action); + }); + + builder.addCase(deleteItem.pending, (state) => { + state.loading = true; + resetNotify(state); + }); + + builder.addCase(deleteItem.fulfilled, (state) => { + state.loading = false; + fulfilledNotify(state, `${'Test'.slice(0, -1)} has been deleted`); + }); + + builder.addCase(deleteItem.rejected, (state, action) => { + state.loading = false; + rejectNotify(state, action); + }); + + builder.addCase(create.pending, (state) => { + state.loading = true; + resetNotify(state); + }); + builder.addCase(create.rejected, (state, action) => { + state.loading = false; + rejectNotify(state, action); + }); + + builder.addCase(create.fulfilled, (state) => { + state.loading = false; + fulfilledNotify(state, `${'Test'.slice(0, -1)} has been created`); + }); + + builder.addCase(update.pending, (state) => { + state.loading = true; + resetNotify(state); + }); + builder.addCase(update.fulfilled, (state) => { + state.loading = false; + fulfilledNotify(state, `${'Test'.slice(0, -1)} has been updated`); + }); + builder.addCase(update.rejected, (state, action) => { + state.loading = false; + rejectNotify(state, action); + }); + + builder.addCase(uploadCsv.pending, (state) => { + state.loading = true; + resetNotify(state); + }); + builder.addCase(uploadCsv.fulfilled, (state) => { + state.loading = false; + fulfilledNotify(state, 'Test has been uploaded'); + }); + builder.addCase(uploadCsv.rejected, (state, action) => { + state.loading = false; + rejectNotify(state, action); + }); + }, +}); + +// Action creators are generated for each case reducer function +export const { setRefetch } = testSlice.actions; + +export default testSlice.reducer;