All files / src/shared/GiveExportModal/hooks fn.ts

100% Statements 46/46
72.97% Branches 27/37
100% Functions 12/12
100% Lines 40/40

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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170                26x 87x   87x         15x   7x 10x     7x 5x       87x                   3x     3x   2x         3x     3x   1x         3x     3x   1x         3x 3x 3x 3x 3x 3x     3x 3x     3x 3x 3x         3x     87x     26x         89x                                                                                                   89x             8x 3x 5x   4x 8x         4x          
import { ProcessorValue } from "@features/Merchants/MerchantSidePanel/types";
import { useUnixInTimezone } from "@utils/date.helpers";
import { PLATFORM_TIMEZONE } from "@utils/timezones";
import { exportType, TableType } from "../const";
import { FormValues } from "../giveExportTypes";
import { startOfMonth } from "date-fns";
import { formatInTimeZone } from "date-fns-tz";
 
export const useBuildFilterString = () => {
  const { unixInTimezone } = useUnixInTimezone();
 
  const addArrayFilter = (
    arr: (string | number | null | undefined)[] | undefined,
    formatter: (value: string | number) => string,
    parts: string[],
  ) => {
    if (!Array.isArray(arr) || !arr.length) return;
 
    const filtered = arr
      .filter((item): item is string | number => item != null && item !== "")
      .map(formatter);
 
    if (filtered.length) {
      parts.push(`(${filtered.join(",")})`);
    }
  };
 
  const buildFilterString = (filterObj: {
    dateRange?: { startDate?: string; endDate?: string };
    merchantAccIDs?: (number | null | undefined)[];
    reasons?: (string | null | undefined)[];
    cardBrands?: (string | null | undefined)[];
    statuses?: (string | null | undefined)[]; // added for things like under_review
    fileName?: string; // ignored intentionally
    timeZone?: string;
    processorName?: ProcessorValue;
  }) => {
    const parts: string[] = [];
 
    // Handle merchantAccIDs
    addArrayFilter(
      filterObj.merchantAccIDs,
      (id) => `merchant.accID:${id}`,
      parts,
    );
 
    // Handle reasons
    addArrayFilter(filterObj.reasons, (r) => `reason:"${r}"`, parts);
 
    // Handle cardBrands
    addArrayFilter(
      filterObj.cardBrands,
      (b) => `cardholder.cardBrand:"${b}"`,
      parts,
    );
 
    // Handle statuses
    addArrayFilter(filterObj.statuses, (s) => `status:"${s}"`, parts);
 
    // Handle processor
    addArrayFilter(
      [filterObj.processorName],
      (r) => `processorName:"${r}"`,
      parts,
    );
 
    // Handle dateRange (convert to epoch seconds with d prefix)
    Eif (filterObj.dateRange) {
      const { startDate, endDate } = filterObj.dateRange;
      let range = [];
      Eif (startDate || endDate) range.push("(");
      Eif (startDate)
        range.push(
          `createdAt:>=d${unixInTimezone(startDate, filterObj.timeZone)}`,
        );
      Eif (endDate)
        range.push(
          `;createdAt:<=d${unixInTimezone(endDate, filterObj.timeZone)}`,
        );
      Eif (startDate || endDate) {
        range.push(")");
        parts.push(range.join(""));
      }
    }
 
    // Join with `;` for API format
    return parts.join(";") || "";
  };
 
  return { buildFilterString };
};
 
export const getDefaultValues = (
  type: TableType,
  timeZone?: string | null,
  hasFilters?: boolean,
) => {
  const defaults: Record<TableType, Partial<FormValues>> = {
    [exportType.ACQUIRE_DISPUTE]: {
      dateRange: {
        value: "All",
        label: "All Time",
        startDate: new Date(),
        endDate: new Date(),
        timeZone: timeZone,
      },
      merchants: "all",
      reason: "all",
      cardTypes: "all",
      merchantAccIDs: [],
      reasons: [],
      cardBrands: [],
      processorName: "all",
    },
    [exportType.RISK_TRANSACTIONS]: {
      type: { value: "all", label: "All Data" },
      reportType: "only_in_view",
      columns: [
        "Customer First Name",
        "Customer Last Name",
        "Customer Email",
        "Name on Card",
        "Card Type",
        "Card Number Last4",
        "Transaction Id",
        "Amount",
        "Transaction Status",
        "Risk Level",
      ],
    },
    [exportType.MERCHANT_TABLE]: {
      dateRange: {
        value: "current_month",
        label: "Current Month",
        startDate: startOfMonth(new Date()),
        endDate: new Date(),
        timeZone: timeZone,
      },
      type: hasFilters
        ? { value: "filtered", label: "Only filtered data" }
        : { value: "all", label: "All Data" },
      reportType: "only_in_view",
      columnsIncluded: "visible",
      columns: [],
    },
  };
 
  return defaults[type];
};
 
export function buildExportDateRange(
  dateRange?: FormValues["dateRange"] | null,
): { startDate: string; endDate: string } | null {
  // "All"/"all_time" means no createdAt filter at all.
  if (!dateRange || dateRange.value === "All" || dateRange.value === "all_time")
    return null;
  if (!dateRange.startDate || !dateRange.endDate) return null;
 
  const timeZone = dateRange.timeZone || PLATFORM_TIMEZONE;
  const day = (date: Date) => formatInTimeZone(date, timeZone, "yyyy-MM-dd");
 
  // Boundaries are the calendar day as seen in the selected timezone, but
  // expressed as UTC instants — unixInTimezone parses the "Z" strings as UTC,
  // which is the epoch shape the disputes filter has always received.
  return {
    startDate: `${day(dateRange.startDate)}T00:00:00Z`,
    endDate: `${day(dateRange.endDate)}T23:59:59Z`,
  };
}