All files / src/features/Campaigns/CampaignDetails/hooks useGeneratePdf.tsx

12.5% Statements 4/32
0% Branches 0/26
20% Functions 1/5
13.33% Lines 4/30

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                          1x 51x   51x                                                                                                                                                                 51x            
import { useGetMerchantById } from "@hooks/enterprise-api/account/useGetMerchants";
import { pdf } from "@react-pdf/renderer";
import InvoicePDFPreview from "@sections/PayBuilder/components/InvoicePreview/InvoicePDFPreview";
import {
  extractParagraphs,
  getHTMLFromWysiwyg,
  isLogoMediaItem,
} from "@sections/PayBuilder/components/InvoicePreview/utils";
import { DEFAULT_INVOICE_REFERENCE } from "@sections/PayBuilder/consts";
import DOMPurify from "dompurify";
import { saveAs } from "file-saver";
import { isUrl } from "@sections/PayBuilder/helpers";
 
const useGeneratePdf = ({ data, productInventory, merchantId }: any) => {
  const { data: merchant } = useGetMerchantById({ merchantId });
 
  const generatePdf = async () => {
    const _data = data as any;
    const invoiceDate = _data?.createdAt || new Date();
    const invoiceReference = _data?.reference || DEFAULT_INVOICE_REFERENCE;
    const customer = {
      ..._data?.customer,
      address: _data?.customer?.billingAddress,
    };
    const from = merchant;
 
    const cartItems = productInventory?.data?.map((item: any) => ({
      productVariantName: item?.name,
      productVariantPrice: item?.price / 100,
      quantity:
        item?.initialInventory ||
        (data?.status === "paid" ? item?.numSold : item?.inventory), // @todo delete the other conditions, we should only use initialInventory, it's just to prevent issues while dev and stg are not aligned
    }));
 
    const getParagraphs = () => {
      const logo = data?.paymentLogoURL;
      const shouldLogoBeImage = isLogoMediaItem(logo);
 
      if (
        logo &&
        Object.keys(logo).length > 0 &&
        (typeof logo === "string" || !shouldLogoBeImage)
      ) {
        if (typeof logo === "string" && isUrl(logo)) return [];
 
        const markup = getHTMLFromWysiwyg({
          logo: typeof logo === "string" ? logo : (logo as any).URL,
        });
        if (markup) {
          const sanitizedMarkup = DOMPurify.sanitize(markup);
          const paragraphs = extractParagraphs(sanitizedMarkup);
 
          return paragraphs;
        }
 
        return [];
      } else {
        return [];
      }
    };
 
    const _subTotal = cartItems?.reduce(
      (acc: number, item: any) =>
        acc + item.productVariantPrice * item.quantity,
      0,
    );
 
    const subTotal = _subTotal?.toFixed(2);
 
    const values = {
      Style: {
        logo: isUrl(data?.paymentLogoURL)
          ? data?.paymentLogoStyles
          : data?.paymentLogoURL,
      },
      About: { endsAt: data?.endsAt ? data?.endsAt : new Date() },
    };
 
    try {
      const blob = await pdf(
        <InvoicePDFPreview
          values={values}
          invoiceDate={invoiceDate}
          cartItems={cartItems}
          from={from}
          invoiceReference={invoiceReference}
          to={customer}
          subTotal={subTotal}
          paragraphs={getParagraphs()}
        />,
      ).toBlob();
 
      saveAs(blob, `Invoice_${invoiceReference}`);
    } catch (error) {
      console.error("PDF rendering failed:", error);
    }
  };
  return {
    generatePdf,
  };
};
 
export { useGeneratePdf };