refactor(api): split resource read models
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
import { fmtEur } from "../lib/format-utils.js";
|
||||
|
||||
export const RESOURCE_SUMMARY_SELECT = {
|
||||
id: true,
|
||||
eid: true,
|
||||
displayName: true,
|
||||
chapter: true,
|
||||
isActive: true,
|
||||
areaRole: { select: { name: true } },
|
||||
country: { select: { code: true, name: true } },
|
||||
metroCity: { select: { name: true } },
|
||||
orgUnit: { select: { name: true } },
|
||||
} as const;
|
||||
|
||||
export const RESOURCE_SUMMARY_DETAIL_SELECT = {
|
||||
...RESOURCE_SUMMARY_SELECT,
|
||||
fte: true,
|
||||
lcrCents: true,
|
||||
chargeabilityTarget: true,
|
||||
} as const;
|
||||
|
||||
export const RESOURCE_IDENTIFIER_SELECT = {
|
||||
id: true,
|
||||
eid: true,
|
||||
displayName: true,
|
||||
chapter: true,
|
||||
isActive: true,
|
||||
} as const;
|
||||
|
||||
export const RESOURCE_IDENTIFIER_DETAIL_SELECT = {
|
||||
...RESOURCE_IDENTIFIER_SELECT,
|
||||
email: true,
|
||||
fte: true,
|
||||
lcrCents: true,
|
||||
ucrCents: true,
|
||||
chargeabilityTarget: true,
|
||||
availability: true,
|
||||
skills: true,
|
||||
postalCode: true,
|
||||
federalState: true,
|
||||
areaRole: { select: { name: true, color: true } },
|
||||
country: { select: { code: true, name: true, dailyWorkingHours: true } },
|
||||
metroCity: { select: { name: true } },
|
||||
managementLevelGroup: { select: { name: true, targetPercentage: true } },
|
||||
orgUnit: { select: { name: true, level: true } },
|
||||
_count: { select: { assignments: true, vacations: true } },
|
||||
} as const;
|
||||
|
||||
export const RESOURCE_DIRECTORY_SELECT = {
|
||||
id: true,
|
||||
eid: true,
|
||||
displayName: true,
|
||||
chapter: true,
|
||||
isActive: true,
|
||||
} as const;
|
||||
|
||||
export function mapResourceSummary(resource: {
|
||||
id: string;
|
||||
eid: string;
|
||||
displayName: string;
|
||||
chapter: string | null;
|
||||
isActive: boolean;
|
||||
areaRole: { name: string } | null;
|
||||
country: { code: string; name: string } | null;
|
||||
metroCity: { name: string } | null;
|
||||
orgUnit: { name: string } | null;
|
||||
}) {
|
||||
return {
|
||||
id: resource.id,
|
||||
eid: resource.eid,
|
||||
name: resource.displayName,
|
||||
chapter: resource.chapter,
|
||||
role: resource.areaRole?.name ?? null,
|
||||
country: resource.country?.name ?? resource.country?.code ?? null,
|
||||
countryCode: resource.country?.code ?? null,
|
||||
metroCity: resource.metroCity?.name ?? null,
|
||||
orgUnit: resource.orgUnit?.name ?? null,
|
||||
active: resource.isActive,
|
||||
};
|
||||
}
|
||||
|
||||
export function mapResourceSummaryDetail(resource: {
|
||||
id: string;
|
||||
eid: string;
|
||||
displayName: string;
|
||||
chapter: string | null;
|
||||
fte: number | null;
|
||||
lcrCents: number | null;
|
||||
chargeabilityTarget: number | null;
|
||||
isActive: boolean;
|
||||
areaRole: { name: string } | null;
|
||||
country: { code: string; name: string } | null;
|
||||
metroCity: { name: string } | null;
|
||||
orgUnit: { name: string } | null;
|
||||
}) {
|
||||
return {
|
||||
id: resource.id,
|
||||
eid: resource.eid,
|
||||
name: resource.displayName,
|
||||
chapter: resource.chapter,
|
||||
role: resource.areaRole?.name ?? null,
|
||||
country: resource.country?.name ?? resource.country?.code ?? null,
|
||||
countryCode: resource.country?.code ?? null,
|
||||
metroCity: resource.metroCity?.name ?? null,
|
||||
orgUnit: resource.orgUnit?.name ?? null,
|
||||
fte: resource.fte,
|
||||
lcr: resource.lcrCents != null ? fmtEur(resource.lcrCents) : null,
|
||||
chargeabilityTarget: resource.chargeabilityTarget != null ? `${resource.chargeabilityTarget}%` : null,
|
||||
active: resource.isActive,
|
||||
};
|
||||
}
|
||||
|
||||
export function mapResourceDetail(resource: {
|
||||
id: string;
|
||||
eid: string;
|
||||
displayName: string;
|
||||
email: string | null;
|
||||
chapter: string | null;
|
||||
fte: number | null;
|
||||
lcrCents: number | null;
|
||||
ucrCents: number | null;
|
||||
chargeabilityTarget: number | null;
|
||||
isActive: boolean;
|
||||
skills: unknown;
|
||||
postalCode: string | null;
|
||||
federalState: string | null;
|
||||
areaRole: { name: string; color: string | null } | null;
|
||||
country: { code: string; name: string; dailyWorkingHours: number | null } | null;
|
||||
metroCity: { name: string } | null;
|
||||
managementLevelGroup: { name: string; targetPercentage: number | null } | null;
|
||||
orgUnit: { name: string; level: number } | null;
|
||||
_count: { assignments: number; vacations: number };
|
||||
}) {
|
||||
const skills = Array.isArray(resource.skills) ? resource.skills as { name?: string; level?: number }[] : [];
|
||||
return {
|
||||
id: resource.id,
|
||||
eid: resource.eid,
|
||||
name: resource.displayName,
|
||||
email: resource.email,
|
||||
chapter: resource.chapter,
|
||||
role: resource.areaRole?.name ?? null,
|
||||
country: resource.country?.name ?? resource.country?.code ?? null,
|
||||
countryCode: resource.country?.code ?? null,
|
||||
countryHours: resource.country?.dailyWorkingHours ?? 8,
|
||||
metroCity: resource.metroCity?.name ?? null,
|
||||
fte: resource.fte,
|
||||
lcr: resource.lcrCents != null ? fmtEur(resource.lcrCents) : null,
|
||||
ucr: resource.ucrCents != null ? fmtEur(resource.ucrCents) : null,
|
||||
chargeabilityTarget: resource.chargeabilityTarget != null ? `${resource.chargeabilityTarget}%` : null,
|
||||
managementLevel: resource.managementLevelGroup?.name ?? null,
|
||||
orgUnit: resource.orgUnit?.name ?? null,
|
||||
postalCode: resource.postalCode,
|
||||
federalState: resource.federalState,
|
||||
active: resource.isActive,
|
||||
totalAssignments: resource._count.assignments,
|
||||
totalVacations: resource._count.vacations,
|
||||
skillCount: skills.length,
|
||||
topSkills: skills.slice(0, 10).map((skill) => `${skill.name ?? "?"} (${skill.level ?? "?"})`),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user