mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
refactor(nestjs): Implement users module
This commit is contained in:
@@ -11,13 +11,9 @@ import {
|
||||
Put,
|
||||
Get,
|
||||
Body,
|
||||
Req,
|
||||
Res,
|
||||
Next,
|
||||
HttpCode,
|
||||
Param,
|
||||
} from '@nestjs/common';
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { BuildOrganizationService } from './commands/BuildOrganization.service';
|
||||
import {
|
||||
BuildOrganizationDto,
|
||||
@@ -28,6 +24,7 @@ import { UpdateOrganizationService } from './commands/UpdateOrganization.service
|
||||
import { IgnoreTenantInitializedRoute } from '../Tenancy/EnsureTenantIsInitialized.guard';
|
||||
import { IgnoreTenantSeededRoute } from '../Tenancy/EnsureTenantIsSeeded.guards';
|
||||
import { GetBuildOrganizationBuildJob } from './commands/GetBuildOrganizationJob.service';
|
||||
import { OrganizationBaseCurrencyLocking } from './Organization/OrganizationBaseCurrencyLocking.service';
|
||||
|
||||
@ApiTags('Organization')
|
||||
@Controller('organization')
|
||||
@@ -39,6 +36,7 @@ export class OrganizationController {
|
||||
private readonly getCurrentOrgService: GetCurrentOrganizationService,
|
||||
private readonly updateOrganizationService: UpdateOrganizationService,
|
||||
private readonly getBuildOrganizationJobService: GetBuildOrganizationBuildJob,
|
||||
private readonly orgBaseCurrencyLockingService: OrganizationBaseCurrencyLocking,
|
||||
) {}
|
||||
|
||||
@Post('build')
|
||||
@@ -81,6 +79,14 @@ export class OrganizationController {
|
||||
return { organization };
|
||||
}
|
||||
|
||||
@Get('base-currency-mutate')
|
||||
async baseCurrencyMutate() {
|
||||
const abilities =
|
||||
await this.orgBaseCurrencyLockingService.baseCurrencyMutateLocks();
|
||||
|
||||
return { abilities };
|
||||
}
|
||||
|
||||
@Put()
|
||||
@HttpCode(200)
|
||||
@ApiOperation({ summary: 'Update organization information' })
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { getPreventMutateBaseCurrencyModels } from '@/common/decorators/LockMutateBaseCurrency.decorator';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
|
||||
interface MutateBaseCurrencyLockMeta {
|
||||
modelName: string;
|
||||
@@ -9,26 +10,27 @@ interface MutateBaseCurrencyLockMeta {
|
||||
|
||||
@Injectable()
|
||||
export class OrganizationBaseCurrencyLocking {
|
||||
constructor(private readonly moduleRef: ModuleRef) {}
|
||||
|
||||
/**
|
||||
* Retrieves the tenant models that have prevented mutation base currency.
|
||||
*/
|
||||
private getModelsPreventsMutate = (tenantId: number) => {
|
||||
const Models = this.tenancy.models(tenantId);
|
||||
private getModelsPreventsMutate() {
|
||||
const lockedModels = getPreventMutateBaseCurrencyModels();
|
||||
|
||||
const filteredEntries = Object.entries(Models).filter(
|
||||
const filteredEntries = Array.from(lockedModels).filter(
|
||||
([key, Model]) => !!Model.preventMutateBaseCurrency,
|
||||
);
|
||||
return Object.fromEntries(filteredEntries);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Detarmines the mutation base currency model is locked.
|
||||
* @param {Model} Model
|
||||
* @returns {Promise<MutateBaseCurrencyLockMeta | false>}
|
||||
*/
|
||||
private isModelMutateLocked = async (
|
||||
private async isModelMutateLocked(
|
||||
Model,
|
||||
): Promise<MutateBaseCurrencyLockMeta | false> => {
|
||||
): Promise<MutateBaseCurrencyLockMeta | false> {
|
||||
const validateQuery = Model.query();
|
||||
|
||||
if (typeof Model?.modifiers?.preventMutateBaseCurrency !== 'undefined') {
|
||||
@@ -45,21 +47,24 @@ export class OrganizationBaseCurrencyLocking {
|
||||
pluralName: Model.pluralName,
|
||||
}
|
||||
: false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the base currency mutation locks of the tenant models.
|
||||
* @param {number} tenantId
|
||||
* @returns {Promise<MutateBaseCurrencyLockMeta[]>}
|
||||
*/
|
||||
public async baseCurrencyMutateLocks(
|
||||
tenantId: number,
|
||||
): Promise<MutateBaseCurrencyLockMeta[]> {
|
||||
const PreventedModels = this.getModelsPreventsMutate(tenantId);
|
||||
public async baseCurrencyMutateLocks(): Promise<
|
||||
MutateBaseCurrencyLockMeta[]
|
||||
> {
|
||||
const PreventedModels = this.getModelsPreventsMutate();
|
||||
const opers = Object.entries(PreventedModels).map(([ModelName, Model]) => {
|
||||
const InjectedModelProxy = this.moduleRef.get(ModelName, {
|
||||
strict: false,
|
||||
});
|
||||
const InjectedModel = InjectedModelProxy();
|
||||
|
||||
const opers = Object.entries(PreventedModels).map(([ModelName, Model]) =>
|
||||
this.isModelMutateLocked(Model),
|
||||
);
|
||||
return this.isModelMutateLocked(InjectedModel);
|
||||
});
|
||||
const results = await Promise.all(opers);
|
||||
|
||||
return results.filter(
|
||||
@@ -69,12 +74,11 @@ export class OrganizationBaseCurrencyLocking {
|
||||
|
||||
/**
|
||||
* Detarmines the base currency mutation locked.
|
||||
* @param {number} tenantId
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
public isBaseCurrencyMutateLocked = async (tenantId: number) => {
|
||||
const locks = await this.baseCurrencyMutateLocks(tenantId);
|
||||
public async isBaseCurrencyMutateLocked() {
|
||||
const locks = await this.baseCurrencyMutateLocks();
|
||||
|
||||
return !isEmpty(locks);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { SeedMigration } from '@/lib/Seeder/SeedMigration';
|
||||
import { Tenant } from '@/system/models';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import TenantDBManager from '@/services/Tenancy/TenantDBManager';
|
||||
import config from '../../config';
|
||||
import { ERRORS } from './constants';
|
||||
import OrganizationService from './OrganizationService';
|
||||
import TenantsManagerService from '@/services/Tenancy/TenantsManager';
|
||||
|
||||
@Service()
|
||||
export default class OrganizationUpgrade {
|
||||
@Inject()
|
||||
private organizationService: OrganizationService;
|
||||
|
||||
@Inject()
|
||||
private tenantsManager: TenantsManagerService;
|
||||
|
||||
@Inject('agenda')
|
||||
private agenda: any;
|
||||
|
||||
/**
|
||||
* Upgrades the given organization database.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public upgradeJob = async (tenantId: number): Promise<void> => {
|
||||
const tenant = await Tenant.query()
|
||||
.findById(tenantId)
|
||||
.withGraphFetched('metadata');
|
||||
|
||||
// Validate tenant version.
|
||||
this.validateTenantVersion(tenant);
|
||||
|
||||
// Initialize the tenant.
|
||||
const seedContext = this.tenantsManager.getSeedMigrationContext(tenant);
|
||||
|
||||
// Database manager.
|
||||
const dbManager = new TenantDBManager();
|
||||
|
||||
// Migrate the organization database schema.
|
||||
await dbManager.migrate(tenant);
|
||||
|
||||
// Seeds the organization database data.
|
||||
await new SeedMigration(seedContext.knex, seedContext).latest();
|
||||
|
||||
// Update the organization database version.
|
||||
await this.organizationService.flagTenantDBBatch(tenantId);
|
||||
|
||||
// Remove the tenant job id.
|
||||
await Tenant.markAsUpgraded(tenantId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Running organization upgrade job.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
public upgrade = async (tenantId: number): Promise<{ jobId: string }> => {
|
||||
const tenant = await Tenant.query().findById(tenantId);
|
||||
|
||||
// Validate tenant version.
|
||||
this.validateTenantVersion(tenant);
|
||||
|
||||
// Validate tenant upgrade is not running.
|
||||
this.validateTenantUpgradeNotRunning(tenant);
|
||||
|
||||
// Send welcome mail to the user.
|
||||
const jobMeta = await this.agenda.now('organization-upgrade', {
|
||||
tenantId,
|
||||
});
|
||||
// Transformes the mangodb id to string.
|
||||
const jobId = new ObjectId(jobMeta.attrs._id).toString();
|
||||
|
||||
// Markes the tenant as currently building.
|
||||
await Tenant.markAsUpgrading(tenantId, jobId);
|
||||
|
||||
return { jobId };
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates the given tenant version.
|
||||
* @param {ITenant} tenant
|
||||
*/
|
||||
private validateTenantVersion(tenant) {
|
||||
if (tenant.databaseBatch >= config.databaseBatch) {
|
||||
throw new ServiceError(ERRORS.TENANT_DATABASE_UPGRADED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given tenant upgrade is not running.
|
||||
* @param tenant
|
||||
*/
|
||||
private validateTenantUpgradeNotRunning(tenant) {
|
||||
if (tenant.isUpgradeRunning) {
|
||||
throw new ServiceError(ERRORS.TENANT_UPGRADE_IS_RUNNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export class CommandOrganizationValidators {
|
||||
constructor(
|
||||
private readonly baseCurrencyMutateLocking: OrganizationBaseCurrencyLocking,
|
||||
) {}
|
||||
|
||||
|
||||
/**
|
||||
* Validate mutate base currency ability.
|
||||
* @param {Tenant} tenant -
|
||||
@@ -23,9 +23,7 @@ export class CommandOrganizationValidators {
|
||||
) {
|
||||
if (tenant.isReady && newBaseCurrency !== oldBaseCurrency) {
|
||||
const isLocked =
|
||||
await this.baseCurrencyMutateLocking.isBaseCurrencyMutateLocked(
|
||||
tenant.id,
|
||||
);
|
||||
await this.baseCurrencyMutateLocking.isBaseCurrencyMutateLocked();
|
||||
|
||||
if (isLocked) {
|
||||
throw new ServiceError(ERRORS.BASE_CURRENCY_MUTATE_LOCKED);
|
||||
|
||||
Reference in New Issue
Block a user