@senior-gestao-empresarial/angular-components 8.1.0 → 8.1.1

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.
@@ -8,6 +8,36 @@ import { MessageService } from 'primeng/api';
8
8
  import { TranslateService } from '@ngx-translate/core';
9
9
  import { HttpInterceptorModule } from '@seniorsistemas/platform-components';
10
10
 
11
+ /** Formato de data esperado pela consulta */
12
+ const QUERY_DATE_FORMAT = 'YYYY-MM-DD';
13
+ /**
14
+ * Equivalente em moment de cada token do dialeto legado (PrimeNG) usado por
15
+ * `calendarLocaleOptions.dateFormat` — é o mesmo dialeto que
16
+ * `convertToMomentDateFormat` (`@seniorsistemas/angular-components/table`)
17
+ * converte para formatar colunas de data na grid a partir dessa propriedade.
18
+ */
19
+ const LEGACY_CALENDAR_DATE_TOKENS = {
20
+ dd: 'DD',
21
+ d: 'D',
22
+ mm: 'MM',
23
+ m: 'M',
24
+ yy: 'YYYY',
25
+ y: 'YY',
26
+ };
27
+ /**
28
+ * Equivalente em moment de cada token do dialeto nativo do `s-datepicker`,
29
+ * usado pela propriedade `dateFormat` (a que o `CalendarFieldComponent`
30
+ * repassa direto ao `s-datepicker`). Aqui `yy` é ano com 2 dígitos — ao
31
+ * contrário do dialeto do PrimeNG, onde `yy` tem 4 dígitos.
32
+ */
33
+ const DATEPICKER_DATE_TOKENS = {
34
+ yyyy: 'YYYY',
35
+ yy: 'YY',
36
+ MM: 'MM',
37
+ mm: 'MM',
38
+ dd: 'DD',
39
+ d: 'D',
40
+ };
11
41
  /** Filter System Query Option - Operators supported in the expression language */
12
42
  var EnumLogicalOperator;
13
43
  (function (EnumLogicalOperator) {
@@ -174,6 +204,9 @@ class ErpLookups {
174
204
  }
175
205
  return `(${field.name} eq '${sanitizedValue}')`;
176
206
  }
207
+ if (field.type === 'date') {
208
+ return this.mountDateFilter(field, value);
209
+ }
177
210
  return `(${field.name} eq '${value}')`;
178
211
  })
179
212
  .filter((filter) => !!filter)
@@ -181,25 +214,39 @@ class ErpLookups {
181
214
  }
182
215
  else {
183
216
  filterQuery = lookupFields
184
- .filter((field) => field.type === 'string')
185
217
  .map((field) => {
186
- return `(containing(lower(${field.name}), lower('${value.replace(/\\/g, '').replace(/'/g, "\\'")}')))`;
218
+ if (field.type === 'string') {
219
+ return `(containing(lower(${field.name}), lower('${value.replace(/\\/g, '').replace(/'/g, "\\'")}')))`;
220
+ }
221
+ if (field.type === 'date') {
222
+ return this.mountDateFilter(field, value);
223
+ }
224
+ return null;
187
225
  })
226
+ .filter((filter) => !!filter)
188
227
  .join(' or ');
189
228
  }
190
229
  const defaultFilterQuery = this.mountDefaultFilter(defaultFilter);
230
+ /**
231
+ * Sem nenhum campo consultável para o texto digitado o filtro do texto
232
+ * é omitido: um grupo vazio (`()`) é rejeitado pelo backend com 500.
233
+ */
191
234
  if (defaultFilterQuery) {
192
- filterQuery = `((${defaultFilterQuery}) and (${filterQuery}))`;
235
+ filterQuery = filterQuery
236
+ ? `((${defaultFilterQuery}) and (${filterQuery}))`
237
+ : `(${defaultFilterQuery})`;
193
238
  }
194
239
  else {
195
- filterQuery = '(' + filterQuery + ')';
240
+ filterQuery = filterQuery ? '(' + filterQuery + ')' : '';
196
241
  }
197
242
  const dynamicFilterQuery = this.mountDynamicFilter(dynamicFilter);
198
243
  if (dynamicFilterQuery) {
199
- filterQuery = `((${dynamicFilterQuery}) and (${filterQuery}))`;
244
+ filterQuery = filterQuery
245
+ ? `((${dynamicFilterQuery}) and (${filterQuery}))`
246
+ : `(${dynamicFilterQuery})`;
200
247
  }
201
248
  else {
202
- filterQuery = '(' + filterQuery + ')';
249
+ filterQuery = filterQuery ? '(' + filterQuery + ')' : '';
203
250
  }
204
251
  return filterQuery;
205
252
  }
@@ -445,6 +492,82 @@ class ErpLookups {
445
492
  })
446
493
  .join(' - ');
447
494
  }
