# Strange expansion of a macro inside an environment

I'm, I should confess, a total newbie. I'm trying to generate invoices with LaTeX, so I'm using the fp package.

But the strange thing is that calculations occur many times when they should only occur once per product. Here's my LaTeX file, below, can you please help me understand why it's behaving like this? And help me improve it?

The two important pieces of it are probably the environment invoice and the macro product. For each product I multiply the unit price times the quantity, get that amount and add it to the total amount of the invoice called TotalHT

\documentclass[a4paper,12pt]{article}

\usepackage[frenchb]{babel}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{array}
\usepackage{tabularx}
\usepackage{fancyhdr}
\usepackage{textcomp}
\usepackage{fltpoint}
\usepackage[nomessages]{fp}
\RequirePackage{numprint}

% - Page and Headers Style {{{
\setlength{\parindent}{0pt}
\pagestyle{fancy}
\fancyhf{}
% - }}}

% - New Commands {{{

\def\TotalHT{0}

% set standard decimal position (numprint package)
\nprounddigits{2}

\newcommand{\nous}{
\small{
\textsf{%
\textsc{My Company}\\
}
}
}

\newcommand{\client}[1]{%
\vspace{1cm}
\begin{flushright}
\small{\textsf {#1}}
\end{flushright}
}

\newcommand{\numero}[2]{%
\vspace*{1cm}
\begin{center}
\Huge{\textbf{Facture n° #1}}\\
\textsf{\small{Du #2}}
\end{center}
}

\newcommand{\firstth}[1]{
\multicolumn{1}{|l|}{#1}
}

\newenvironment{invoice}{%
\ignorespaces
\small
\tabularx{\textwidth}{|X|r|c|r|}
\hline
\firstth{Designation} & Unit Price. & Qty. & Amount\\
\hline
}%
{%
\endtabularx%
}

\newcommand{\product}[3]{%
\FPround\p{#2}{2}
\FPeval\m{\p * #3}
\FPround\m\m{2}
\global\let\TotalHT\TotalHT
\message{t \TotalHT  prod #1}
#1 &
\FPround{\p}{#2}{2}\numprint\p &
#3 &
\FPround\p{#2}{2}
\FPeval\m{\p * #3}
\numprint\m\\
\hline
}

\newcommand{\totalttc}{
\FPround\TotalHT\TotalHT{2}
& \multicolumn{2}{r|}{\textbf{Total TTC}} & \numprint\TotalHT \\
\cline{2-4}
}

\newcommand{\enlettres}[1]{
\vspace*{1cm}
\textsf{Arrêter la présente facture à la somme de \textbf{#1}.}
}

% - }}}

\begin{document}
\numero{01/2010}{17/03/2010}

\client{
My Client Sarl.\\
His phone
}

\begin{invoice}
\product{product One}{1000.00}{1}
\product{product Two}{2000}{1}
\product{product Three}{3000.00}{1}
\product{Product Four}{5000.00}{1}
\totalttc
\end{invoice}

\enlettres{Cent dix-sept milles cinq cents euros et zéro centimes}
\end{document}


Whenever I run this through pdflatex, I have the message \message{t \TotalHT prod #1} appear more than once for each product. But then again, in the table that's generated in the PDF I have exactly one row per product, but the total is wrong.

Thanks a lot for helping me understand this!

P.S. three brackets in comments like % - }}} and % - New Commands {{{ are just here for folding in vim

-

As Mathew said as well the tabularx is the culprit. I also did some minor changes to the way you used the fp package. Below code works.

\documentclass[a4paper,12pt]{article}
\usepackage[frenchb]{babel}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{array}
\usepackage[nomessages]{fp}
\gdef\TotalHT{0}
\newcommand{\product}[3]{%
#1  &#2   &#3  &\FPmul\temp{#2}{#3}\FPround\temp{\temp}{2}\temp
%% Totalize
\FPround\total{\total}{2}
\global\let\TotalHT\total
\\ }
\newcommand{\totalttc}{
\TotalHT  }
\begin{document}
\begin{tabular}{lrrr}
\product{product One}{1000.00}{1}
\product{product Two}{2000}{1}
\product{product Three}{3000.00}{1}
\product{Product Four}{5000.00}{1}
\product{Product Four}{5000.00}{1}
&&& Total \totalttc
\end{tabular}
\end{document}

-
Hey! That's great! I was wondering how to optimize that very part in fact! – user4038 Mar 7 '11 at 18:36
@sam thanks! You can simply turn the tabular into an environment, which I skipped for clarity. I would also rename the product to addRow it makes more sense. Your example is a great looking document though. Also consider using longtable rather than tabular, if you are going to have long invoices. – Yiannis Lazarides Mar 7 '11 at 19:52
Thank you @Yiannis! In fact, I translated in a hurry this doc from French, where "product" was "produit" and "invoice" was "facture". I'm working on a draft so that I'll be able to create a new class and then use that cls in every invoice I typeset "cleanly" -I wonder even if cleanly is an english word ;) – user4038 Mar 7 '11 at 21:32
@sam: Vous avez raison; "cleanly" est un vrai mot anglais. – Matthew Leingang Mar 7 '11 at 21:38
Mille mercis encore, Matthew! :) -- I browsed this site and many of you seem so professional and the kind of people who do know their stuff. Where did you guys learn TeX? Online? Do you have some good hints for a newbie like me? I'd love to be more fluent with it, since I spend most of my time in the CLI and would love to share that passion with people like you! – user4038 Mar 7 '11 at 21:46

The tabularx environment that you are using to typeset the table is evaluating the table contents three times before setting it once. This is probably to help it do its calculations.

You can avoid this issue by using a tabular environment instead:

\newenvironment{invoice}{%
\ignorespaces
\small
\tabular{|p{0.5\textwidth}|r|c|r|}
\hline
\firstth{Designation} & Unit Price. & Qty. & Amount\\
\hline
}%
{%
\endtabular%
}


Not quite as pretty as tabularx but gets the job done.

If you want tabularx and don't mind repeating the calculations, just make sure you initialize:

\newenvironment{invoice}{%
\ignorespaces
\small
\tabularx{\textwidth}{|X|r|c|r|}
\hline
\firstth{Designation} & Unit Price. & Qty. & Amount\\
\hline
\def\TotalHT{0}
\global\let\TotalHT\TotalHT
}%
{%
\endtabularx%
}


Yet another way might be to store the order in a list data structure and total it separately from setting the table. But I suspect this is more trouble than it's worth.

-
PS Welcome to TeX.SE! You will get a quicker answer if you trim down your question and sample document to the smallest possible example of the odd behavior. Otherwise answerers may find it overwhelming. – Matthew Leingang Mar 7 '11 at 17:55
Thank you so much @Matthew and @Yiannis! Your explanations and suggestions are great! @Matthew thanks also for the advice about TeX.SE! I feel that this community is really a warm one (and sorry for my poor english) – user4038 Mar 7 '11 at 18:37