About
Shop
LaTeX
Software
Books
Gallery
News
Contact
Blog
Settings
Latest news 2019-12-05: new blog post "RSS Feeds and Other Notifications."

Exercise 14: Custom Invoice using CSV Files (Solution)

This is a solution to the CSV part of Exercise 14.

You need the sample files people.csv, booklist.csv, country-codes.csv, ordergroups.csv and orders.csv.

\documentclass{isodoc}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{datatool}

\usepackage{longtable}
\usepackage{array}
\usepackage{booktabs}

\DTLloaddb{orders}{orders.csv}
\DTLloaddb{ordergroups}{ordergroups.csv}
\DTLloaddb{books}{booklist.csv}
\DTLloaddb{countries}{country-codes.csv}
\DTLloaddb{people}{people.csv}

\DTLassignfirstmatch{ordergroups}{id}{2}{%
  \CustomerId=customerid,%
  \OrderDiscount=discount,%
  \Postage=postage%
}
\xDTLassignfirstmatch{people}{id}{\CustomerId}{%
  \Title=title,%
  \Forenames=forenames,%
  \Surname=surname,%
  \AddressI=address1,%
  \AddressII=address2,%
  \Town=town,%
  \County=county,%
  \Postcode=postcode,%
  \CountryCode=country%
}
\xDTLassignfirstmatch{countries}{code}{\CountryCode}{\CountryName=name}

\begin{document}
\newcommand*{\CurrentTotal}{0}% initialise running total
\newcommand*{\VatTotal}{0}% initialise VAT total
\newcommand*{\mytablecontents}{}% initialise hook
\newcommand*{\vatrating}{}

\DTLforeach*[\equal{\OrderGroupId}{2}]{orders}%
{%
  \OrderGroupId=groupid,%
  \BookId=bookid,%
  \OrderQuantity=quantity%
}%
{%
  \xDTLassignfirstmatch{books}{id}{\BookId}%
  {%
    \BookTitle=title,%
    \BookAuthor=author,%
    \BookFormat=format,%
    \BookPrice=price%
  }%
% Compute quantity x price:
  \dtlmul{\subtotal}{\OrderQuantity}{\BookPrice}%
% Is this an ebook?
  \ifdefstring{\BookFormat}{ebook}%
  {% compute 20% VAT
    \dtlmul{\vat}{\subtotal}{0.2}%
   % add to VAT total
    \dtladd{\VatTotal}{\VatTotal}{\vat}%
    \renewcommand*{\vatrating}{20}%
  }%
  {%
    \renewcommand*{\vatrating}{0}%
  }%
% Add subtotal to the running total:
  \dtladd{\CurrentTotal}{\CurrentTotal}{\subtotal}%
% Round to 2 d.p.
  \dtlround{\subtotal}{\subtotal}{2}%
% Append to hook:
  \eappto\mytablecontents{%
   ``\BookTitle'' (\BookFormat) \noexpand&
   \OrderQuantity \noexpand&
   \BookPrice \noexpand&
   \vatrating\% \noexpand& 
   \subtotal\noexpand\\}%
}%
% Round the subtotal to 2 d.p.
\dtlround{\subtotal}{\CurrentTotal}{2}%
% Round the VAT to 2 d.p.
\dtlround{\VatTotal}{\VatTotal}{2}%
% Add the VAT to running total:
\dtladd{\CurrentTotal}{\CurrentTotal}{\VatTotal}%
% Add postage to running total:
\dtladd{\CurrentTotal}{\CurrentTotal}{\Postage}%
% Subtract discount from running total:
\dtlsub{\CurrentTotal}{\CurrentTotal}{\OrderDiscount}%
% Round to 2 d.p.:
\dtlround{\CurrentTotal}{\CurrentTotal}{2}%

\invoice
[
  to={\DTLifnullorempty{\Title}{}{\Title\ }%
  \Forenames\ \Surname\\%
  \AddressI\\%
  \DTLifnullorempty{\AddressII}{}{\AddressII\\}%
  \Town\\%
  \DTLifnullorempty{\County}{}{\County\\}%
  \Postcode\\%
  \CountryName},
  currency={\pounds}
]
{
  \begin{longtable}{>{\raggedright}p{0.3\linewidth}rrrr}
  \bfseries Item &
  \bfseries Quantity &
  \bfseries Unit Price (\pounds) &
  \bfseries VAT \% &
  \bfseries Price (\pounds)\\
  \midrule
  \endhead
  \mytablecontents
  \midrule
  \multicolumn{4}{r}{\bfseries Sub-Total} & \subtotal\\
  \multicolumn{4}{r}{\bfseries VAT} & \VatTotal\\
  \multicolumn{4}{r}{\bfseries Postage and Packaging} & \Postage\\
  \multicolumn{4}{r}{\bfseries Promotional Discount} & $-\OrderDiscount$\\
  \midrule
  \multicolumn{4}{r}{\bfseries Total} & \CurrentTotal
  \end{longtable}
}

\end{document}

Download invoice-longtable-csv.tex or invoice-longtable-csv.pdf.

© 2015 Dickimaw Books. "Dickimaw", "Dickimaw Books" and the Dickimaw parrot logo are trademarks. The Dickimaw parrot was painted by Magdalene Pritchett.

Terms of Use Privacy Policy Cookies Site Map FAQs