@seniorsistemas/hcm-clocking-event-rule-nodejs 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/.github/copilot-instructions.md +11 -0
  2. package/.github/workflows/release.yaml +10 -0
  3. package/.gitlab-ci.yml +68 -0
  4. package/CHANGELOG.md +274 -0
  5. package/README.doc.md +658 -0
  6. package/README.md +117 -0
  7. package/assets/favicon.ico +0 -0
  8. package/catalog-info.yaml +19 -0
  9. package/jest.config.js +17 -0
  10. package/package.json +48 -0
  11. package/prompt.md +15 -0
  12. package/run_build_win.bat +1 -0
  13. package/run_link.bat +3 -0
  14. package/run_test.bat +1 -0
  15. package/sonar-project.properties +21 -0
  16. package/src/data/changes/changes.ts +92 -0
  17. package/src/data/context/context.ts +251 -0
  18. package/src/data/context/contextReference.ts +376 -0
  19. package/src/data/contract/contract.ts +272 -0
  20. package/src/data/dataset/database.ts +130 -0
  21. package/src/data/dataset/dataset.ts +275 -0
  22. package/src/data/definition/timeEvaluationSituationDefinitionHistory.ts +1425 -0
  23. package/src/data/employee/employee.ts +434 -0
  24. package/src/data/foundation/companyBranch.ts +66 -0
  25. package/src/data/foundation/costCenter.ts +47 -0
  26. package/src/data/foundation/employer.ts +35 -0
  27. package/src/data/foundation/employmentRelationship.ts +63 -0
  28. package/src/data/foundation/holiday.ts +84 -0
  29. package/src/data/foundation/holidayGroup.ts +47 -0
  30. package/src/data/foundation/jobPosition.ts +73 -0
  31. package/src/data/foundation/person.ts +35 -0
  32. package/src/data/foundation/situation.ts +301 -0
  33. package/src/data/foundation/syndicate.ts +244 -0
  34. package/src/data/foundation/workschedule.ts +688 -0
  35. package/src/data/foundation/workshift.ts +647 -0
  36. package/src/data/foundation/workshiftBase.ts +113 -0
  37. package/src/data/histories/companyBranchHistory.ts +128 -0
  38. package/src/data/histories/costCenterHistory.ts +114 -0
  39. package/src/data/histories/employmentRelationshipHistory.ts +116 -0
  40. package/src/data/histories/histories.ts +419 -0
  41. package/src/data/histories/jobPositionHistory.ts +117 -0
  42. package/src/data/histories/leaveHistory.ts +227 -0
  43. package/src/data/histories/timeEvaluationHistory.ts +191 -0
  44. package/src/data/histories/workshiftHistory.ts +66 -0
  45. package/src/data/hourBank/hourBank.ts +43 -0
  46. package/src/data/hourBank/hourBankAccount.ts +77 -0
  47. package/src/data/log/log.ts +38 -0
  48. package/src/data/schedules/bridge.ts +84 -0
  49. package/src/data/schedules/compensation.ts +332 -0
  50. package/src/data/schedules/overtimeAuthorization.ts +174 -0
  51. package/src/data/schedules/readiness.ts +150 -0
  52. package/src/data/schedules/schedules.ts +398 -0
  53. package/src/data/schedules/workscheduleChange.ts +91 -0
  54. package/src/data/schedules/workshiftChange.ts +76 -0
  55. package/src/data/timeEvaluation/adjustmentReason.ts +46 -0
  56. package/src/data/timeEvaluation/clockingEvent.ts +198 -0
  57. package/src/data/timeEvaluation/estimatedHours.ts +245 -0
  58. package/src/data/timeEvaluation/interval.ts +568 -0
  59. package/src/data/timeEvaluation/separatedHours.ts +134 -0
  60. package/src/data/timeEvaluation/timeEvaluation.ts +1540 -0
  61. package/src/data/timeEvaluation/timeEvaluationSituation.ts +154 -0
  62. package/src/data/user/user.ts +44 -0
  63. package/src/index.ts +60 -0
  64. package/src/test/builder/bridgeBuilder.builder.ts +28 -0
  65. package/src/test/builder/clockingEvent.builder.ts +49 -0
  66. package/src/test/builder/companyBranchHistoryBuilder.ts +29 -0
  67. package/src/test/builder/compensation.builder.ts +84 -0
  68. package/src/test/builder/contextReference.builder.ts +69 -0
  69. package/src/test/builder/costCenterHistoryBuilder.ts +29 -0
  70. package/src/test/builder/database.builder.ts +21 -0
  71. package/src/test/builder/datasetBuilder.ts +111 -0
  72. package/src/test/builder/dateIntervalBuilder.ts +25 -0
  73. package/src/test/builder/employee.builder.ts +91 -0
  74. package/src/test/builder/employmentRelationshipBuilder.ts +35 -0
  75. package/src/test/builder/employmentRelationshipHistoryBuilder.ts +29 -0
  76. package/src/test/builder/historiesBuilder.ts +56 -0
  77. package/src/test/builder/holiday.builder.ts +44 -0
  78. package/src/test/builder/hourBankAccountBuilder.ts +77 -0
  79. package/src/test/builder/hourBankBuilder.ts +32 -0
  80. package/src/test/builder/interval.builder.ts +113 -0
  81. package/src/test/builder/jobPositionHistoryBuilder.ts +29 -0
  82. package/src/test/builder/overtimeAuthorization.builder.ts +42 -0
  83. package/src/test/builder/readinessBuilder.builder.ts +57 -0
  84. package/src/test/builder/schedules.builder.ts +126 -0
  85. package/src/test/builder/situation.builder.ts +59 -0
  86. package/src/test/builder/syndicate.builder.ts +96 -0
  87. package/src/test/builder/syndicateHistoryBuilder.ts +33 -0
  88. package/src/test/builder/timeEvaluation.builder.ts +138 -0
  89. package/src/test/builder/timeEvaluationHistory.builder.ts +49 -0
  90. package/src/test/builder/timeEvaluationSituation.builder.ts +34 -0
  91. package/src/test/builder/workschedule.builder.ts +96 -0
  92. package/src/test/builder/workshift.builder.ts +179 -0
  93. package/src/test/builder/workshiftBuilder.ts +55 -0
  94. package/src/test/data/clockingEvent.spec.ts +56 -0
  95. package/src/test/data/context.spec.ts +176 -0
  96. package/src/test/data/currentUser.spec.ts +11 -0
  97. package/src/test/data/dataset.spec.ts +144 -0
  98. package/src/test/data/employee/employee.spec.ts +20 -0
  99. package/src/test/data/employmentRelationship/employmentRelationship.spec.ts +48 -0
  100. package/src/test/data/estimatedHours/estimatedHours.spec.ts +96 -0
  101. package/src/test/data/histories/costCenterHistory.spec.ts +32 -0
  102. package/src/test/data/histories/histories.spec.ts +306 -0
  103. package/src/test/data/holyday.spec.ts +89 -0
  104. package/src/test/data/hourBank/hourBank.spec.ts +48 -0
  105. package/src/test/data/hourBank/hourBankAccount.spec.ts +32 -0
  106. package/src/test/data/schedules/bridge.spec.ts +13 -0
  107. package/src/test/data/schedules/compesation.spect.ts +89 -0
  108. package/src/test/data/schedules/overtimeAuthorization.spec.ts +52 -0
  109. package/src/test/data/schedules/readiness.spec.ts +64 -0
  110. package/src/test/data/schedules/schedules.spec.ts +134 -0
  111. package/src/test/data/schedules/workscheduleChange.spec.ts +21 -0
  112. package/src/test/data/syndicate/syndicate.spec.ts +51 -0
  113. package/src/test/data/timeEvaluation.spec.ts +1057 -0
  114. package/src/test/data/timeEvaluationDefinition.spec.ts +144 -0
  115. package/src/test/data/workschedule/workschedule.spec.ts +194 -0
  116. package/src/test/data/workshift/workshift.spec.ts +79 -0
  117. package/src/test/utils/date.utils.spec.ts +198 -0
  118. package/src/test/utils/dateIntervalUtils.spec.ts +210 -0
  119. package/src/test/utils/object.utils.spec.ts +83 -0
  120. package/src/utils/dateIntervalUtils.ts +284 -0
  121. package/src/utils/dateUtils.ts +456 -0
  122. package/src/utils/decompressGzipLambda.ts +15 -0
  123. package/src/utils/object.utils.ts +156 -0
  124. package/trivy/vulnerabilities_scan.json +1160 -0
  125. package/tsconfig.json +32 -0
  126. package/tsconfig.spec.json +21 -0
  127. package/tslint.json +92 -0
  128. package/typedoc.json +22 -0
