Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { keyBy } from 'lodash-es'; import { In, Repository } from 'typeorm'; import { Calculation, Period, Plan, type Company } from '@amalia/core/models'; import { CALCULATION_ONGOING_STATUSES, CalculationStatus, CalculationType } from '@amalia/core/types'; import { canViewThisStatement, defineAbilityFor } from '@amalia/kernel/auth/shared'; import { type AuthenticatedContext } from '@amalia/kernel/auth/types'; @Injectable() export class CalculationsService { public constructor( @InjectRepository(Calculation) private readonly calculationRepository: Repository<Calculation>, @InjectRepository(Period) private readonly periodRepository: Repository<Period>, @InjectRepository(Plan) private readonly planRepository: Repository<Plan>, ) {} public async getCalculation(company: Company, calculationId: string, relations?: string[]) { return this.calculationRepository.findOne({ where: { company: { id: company.id }, id: calculationId }, relations, }); } public async getOngoingCalculations(company: Company) { return this.calculationRepository.find({ where: { company: { id: company.id }, status: In(CALCULATION_ONGOING_STATUSES) }, relations: ['creator'], }); } public async findCalculations( company: Company, periodId: string, status?: CalculationStatus[], count?: number, calculationType?: CalculationType, ) { const query = this.calculationRepository .createQueryBuilder('calculation') .where('calculation.companyId = :companyId', { companyId: company.id }) .andWhere('calculation.descriptor @> :periodIdCondition', { periodIdCondition: JSON.stringify([{ periodId }]) }); if (status && status.length > 0) { query.andWhere('calculation.status IN (:...status)', { status }); } if (calculationType) { query.andWhere('calculation.type = :calculationType', { calculationType, }); } query.addOrderBy('"createdAt"', 'DESC'); query.limit(count || 100); return query.getMany(); } public async filterCalculationsByAccessRight( authenticatedContext: AuthenticatedContext, calculations: Calculation[], ): Promise<Calculation[]> { const periodIds = calculations.flatMap((calculation) => calculation.descriptor.map((step) => step.periodId)); const planIds = calculations.flatMap((calculation) => calculation.descriptor.flatMap((step) => step.batches.map((batch) => batch.planId)), ); const periods = await this.periodRepository.find({ where: { company: { id: authenticatedContext.user.companyId }, id: In(periodIds) }, }); const periodsMap = keyBy(periods, 'id'); const plans = await this.planRepository.find({ where: { company: { id: authenticatedContext.user.companyId }, id: In(planIds) }, }); const plansMap = keyBy(plans, 'id'); const ability = defineAbilityFor(authenticatedContext); return calculations.map((calculation) => ({ ...calculation, descriptor: calculation.descriptor .map((step) => ({ ...step, batches: step.batches .map((batch) => ({ ...batch, users: batch.users.filter((user) => canViewThisStatement(ability, { user, period: periodsMap[step.periodId], plan: plansMap[batch.planId], }), ), })) .filter((batch) => batch.users.length > 0), })) .filter((step) => step.batches.length > 0), })); } } |