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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 1x 4x 4x 4x 4x 4x 1x 1x 4x 4x 4x 4x 4x 2x 2x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 5x 5x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 1x | import { BadRequestException, ForbiddenException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { isNil } from 'lodash-es';
import { Brackets, Repository } from 'typeorm';
import { VariableType } from '@amalia/amalia-lang/tokens/types';
import { Plan, Team, User, Variable, VariableValue, type Company, type Period } from '@amalia/core/models';
import { FormatsEnum } from '@amalia/data-capture/fields/types';
import { assert } from '@amalia/ext/typescript';
import { getViewQuotasSubset, SubsetAccessEnum, SubsetsAccessHelper } from '@amalia/kernel/auth/shared';
import { type AuthenticatedContext } from '@amalia/kernel/auth/types';
/**
* Service variable value.
*/
@Injectable()
export class VariableValuesService {
public constructor(
@InjectRepository(VariableValue)
private readonly variableValueRepository: Repository<VariableValue>,
) {}
/**
* Find variable value by variable id and user id.
* @param variable
* @param user
* @param plan
* @param team
* @param company
* @param startDate
* @param endDate
* @param relations
*/
public async findVariableValueByUserPlanTeamAndDates(
variable: Variable,
user: User | null,
plan: Plan | null,
team: Team | null,
company: Pick<Company, 'id'>,
startDate: number | null,
endDate: number | null,
relations?: string[],
): Promise<VariableValue | null> {
const variableValue = await this.variableValueRepository.findOne({
where: {
variable: { id: variable.id },
company: { id: company.id },
// Issues when finding on null values. Fix from here: https://github.com/typeorm/typeorm/issues/5274
...(user && { user: { id: user.id } }),
...(plan && { plan: { id: plan.id } }),
...(team && { team: { id: team.id } }),
...(startDate && { startDate }),
...(endDate && { endDate }),
},
relations,
});
return variableValue || null;
}
/**
* Fin all variable values attached to a variable and/or a user, optional in the period
* @param company
* @param variableId id of the variable
* @param userId id of the user
* @param planId
* @param teamIds
* @param authenticatedContext
* @param period period
*/
public async findAll(
company: Company,
variableId: string | null,
userId: string | null,
planId: string | null,
teamIds: string[] | null,
authenticatedContext?: AuthenticatedContext,
period?: Pick<Period, 'endDate' | 'startDate'>,
): Promise<VariableValue[]> {
assert(variableId || userId, new BadRequestException('No id param'));
const queryBuilder = this.variableValueRepository.createQueryBuilder('variableValue');
queryBuilder
.where('variableValue.company = :companyId', { companyId: company.id })
.andWhere(
new Brackets((qb) => {
if (userId) {
qb.where('variableValue.user = :userId', { userId });
}
}),
)
.andWhere(
new Brackets((qb) => {
if (planId) {
qb.where('variableValue.plan = :planId', { planId });
}
}),
)
.andWhere(
new Brackets((qb) => {
if (teamIds && teamIds.length > 0) {
qb.where('variableValue.team IN (:...teamIds)', { teamIds });
}
}),
)
.andWhere(
new Brackets((qb) => {
if (variableId) {
qb.where('variableValue.variable = :variableId', {
variableId,
});
}
}),
);
queryBuilder.leftJoinAndSelect('variableValue.variable', 'variable');
queryBuilder.leftJoin('variableValue.plan', 'assignedPlan');
queryBuilder.leftJoin('assignedPlan.planAssignements', 'assignedPlanAssignements');
if (period) {
// Period StartDate <= EffectiveUntil + Period EndDate >= EffectiveAsOf
const { endDate, startDate } = period;
queryBuilder.andWhere('COALESCE(variableValue.startDate, :endDate) <= :endDate', {
endDate,
});
queryBuilder.andWhere('COALESCE(variableValue.endDate, :startDate) >= :startDate', {
startDate,
});
}
// RIGHTS
let subsetAccess = null;
if (authenticatedContext && variableId) {
subsetAccess = SubsetsAccessHelper.getSubset(authenticatedContext, getViewQuotasSubset);
if (subsetAccess === SubsetAccessEnum.NOTHING) {
throw new ForbiddenException("You don't have access to Variables");
}
if (subsetAccess === SubsetAccessEnum.MATCH_TEAMS_AND_MANAGEES) {
const subordinatesIds = authenticatedContext.hierarchy.getSubordinates(new Date()).map((s) => s.user.id);
const teamIds = authenticatedContext.hierarchy
.getTeamIdsWhereUserIsManager(new Date())
.concat(authenticatedContext.hierarchy.getUserTeamAssignments(new Date()).map((ta) => ta.teamId));
const myManagees = subordinatesIds.length > 0 ? subordinatesIds : [authenticatedContext.user.id];
queryBuilder.andWhere('(variable.type != :userType OR variableValue.userId IN (:...myManagees))', {
userType: VariableType.user,
myManagees,
});
queryBuilder.andWhere(
teamIds.length > 0
? '(variable.type != :teamType OR variableValue.teamId IN (:...myTeams))'
: '(variable.type != :teamType)',
{
teamType: VariableType.team,
myTeams: teamIds,
},
);
queryBuilder.andWhere('(variable.type != :planType OR assignedPlanAssignements.userId IN (:...myManagees))', {
planType: VariableType.plan,
myManagees,
});
}
}
queryBuilder.orderBy('variableValue.id');
const rows = await queryBuilder.getMany();
return rows.map((r) => ({
...r,
value: VariableValuesService.formatVariableValue(r.variable!, r.value),
}));
}
/**
* Variable value is stored as varchar in db and mapped to a string by typeorm.
*
* If the quota is in number, convert it to JS number format.
*
* @param variable
* @param value
* @private
*/
public static formatVariableValue(variable: Variable, value: VariableValue['value']) {
switch (variable.format) {
case FormatsEnum.currency:
case FormatsEnum.date:
case FormatsEnum.number:
case FormatsEnum.percent:
return isNil(value) ? value : +value;
case FormatsEnum.text:
return value;
default:
throw new Error('Variable format not supported');
}
}
}
|