import { addMinutes, differenceInYears, isBefore } from 'date-fns' import { Transform, Type } from 'class-transformer' import { isInteger, isNil, trim } from 'lodash' import { CountryHelper, keepNumbers, isNotBlank, LanguageCountryCode, parseDate, Timezone, CountryCode } from '../utils' import { Anthropometry } from './anthropometry.model' import { BaseModel } from './base.model' import { Gender } from './gender.model' import { PatientRestriction } from './patient_restriction.model' import { Subscription } from './subscription.model' const interval = 10 export const FEMALE = 1 export const MALE = 2 const ALLOWED_CONTRIES_DOCUMENT_LOGIN = [LanguageCountryCode.ES_EC, LanguageCountryCode.PT_BR] export class Patient extends BaseModel { id: string name: string email: string @Transform(value => keepNumbers(value)) document_number: string @Transform( (value, obj) => trim(value).charAt(0) === '+' || isNil(obj.country_code) ? value : `+${CountryHelper.getCallingCode(obj.country_code)}${keepNumbers(value)}`, { toClassOnly: true }, ) cell_phone: string gender_id?: number country_code: CountryCode goal_id?: string menu_id?: string user_id?: string collaborator?: boolean internal_collaborator?: boolean telegram_id?: string device_id?: string tenant?: string @Transform(value => parseDate(value), { toClassOnly: true }) birth_date: Date @Transform(value => parseDate(value), { toClassOnly: true }) created_at: Date @Transform(value => parseDate(value), { toClassOnly: true }) updated_at: Date @Transform(value => parseDate(value), { toClassOnly: true }) auth_token_created_at: Date @Transform(value => parseDate(value), { toClassOnly: true }) sign_up_at?: Date @Transform(value => (!isNil(value) ? (isInteger(+value) ? +value : +value * 100) : null), { toClassOnly: true }) height?: number @Transform(value => +value, { toClassOnly: true }) weight?: number @Type(() => PatientRestriction) patient_restrictions: PatientRestriction[] @Type(() => Subscription) subscription: Subscription @Type(() => Subscription) subscriptions: Subscription[] @Type(() => Gender) gender: Gender @Type(() => Anthropometry) anthropometries: Anthropometry[] auth_token: string bioimpedance_credit: number teleconsultations_credit: number is_centauro: boolean timezone?: Timezone omie_code: string is_smartfit: boolean smartfit_id?: number smartfit_token: string smartfit_unit_id?: number smartfit_main_purchase_id?: number smartfit_unit_acronym: string get isInternalOrExternalCollaborator(): boolean { return this.collaborator || this.internal_collaborator } get genderInitial(): string { const isMale = this.gender ? this.gender.male : this.gender_id === MALE return isMale ? 'M' : 'F' } get subscriber(): boolean { return this.isInternalOrExternalCollaborator || this.hasActiveSubscription } get hasActiveSubscription(): boolean { return !isNil(this.subscription) && !this.subscription.isCancelled } get login(): string { if (isNil(this.country_code)) return this.document_number || this.email return this[Patient.loginField(this.country_code)] } get age(): number { return differenceInYears(new Date(), this.birth_date) } hasAuthToken(): boolean { return isNotBlank(this.auth_token) } hasExpiredAuthToken(): boolean { return this.hasAuthToken() && isBefore(addMinutes(this.auth_token_created_at, interval), new Date()) } cleanAuthToken(): void { this.auth_token = null this.auth_token_created_at = null } setAuthToken(authToken: string): void { this.auth_token = authToken this.auth_token_created_at = new Date() } get locale(): string { return this.country_code.split('_')[0] } get restriction_ids(): string[] { return (this.patient_restrictions ?? []).map((r: PatientRestriction) => r.restriction_id) } get firstName(): string { return this.name.split(' ')[0] } static loginField(countryCode: CountryCode): 'document_number' | 'email' { return ALLOWED_CONTRIES_DOCUMENT_LOGIN.includes(CountryHelper.parseLanguageCode(countryCode)) ? 'document_number' : 'email' } }