@@ -0,0 +1,1540 @@
1
+ import { DateUtils } from "../../utils/dateUtils";
2
+ import { TimeEvaluationSituation } from "./timeEvaluationSituation";
3
+ import { Interval, IntervalTypes, IntervalSubTypes } from "./interval";
4
+ import { Workschedule, IntervalType } from './../foundation/workschedule';
5
+ import { Workshift } from "./../foundation/workshift";
6
+ import { SeparatedHours } from "./separatedHours";
7
+ import { ContextReference } from "./../context/contextReference";
8
+ import { ClockingEvent, ClockingEventOriginType } from "./clockingEvent";
9
+ import { ObjectUtils } from "src/utils/object.utils";
10
+ import { Schedules } from "./../schedules/schedules";
11
+ import { Bridge } from "./../schedules/bridge";
12
+ import { HourBankAccount } from "./../hourBank/hourBankAccount";
13
+ import { TimeEvaluationSituationDefinitionHistory } from "./../definition/timeEvaluationSituationDefinitionHistory";
14
+ import { Histories } from "./../histories/histories";
15
+ import { JobPositionHistory } from "./../histories/jobPositionHistory";
16
+ import { CompanyBranchHistory } from "./../histories/companyBranchHistory";
17
+ import { EstimatedHours } from "./estimatedHours";
18
+ import { TimeEvaluationHistory } from './../histories/timeEvaluationHistory';
19
+ import { Syndicate } from "./../foundation/syndicate";
20
+ import { EmploymentRelationshipHistory } from "./../histories/employmentRelationshipHistory";
21
+ import { WorkscheduleChange } from "./../schedules/workscheduleChange";
22
+ import { WorkshiftChange } from "./../schedules/workshiftChange";
23
+ import { Readiness } from "./../schedules/readiness";
24
+ import { OvertimeAuthorization } from "./../schedules/overtimeAuthorization";
25
+ import { Compensation } from "./../schedules/compensation";
26
+ import { WorkshiftHistory } from "./../histories/workshiftHistory";
27
+ import { Holiday } from "./../foundation/holiday";
28
+ import { LeaveHistory } from "./../histories/leaveHistory";
29
+ import { CostCenter } from './../foundation/costCenter';
30
+ import { Contract } from "./../contract/contract";
31
+
32
+
33
+ /**
34
+ * Interface para os parâmetros do construtor de TimeEvaluation.
35
+ * @hidden
36
+ */
37
+ export interface TimeEvaluationParams {
38
+ date: Date;
39
+ workscheduleId: string;
40
+ workscheduleWorkshiftId: string;
41
+ workshiftId: string;
42
+ timeEvaluationSituations: TimeEvaluationSituation[];
43
+ clockingEvents: ClockingEvent[];
44
+ intervals: Interval[];
45
+ schedules: Schedules;
46
+ histories: Histories;
47
+ hourBankAccounts: HourBankAccount[];
48
+ situationDefinitionKey: string;
49
+ estimatedHours: EstimatedHours;
50
+ syndicateKey: string;
51
+ holiday?: Holiday;
52
+ missingClockingEvent: boolean;
53
+ costCenterKey: string;
54
+ }
55
+
56
+
57
+ /**
58
+ * Representa a apuração de ponto e as apurações acontecem diariamente.
59
+ *
60
+ * Nesta classe podem ser encontradas as informações:
61
+ * - Data da apuração.
62
+ * - Horário de trabalho.
63
+ * - Escala do dia.
64
+ * - Situações apuradas, bem com alterar essas situações.
65
+ * - Marcações de ponto do colaborador.
66
+ * - Intervalos apurados, como por exemplo, faltas, atrasos, extras, etc.
67
+ * - Programações de horários, como por exemplo, pontes e trocas de horário.
68
+ * - Histórico de apuração de ponto, como por exemplo, históricos de cargo, sindicato e filial.
69
+ * - Contas de banco de horas do colaborador.
70
+ * - Gerenciar as pendências do dia.
71
+ *
72
+ * Exemplo de uso:
73
+ * ```typescript
74
+ * timeEvaluation.setSituationHour(15, 60); // Define 60 minutos na situação 15 (faltas).
75
+ * timeEvaluation.sumSituationHour(16, 30); // Soma 30 minutos na situação 16 (extras).
76
+ * const hours = timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas).
77
+ * timeEvaluation.resetSituationHour(15); // Zera a quantidade de horas da situação 15 (faltas).
78
+ * timeEvaluation.resetSituationHourByCodes(15, 16); // Zera a quantidade de horas das situações 15 e 16 (faltas e extras).
79
+ *
80
+ * const separatedHours = timeEvaluation.getSeparateHours(IntervalTypes.ABSENCE, true); // Retorna as horas apuradas separadas em diurnas, noturnas e o total, do tipo de intervalo falta, considerando tolerância.
81
+ * const separatedHoursWithPart = timeEvaluation.getSeparateHoursWithExpedientPart(IntervalTypes.ABSENCE, 1, true); // Retorna as horas apuradas separadas em diurnas, noturnas e o total, do tipo de intervalo falta, e primeira parte do expediente, considerando tolerância.
82
+ * const separatedHoursIntervalSubType = timeEvaluation.getSeparateHoursIntervalSubType(IntervalSubTypes.DELAY, true); // Retorna as horas apuradas separadas em diurnas, noturnas e o total, do subtipo de intervalo atraso, considerando tolerância.
83
+ * ```
84
+ *
85
+ *
86
+ */
87
+ export class TimeEvaluation {
88
+ /**
89
+ * Data da apuração.
90
+ */
91
+ private readonly _date: Date;
92
+ /**
93
+ * Indica se deve gerar ajustes pendentes para o dia apurado.
94
+ */
95
+ private _generatePendingAdjustment: boolean | undefined;
96
+
97
+ /**
98
+ * Horário de trabalho do dia apurado considerando trocas de horário, busca automática e pontes.
99
+ */
100
+ private readonly _workschedulId: string;
101
+ /**
102
+ * Horário de trabalho conforme a escala, considerando o histórico e as programações de troca de escala.
103
+ * Não considera trocas de horário, busca automática e nem pontes.
104
+ */
105
+ private readonly _workscheduleWorkshiftId: string;
106
+ /**
107
+ * Escala.
108
+ */
109
+ private readonly _workshiftId: string;
110
+ /**
111
+ * Situações.
112
+ */
113
+ private readonly _timeEvaluationSituations: TimeEvaluationSituation[];
114
+ /**
115
+ * Marcações de ponto.
116
+ */
117
+ private readonly _clockingEvents: ClockingEvent[];
118
+ /**
119
+ * Intevalos de apuração.
120
+ */
121
+ private readonly _intervals: Interval[];
122
+
123
+ /**
124
+ * Programações de horários, como por exemplo, pontes e trocas de horário.
125
+ */
126
+ private readonly _schedules: Schedules;
127
+ /**
128
+ * Histórico de apuração de ponto, como por exemplo, históricos de cargo, sindicato filial.
129
+ */
130
+ private readonly _histories: Histories;
131
+
132
+ /**
133
+ * Contas de banco de horas do colaborador.
134
+ */
135
+ private readonly _hourBankAccounts: HourBankAccount[];
136
+ /**
137
+ * Mensagem de erro para dia inválido.
138
+ */
139
+ private _errorMessage = "";
140
+ /**
141
+ * Chave de definição de situação.
142
+ */
143
+ private readonly _situationDefinitionKey: string;
144
+ /**
145
+ * Previsão de horas.
146
+ */
147
+ private readonly _estimatedHours: EstimatedHours;
148
+ private readonly _syndicateKey: string;
149
+ private readonly _holiday: Holiday | undefined;
150
+ private readonly _costCenterKey: string;
151
+ private readonly _missingClockingEvent: boolean;
152
+
153
+
154
+ /** @hidden */
155
+ constructor(params: TimeEvaluationParams) {
156
+ this._date = ObjectUtils.toDateOrThrow(params.date, "timeEvaluation.date");
157
+ this._timeEvaluationSituations = [];
158
+ this._intervals = [];
159
+
160
+ this._workshiftId = params.workshiftId;
161
+ this._workschedulId = params.workscheduleId;
162
+ this._workscheduleWorkshiftId = params.workscheduleWorkshiftId;
163
+ this._clockingEvents = params.clockingEvents;
164
+ this._schedules = params.schedules;
165
+ this._histories = params.histories;
166
+ this._hourBankAccounts = params.hourBankAccounts;
167
+ this._situationDefinitionKey = params.situationDefinitionKey;
168
+ this._syndicateKey = params.syndicateKey;
169
+ this._holiday = params.holiday;
170
+ this._costCenterKey = params.costCenterKey;
171
+ this._missingClockingEvent = params.missingClockingEvent;
172
+
173
+ if (Array.isArray(params.timeEvaluationSituations)) {
174
+ for (const timeEvaluationSituationItem of params.timeEvaluationSituations) {
175
+ this._timeEvaluationSituations.push(
176
+ TimeEvaluationSituation.clone(timeEvaluationSituationItem)
177
+ );
178
+ }
179
+ }
180
+
181
+ this.mapIntervals(params);
182
+
183
+ if (params.estimatedHours) {
184
+ this._estimatedHours = new EstimatedHours({
185
+ meal: params.estimatedHours.meal,
186
+ snack: params.estimatedHours.snack,
187
+ work: params.estimatedHours.work
188
+ });
189
+ }
190
+
191
+ this._clockingEvents = [];
192
+ if (Array.isArray(params.clockingEvents)) {
193
+ for (const event of params.clockingEvents) {
194
+ this._clockingEvents.push(new ClockingEvent(event));
195
+ }
196
+ }
197
+ }
198
+
199
+ private mapIntervals(params: TimeEvaluationParams) {
200
+ if (Array.isArray(params.intervals)) {
201
+ for (const intervalItem of params.intervals) {
202
+ this._intervals.push(Interval.clone(intervalItem));
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Data de apuração.
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * let date = timeEvaluation.date; // Retorna a data de apuração.
213
+ * ```
214
+ *
215
+ * @returns Data de apuração.
216
+ */
217
+ get date(): Date {
218
+ return this._date;
219
+ }
220
+
221
+ /**
222
+ * Horário de trabalho do dia apurado considerando trocas de horário, busca automática e pontes.
223
+ * @hidden
224
+ */
225
+ private get workscheduleId(): string {
226
+ return this._workschedulId;
227
+ }
228
+
229
+ /**
230
+ * Horário de trabalho conforme a escala, considerando o histórico e as programações de troca de escala.
231
+ * Não considera trocas de horário, busca automática e nem pontes.
232
+ * @hidden
233
+ */
234
+ private get workscheduleWorkshiftId(): string {
235
+ return this._workscheduleWorkshiftId;
236
+ }
237
+ /**
238
+ * Id da Escala
239
+ * @hidden
240
+ */
241
+ private get workshiftId(): string {
242
+ return this._workshiftId;
243
+ }
244
+
245
+ /**
246
+ * Horário de trabalho.
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * let workschedule = timeEvaluation.workschedule; // Retorna o horário de trabalho do dia apurado.
251
+ * workschedule.code; // Retorna o código do horário de trabalho.
252
+ * ```
253
+ * @returns Horário de trabalho do dia apurado.
254
+ * @throws Se o horário de trabalho não for encontrado no contexto.
255
+ * @see {@link Workschedule}
256
+ */
257
+ get workschedule(): Workschedule {
258
+ const workschedule = ContextReference.getGlobalInstance().getWorkschedule(this._workschedulId);
259
+ if (!workschedule) {
260
+ throw new Error(`Workschedule with id ${this._workschedulId} not found`);
261
+ }
262
+ return workschedule;
263
+ }
264
+
265
+ /**
266
+ * Horário de trabalho conforme a escala, considerando o histórico e as programações de troca de escala.
267
+ * Não considera trocas de horário, busca automática e nem pontes.
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * let workscheduleWorkshift = timeEvaluation.workscheduleWorkshift; // Retorna o horário de trabalho conforme a escala do dia apurado.
272
+ * workscheduleWorkshift.code; // Retorna o código do horário de trabalho conforme a escala.
273
+ * ```
274
+ * @returns Horário de trabalho conforme a escala do dia apurado.
275
+ * @throws Se o horário de trabalho conforme a escala não for encontrado no contexto.
276
+ * @see {@link Workschedule}
277
+ */
278
+ get workscheduleWorkshift(): Workschedule {
279
+ const workshift = ContextReference.getGlobalInstance().getWorkschedule(this._workscheduleWorkshiftId);
280
+ if (!workshift) {
281
+ throw new Error(`Workschedule with id ${this._workscheduleWorkshiftId} not found`);
282
+ }
283
+ return workshift;
284
+ }
285
+
286
+ /**
287
+ * Escala apurada no dia.
288
+ *
289
+ * @example
290
+ * ```typescript
291
+ * let workshift = timeEvaluation.workshift; // Retorna a escala apurada no dia.
292
+ * workshift.code; // Retorna o código da escala apurada no dia.
293
+ * ```
294
+ * @returns Escala apurada no dia.
295
+ * @throws Se a escala não for encontrada no contexto.
296
+ * @see {@link Workshift}
297
+ */
298
+ get workshift(): Workshift {
299
+ const workshift = ContextReference.getGlobalInstance().getWorkshift(this._workshiftId);
300
+ if (!workshift) {
301
+ throw new Error(`Workshift with id ${this._workshiftId} not found`);
302
+ }
303
+ return workshift;
304
+ }
305
+
306
+ /**
307
+ * Lista das situações calculadas na apuração do dia.
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * let situations = timeEvaluation.timeEvaluationSituations; // Retorna as situações calculadas na apuração do dia.
312
+ * situations.forEach(situation => {
313
+ * console.log(situation.situationCode); // Exibe o código de cada situação.
314
+ * console.log(situation.numberOfHours); // Exibe a quantidade de horas de cada situação.
315
+ * });
316
+ * ```
317
+ * @returns Lista de situações calculadas na apuração do dia.
318
+ * @see {@link TimeEvaluationSituation}
319
+ */
320
+ get timeEvaluationSituations(): TimeEvaluationSituation[] {
321
+ return this._timeEvaluationSituations;
322
+ }
323
+
324
+ /**
325
+ * Lista das marcações de ponto para o dia apurado.
326
+ *
327
+ * @example
328
+ * ```typescript
329
+ * let clockingEvents = timeEvaluation.clockingEvents; // Retorna as marcações de ponto do dia apurado.
330
+ * clockingEvents.forEach(event => {
331
+ * console.log(event.clockingTime); // Exibe o horário de cada marcação.
332
+ * console.log(event.originType); // Exibe o tipo de origem da marcação.
333
+ * });
334
+ * ```
335
+ * @returns Lista de marcações de ponto do dia apurado.
336
+ * @see {@link ClockingEvent}
337
+ */
338
+ get clockingEvents(): ClockingEvent[] {
339
+ return this._clockingEvents;
340
+ }
341
+
342
+ /**
343
+ * Retorna uma lista de intervalos calculados na apuração.
344
+ * Referência no Controle de ponto: NumInt, MSaInD[], MSaInN[], MInExD[], MInExN[].
345
+ *
346
+ * @example
347
+ * ```typescript
348
+ * let intervals = timeEvaluation.intervals; // Retorna os intervalos calculados na apuração.
349
+ * intervals.forEach(interval => {
350
+ * console.log(interval.clockingEventStart); // Exibe o horário inicial de cada intervalo.
351
+ * console.log(interval.clockingEventEnd); // Exibe o horário final de cada intervalo.
352
+ * console.log(interval.type); // Exibe o tipo de intervalo.
353
+ * });
354
+ * ```
355
+ *
356
+ * @return Lista de intervalos de marcações no dia apurado.
357
+ * @see {@link Interval}
358
+ */
359
+ get intervals(): Interval[] {
360
+ return this._intervals;
361
+ }
362
+
363
+ /**
364
+ * Chave de identificação do sindicato.
365
+ * @hidden
366
+ */
367
+ private static syndicateKey(timeEvaluation: TimeEvaluation): string {
368
+ return timeEvaluation._syndicateKey;
369
+ }
370
+
371
+ /**
372
+ * Sindicato do histórico vigente no dia apurado.
373
+ * @example
374
+ * ```typescript
375
+ * let syndicate = timeEvaluation.syndicate; // Retorna o sindicato do histórico vigente no dia apurado.
376
+ * syndicate.code; // Retorna o código do sindicato.
377
+ * syndicate.nightStartHour; // Retorna a hora inicial do turno noturno do sindicato.
378
+ * syndicate.nightEndHour; // Retorna a hora final do turno noturno do sindicato.
379
+ * syndicate.minimumInterval4to6Hours; // Retorna o intervalo mínimo para jornada entre 4 e 6 horas do sindicato.
380
+ * ```
381
+ *
382
+ * @returns Sindicato do histórico vigente no dia apurado.
383
+ * @throws Se o sindicato não for encontrado no contexto.
384
+ * @see {@link Syndicate}
385
+ */
386
+ get syndicate(): Syndicate {
387
+ const syndicate = ContextReference.getGlobalInstance().getSyndicate(this._syndicateKey);
388
+ if (!syndicate) {
389
+ throw new Error(`Syndicate with key ${this._syndicateKey} not found`);
390
+ }
391
+ return syndicate;
392
+ }
393
+
394
+ /**
395
+ * Chave de identificação do centro de custo.
396
+ */
397
+ private get costCenterKey(): string {
398
+ return this._costCenterKey;
399
+ }
400
+
401
+ /**
402
+ * Centro de custo do histórico vigente no dia apurado.
403
+ * @example
404
+ * ```typescript
405
+ * let costCenter = timeEvaluation.costCenter; // Retorna o centro de custo.
406
+ * costCenter.code; // Retorna o código do centro de custo.
407
+ * ```
408
+ *
409
+ * @returns Centro de custo no dia apurado.
410
+ * @throws Se o centro de custo não for encontrado no contexto.
411
+ * @see {@link CostCenter}
412
+ */
413
+ get costCenter(): CostCenter {
414
+ const costCenter = ContextReference.getGlobalInstance().getCostCenter(this._costCenterKey);
415
+ if (!costCenter) {
416
+ throw new Error(`Cost center with key ${this._costCenterKey} not found`);
417
+ }
418
+ return costCenter;
419
+ }
420
+
421
+ /**
422
+ * Retorna a quantidade de Horas previstas para o dia em minutos.
423
+ *
424
+ * @example
425
+ * ```typescript
426
+ * let estimatedHours = timeEvaluation.estimatedHours; // Retorna as horas previstas para o dia em minutos.
427
+ * estimatedHours.work; // Retorna as horas de trabalho previstas em minutos.
428
+ * estimatedHours.meal; // Retorna as horas de refeição previstas em minutos.
429
+ * estimatedHours.snack; // Retorna as horas de lanche previstas em minutos.
430
+ * ```
431
+ * @returns Horas previstas para o dia apurado.
432
+ * @see {@link EstimatedHours}
433
+ *
434
+ */
435
+ get estimatedHours(): EstimatedHours {
436
+ return this._estimatedHours;
437
+ }
438
+
439
+ /**
440
+ * Atualiza a quantidade de horas de uma situação se existir ou cria uma nova situação com a quantidade de horas em minutos.
441
+ *
442
+ * @example
443
+ * ```typescript
444
+ * timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas), 100 minutos.
445
+ * timeEvaluation.setSituationHour(15, 120); // Define 120 minutos na situação 15 (faltas).
446
+ * timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas), agora 120 minutos.
447
+ * ```
448
+ *
449
+ * @param situationCode Código da Situação.
450
+ * @param numberOfHours Quantidade de horas em minutos.
451
+ */
452
+ public setSituationHour(situationCode: number, numberOfHours: number): void {
453
+ const situation = this.findSituationByCode(situationCode);
454
+
455
+ if (situation) {
456
+ situation.numberOfHours = numberOfHours;
457
+ }
458
+
459
+ if (!situation && numberOfHours > 0) {
460
+ this.createTimeEvaluationSituation(situationCode, numberOfHours);
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Soma uma quantidade de horas em uma situação em minutos.
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas), 100 minutos.
470
+ * timeEvaluation.sumSituationHour(15, 30); // Soma 30 minutos na situação 15 (faltas).
471
+ * timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas) somando as horas, 130 minutos.
472
+ * ```
473
+ *
474
+ * @param situationCode Código da situação.
475
+ * @param numberOfHours Quantidade de horas em minutos.
476
+ */
477
+ public sumSituationHour(situationCode: number, numberOfHours: number): void {
478
+ const situation = this.findSituationByCode(situationCode);
479
+
480
+ if (situation) {
481
+ situation.addNumberOfHours(numberOfHours);
482
+ } else {
483
+ this.createTimeEvaluationSituation(situationCode, numberOfHours);
484
+ }
485
+ }
486
+
487
+ /**
488
+ * Retorna a quantidade de horas de uma situação em minutos. Retorna 0 se não encontrar.
489
+ *
490
+ * @example
491
+ * ```typescript
492
+ * let hours = timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas).
493
+ * ```
494
+ *
495
+ * @param situationCode Código da situação.
496
+ * @returns Quantidade de horas em minutos conforme o código de situação.
497
+ */
498
+ public getSituationHour(situationCode: number): number {
499
+ const situation = this.findSituationByCode(situationCode);
500
+ return situation ? situation.numberOfHours : 0;
501
+ }
502
+
503
+ /**
504
+ * Rertorna a quantidade de horas de uma lista de situações em minutos. Retorna 0 se não encontrar.
505
+ *
506
+ * @example
507
+ * ```typescript
508
+ * let hours = timeEvaluation.getSituationHourByCodes(15, 16); // Retorna a quantidade de horas em minutos das situações 15 (faltas) e 16 (extras).
509
+ * ```
510
+ *
511
+ * @param situationCodes Lista de códigos da situação.
512
+ * @returns Quantidade de horas em minutos conforme o código de situação.
513
+ */
514
+ public getSituationHourByCodes(...situationCodes: number[]): number {
515
+ return situationCodes.reduce((totalHours, situationCode) => {
516
+ const situation = this.findSituationByCode(situationCode);
517
+ return totalHours + (situation ? situation.numberOfHours : 0);
518
+ }, 0);
519
+ }
520
+
521
+
522
+ /**
523
+ * Zera a quantidade de horas de uma situação.
524
+ *
525
+ * @example
526
+ * ```typescript
527
+ * timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas), 100 minutos.
528
+ * timeEvaluation.resetSituationHour(15); // Zera a quantidade de horas da situação 15 (faltas).
529
+ * timeEvaluation.getSituationHour(15); // Retorna 0, pois a situação foi zerada.
530
+ * ```
531
+ *
532
+ * @param situationCode Código da situação.
533
+ */
534
+ public resetSituationHour(situationCode: number): void {
535
+ this.setSituationHour(situationCode, 0);
536
+ }
537
+
538
+ /**
539
+ * Zera a quantidade de horas de uma lista de situações.
540
+ *
541
+ * @example
542
+ * ```typescript
543
+ * timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas), 100 minutos.
544
+ * timeEvaluation.getSituationHour(16); // Retorna a quantidade de horas em minutos da situação 16 (extras), 50 minutos.
545
+ * timeEvaluation.resetSituationHourByCodes(15, 16); // Zera a quantidade de horas das situações 15 e 16 (faltas e extras).
546
+ * timeEvaluation.getSituationHour(15); // Retorna 0, pois a situação 15 foi zerada.
547
+ * timeEvaluation.getSituationHour(16); // Retorna 0, pois a situação 16 foi zerada.
548
+ * ```
549
+ * @param situationCodes Lista de códigos da situação.
550
+ */
551
+ public resetSituationHourByCodes(...situationCodes: number[]): void {
552
+ situationCodes.forEach((situationCode) => {
553
+ this.setSituationHour(situationCode, 0);
554
+ });
555
+ }
556
+
557
+ /**
558
+ * Zera a quantidade de horas de uma situação conforme faixa de códigos.
559
+ *
560
+ * @example
561
+ * ```typescript
562
+ * timeEvaluation.getSituationHour(14); // Retorna a quantidade de horas em minutos da situação 14 (trabalhando), 120 minutos.
563
+ * timeEvaluation.getSituationHour(15); // Retorna a quantidade de horas em minutos da situação 15 (faltas), 100 minutos.
564
+ * timeEvaluation.getSituationHour(16); // Retorna a quantidade de horas em minutos da situação 16 (extras), 50 minutos.
565
+ * timeEvaluation.resetSituationHourByRange(15, 16); // Zera a quantidade de horas das situações entre os códigos 15 a 16 (faltas e extras).
566
+ * timeEvaluation.getSituationHour(14); // Retorna 120, pois a situação 14 não foi zerada.
567
+ * timeEvaluation.getSituationHour(15); // Retorna 0, pois a situação 15 foi zerada.
568
+ * timeEvaluation.getSituationHour(16); // Retorna 0, pois a situação 16 foi zerada.
569
+ * ```
570
+ * @param startCode Código de situação inicial da faixa.
571
+ * @param endCode Código de situração final da faixa.
572
+ */
573
+ public resetSituationHourByRange(startCode: number, endCode: number): void {
574
+ for (let situationCode = startCode; situationCode <= endCode; situationCode++) {
575
+ this.setSituationHour(situationCode, 0);
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Retorna a soma das horas em minutos de uma faixa de situações. Retorna 0 se não encontrar situações com os códigos informados.
581
+ *
582
+ * @example
583
+ * ```typescript
584
+ * timeEvaluation.setSituationHour(15, 60); // Define 60 minutos na situação 15 (faltas).
585
+ * timeEvaluation.setSituationHour(16, 30); // Define 30 minutos na situação 16 (extras).
586
+ * timeEvaluation.getSituationHourByRange(15, 16); // Retorna 90, pois soma 60 minutos da situação 15 e 30 minutos da situação 16.
587
+ * ```
588
+ *
589
+ * @param startCode Código de situação inicial da faixa.
590
+ * @param endCode Código de situação final da faixa.
591
+ * @returns Soma das horas em minutos para as situações no intervalo da faixa.
592
+ */
593
+ public getSituationHourByRange(startCode: number, endCode: number): number {
594
+ const totalHours = 0;
595
+
596
+ if (startCode > endCode) {
597
+ throw new Error("startCode must be less than or equal to endCode");
598
+ }
599
+
600
+ const total = this.timeEvaluationSituations.filter(
601
+ (situation) => situation.situationCode >= startCode && situation.situationCode <= endCode
602
+ ).reduce((accumulator, situation) => {
603
+ return accumulator + situation.numberOfHours;
604
+ }, totalHours);
605
+
606
+ if (total > 0) {
607
+ return total;
608
+ }
609
+
610
+ return 0;
611
+ }
612
+
613
+ private findSituationByCode(situationCode: number): TimeEvaluationSituation | undefined {
614
+ return this._timeEvaluationSituations.find(
615
+ (timeEvaluationSituation) => timeEvaluationSituation.situationCode === situationCode
616
+ );
617
+ }
618
+
619
+ private createTimeEvaluationSituation(situationCode: number, numberOfHours: number): void {
620
+ const timeEvaluationSituation = new TimeEvaluationSituation({
621
+ numberOfHours,
622
+ situationCode,
623
+ situationId: ""
624
+ });
625
+ // Sujar o buffer
626
+ timeEvaluationSituation.numberOfHours = numberOfHours;
627
+ this._timeEvaluationSituations.push(timeEvaluationSituation);
628
+ }
629
+
630
+ /**
631
+ * Retorna a quantidade de horas em minutos de um tipo de intervalo com opção de considerar/desconsiderar a tolerância.
632
+ *
633
+ * @example
634
+ * ```typescript
635
+ * let separatedHours = timeEvaluation.getSeparateHours(IntervalTypes.ABSENCE, true); // Retorna as horas apuradas separadas em diurnas, noturnas e o total, do tipo de intervalo Falta, considerando tolerância.
636
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
637
+ * separatedHours.nightlyHours; // Retorna as horas noturnas em minutos.
638
+ * separatedHours.total; // Retorna o total de horas (diurnas + noturnas) em minutos.
639
+ * ```
640
+ *
641
+ * @param intervalType tipo do intervalo
642
+ * @param tolerance se deve aplicar as tolerâncias nos intervalos de faltas e extras
643
+ * @returns um objeto do tipo SeparatedHours que contém as horas diurnas e noturnas.
644
+ *
645
+ * @see {@link SeparatedHours}
646
+ * @see {@link IntervalTypes}
647
+ */
648
+ public getSeparateHours(intervalType: IntervalTypes, tolerance: boolean): SeparatedHours {
649
+ return this.handleEmptyIntervals(() => this.getHours(DateUtils.MIN_DATE, DateUtils.MAX_DATE, intervalType, tolerance));
650
+ }
651
+
652
+ /**
653
+ * Retorna a quantidade de horas diurnas e noturnas em minutos de uma parte do expediente.
654
+ * A divisão do expediente em partes acontece na hora final dos intervalos do tipo meal (refeição).
655
+ * ```
656
+ * Representação das partes do expediente
657
+ *
658
+ * |----------------------------------------expedient-----------------------------------------|
659
+ * |----------------------part(1)----------------------|---------------part(2)----------------|
660
+ * 08:00 10:00 10:15 12:00 13:30 16:30 16:45 18:00
661
+ * |------------|------------|------------|------------|------------|------------|------------|
662
+ * | work(1) | snack(1) | work(2) | meal(1) | work(3) | snack(2) | work(4) |
663
+ * ```
664
+ * @example
665
+ * ```typescript
666
+ * let separatedHours = timeEvaluation.getSeparateHoursWithExpedientPart(IntervalTypes.ABSENCE, 1, true);
667
+ * // Retorna as horas apuradas separadas em diurnas, noturnas e o total, do tipo de intervalo falta, e primeira parte do expediente, considerando tolerância
668
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
669
+ * ```
670
+ *
671
+ *
672
+ * @param intervalType tipo do intervalo.
673
+ * @param part Parte. Ex.: 1, 2... Refere-se a cada parte do expediente que é gerado pelos intervalos de refeição.
674
+ * @param tolerance Se deve aplicar as tolerâncias nos intervalos de faltas e extras.
675
+ * @return Objeto do tipo SeparatedHours que contém as horas diurnas e noturnas.
676
+ * @see {@link SeparatedHours}
677
+ * @see {@link IntervalTypes}
678
+ */
679
+ public getSeparateHoursWithExpedientPart(intervalType: IntervalTypes, part: number, tolerance: boolean): SeparatedHours {
680
+ return this.handleEmptyIntervals(() => this.getHoursWithExpedientPart(DateUtils.MIN_DATE, DateUtils.MAX_DATE, intervalType, part, tolerance));
681
+ }
682
+
683
+ /**
684
+ * Retorna a quantidade de horas diurnas e noturnas em minutos de um subtipo de intervalo.
685
+ * Referência no Controle de ponto: ApuDiu[], ApuNot[].
686
+ *
687
+ * @example
688
+ * ```typescript
689
+ * let separatedHours = timeEvaluation.getSeparateHoursIntervalSubType(IntervalSubTypes.DELAY, true); // Retorna as horas em minutos apuradas separadas em diurnas, noturnas e o total, do subtipo de intervalo atraso, considerando tolerância.
690
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
691
+ * ```
692
+ *
693
+ * @param intervalSubType Subtipo do intervalo.
694
+ * @param tolerance Se deve aplicar as tolerâncias nos intervalos de faltas e extras.
695
+ * @return Objeto do tipo SeparatedHours que contém as horas diurnas e noturnas.
696
+ *
697
+ * @see {@link SeparatedHours}
698
+ * @see {@link IntervalSubTypes}
699
+ *
700
+ */
701
+ public getSeparateHoursIntervalSubType(intervalSubType: IntervalSubTypes, tolerance: boolean): SeparatedHours {
702
+ return this.handleEmptyIntervals(() => this.getHoursIntervalSubType(DateUtils.MIN_DATE, DateUtils.MAX_DATE, intervalSubType, tolerance));
703
+ }
704
+
705
+ /**
706
+ * Retorna a quantidade de horas diurnas e noturnas em minutos de um subtipo de intervalo numa parte do expediente.
707
+ * A divisão do expediente em partes acontece na hora final dos intervalos do tipo meal (refeição).
708
+ * ```
709
+ * Representação das partes do expediente
710
+ *
711
+ * |----------------------------------------expedient-----------------------------------------|
712
+ * |----------------------part(1)----------------------|---------------part(2)----------------|
713
+ * 08:00 10:00 10:15 12:00 13:30 16:30 16:45 18:00
714
+ * |------------|------------|------------|------------|------------|------------|------------|
715
+ * | work(1) | snack(1) | work(2) | meal(1) | work(3) | snack(2) | work(4) |
716
+ * ```
717
+ * @example
718
+ * ```typescript
719
+ * let separatedHours = timeEvaluation.getSeparateHoursIntervalSubTypeWithExpedientPart(IntervalSubTypes.DELAY, 1, true); // Retorna as horas apuradas separadas em diurnas, noturnas e o total, do subtipo de intervalo atraso, e primeira parte do expediente, considerando tolerância.
720
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
721
+ * ```
722
+ *
723
+ * @param intervalSubType Subtipo do intervalo.
724
+ * @param part Parte. Ex.: 1, 2... Refere-se a cada parte do expediente que é gerado pelos intervalos de refeição.
725
+ * @param tolerance Se deve aplicar as tolerâncias nos intervalos de faltas e extras.
726
+ * @return Objeto do tipo SeparatedHours que contém as horas diurnas e noturnas.
727
+ *
728
+ * @see {@link SeparatedHours}
729
+ * @see {@link IntervalSubTypes}
730
+ */
731
+ public getSeparateHoursIntervalSubTypeWithExpedientPart(intervalSubType: IntervalSubTypes, part: number, tolerance: boolean): SeparatedHours {
732
+ return this.handleEmptyIntervals(() => this.getHoursIntervalSubTypeWithExpedientPart(DateUtils.MIN_DATE, DateUtils.MAX_DATE, intervalSubType, part, tolerance));
733
+ }
734
+
735
+ /**
736
+ * Retorna um determinado intervalo calculado na apuração pela sua posição.
737
+ * Referência no Controle de ponto: NumInt, MSaInD[], MSaInN[], MInExD[], MInExN[].
738
+ *
739
+ * - ATENÇÃO: Index é baseado em 1, ou seja, o primeiro intervalo calculado tem índice 1. Se o índice for inválido (0 ou valor maior que a quantidade de intervalos), o método retornará undefined.
740
+ * @example
741
+ * ```typescript
742
+ * Interval interval = getCalculatedIntervalByIndex(1); // Retorna o primeiro intervalo calculado.
743
+ * ```
744
+ *
745
+ * @param index Índice do intervalo calculado, o index inicia em 1.
746
+ * @return Um intervalo calculado, ou null se o índice for inválido.
747
+ *
748
+ * @see {@link Interval}
749
+ */
750
+ public getCalculatedIntervalByIndex(index: number): Interval | undefined {
751
+ const adjustedIndex = index - 1;
752
+ if (adjustedIndex >= 0 && adjustedIndex < this._intervals.length) {
753
+ return this._intervals[adjustedIndex];
754
+ }
755
+ return undefined;
756
+ }
757
+
758
+ /**
759
+ * Retorna um determinado intervalo calculado na apuração pelo seu tipo.
760
+ *
761
+ * @example
762
+ * ```typescript
763
+ * Interval[] intervals = getCalculatedIntervalByType(IntervalTypes.WORKING); // Retorna os intervalos do tipo WORKING.
764
+ * intervals.forEach(interval => {
765
+ * console.log(interval.clockingEventStart); // Exibe o horário inicial de cada intervalo.
766
+ * console.log(interval.clockingEventEnd); // Exibe o horário final de cada intervalo.
767
+ * });
768
+ * ```
769
+ *
770
+ * @param intervalType Tipo de intervalo.
771
+ * @return Um intervalo calculado na apuração pelo seu tipo.
772
+ * @see {@link IntervalTypes}
773
+ * @see {@link Interval}
774
+ *
775
+ */
776
+ public getCalculatedIntervalByType(intervalType: IntervalTypes): Interval[] {
777
+ return this._intervals.filter(interval => interval.type === intervalType);
778
+ }
779
+
780
+ /**
781
+ * Retorna uma lista de intervalos calculados na apuração de um subtipo de intervalo.
782
+ *
783
+ * @example
784
+ * ```typescript
785
+ * Interval[] intervals = getCalculatedIntervalBySubType(IntervalSubTypes.DELAY); // Retorna os intervalos do subtipo DELAY.
786
+ * intervals.forEach(interval => {
787
+ * console.log(interval.clockingEventStart); // Exibe o horário inicial de cada intervalo.
788
+ * console.log(interval.clockingEventEnd); // Exibe o horário final de cada intervalo.
789
+ * });
790
+ * ```
791
+ *
792
+ * @param intervalSubType Subtipo de intervalo.
793
+ * @return Um subtipo de intervalo.
794
+ *
795
+ * @see {@link IntervalSubTypes}
796
+ * @see {@link Interval}
797
+ */
798
+ public getCalculatedIntervalBySubType(intervalSubType: IntervalSubTypes): Interval[] {
799
+ return this._intervals.filter(interval => interval.subType === intervalSubType);
800
+ }
801
+
802
+ /**
803
+ * Retorna a quantidade de horas extras diurnas e noturnas em minutos dentro de um intervalo de tempo para o dia que está sendo calculado.
804
+ * Referência no Controle de ponto: ExtrasIntervalo.
805
+ *
806
+ * @example
807
+ * ```typescript
808
+ * SeparatedHours overtime = timeEvaluation.getOvertimeByRangeTime(360, 480); // Retorna as horas extras diurnas e noturnas em minutos entre 06:00 e 08:00 no dia atual.
809
+ * overtime.dailyHours; // Retorna as horas extras diurnas em minutos.
810
+ * overtime.nightlyHours; // Retorna as horas extras noturnas em minutos.
811
+ * overtime.total; // Retorna o total de horas extras (diurnas + noturnas) em minutos.
812
+ * ```
813
+ *
814
+ * @param startClocking Hora em minutos do início do intervalo.
815
+ * @param endClocking Hora em minutos do fim do intervalo.
816
+ * @return Objeto do tipo SeparatedHours que contém a quantidade de horas extras diurnas e noturnas em minutos dentro de um intervalo de tempo.
817
+ *
818
+ * @see {@link SeparatedHours}
819
+ * @see {@link IntervalTypes}
820
+ *
821
+ */
822
+ public getOvertimeByRangeTime(startClocking: number, endClocking: number): SeparatedHours {
823
+ const startClockingDate = DateUtils.addMinutes(this._date, startClocking);
824
+ const endClockingDate = DateUtils.addMinutes(this._date, endClocking);
825
+ return this.handleEmptyIntervals(() => this.getHours(startClockingDate, endClockingDate, IntervalTypes.OVERTIME, true));
826
+ }
827
+
828
+ /**
829
+ * Retorna uma lista com as marcações realizadas pelo colaborador que está sendo processado na data.
830
+ * Caso não tenham marcações no dia o método irá retornar uma lista vazia.
831
+ * Referência no Controle de ponto: QtdMar, FLeMar, FPxMar, DatMar, HorMar, FncMar, RlgMar, OriMar, ConGer.
832
+ *
833
+ * @example
834
+ * ```typescript
835
+ * ClockingEvent[] clockingEvents = timeEvaluation.getClockingEvents(true); // Retorna uma lista com as marcações realizadas pelo colaborador no dia apurado considerando as marcações geradas.
836
+ * clockingEvents.forEach(event => {
837
+ * console.log(event.clockingTime); // Exibe o horário de cada marcação.
838
+ * console.log(event.originType); // Exibe o tipo de origem da marcação.
839
+ * });
840
+ * ```
841
+ *
842
+ * @param isConsiderGenerated Indica se deve trazer as marcações geradas pelo sistema.
843
+ * @return Objetos do tipo ClockingEvent (marcações) realizadas pelo colaborador que está sendo processado na data.
844
+ *
845
+ * @see {@link ClockingEvent}
846
+ * @see {@link ClockingEventOriginType}
847
+ *
848
+ */
849
+ public getClockingEvents(isConsiderGenerated: boolean): ClockingEvent[] {
850
+ if (!this._clockingEvents?.length) {
851
+ return [];
852
+ }
853
+ if (isConsiderGenerated) {
854
+ return this._clockingEvents;
855
+ }
856
+ return this._clockingEvents.filter(
857
+ (clockingEvent) => clockingEvent.originType !== ClockingEventOriginType.GENERATED
858
+ );
859
+ }
860
+
861
+
862
+ /**
863
+ * Retorna a quantidade em minutos de horas separadas de um intervalo de tempo.
864
+ *
865
+ * @example
866
+ * ```typescript
867
+ * SeparatedHours separatedHours = timeEvaluation.getHours(new Date('2023-01-01T08:00:00'), new Date('2023-01-01T18:00:00'), IntervalTypes.ABSENCE, true); // Retorna as horas apuradas separadas em diurnas, noturnas e o total, do tipo de intervalo falta, considerando tolerância.
868
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
869
+ * separatedHours.nightlyHours; // Retorna as horas noturnas em minutos.
870
+ * separatedHours.total; // Retorna o total de horas (diurnas + noturnas) em minutos.
871
+ * ```
872
+ *
873
+ * @param startClocking Data de início.
874
+ * @param endClocking Data de fim.
875
+ * @param intervalType Tipo de intervalo.
876
+ * @param tolerance Considerar tolerância.
877
+ * @returns Horas separadas de um intervalo.
878
+ * @see {@link SeparatedHours}
879
+ * @see {@link IntervalTypes}
880
+ * @see {@link Interval}
881
+ *
882
+ */
883
+ private getHours(startClocking: Date, endClocking: Date, intervalType: IntervalTypes, tolerance: boolean): SeparatedHours {
884
+ const separatedHours = this.initializeSeparatedHours();
885
+
886
+ this.processIntervals(interval => {
887
+ const type = this.getIntervalType(interval, tolerance);
888
+ if (intervalType === type) {
889
+ separatedHours.sumSeparatedHours(this.calculateSeparateHours(startClocking, endClocking, interval));
890
+ }
891
+ });
892
+
893
+ return separatedHours;
894
+ }
895
+
896
+ /**
897
+ * Retorna a quantidade de horas separadas de um intervalo considerando o expediente e a parte do expediente.
898
+ * A divisão do expediente em partes acontece na hora final dos intervalos do tipo meal (refeição).
899
+ * ```
900
+ * Representação das partes do expediente
901
+ *
902
+ * |----------------------------------------expedient-----------------------------------------|
903
+ * |----------------------part(1)----------------------|---------------part(2)----------------|
904
+ * 08:00 10:00 10:15 12:00 13:30 16:30 16:45 18:00
905
+ * |------------|------------|------------|------------|------------|------------|------------|
906
+ * | work(1) | snack(1) | work(2) | meal(1) | work(3) | snack(2) | work(4) |
907
+ * ```
908
+ *
909
+ * @example
910
+ * ```typescript
911
+ * SeparatedHours separatedHours = timeEvaluation.getHoursWithExpedientPart(new Date('2023-01-01T08:00:00'), new Date('2023-01-01T18:00:00'), IntervalTypes.ABSENCE, 1, true); // Retorna em minutos as horas apuradas separadas em diurnas, noturnas e o total, do tipo de intervalo falta, considerando tolerância e a parte do expediente.
912
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
913
+ * separatedHours.nightlyHours; // Retorna as horas noturnas em minutos.
914
+ * separatedHours.total; // Retorna o total de horas (diurnas + noturnas) em minutos.
915
+ * ```
916
+ *
917
+ *
918
+ * @param startClocking Data de início.
919
+ * @param endClocking Data de fim.
920
+ * @param intervalType Tipo de intervalo.
921
+ * @param part Parte do expediente. Ex.: 1, 2...
922
+ * @param tolerance Considerar tolerância.
923
+ * @return Objeto do tipo SeparatedHours que contém as horas diurnas e noturnas.
924
+ * @see {@link SeparatedHours}
925
+ * @see {@link IntervalTypes}
926
+ * @see {@link Interval}
927
+ *
928
+ */
929
+ private getHoursWithExpedientPart(startClocking: Date, endClocking: Date, intervalType: IntervalTypes, part: number, tolerance: boolean): SeparatedHours {
930
+ const separatedHours = this.initializeSeparatedHours();
931
+
932
+ this.processIntervals(interval => {
933
+ const type = this.getIntervalType(interval, tolerance);
934
+ if (intervalType === type && interval.positionWorkingPart?.workingHours === 1 && interval.positionWorkingPart?.part === part) {
935
+ separatedHours.sumSeparatedHours(this.calculateSeparateHours(startClocking, endClocking, interval));
936
+ }
937
+ });
938
+
939
+ return separatedHours;
940
+ }
941
+
942
+ /**
943
+ * Retorna a quantidade de horas separadas de um subtipo de intervalo.
944
+ *
945
+ * @example
946
+ * ```typescript
947
+ * SeparatedHours separatedHours = timeEvaluation.getHoursIntervalSubType(new Date('2023-01-01T08:00:00'), new Date('2023-01-01T18:00:00'), IntervalSubTypes.DELAY, true); // Retorna em minutos as horas apuradas separadas em diurnas, noturnas e o total, do subtipo de intervalo atraso, considerando tolerância.
948
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
949
+ * separatedHours.nightlyHours; // Retorna as horas noturnas em minutos.
950
+ * separatedHours.total; // Retorna o total de horas (diurnas + noturnas) em minutos.
951
+ * ```
952
+ *
953
+ * @param startClocking Data de início.
954
+ * @param endClocking Data de fim.
955
+ * @param intervalSubType Subtipo de intervalo.
956
+ * @param tolerance Considerar tolerância.
957
+ * @return Objeto do tipo SeparatedHours que contém as horas diurnas e noturnas.
958
+ * @see {@link SeparatedHours}
959
+ * @see {@link IntervalSubTypes}
960
+ * @see {@link Interval}
961
+ *
962
+ */
963
+ private getHoursIntervalSubType(startClocking: Date, endClocking: Date, intervalSubType: IntervalSubTypes, tolerance: boolean): SeparatedHours {
964
+ const separatedHours = this.initializeSeparatedHours();
965
+
966
+ this.processIntervals(interval => {
967
+ const type = this.getIntervalSubType(interval, tolerance);
968
+ if (intervalSubType === type) {
969
+ separatedHours.sumSeparatedHours(this.calculateSeparateHours(startClocking, endClocking, interval));
970
+ }
971
+ });
972
+
973
+ return separatedHours;
974
+ }
975
+
976
+ /**
977
+ * Retorna em minutos a quantidade de horas separadas de um subtipo de intervalo considerando o a parte do expediente.
978
+ *
979
+ * @example
980
+ * ```typescript
981
+ * SeparatedHours separatedHours = timeEvaluation.getHoursIntervalSubTypeWithExpedientPart(new Date('2023-01-01T08:00:00'), new Date('2023-01-01T18:00:00'), IntervalSubTypes.DELAY, 1, true); // Retorna em minutos as horas apuradas separadas em diurnas, noturnas e o total, do subtipo de intervalo atraso, considerando tolerância e a parte do expediente.
982
+ * separatedHours.dailyHours; // Retorna as horas diurnas em minutos.
983
+ * separatedHours.nightlyHours; // Retorna as horas noturnas em minutos.
984
+ * separatedHours.total; // Retorna o total de horas (diurnas + noturnas) em minutos.
985
+ * ```
986
+ *
987
+ * @param startClocking Data de início.
988
+ * @param endClocking Data de fim.
989
+ * @param intervalSubType Subtipo de intervalo.
990
+ * @param part Parte do expediente. Ex.: 1, 2...
991
+ * @param tolerance Considerar tolerância.
992
+ * @return Objeto do tipo SeparatedHours que contém as horas diurnas e noturnas.
993
+ * @see {@link SeparatedHours}
994
+ * @see {@link IntervalSubTypes}
995
+ * @see {@link Interval}
996
+ *
997
+ */
998
+ private getHoursIntervalSubTypeWithExpedientPart(startClocking: Date, endClocking: Date, intervalSubType: IntervalSubTypes, part: number, tolerance: boolean): SeparatedHours {
999
+ const separatedHours = this.initializeSeparatedHours();
1000
+
1001
+ this.processIntervals(interval => {
1002
+ const type = this.getIntervalSubType(interval, tolerance);
1003
+ if (intervalSubType === type && interval.positionWorkingPart?.workingHours === 1 && interval.positionWorkingPart?.part === part) {
1004
+ separatedHours.sumSeparatedHours(this.calculateSeparateHours(startClocking, endClocking, interval));
1005
+ }
1006
+ });
1007
+
1008
+ return separatedHours;
1009
+ }
1010
+
1011
+ private getIntervalType(interval: Interval, tolerance: boolean): IntervalTypes {
1012
+ if (interval.isTolerancePeriod && !tolerance) {
1013
+ return interval.typeIntervalTolerance;
1014
+ }
1015
+ return interval.type;
1016
+ }
1017
+
1018
+ private getIntervalSubType(interval: Interval, tolerance: boolean): IntervalSubTypes {
1019
+ if (interval.isTolerancePeriod && !tolerance) {
1020
+ return interval.subTypeIntervalTolerance;
1021
+ }
1022
+ return interval.subType;
1023
+ }
1024
+
1025
+ private initializeSeparatedHours(): SeparatedHours {
1026
+ return new SeparatedHours({ dailyHours: 0, nightlyHours: 0 });
1027
+ }
1028
+
1029
+ private handleEmptyIntervals<T>(callback: () => T): T {
1030
+ if (!this.intervals?.length) {
1031
+ return this.initializeSeparatedHours() as T;
1032
+ }
1033
+ return callback();
1034
+ }
1035
+
1036
+ private processIntervals(callback: (interval: Interval) => void): void {
1037
+ if (Array.isArray(this.intervals)) {
1038
+ for (const interval of this.intervals) {
1039
+ callback(interval);
1040
+ }
1041
+ }
1042
+ }
1043
+
1044
+ private calculateSeparateHours(startClocking: Date, endClocking: Date, interval: Interval): SeparatedHours {
1045
+ const separedHours = new SeparatedHours({ dailyHours: 0, nightlyHours: 0 });
1046
+
1047
+ if (DateUtils.isBeforeOrEquals(startClocking, interval.clockingEventStart) && DateUtils.isAfterOrEquals(endClocking, interval.clockingEventEnd)) {
1048
+ this.sumCompleteInterval(interval, separedHours);
1049
+ } else if (DateUtils.between(startClocking, interval.clockingEventStart, interval.clockingEventEnd) ||
1050
+ DateUtils.between(endClocking, interval.clockingEventStart, interval.clockingEventEnd)) {
1051
+ this.sumBetweenClocking(interval, endClocking, startClocking, separedHours);
1052
+ }
1053
+
1054
+ return separedHours;
1055
+ }
1056
+
1057
+ private sumCompleteInterval(interval: Interval, separedHours: SeparatedHours) {
1058
+ if (!interval.isNightly) {
1059
+ separedHours.sumDailyHours(interval.getIntervalInMinutes());
1060
+ } else {
1061
+ separedHours.sumNightlyHours(interval.getIntervalInMinutes());
1062
+ }
1063
+ }
1064
+
1065
+ private sumBetweenClocking(interval: Interval, endClocking: Date, startClocking: Date, separedHours: SeparatedHours) {
1066
+ const menorFim = DateUtils.isBefore(interval.clockingEventEnd, endClocking) ? interval.clockingEventEnd : endClocking;
1067
+ const maiorInicio = DateUtils.isAfter(interval.clockingEventStart, startClocking) ? interval.clockingEventStart : startClocking;
1068
+ if (!interval.isNightly) {
1069
+ separedHours.sumDailyHours(DateUtils.getDateInMinutes(menorFim, maiorInicio));
1070
+ } else {
1071
+ separedHours.sumNightlyHours(DateUtils.getDateInMinutes(menorFim, maiorInicio));
1072
+ }
1073
+ }
1074
+
1075
+ /**
1076
+ * Invalida uma apuração. A apuração invalidada não será considerada no cálculo.
1077
+ * A apuração não será alterada.
1078
+ *
1079
+ * @example
1080
+ * ```typescript
1081
+ * timeEvaluation.invalidate("Erro na apuração, dados inconsistentes");
1082
+ * ```
1083
+ *
1084
+ * @param message Motivo.
1085
+ */
1086
+ public invalidate(message: string) {
1087
+ this._errorMessage = message
1088
+ }
1089
+
1090
+ /**
1091
+ * Recupera a mensagem de erro de um dia invalidado.
1092
+ *
1093
+ * @example
1094
+ * ```typescript
1095
+ * if (timeEvaluation.errorMessage) {
1096
+ * console.error(timeEvaluation.errorMessage);
1097
+ * }
1098
+ * ```
1099
+ */
1100
+ get errorMessage(): string {
1101
+ return this._errorMessage;
1102
+ }
1103
+
1104
+ /**
1105
+ * Busca a ponte que corresponde a data de apuração, caso tenha ponte para a data de apuração, seja a data de origem ou a de destino.
1106
+ *
1107
+ * @example
1108
+ * ```typescript
1109
+ * const bridge = timeEvaluation.bridge;
1110
+ * if (bridge) {
1111
+ * console.log(`Ponte encontrada na data ${timeEvaluation.date}: origem: ${bridge.originDate}`);
1112
+ * } else {
1113
+ * console.log(`Não foi encontrado ponte na data ${timeEvaluation.date}`);
1114
+ * }
1115
+ * ```
1116
+ *
1117
+ * @return A ponte que corresponde ao critério ou undefined se não encontrar.
1118
+ *
1119
+ * @see {@link Bridge}
1120
+ */
1121
+ get bridge(): Bridge | undefined {
1122
+ return this._schedules.findBridgeByDate(this._date);
1123
+ }
1124
+
1125
+ /**
1126
+ * Busca a programação de autorização de horas extras para o dia apurado.
1127
+ * Caso não exista uma programação de autorização de horas extras para o dia, retorna uma lista vazia.
1128
+ *
1129
+ * @example
1130
+ * ```typescript
1131
+ * const overtimeAuthorizations = timeEvaluation.overtimeAuthorizations;
1132
+ * if (overtimeAuthorizations.length > 0) {
1133
+ * console.log(`Autorização de hora extra encontrada na data${timeEvaluation.date}: ${overtimeAuthorizations.length}`);
1134
+ * } else {
1135
+ * console.log(`Não foi encontrado autorização de hora extra na data ${timeEvaluation.date}`);
1136
+ * }
1137
+ * ```
1138
+ *
1139
+ * @return A programação de autorização de horas extras ou uma lista vazia se não encontrar.
1140
+ *
1141
+ * @see {@link OvertimeAuthorization}
1142
+ */
1143
+ get overtimeAuthorizations(): OvertimeAuthorization[] {
1144
+ return this._schedules.findOvertimeAuthorizationByDate(this._date);
1145
+ }
1146
+
1147
+ /**
1148
+ * Retorna a troca de escala do colaborador no dia apurado.
1149
+ * Caso não exista uma troca de escala para o dia, retorna undefined.
1150
+ *
1151
+ * @example
1152
+ * ```typescript
1153
+ * const workshiftChange = timeEvaluation.workshiftChange;
1154
+ * if (workshiftChange) {
1155
+ * console.log(`Troca de escala encontrada na data ${timeEvaluation.date}: ${workshiftChange.companyBranch.code}`);
1156
+ * } else {
1157
+ * console.log(`Não foi encontrada troca de escala na data ${timeEvaluation.date}`);
1158
+ * }
1159
+ * ```
1160
+ *
1161
+ * @returns A troca de escala ou undefined se não encontrar.
1162
+ *
1163
+ * @see {@link WorkshiftChange}
1164
+ */
1165
+ get workshiftChange(): WorkshiftChange | undefined {
1166
+ return this._schedules.findWorkshiftChangeByDate(this._date);
1167
+ }
1168
+
1169
+ /**
1170
+ * Retorna uma ou mais programações de sobreaviso do colaborador no dia apurado.
1171
+ *
1172
+ * @example
1173
+ * ```typescript
1174
+ * const readinesses = timeEvaluation.readinesses;
1175
+ * if (readinesses.length > 0) {
1176
+ * console.log(`Programação de sobreaviso encontrado na data ${timeEvaluation.date}: ${readinesses.length}`);
1177
+ * } else {
1178
+ * console.log(`Não foi encontrado programação de sobreaviso na data ${timeEvaluation.date}`);
1179
+ * }
1180
+ * ```
1181
+ * @returns A programação de sobreaviso ou undefined se não encontrar.
1182
+ *
1183
+ * @see {@link Readiness}
1184
+ */
1185
+ get readinesses(): Readiness[] {
1186
+ return this._schedules.findReadinessByDate(this._date);
1187
+ }
1188
+
1189
+ /**
1190
+ * Retorna uma ou mais compensações de horas do colaborador no dia apurado.
1191
+ * Caso não exista uma compensação de horas para o dia, retorna uma lista vazia.
1192
+ * @example
1193
+ * ```typescript
1194
+ * const compensations = timeEvaluation.compensations;
1195
+ * if (compensations.length > 0) {
1196
+ * console.log(`Compensação de horas encontrada na data ${timeEvaluation.date}: ${compensations.length}`);
1197
+ * } else {
1198
+ * console.log(`Não foi encontrado compensação de horas na data ${timeEvaluation.date}`);
1199
+ * }
1200
+ * ```
1201
+ *
1202
+ * @returns A lista de compensações de horas ou uma lista vazia se não encontrar.
1203
+ *
1204
+ * @see {@link Compensation}
1205
+ */
1206
+ get compensations(): Compensation[] {
1207
+ return this._schedules.findCompensationByDate(this._date);
1208
+ }
1209
+
1210
+ /**
1211
+ * Retorna o histórico de cargo da apuração.
1212
+ *
1213
+ * @example
1214
+ * ```typescript
1215
+ * const jobPositionHistory = timeEvaluation.jobPositionHistory;
1216
+ * console.log(`Histórico de cargo encontrado na data ${timeEvaluation.date}: ${jobPositionHistory.jobPosition}`);
1217
+ * ```
1218
+ *
1219
+ * @returns Histórico de cargo.
1220
+ *
1221
+ * @see {@link JobPositionHistory}
1222
+ */
1223
+ get jobPositionHistory(): JobPositionHistory {
1224
+ const jobPositionHistory = this._histories.findJobPositionByDate(this._date);
1225
+
1226
+ if (!jobPositionHistory) {
1227
+ throw new Error(`Job position history for date ${this._date} not found`);
1228
+ }
1229
+
1230
+ return jobPositionHistory;
1231
+ }
1232
+
1233
+ /**
1234
+ * Retorna o histórico de filial da apuração.
1235
+ *
1236
+ * @example
1237
+ * ```typescript
1238
+ * const companyBranchHistory = timeEvaluation.companyBranchHistory;
1239
+ * console.log(`Histórico de filial encontrado na data ${timeEvaluation.date}: ${companyBranchHistory.companyBranch}`);
1240
+ * ```
1241
+ *
1242
+ * @returns Histórico de filial.
1243
+ * @see {@link CompanyBranchHistory}
1244
+ */
1245
+ get companyBranchHistory(): CompanyBranchHistory {
1246
+ const companyBrach = this._histories.findCompanyBranchByDate(this._date);
1247
+ if (!companyBrach) {
1248
+ throw new Error(`Company branch history for date ${this._date} not found`);
1249
+ }
1250
+
1251
+ return companyBrach;
1252
+ }
1253
+
1254
+ /**
1255
+ * Retorna o histórico de apuração no dia apurado. Neste histórico é retornado a definição de situação, que também é em
1256
+ * formato de histórico, ou seja, um histórico de apuração pode ter uma lista de históricos de definição de situação.
1257
+ * Caso desejar retornar a definição de situação vigente na data utilizar diretamente o timeEvaluation.situationDefinition.
1258
+ *
1259
+ * @example
1260
+ * ```typescript
1261
+ * const timeEvaluationHistory = timeEvaluation.timeEvaluationHistory;
1262
+ * console.log(`Histórico de apuração encontrado na data ${timeEvaluation.date}: ${timeEvaluationHistory.startDate}`);
1263
+ * ```
1264
+ * @returns Histórico de apuração
1265
+ */
1266
+ get timeEvaluationHistory(): TimeEvaluationHistory {
1267
+ const timeEvaluationHistory = this._histories.findTimeEvaluationHistoryByDate(this._date);
1268
+
1269
+ if (!timeEvaluationHistory) {
1270
+ throw new Error(`Time evaluation history for date ${this._date} not found`);
1271
+ }
1272
+
1273
+ return timeEvaluationHistory;
1274
+ }
1275
+
1276
+ /**
1277
+ * Retorna o histórico de escala de trabalho do colaborador no dia apurado.
1278
+ *
1279
+ * @example
1280
+ * ```typescript
1281
+ * const workshiftHistory = timeEvaluation.workshiftHistory;
1282
+ * console.log(`Histórico de escala encontrado na data ${timeEvaluation.date}: ${workshiftHistory.workshift}`);
1283
+ * ```
1284
+ * @returns Histórico de escala de trabalho.
1285
+ * @see {@link WorkshiftHistory}
1286
+ */
1287
+ get workshiftHistory(): WorkshiftHistory {
1288
+ const workshiftHistory = this._histories.findWorkshiftHistoryByDate(this._date);
1289
+ if (!workshiftHistory) {
1290
+ throw new Error(`Workshift history for date ${this._date} not found`);
1291
+ }
1292
+ return workshiftHistory;
1293
+ }
1294
+
1295
+ /**
1296
+ * Retorna as contas de banco de horas válidas para a data de apuração.
1297
+ * Verifica se a data de apuração está entre creationDate e extinctionDate da conta.
1298
+ * Retorna vazio caso o colaborador não tenha contas de banco de horas ou se as contas não estiverem ativas na data de apuração.
1299
+ *
1300
+ * @example
1301
+ * ```typescript
1302
+ * const hourBankAccounts = timeEvaluation.hourBankAccounts;
1303
+ * if (hourBankAccounts.length > 0) {
1304
+ * console.log(`Contas de banco de horas encontradas na data ${timeEvaluation.date}: ${hourBankAccounts.length}`);
1305
+ * } else {
1306
+ * console.log(`Não foi encontrado contas de banco de horas na data ${timeEvaluation.date}`);
1307
+ * }
1308
+ * ```
1309
+ *
1310
+ * @returns A conta de banco de horas válida ou undefined se não encontrar.
1311
+ * @see {@link HourBankAccount}
1312
+ */
1313
+ get hourBankAccounts(): HourBankAccount[] {
1314
+ if (this._hourBankAccounts == null || this._hourBankAccounts.length === 0) {
1315
+ return [];
1316
+ }
1317
+
1318
+ return this._hourBankAccounts.filter((account) => {
1319
+ return DateUtils.isAfterOrEquals(this._date, account.creationDate) &&
1320
+ (account.extinctionDate === null || DateUtils.isBeforeOrEquals(this._date, account.extinctionDate));
1321
+ });
1322
+ }
1323
+
1324
+ /**
1325
+ * Retorna a definição de situação de apuração de ponto vigente na data de apuração.
1326
+ *
1327
+ * @example
1328
+ * ```typescript
1329
+ * const situationDefinition = timeEvaluation.situationDefinition;
1330
+ * console.log(`Definição de situação encontrado na data ${timeEvaluation.date}: ${situationDefinition.workSituation.code}`);
1331
+ * ```
1332
+ *
1333
+ * @returns A definição de situação de apuração de ponto.
1334
+ * @see {@link TimeEvaluationSituationDefinitionHistory}
1335
+ */
1336
+ get situationDefinition(): TimeEvaluationSituationDefinitionHistory {
1337
+ const situationDefinition = ContextReference.getGlobalInstance().getTimeEvaluationSituationDefinitionHistory(this._situationDefinitionKey);
1338
+ if (!situationDefinition) {
1339
+ throw new Error(`Time evaluation situation definition with key ${this._situationDefinitionKey} not found`);
1340
+ }
1341
+ return situationDefinition;
1342
+ }
1343
+
1344
+ /**
1345
+ * @hidden
1346
+ * Retorna a chave da definição de situação de apuração de ponto vigente na data de apuração.
1347
+ *
1348
+ * @example
1349
+ * ```typescript
1350
+ * const situationDefinitionKey = timeEvaluation.situationDefinitionKey;
1351
+ * console.log(`Situation definition key for date ${timeEvaluation.date}: ${situationDefinitionKey}`);
1352
+ * ```
1353
+ *
1354
+ * @returns A chave da definição de situação de apuração de ponto.
1355
+ */
1356
+ private get situationDefinitionKey(): string {
1357
+ return this._situationDefinitionKey;
1358
+ }
1359
+
1360
+ /**
1361
+ * Retorna o histórico de vínculo da apuração.
1362
+ *
1363
+ * @example
1364
+ * ```typescript
1365
+ * const employmentRelationshipHistory = timeEvaluation.employmentRelationshipHistory;
1366
+ * console.log(`Histórico de vínculo encontrado na data ${timeEvaluation.date}: ${employmentRelationshipHistory}`);
1367
+ * ```
1368
+ *
1369
+ * @returns Histórico de vínculo.
1370
+ */
1371
+ get employmentRelationshipHistory(): EmploymentRelationshipHistory {
1372
+ const employmentRelationshipHistory = this._histories.findEmploymentRelationshipByDate(this._date);
1373
+ if (!employmentRelationshipHistory) {
1374
+ throw new Error(`Employment relationship not found for date: ${this._date}`);
1375
+ }
1376
+ return employmentRelationshipHistory;
1377
+ }
1378
+
1379
+ /**
1380
+ * Retorna o feriado do dia apurado.
1381
+ * Se não encontrar o feriado, retorna undefined.
1382
+ *
1383
+ * @example
1384
+ * ```typescript
1385
+ * const holiday = timeEvaluation.holiday;
1386
+ * if (holiday) {
1387
+ * console.log(`Feriado encontrado na data ${timeEvaluation.date}: ${holiday.date}`);
1388
+ * }
1389
+ * ```
1390
+ *
1391
+ * @returns Feriado.
1392
+ */
1393
+ get holiday(): Holiday | undefined {
1394
+ return this._holiday;
1395
+ }
1396
+
1397
+ /**
1398
+ * Permite modificar o indicador para gerar pendência no dia apurado.
1399
+ *
1400
+ * generatePendingAdjustment = true: gera pendência de acerto no dia caso não exista.
1401
+ * Caso já exista uma pendência, mantém o seu status como está;
1402
+ *
1403
+ * generatePendingAdjustment = false: não gera pendência de acerto no dia.
1404
+ * Caso já exista uma pendência de acerto no dia e seu o status é:
1405
+ * - com gestor -> mantém com o gestor;
1406
+ * - com colaborador -> muda para o gestor;
1407
+ * - tratada -> mantém tratada;
1408
+ * - expirada -> mantém expirada.
1409
+ *
1410
+ * Caso este parâmetro não seja definido, vai seguir o padrão do sistema.
1411
+ *
1412
+ * @example
1413
+ * ```typescript
1414
+ * timeEvaluation.generatePendingAdjustment = true; // Gera pendência de acerto no dia apurado.
1415
+ * timeEvaluation.generatePendingAdjustment = false; // Não gera pendência de acerto no dia apurado.
1416
+ * ```
1417
+ *
1418
+ * @param value Valor booleano para definir se deve gerar pendência de acerto no dia apurado.
1419
+ */
1420
+ set generatePendingAdjustment(value: boolean) {
1421
+ this._generatePendingAdjustment = value;
1422
+ }
1423
+
1424
+ /**
1425
+ * Indica se deve gerar pendência no dia.
1426
+ * A Rotina de geração de pendência de acerto deve ser executada após a apuração do dia.
1427
+ * O valor retornado será undefined se não tiver sido definido, caso for definido o valor será true ou false conforme configurado na regra.
1428
+ * @example
1429
+ * ```typescript
1430
+ * const shouldGeneratePending = timeEvaluation.generatePendingAdjustment;
1431
+ *
1432
+ * if(shouldGeneratePending === undefined) {
1433
+ * console.log("A geração de pendência não foi definida, seguindo o padrão do sistema.");
1434
+ * } else if (shouldGeneratePending) {
1435
+ * console.log("Geração de pendência foi alterada na customização e será gerada uma pendência de acerto no dia.");
1436
+ * } else {
1437
+ * console.log("Não será gerada uma pendência de acerto no dia.");
1438
+ * }
1439
+ * ```
1440
+ */
1441
+ get generatePendingAdjustment(): boolean | undefined {
1442
+ return this._generatePendingAdjustment;
1443
+ }
1444
+
1445
+ /**
1446
+ * Indica se o dia de apuração não possui alguma das marcações de ponto obrigatórias.
1447
+ * Isso pode ocorrer quando o colaborador não registrou ponto no dia ou quando o sistema não conseguiu registrar as marcações.
1448
+ * Observações:
1449
+ *
1450
+ * 1) Horarios do tipo flexíveis vão sempre retornar false.
1451
+ *
1452
+ * 2) Colaborador em afastamento de férias vai sempre retornar false.
1453
+ *
1454
+ * 3) Somente as marcações obrigatórias são consideradas para essa verificação.
1455
+ *
1456
+ * Nos horários com marcações não obrigatórias, as marcação não obrigatórias são ignoradas. O sistema aloca as marcações para se encaixar o mais próximo possível do esperado.
1457
+ * Cenários:
1458
+ *
1459
+ * Horário: 08:00 12:00 13:00 15:30 16:00 18:00, onde as marcações da 15:30 e 16:00 são opcionais.
1460
+ * Se o colaborador registrar marcações as 08:00, 12:00, 13:00 e 16:00, o sistema vai retornar que esta faltando marcação, porque considera que a das 16 horas é uma marcação não obrigatória.
1461
+ *
1462
+ * @example
1463
+ * ```typescript
1464
+ * if (timeEvaluation.missingClockingEvent) {
1465
+ * console.log("O dia de apuração não possui todas as marcações de ponto.");
1466
+ * } else {
1467
+ * console.log("O dia de apuração possui marcações de ponto.");
1468
+ * }
1469
+ * ```
1470
+ */
1471
+ get missingClockingEvent(): boolean {
1472
+ return this._missingClockingEvent;
1473
+ }
1474
+
1475
+ /**
1476
+ * Retorna o histórico de afastamento do colaborador utilizado no dia apurado.
1477
+ * Caso não encontre o histórico de afastamento, retorna uma lista vazia.
1478
+ * Existem casos que o afastamento é criado mas não aplicado no dia apurado, como por exemplo:
1479
+ * - Afastamentos em DSR (não são aplicados).
1480
+ *
1481
+ * @example
1482
+ * ```typescript
1483
+ * const leaveHistories = timeEvaluation.leaveHistories;
1484
+ * if (leaveHistories.length > 0) {
1485
+ * console.log(`Históricos de afastamento encontrados na apuração do dia ${timeEvaluation.date}, quantidade: ${leaveHistories.length}`);
1486
+ * } else {
1487
+ * console.log(`Não foram encontrados históricos de afastamento para a apuração do dia ${timeEvaluation.date}`);
1488
+ * }
1489
+ * ```
1490
+ *
1491
+ * @returns Lista de afastamentos do colaborador no dia apurado.
1492
+ * @see {@link LeaveHistory}
1493
+ */
1494
+ get leaveHistories(): LeaveHistory[] {
1495
+ return this._histories.findLeaveHistoryByTimeEvaluationDate(this._date);
1496
+ }
1497
+
1498
+ /**
1499
+ * Retorna a programação de troca de horário vigente na data de apuração.
1500
+ * @example
1501
+ * ```typescript
1502
+ * const workscheduleChange = timeEvaluation.workscheduleChange;
1503
+ * if (workscheduleChange) {
1504
+ * console.log(`Troca de horário encontrada na data ${timeEvaluation.date}: ${workscheduleChange.workschedule.code}`);
1505
+ * }
1506
+ * ```
1507
+ *
1508
+ * @returns A programação de troca de horário ou undefined se não encontrar.
1509
+ * @see {@link WorkscheduleChange}
1510
+ */
1511
+ get workscheduleChange(): WorkscheduleChange | undefined {
1512
+ return this._schedules.findWorkscheduleChangeByDate(this._date);
1513
+ }
1514
+
1515
+
1516
+ public static clone(timeEvaluation: TimeEvaluation, contract: Contract
1517
+ ): TimeEvaluation {
1518
+ const timeEvaluationParams: TimeEvaluationParams = {
1519
+ date: timeEvaluation.date,
1520
+ missingClockingEvent: timeEvaluation.missingClockingEvent,
1521
+ workscheduleId: timeEvaluation.workscheduleId,
1522
+ workscheduleWorkshiftId: timeEvaluation.workscheduleWorkshiftId,
1523
+ workshiftId: timeEvaluation.workshiftId,
1524
+ timeEvaluationSituations: timeEvaluation.timeEvaluationSituations,
1525
+ clockingEvents: timeEvaluation.clockingEvents,
1526
+ intervals: timeEvaluation.intervals,
1527
+ schedules: contract.schedules,
1528
+ histories: contract.histories,
1529
+ hourBankAccounts: contract.hourBankAccounts,
1530
+ situationDefinitionKey: timeEvaluation.situationDefinitionKey,
1531
+ estimatedHours: timeEvaluation.estimatedHours,
1532
+ syndicateKey: timeEvaluation._syndicateKey,
1533
+ holiday: contract.getHolidayByDate(ObjectUtils.toDateOrThrow(timeEvaluation.date, "timeEvaluation.date")),
1534
+ costCenterKey: timeEvaluation.costCenterKey,
1535
+ };
1536
+
1537
+ return new TimeEvaluation(timeEvaluationParams);
1538
+ }
1539
+
1540
+ }