\documentclass[12pt]{article}
\usepackage[a4paper, margin=1in]{geometry}
\usepackage{graphicx}
\usepackage{array}
\usepackage{pgffor}
\usepackage{xfp}
\usepackage{etoolbox}
% Company Information Variables
\newcommand{\companyname}{Company Name}
\newcommand{\companyaddress}{Address}
\newcommand{\companycity}{Street}
\newcommand{\companystate}{State}
\newcommand{\companyzip}{Zip}
\newcommand{\companyemail}{email@company.com}
\newcommand{\companyphone}{000-000-0000}
\newcommand{\companylogo}{logo.png}
\newcommand{\companyfooter}{Thank you for your business!}
% Client ID
\newcommand{\invoiceto}{Contracted}
\newcommand{\invoicedate}{11/30/2024}
\newcommand{\invoiceid}{003}
\makeatletter
% Initialize project list
\def\projectlist{}
\def\grandtotal{0}
\newcommand{\addprojecttolist}[1]{%
\xifinlist{#1}{\projectlist}{}{%
\listgadd{\projectlist}{#1}%
}%
}
% Define work item
\newcommand{\definework}[4]{%
\addprojecttolist{#1}%
\@ifundefined{proj:#1}{%
\expandafter\def\csname proj:#1\endcsname{}%
\expandafter\def\csname projtotal:#1\endcsname{0}%
}{}%
\expandafter\g@addto@macro\csname proj:#1\endcsname{%
#2 & #3 & #4 & \fpeval{#3 * #4} \\
}%
\expandafter\xdef\csname projtotal:#1\endcsname{\fpeval{\csname projtotal:#1\endcsname + (#3 * #4)}}%
\xdef\grandtotal{\fpeval{\grandtotal + (#3 * #4)}}%
}
% Define expense item
\newcommand{\defineexpense}[3]{%
\addprojecttolist{#1}%
\@ifundefined{proj:#1}{%
\expandafter\def\csname proj:#1\endcsname{}%
\expandafter\def\csname projtotal:#1\endcsname{0}%
}{}%
\expandafter\g@addto@macro\csname proj:#1\endcsname{%
#2 & {---} & {---} & #3 \\
}%
\expandafter\xdef\csname projtotal:#1\endcsname{\fpeval{\csname projtotal:#1\endcsname + #3}}%
\xdef\grandtotal{\fpeval{\grandtotal + #3}}%
}
\makeatother % Reset @ handling
% Display a single project
\newcommand{\displayproject}[1]{%
\noindent\newline\textbf{Project Name:} #1\par\vspace{0.3cm}
\noindent
\begin{tabular}{|p{7.5cm}|p{2cm}|p{2cm}|p{2.5cm}|}
\hline
\textbf{Description} & \textbf{Hours} & \textbf{Rate (\$)} & \textbf{Amount (\$)} \\
\hline
\csname proj:#1\endcsname
\hline
\multicolumn{3}{|l|}{\textbf{Total}} & \csname projtotal:#1\endcsname \\ \hline
\end{tabular}
\vspace{1cm}
}
% Define the list processor
\newcommand{\processprojects}[1]{%
\displayproject{#1}%
}
\begin{document}
% Define projects
\definework{Contract Work}{Hourly Contract Work}{50}{40}
\defineexpense{Contract Work}{Individual Expense}{50}
% Logo and header
\begin{center}
\includegraphics[width=2.5cm]{\companylogo}
{\Large\bfseries \companyname}\\
{\companyaddress, \companycity, \companystate, \companyzip}\\
Email: \companyemail \hspace{1cm} Phone: \companyphone
\end{center}
\vspace{0.5cm}
\hrule
\vspace{0.5cm}
% Invoice Info
\noindent{\textbf{Invoice To:}} \invoiceto\\
\noindent{\textbf{Invoice Number:}} \#\invoiceid\\
{\textbf{Invoice Date:}} \invoicedate\\
% Display projects
\forlistloop{\processprojects}{\projectlist}
\noindent{\textbf{Grand Total:}} \$\fpeval{\grandtotal}
% Footer
\begin{center}
{\textit{\companyname\ — \companyfooter}}
\end{center}
\end{document}