495
+ /**
496
+ * Filtro de um campo de data a partir do texto digitado no autocomplete.
497
+ *
498
+ * Campo de data não aceita `containing`, então o texto só vira filtro
499
+ * quando é uma data válida no formato do próprio campo: `view: 'month'`
500
+ * lê mês/ano e consulta o mês inteiro; nos demais casos lê a data
501
+ * completa e consulta o dia. Texto que não é data devolve `null` e o
502
+ * campo fica de fora do filtro.
503
+ */
504
+ mountDateFilter(field, value) {
505
+ const isMonthView = field.view === 'month';
506
+ const parsedValue = moment(value, this.dateFilterFormats(field, isMonthView), true);
507
+ if (!parsedValue.isValid()) {
508
+ return null;
509
+ }
510
+ if (isMonthView) {
511
+ const firstDay = parsedValue
512
+ .clone()
513
+ .startOf('month')
514
+ .format(QUERY_DATE_FORMAT);
515
+ const lastDay = parsedValue
516
+ .clone()
517
+ .endOf('month')
518
+ .format(QUERY_DATE_FORMAT);
519
+ return `(${field.name} ge '${firstDay}' and ${field.name} le '${lastDay}')`;
520
+ }
521
+ return `(${field.name} eq '${parsedValue.format(QUERY_DATE_FORMAT)}')`;
522
+ }
523
+ /**
524
+ * Formatos em que o texto digitado em um campo de data é interpretado.
525
+ *
526
+ * A ordem dos componentes e o separador vêm do locale do usuário — o
527
+ * `LocaleService` da plataforma aplica esse locale no moment, então
528
+ * `pt-BR` lê `dd/mm/aaaa` e `en-US` lê `mm/dd/aaaa`. Quando o campo
529
+ * define o próprio formato de exibição, ele tem prioridade: é o formato
530
+ * que o usuário vê no input — `dateFormat` no dialeto nativo do
531
+ * `s-datepicker`, ou `calendarLocaleOptions.dateFormat` (deprecated) no
532
+ * dialeto legado do PrimeNG. Cada formato também é aceito sem o zero à
533
+ * esquerda.
534
+ */
535
+ dateFilterFormats(field, isMonthView) {
536
+ const { dateFormat, calendarLocaleOptions } = field;
537
+ const fieldFormat = dateFormat
538
+ ? this.fromDatepickerDateFormat(dateFormat)
539
+ : this.fromLegacyCalendarDateFormat(calendarLocaleOptions?.dateFormat);
540
+ const localeFormat = moment.localeData().longDateFormat('L');
541
+ const format = fieldFormat ??
542
+ (isMonthView ? this.withoutDayToken(localeFormat) : localeFormat);
543
+ const shortFormat = format.replace(/D+/g, 'D').replace(/M+/g, 'M');
544
+ return format === shortFormat ? [format] : [format, shortFormat];
545
+ }
546
+ /**
547
+ * Converte o `dateFormat` nativo do `s-datepicker` (ex.: `dd/MM/yyyy`)
548
+ * para o equivalente em moment.
549
+ */
550
+ fromDatepickerDateFormat(format) {
551
+ return format.replace(/yyyy|yy|MM|mm|dd|d/g, (token) => DATEPICKER_DATE_TOKENS[token]);
552
+ }
553
+ /**
554
+ * Converte o `calendarLocaleOptions.dateFormat` legado (dialeto PrimeNG,
555
+ * ex.: `dd/mm/yy`) para o equivalente em moment.
556
+ */
557
+ fromLegacyCalendarDateFormat(format) {
558
+ if (!format) {
559
+ return undefined;
560
+ }
561
+ return format.replace(/dd|d|mm|m|yy|y/g, (token) => LEGACY_CALENDAR_DATE_TOKENS[token]);
562
+ }
563
+ /** Remove o componente de dia de um formato de data */
564
+ withoutDayToken(format) {
565
+ const separator = format.replace(/[A-Za-z]/g, '')[0] ?? '/';
566
+ return format
567
+ .split(/[^A-Za-z]/)
568
+ .filter((token) => !/^D+$/.test(token))
569
+ .join(separator);
570
+ }
448
571
  mountCustomFilter({ erpLookupsSearchField, filterData, }) {
449
572
  const { erpLookupsFormField, name } = erpLookupsSearchField;
450
573
  return `(${(erpLookupsFormField?.customFilters ?? [])
@@ -7464,18 +7587,13 @@ var EnumSituacaoCompetencia;
7464
7587
  EnumSituacaoCompetencia["FECHADA"] = "FECHADA";
7465
7588
  })(EnumSituacaoCompetencia || (EnumSituacaoCompetencia = {}));
7466
7589
 
7590
+ /**
7591
+ * A competência é sempre consultada no escopo de uma empresa — via
7592
+ * `entityDependency` de `e070empDere` — então código e nome fantasia da
7593
+ * empresa ficam fora do lookup: seriam a mesma informação repetida em toda
7594
+ * linha da grid e em todo item do autocomplete.
7595
+ */
7467
7596
  const lookupFields$5 = [
7468
- {
7469
- name: 'e070empDere.e070emp.codEmp',
7470
- type: 'integer',
7471
- },
7472
- {
7473
- name: 'e070empDere.e070emp.sigEmp',
7474
- type: 'string',
7475
- },
7476
- ];
7477
- const searchFields$4 = ({ translateService, }) => [
7478
- ...lookupFields$5,
7479
7597
  {
7480
7598
  name: 'competencia',
7481
7599
  type: 'date',
@@ -7486,6 +7604,9 @@ const searchFields$4 = ({ translateService, }) => [
7486
7604
  // de mês/ano é definido aqui e não em `dateFormat`.
7487
7605
  calendarLocaleOptions: { dateFormat: 'mm/yy' },
7488
7606
  },
7607
+ ];
7608
+ const searchFields$4 = ({ translateService, }) => [
7609
+ ...lookupFields$5,
7489
7610
  {
7490
7611
  name: 'situacao',
7491
7612
  type: 'enum',