All files / libs/assignments/quotas/components/src/lib/quotas-csv/export ExportQuotaAssignments.tsx

0% Statements 0/87
0% Branches 0/1
0% Functions 0/1
0% Lines 0/87

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88                                                                                                                                                                               
import { type UTCDate } from '@date-fns/utc';
import { IconDownload } from '@tabler/icons-react';
import { eachMonthOfInterval, eachQuarterOfInterval, endOfYear, startOfYear } from 'date-fns';
import { memo, useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { match } from 'ts-pattern';

import { Button } from '@allshares/studio-design-system';
import { type Quota } from '@amalia/amalia-lang/tokens/types';
import {
  FIXED_START_DATE,
  type QuotaPlanAssignments,
  type QuotaTeamAssignments,
  type QuotaUserAssignments,
} from '@amalia/assignments/quotas/types';
import { FormatsEnum } from '@amalia/data-capture/fields/types';
import { convertUtcTimestampToDate, toTimestamp, type UnixTimestampInSeconds } from '@amalia/ext/dates';
import { useUtcDate } from '@amalia/ext/react/hooks';
import { CsvFileGenerator } from '@amalia/kernel/file-generation/csv';
import { PeriodFrequencyEnum } from '@amalia/payout-definition/periods/types';
import { DownloadsApiClient } from '@amalia/reporting/exports/state';

import { QUOTA_FREQUENCY_COLUMNS, QUOTA_TYPE_ID_COLUMN } from '../quotas-csv.constants';

const getIdColumnValue = (assignment: QuotaPlanAssignments | QuotaTeamAssignments | QuotaUserAssignments) =>
  'team' in assignment ? assignment.team.name : 'user' in assignment ? assignment.user.email : assignment.plan.name;

const getAssignmentsStartDate = (frequency: Quota['frequency'], utcReferenceDate: UTCDate) =>
  match<typeof frequency, (UnixTimestampInSeconds | typeof FIXED_START_DATE)[]>(frequency)
    .with(PeriodFrequencyEnum.null, () => [FIXED_START_DATE])
    .with(PeriodFrequencyEnum.month, () =>
      eachMonthOfInterval({
        start: startOfYear(utcReferenceDate),
        end: endOfYear(utcReferenceDate),
      }).map((month) => toTimestamp(month)),
    )
    .with(PeriodFrequencyEnum.quarter, () =>
      eachQuarterOfInterval({
        start: startOfYear(utcReferenceDate),
        end: endOfYear(utcReferenceDate),
      }).map((quarter) => toTimestamp(quarter)),
    )
    .with(PeriodFrequencyEnum.year, () => [toTimestamp(startOfYear(utcReferenceDate))])
    .exhaustive();

export type ExportQuotaAssignmentsProps = {
  readonly quota: Pick<Quota, 'format' | 'frequency' | 'name' | 'type'>;
  readonly quotaAssignments: QuotaPlanAssignments[] | QuotaTeamAssignments[] | QuotaUserAssignments[];
  readonly referenceDate?: Date;
};

export const ExportQuotaAssignments = memo(function ExportQuotaAssignments({
  quota,
  quotaAssignments,
  referenceDate,
}: ExportQuotaAssignmentsProps) {
  const utcReferenceDate = useUtcDate(referenceDate);

  const handleExport = useCallback(async () => {
    const assignmentStartDates = getAssignmentsStartDate(quota.frequency, utcReferenceDate);

    DownloadsApiClient.downloadCsvFile(
      await new CsvFileGenerator().generate({
        fields: [QUOTA_TYPE_ID_COLUMN[quota.type], ...QUOTA_FREQUENCY_COLUMNS[quota.frequency]],
        data: quotaAssignments.map((assignment) => [
          getIdColumnValue(assignment),
          ...assignmentStartDates.map((column) => {
            const value = assignment.assignmentsByStartDate[column].quotaAssignment?.value;

            return value && quota.format === FormatsEnum.date ? convertUtcTimestampToDate(value as number) : value;
          }),
        ]),
      }),
      `${quota.name}_export`,
    );
  }, [quota, quotaAssignments, utcReferenceDate]);

  return (
    <Button
      icon={<IconDownload />}
      variant="primary-light"
      onClick={handleExport}
    >
      <FormattedMessage defaultMessage="Export" />
    </Button>
  );
});