import { format, utcToZonedTime } from 'date-fns-tz';
import { jsPDF as JsPDF } from 'jspdf';
import Cookies from 'universal-cookie';
import { DELIVERY_HANDOFF_ID } from '../../constants';
import { formatPrice } from '../../utils';
import getDateWithoutOffset from '../../utils/getDateWithoutOffset';
const generateOrderPDF = (data) => {
const cookies = new Cookies();
const doc = new JsPDF();
const mainTitleFontSize = 20; // ~40px
const cartTitleFontSize = 16; // ~32px
const subtitleFontSize = 10; // ~20px
const itemNameFontSize = 9; // ~18px
const itemDescriptionFontSize = 8; // ~16px
const xAxisMainLayoutStart = 20;
const xAxisInnerLayoutStart = xAxisMainLayoutStart + 5;
const yAxisMainTitlePosition = 20;
const yAxisSubtitlePosition = 30;
const yAxisCartTitlePosition = 50;
const yAxisCartItemsPosition = 55;
const generalTextSpacingValue = 5;
const cartItemContainerHeight = 20;
const {
address,
additionalCharge,
category,
couponAmount,
expected,
handoff,
lineConnection,
location,
quoteId,
subtotalPrice,
taxes,
tip,
totalPrice,
} = data;
const numberOfCartItems = lineConnection?.totalCount;
const timeOfPDFCreation = format(new Date(), 'MMMM dd, yyyy hh:mm a');
doc.setTextColor(1, 1, 1); // #010101
// Title
doc.setFontSize(mainTitleFontSize);
doc.setFont('helvetica', 'normal', 'bold');
doc.text('Dickey’s Barbecue Pit', xAxisMainLayoutStart, yAxisMainTitlePosition);
// Subtitle
doc.setFontSize(subtitleFontSize);
doc.setFont('helvetica', 'normal', 'normal');
doc.text('This Is Not A Finished Order!', xAxisMainLayoutStart, yAxisSubtitlePosition);
doc.text('Pricing Is Subject To Change.', xAxisMainLayoutStart, yAxisSubtitlePosition + 7);
// Date and time
doc.text(`#${quoteId}`, 199, yAxisMainTitlePosition, { align: 'right' });
doc.text(timeOfPDFCreation, 199, yAxisMainTitlePosition + generalTextSpacingValue, {
align: 'right',
});
// Cart title
doc.setFontSize(cartTitleFontSize);
doc.setFont('helvetica', 'normal', 'bold');
doc.text('Cart', xAxisMainLayoutStart, yAxisCartTitlePosition);
if (numberOfCartItems > 0) {
doc.setFontSize(subtitleFontSize);
doc.setFont('helvetica', 'normal', 'normal');
doc.text(
`(${numberOfCartItems} ${numberOfCartItems > 1 ? 'items' : 'item'})`,
xAxisMainLayoutStart + 12,
yAxisCartTitlePosition,
);
}
const generateCartItems = (remainingItems, docPage = 0) => {
const maxItemsPerPage = docPage === 0 ? 9 : 15;
const totalNumberOfCartItemsOnPage =
numberOfCartItems <= maxItemsPerPage ? numberOfCartItems : numberOfCartItems - remainingItems;
console.log('TOTAL NUMBER ', totalNumberOfCartItemsOnPage);
const maxItemDescriptionLength = 210;
const yAxisCartItemsPositionStart =
docPage === 0 ? yAxisCartItemsPosition : yAxisMainTitlePosition;
doc.setDrawColor(200, 201, 217);
doc.roundedRect(
xAxisMainLayoutStart,
yAxisCartItemsPositionStart,
180,
cartItemContainerHeight * totalNumberOfCartItemsOnPage,
1,
1,
);
if (lineConnection?.edges.length > 0) {
data?.lineConnection?.edges.slice(docPage * remainingItems).forEach((line, index) => {
if (!line?.node?.id || !line?.node?.item?.id) return;
if (index < totalNumberOfCartItemsOnPage - 1) {
const yItemsSeparatorPosition = 75 + cartItemContainerHeight * index;
doc.line(xAxisMainLayoutStart, yItemsSeparatorPosition, 200, yItemsSeparatorPosition);
}
const yItemPosition = 58 + cartItemContainerHeight * index;
const image = document
.getElementById(line.node.item.itemimageConnection?.edges[0]?.node?.id)
?.getAttribute('src');
const itemName = line.node.item.label;
const itemPrice =
line?.node?.item?.id === cookies.get('couponItemId')?.couponItemId
? 'FREE'
: `$${formatPrice(line.node.totalPrice)}`;
const itemDescription = line.node.lineMultipleConnection?.edges
?.map(
(edge) =>
`${edge.node?.quantity > 1 ? `${edge.node?.quantity} x ` : ''}${
edge.node?.choice?.label
}`,
)
.join(', ');
const itemQuantity = line.node.quantity;
doc.addImage(image || '', 'JPEG', xAxisInnerLayoutStart, yItemPosition, 22, 14);
doc.setFontSize(itemNameFontSize);
doc.setFont('helvetica', 'normal', 'bold');
doc.text(itemName, 50, yItemPosition + 4);
doc.setFontSize(itemDescriptionFontSize);
doc.setTextColor(87, 87, 87);
doc.setFont('helvetica', 'normal', 'normal');
if (itemDescription.length > maxItemDescriptionLength) {
const truncatedItemDescription = `${itemDescription.substring(
0,
maxItemDescriptionLength,
)}...`;
const splitItemDescription = doc.splitTextToSize(truncatedItemDescription, 100);
doc.text(splitItemDescription, 50, yItemPosition + 8);
} else {
const splitItemDescription = doc.splitTextToSize(itemDescription, 100);
doc.text(splitItemDescription, 50, yItemPosition + 10);
}
doc.setTextColor(1, 1, 1);
doc.setFillColor(255, 247, 208);
doc.roundedRect(150, yItemPosition + 2, 25, 10, 5, 5, 'F');
doc.text(`Quantity: ${itemQuantity}`, 155, yItemPosition + 8);
doc.setFontSize(itemNameFontSize);
doc.setFont('helvetica', 'normal', 'bold');
doc.text(itemPrice, 195, yItemPosition + 8, { align: 'right' });
});
}
};
// Cart items
generateCartItems(0);
// Cart total
const yAxisCartTotalStartPosition =
yAxisCartItemsPosition + cartItemContainerHeight * numberOfCartItems + 10;
if (numberOfCartItems >= 10) {
doc.addPage();
}
const cartTotalWidth = 80;
const cartTotalInitialHeight = 20;
const yAxisCartTotalTitlePosition = yAxisCartTotalStartPosition + 7;
const yAxisCartTotalItemsStart = yAxisCartTotalTitlePosition + 7;
const xAxisCartTotalPriceDisplay = cartTotalWidth + 15;
let currentCartTotalTextSpacingValue = 0;
doc.setFontSize(subtitleFontSize + 1);
doc.setFont('helvetica', 'normal', 'bold');
doc.text('Cart total', xAxisInnerLayoutStart, yAxisCartTotalTitlePosition);
doc.setFontSize(itemNameFontSize);
doc.setFont('helvetica', 'normal', 'normal');
doc.setTextColor(88, 88, 90); // #58585A
doc.text('Subtotal:', xAxisInnerLayoutStart, yAxisCartTotalItemsStart);
doc.text(`$${formatPrice(subtotalPrice)}`, xAxisCartTotalPriceDisplay, yAxisCartTotalItemsStart, {
align: 'right',
});
currentCartTotalTextSpacingValue += generalTextSpacingValue;
taxes.forEach((tax, index) => {
const yAxisTaxPosition =
yAxisCartTotalItemsStart + generalTextSpacingValue + generalTextSpacingValue * index;
doc.text(`${tax.label}:`, xAxisInnerLayoutStart, yAxisTaxPosition);
doc.text(`$${formatPrice(tax.amount)}`, xAxisCartTotalPriceDisplay, yAxisTaxPosition, {
align: 'right',
});
currentCartTotalTextSpacingValue += generalTextSpacingValue;
});
if (additionalCharge > 0) {
doc.text(
'Additional Charge:',
xAxisInnerLayoutStart,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
);
doc.text(
`$${formatPrice(additionalCharge)}`,
xAxisCartTotalPriceDisplay,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
{
align: 'right',
},
);
currentCartTotalTextSpacingValue += generalTextSpacingValue;
}
if (couponAmount > 0) {
doc.text(
'Discount:',
xAxisInnerLayoutStart,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
);
doc.text(
`$${formatPrice(couponAmount)}`,
xAxisCartTotalPriceDisplay,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
{
align: 'right',
},
);
currentCartTotalTextSpacingValue += generalTextSpacingValue;
}
doc.text(
'Tip:',
xAxisInnerLayoutStart,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
);
doc.text(
`$${formatPrice(tip)}`,
xAxisCartTotalPriceDisplay,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
{
align: 'right',
},
);
currentCartTotalTextSpacingValue += generalTextSpacingValue;
doc.setFont('helvetica', 'normal', 'bold');
doc.setTextColor(1, 1, 1);
doc.text(
'Total:',
xAxisInnerLayoutStart,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
);
doc.text(
`$${formatPrice(totalPrice)}`,
xAxisCartTotalPriceDisplay,
yAxisCartTotalItemsStart + currentCartTotalTextSpacingValue,
{
align: 'right',
},
);
doc.setDrawColor(200, 201, 217);
doc.roundedRect(
xAxisMainLayoutStart,
yAxisCartTotalStartPosition,
cartTotalWidth,
cartTotalInitialHeight + currentCartTotalTextSpacingValue,
1,
1,
);
// Order / Delivery options
const yAxisOrderOptionsStart = yAxisCartTotalTitlePosition;
const xAxisOrderOptionsStart = xAxisCartTotalPriceDisplay + 20;
const orderOptionsTextSpacingValue = 7;
let currentOrderOptionsTextSpacingValue = orderOptionsTextSpacingValue;
const inlineTextSpacing = 15;
doc.setFontSize(subtitleFontSize + 1);
doc.setFont('helvetica', 'normal', 'bold');
doc.text('Order options', xAxisOrderOptionsStart, yAxisOrderOptionsStart);
doc.setFontSize(itemDescriptionFontSize);
if (handoff?.id === DELIVERY_HANDOFF_ID) {
const deliveryAddress = `${address?.address}, ${address?.city}, ${address?.state?.abbreviation} ${address?.zip}`;
doc.setTextColor(1, 1, 1);
doc.setFont('helvetica', 'normal', 'bold');
doc.text(
'Address',
xAxisOrderOptionsStart,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
doc.setTextColor(88, 88, 90);
doc.setFont('helvetica', 'normal', 'normal');
doc.text(
deliveryAddress,
xAxisOrderOptionsStart + inlineTextSpacing,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
currentOrderOptionsTextSpacingValue += orderOptionsTextSpacingValue;
}
const storeAddress = location
? `${location?.label}, ${location?.address?.address}, ${location?.address?.city}, ${location?.address?.state?.abbreviation} ${location?.address?.zip}`
: null;
if (storeAddress) {
doc.text(
'Location',
xAxisOrderOptionsStart,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
doc.setTextColor(88, 88, 90);
doc.setFont('helvetica', 'normal', 'normal');
doc.text(
storeAddress,
xAxisOrderOptionsStart + inlineTextSpacing,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
currentOrderOptionsTextSpacingValue += orderOptionsTextSpacingValue;
}
doc.setTextColor(1, 1, 1);
doc.setFont('helvetica', 'normal', 'bold');
doc.text(
'Handoff',
xAxisOrderOptionsStart,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
doc.setTextColor(88, 88, 90);
doc.setFont('helvetica', 'normal', 'normal');
doc.text(
handoff?.label,
xAxisOrderOptionsStart + inlineTextSpacing,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
currentOrderOptionsTextSpacingValue += orderOptionsTextSpacingValue;
doc.setTextColor(1, 1, 1);
doc.setFont('helvetica', 'normal', 'bold');
doc.text(
'Menu',
xAxisOrderOptionsStart,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
doc.setTextColor(88, 88, 90);
doc.setFont('helvetica', 'normal', 'normal');
doc.text(
category?.label,
xAxisOrderOptionsStart + inlineTextSpacing,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
currentOrderOptionsTextSpacingValue += orderOptionsTextSpacingValue;
if (expected && location?.timezone?.label) {
doc.setTextColor(1, 1, 1);
doc.setFont('helvetica', 'normal', 'bold');
doc.text(
'Date & Time',
xAxisOrderOptionsStart,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
doc.setTextColor(88, 88, 90);
doc.setFont('helvetica', 'normal', 'normal');
doc.text(
`${format(
utcToZonedTime(getDateWithoutOffset(expected), location.timezone.label),
'MMMM dd, yyyy',
)} | ${format(
utcToZonedTime(getDateWithoutOffset(expected), location.timezone.label),
'hh:mm a',
)}`,
xAxisOrderOptionsStart + inlineTextSpacing + generalTextSpacingValue,
yAxisOrderOptionsStart + currentOrderOptionsTextSpacingValue,
);
currentOrderOptionsTextSpacingValue += orderOptionsTextSpacingValue;
}
doc.output('dataurlnewwindow');
};
export default generateOrderPDF;