ZUGFeRD Invoice Example

This is a code example of iText PDF, discover more.

1st September 2017
iText PDF

Switch code for this example

Customer.java
  1. /*
  2.  * Part of a set of classes based on a sample database.
  3.  * This example was written by Bruno Lowagie in the context of a book.
  4.  * See http://developers.itextpdf.com/content/zugferd-future-invoicing/3-simple-invoice-database
  5.  */
  6. package com.itextpdf.zugferd.pojo;
  7.  
  8. /**
  9.  * Plain Old Java Object containing info about a Customer.
  10.  * @author Bruno Lowagie (iText Software)
  11.  */
  12. public class Customer {
  13.    
  14.     /** The id. */
  15.     protected int id;
  16.    
  17.     /** The first name. */
  18.     protected String firstName;
  19.    
  20.     /** The last name. */
  21.     protected String lastName;
  22.    
  23.     /** The street. */
  24.     protected String street;
  25.    
  26.     /** The postal code. */
  27.     protected String postalcode;
  28.    
  29.     /** The city. */
  30.     protected String city;
  31.    
  32.     /** The country id. */
  33.     protected String countryId;
  34.  
  35.     /**
  36.      * Gets the id.
  37.      *
  38.      * @return the id
  39.      */
  40.     public int getId() {
  41.         return id;
  42.     }
  43.  
  44.     /**
  45.      * Sets the id.
  46.      *
  47.      * @param id the new id
  48.      */
  49.     public void setId(int id) {
  50.         this.id = id;
  51.     }
  52.  
  53.     /**
  54.      * Gets the first name.
  55.      *
  56.      * @return the first name
  57.      */
  58.     public String getFirstName() {
  59.         return firstName;
  60.     }
  61.  
  62.     /**
  63.      * Sets the first name.
  64.      *
  65.      * @param firstName the new first name
  66.      */
  67.     public void setFirstName(String firstName) {
  68.         this.firstName = firstName;
  69.     }
  70.  
  71.     /**
  72.      * Gets the last name.
  73.      *
  74.      * @return the last name
  75.      */
  76.     public String getLastName() {
  77.         return lastName;
  78.     }
  79.  
  80.     /**
  81.      * Sets the last name.
  82.      *
  83.      * @param lastName the new last name
  84.      */
  85.     public void setLastName(String lastName) {
  86.         this.lastName = lastName;
  87.     }
  88.  
  89.     /**
  90.      * Gets the street.
  91.      *
  92.      * @return the street
  93.      */
  94.     public String getStreet() {
  95.         return street;
  96.     }
  97.  
  98.     /**
  99.      * Sets the street.
  100.      *
  101.      * @param street the new street
  102.      */
  103.     public void setStreet(String street) {
  104.         this.street = street;
  105.     }
  106.  
  107.     /**
  108.      * Gets the city.
  109.      *
  110.      * @return the city
  111.      */
  112.     public String getCity() {
  113.         return city;
  114.     }
  115.  
  116.     /**
  117.      * Sets the city.
  118.      *
  119.      * @param city the new city
  120.      */
  121.     public void setCity(String city) {
  122.         this.city = city;
  123.     }
  124.  
  125.     /**
  126.      * Gets the postal code.
  127.      *
  128.      * @return the postal code
  129.      */
  130.     public String getPostalcode() {
  131.         return postalcode;
  132.     }
  133.  
  134.     /**
  135.      * Sets the postal code.
  136.      *
  137.      * @param postalcode the new postalcode
  138.      */
  139.     public void setPostalcode(String postalcode) {
  140.         this.postalcode = postalcode;
  141.     }
  142.  
  143.     /**
  144.      * Gets the country id.
  145.      *
  146.      * @return the country id
  147.      */
  148.     public String getCountryId() {
  149.         return countryId;
  150.     }
  151.  
  152.     /**
  153.      * Sets the country id.
  154.      *
  155.      * @param countryId the new country id
  156.      */
  157.     public void setCountryId(String countryId) {
  158.         this.countryId = countryId;
  159.     }
  160.    
  161.     /* (non-Javadoc)
  162.      * @see java.lang.Object#toString()
  163.      */
  164.     @Override
  165.     public String toString() {
  166.         StringBuilder sb = new StringBuilder();
  167.         sb.append(id).append("\n");
  168.         sb.append("    First Name: ").append(firstName).append("\n");
  169.         sb.append("    Last Name: ").append(lastName).append("\n");
  170.         sb.append("    Street: ").append(street).append("\n");
  171.         sb.append("    City: ").append(countryId).append(" ").append(postalcode).append(" ").append(city);
  172.         return sb.toString();
  173.     }
  174. }
Invoice.java
  1. /*
  2.  * Part of a set of classes based on a sample database.
  3.  * This example was written by Bruno Lowagie in the context of a book.
  4.  * See http://developers.itextpdf.com/content/zugferd-future-invoicing/3-simple-invoice-database
  5.  */
  6. package com.itextpdf.zugferd.pojo;
  7.  
  8. import java.util.Date;
  9. import java.util.List;
  10.  
  11. /**
  12.  * Plain Old Java Object containing info about an Invoice.
  13.  * @author Bruno Lowagie (iText Software)
  14.  */
  15. public class Invoice {
  16.    
  17.     /** The id. */
  18.     protected int id;
  19.    
  20.     /** The customer. */
  21.     protected Customer customer;
  22.    
  23.     /** The total. */
  24.     protected double total;
  25.    
  26.     /** The items. */
  27.     protected List<Item> items;
  28.    
  29.     /** The invoice date. */
  30.     protected Date invoiceDate;
  31.  
  32.     /**
  33.      * Gets the id.
  34.      *
  35.      * @return the id
  36.      */
  37.     public int getId() {
  38.         return id;
  39.     }
  40.  
  41.     /**
  42.      * Sets the id.
  43.      *
  44.      * @param id the new id
  45.      */
  46.     public void setId(int id) {
  47.         this.id = id;
  48.     }
  49.  
  50.     /**
  51.      * Gets the customer.
  52.      *
  53.      * @return the customer
  54.      */
  55.     public Customer getCustomer() {
  56.         return customer;
  57.     }
  58.  
  59.     /**
  60.      * Sets the customer.
  61.      *
  62.      * @param customer the new customer
  63.      */
  64.     public void setCustomer(Customer customer) {
  65.         this.customer = customer;
  66.     }
  67.  
  68.     /**
  69.      * Gets the total.
  70.      *
  71.      * @return the total
  72.      */
  73.     public double getTotal() {
  74.         return total;
  75.     }
  76.  
  77.     /**
  78.      * Sets the total.
  79.      *
  80.      * @param total the new total
  81.      */
  82.     public void setTotal(double total) {
  83.         this.total = total;
  84.     }
  85.  
  86.     /**
  87.      * Gets the items.
  88.      *
  89.      * @return the items
  90.      */
  91.     public List<Item> getItems() {
  92.         return items;
  93.     }
  94.  
  95.     /**
  96.      * Sets the items.
  97.      *
  98.      * @param items the new items
  99.      */
  100.     public void setItems(List<Item> items) {
  101.         this.items = items;
  102.     }
  103.  
  104.     /**
  105.      * Gets the invoice date.
  106.      *
  107.      * @return the invoice date
  108.      */
  109.     public Date getInvoiceDate() {
  110.         return invoiceDate;
  111.     }
  112.  
  113.     /**
  114.      * Sets the invoice date.
  115.      *
  116.      * @param invoiceDate the new invoice date
  117.      */
  118.     public void setInvoiceDate(Date invoiceDate) {
  119.         this.invoiceDate = invoiceDate;
  120.     }
  121.    
  122.     /* (non-Javadoc)
  123.      * @see java.lang.Object#toString()
  124.      */
  125.     @Override
  126.     public String toString() {
  127.         StringBuilder sb = new StringBuilder();
  128.         sb.append("Invoice id: ").append(id).append(" Date: ").append(invoiceDate).append(" Total cost: ").append(total).append("\u20ac\n");
  129.         sb.append("Customer: ").append(customer.toString()).append("\n");
  130.         for (Item item : items) {
  131.             sb.append(item.toString()).append("\n");
  132.         }
  133.         return sb.toString();
  134.     }
  135. }
Item.java
  1. /*
  2.  * Part of a set of classes based on a sample database.
  3.  * This example was written by Bruno Lowagie in the context of a book.
  4.  * See http://developers.itextpdf.com/content/zugferd-future-invoicing/3-simple-invoice-database
  5.  */
  6. package com.itextpdf.zugferd.pojo;
  7.  
  8. /**
  9.  * Plain Old Java Object containing info about an Item.
  10.  * @author Bruno Lowagie (iText Software)
  11.  */
  12. public class Item {
  13.    
  14.     /** The item. */
  15.     protected int item;
  16.    
  17.     /** The product. */
  18.     protected Product product;
  19.    
  20.     /** The quantity. */
  21.     protected int quantity;
  22.    
  23.     /** The cost. */
  24.     protected double cost;
  25.  
  26.     /**
  27.      * Gets the item.
  28.      *
  29.      * @return the item
  30.      */
  31.     public int getItem() {
  32.         return item;
  33.     }
  34.  
  35.     /**
  36.      * Sets the item.
  37.      *
  38.      * @param item the new item
  39.      */
  40.     public void setItem(int item) {
  41.         this.item = item;
  42.     }
  43.  
  44.     /**
  45.      * Gets the product.
  46.      *
  47.      * @return the product
  48.      */
  49.     public Product getProduct() {
  50.         return product;
  51.     }
  52.  
  53.     /**
  54.      * Sets the product.
  55.      *
  56.      * @param product the new product
  57.      */
  58.     public void setProduct(Product product) {
  59.         this.product = product;
  60.     }
  61.  
  62.     /**
  63.      * Gets the quantity.
  64.      *
  65.      * @return the quantity
  66.      */
  67.     public int getQuantity() {
  68.         return quantity;
  69.     }
  70.  
  71.     /**
  72.      * Sets the quantity.
  73.      *
  74.      * @param quantity the new quantity
  75.      */
  76.     public void setQuantity(int quantity) {
  77.         this.quantity = quantity;
  78.     }
  79.  
  80.     /**
  81.      * Gets the cost.
  82.      *
  83.      * @return the cost
  84.      */
  85.     public double getCost() {
  86.         return cost;
  87.     }
  88.  
  89.     /**
  90.      * Sets the cost.
  91.      *
  92.      * @param cost the new cost
  93.      */
  94.     public void setCost(double cost) {
  95.         this.cost = cost;
  96.     }
  97.    
  98.     /* (non-Javadoc)
  99.      * @see java.lang.Object#toString()
  100.      */
  101.     @Override
  102.     public String toString() {
  103.         StringBuilder sb = new StringBuilder();
  104.         sb.append("  #").append(item);
  105.         sb.append(product.toString());
  106.         sb.append("\tQuantity: ").append(quantity);
  107.         sb.append("\tCost: ").append(cost).append("\u20ac");
  108.         return sb.toString();
  109.     }
  110. }
PojoFactory.java
  1. /*
  2.  * Part of a set of classes based on a sample database.
  3.  * This example was written by Bruno Lowagie in the context of a book.
  4.  * See http://developers.itextpdf.com/content/zugferd-future-invoicing/3-simple-invoice-database
  5.  */
  6. package com.itextpdf.zugferd.pojo;
  7.  
  8. import java.sql.Connection;
  9. import java.sql.DriverManager;
  10. import java.sql.PreparedStatement;
  11. import java.sql.ResultSet;
  12. import java.sql.SQLException;
  13. import java.sql.Statement;
  14. import java.util.ArrayList;
  15. import java.util.HashMap;
  16. import java.util.List;
  17.  
  18. /**
  19.  * Factory that creates Invoice, Customer, Product, and Item classes.
  20.  * @author Bruno Lowagie (iText Software)
  21.  */
  22. public class PojoFactory {
  23.    
  24.     /** Instance of this PojoFactory that will be reused. */
  25.     protected static PojoFactory factory = null;
  26.    
  27.     /** The connection to the HSQLDB database. */
  28.     protected Connection connection;
  29.    
  30.     /** The customer cache. */
  31.     protected HashMap<Integer, Customer> customerCache = new HashMap<Integer, Customer>();
  32.    
  33.     /** The product cache. */
  34.     protected HashMap<Integer, Product> productCache = new HashMap<Integer, Product>();
  35.    
  36.     /** Prepared statement to get customer data. */
  37.     protected PreparedStatement getCustomer;
  38.  
  39.     /** Prepared statement to get product data. */
  40.     protected PreparedStatement getProduct;
  41.  
  42.     /** Prepared statement to get items. */
  43.     protected PreparedStatement getItems;
  44.    
  45.     /**
  46.      * Instantiates a new POJO factory.
  47.      *
  48.      * @throws ClassNotFoundException the class not found exception
  49.      * @throws SQLException the SQL exception
  50.      */
  51.     private PojoFactory() throws ClassNotFoundException, SQLException {
  52.         Class.forName("org.hsqldb.jdbcDriver");
  53.         connection = DriverManager.getConnection(
  54.             "jdbc:hsqldb:resources/db/invoices", "SA", "");
  55.         getCustomer = connection.prepareStatement("SELECT * FROM Customer WHERE id = ?");
  56.         getProduct = connection.prepareStatement("SELECT * FROM Product WHERE id = ?");
  57.         getItems = connection.prepareStatement("SELECT * FROM Item WHERE invoiceid = ?");
  58.     }
  59.    
  60.     /**
  61.      * Gets the single instance of PojoFactory.
  62.      *
  63.      * @return single instance of PojoFactory
  64.      * @throws SQLException the SQL exception
  65.      */
  66.     public static PojoFactory getInstance() throws SQLException {
  67.         if (factory == null || factory.connection.isClosed()) {
  68.             try {
  69.                 factory = new PojoFactory();
  70.             } catch (ClassNotFoundException cnfe) {
  71.                 throw new SQLException(cnfe.getMessage());
  72.             }
  73.         }
  74.         return factory;
  75.     }
  76.    
  77.     /**
  78.      * Close the database connection.
  79.      *
  80.      * @throws SQLException the SQL exception
  81.      */
  82.     public void close() throws SQLException {
  83.         connection.close();
  84.     }
  85.    
  86.     /**
  87.      * Gets all the {@link Invoice} objects stored in the database.
  88.      *
  89.      * @return the invoices
  90.      * @throws SQLException the SQL exception
  91.      */
  92.     public List<Invoice> getInvoices() throws SQLException {
  93.         List<Invoice> invoices = new ArrayList<Invoice>();
  94.         Statement stm = connection.createStatement();
  95.         ResultSet rs = stm.executeQuery("SELECT * FROM Invoice");
  96.         while (rs.next()) {
  97.             invoices.add(getInvoice(rs));
  98.         }
  99.         stm.close();
  100.         return invoices;
  101.     }
  102.    
  103.     /**
  104.      * Creates an {@link Invoice} object from a database result set.
  105.      *
  106.      * @param rs the result set
  107.      * @return the invoice object
  108.      * @throws SQLException the SQL exception
  109.      */
  110.     public Invoice getInvoice(ResultSet rs) throws SQLException {
  111.         Invoice invoice = new Invoice();
  112.         invoice.setId(rs.getInt("id"));
  113.         invoice.setCustomer(getCustomer(rs.getInt("customerid")));
  114.         List<Item> items = getItems(rs.getInt("id"));
  115.         invoice.setItems(items);
  116.         double total = 0;
  117.         for (Item item : items)
  118.             total += item.getCost();
  119.         invoice.setTotal(total);
  120.         invoice.setInvoiceDate(rs.getDate("invoicedate"));
  121.         return invoice;
  122.     }
  123.    
  124.     /**
  125.      * Creates an {@link Item} object from a database result set.
  126.      *
  127.      * @param rs the result set
  128.      * @return the item object
  129.      * @throws SQLException the SQL exception
  130.      */
  131.     public Item getItem(ResultSet rs) throws SQLException {
  132.         Item item = new Item();
  133.         item.setItem(rs.getInt("Item"));
  134.         Product product = getProduct(rs.getInt("ProductId"));
  135.         item.setProduct(product);
  136.         item.setQuantity(rs.getInt("Quantity"));
  137.         item.setCost(item.getQuantity() * product.getPrice());
  138.         return item;
  139.     }
  140.    
  141.     /**
  142.      * Gets a {@link Customer} object, given a customer id.
  143.      *
  144.      * @param id the customer id
  145.      * @return the customer object
  146.      * @throws SQLException the SQL exception
  147.      */
  148.     public Customer getCustomer(int id) throws SQLException {
  149.         if (customerCache.containsKey(id))
  150.             return customerCache.get(id);
  151.         getCustomer.setInt(1, id);
  152.         ResultSet rs = getCustomer.executeQuery();
  153.         if (rs.next()) {
  154.             Customer customer = new Customer();
  155.             customer.setId(id);
  156.             customer.setFirstName(rs.getString("FirstName"));
  157.             customer.setLastName(rs.getString("LastName"));
  158.             customer.setStreet(rs.getString("Street"));
  159.             customer.setPostalcode(rs.getString("Postalcode"));
  160.             customer.setCity(rs.getString("City"));
  161.             customer.setCountryId(rs.getString("CountryID"));
  162.             customerCache.put(id, customer);
  163.             return customer;
  164.         }
  165.         return null;
  166.     }
  167.    
  168.     /**
  169.      * Gets a {@link Product} object, given a product id.
  170.      *
  171.      * @param id the product id
  172.      * @return the product object
  173.      * @throws SQLException the SQL exception
  174.      */
  175.     public Product getProduct(int id) throws SQLException {
  176.         if (productCache.containsKey(id))
  177.             return productCache.get(id);
  178.         getProduct.setInt(1, id);
  179.         ResultSet rs = getProduct.executeQuery();
  180.         if (rs.next()) {
  181.             Product product = new Product();
  182.             product.setId(id);
  183.             product.setName(rs.getString("Name"));
  184.             product.setPrice(rs.getDouble("Price"));
  185.             product.setVat(rs.getDouble("Vat"));
  186.             productCache.put(id, product);
  187.             return product;
  188.         }
  189.         return null;
  190.     }
  191.    
  192.     /**
  193.      * Gets a list of {@link Item} objects for a specific invoice.
  194.      *
  195.      * @param invoiceid the invoice id
  196.      * @return the items
  197.      * @throws SQLException the SQL exception
  198.      */
  199.     public List<Item> getItems(int invoiceid) throws SQLException {
  200.         List<Item> items = new ArrayList<Item>();
  201.         getItems.setInt(1, invoiceid);
  202.         ResultSet rs = getItems.executeQuery();
  203.         while (rs.next()) {
  204.             items.add(getItem(rs));
  205.         }
  206.         return items;
  207.     }
  208. }
Product.java
  1. /*
  2.  * Part of a set of classes based on a sample database.
  3.  * This example was written by Bruno Lowagie in the context of a book.
  4.  * See http://developers.itextpdf.com/content/zugferd-future-invoicing/3-simple-invoice-database
  5.  */
  6. package com.itextpdf.zugferd.pojo;
  7.  
  8. /**
  9.  * Plain Old Java Object containing info about a Product.
  10.  * @author Bruno Lowagie (iText Software)
  11.  */
  12. public class Product {
  13.    
  14.     /** The id. */
  15.     protected int id;
  16.    
  17.     /** The name. */
  18.     protected String name;
  19.    
  20.     /** The price. */
  21.     protected double price;
  22.    
  23.     /** The vat. */
  24.     protected double vat;
  25.  
  26.     /**
  27.      * Gets the id.
  28.      *
  29.      * @return the id
  30.      */
  31.     public int getId() {
  32.         return id;
  33.     }
  34.  
  35.     /**
  36.      * Sets the id.
  37.      *
  38.      * @param id the new id
  39.      */
  40.     public void setId(int id) {
  41.         this.id = id;
  42.     }
  43.  
  44.     /**
  45.      * Gets the name.
  46.      *
  47.      * @return the name
  48.      */
  49.     public String getName() {
  50.         return name;
  51.     }
  52.  
  53.     /**
  54.      * Sets the name.
  55.      *
  56.      * @param name the new name
  57.      */
  58.     public void setName(String name) {
  59.         this.name = name;
  60.     }
  61.  
  62.     /**
  63.      * Gets the price.
  64.      *
  65.      * @return the price
  66.      */
  67.     public double getPrice() {
  68.         return price;
  69.     }
  70.  
  71.     /**
  72.      * Sets the price.
  73.      *
  74.      * @param price the new price
  75.      */
  76.     public void setPrice(double price) {
  77.         this.price = price;
  78.     }
  79.  
  80.     /**
  81.      * Gets the vat.
  82.      *
  83.      * @return the vat
  84.      */
  85.     public double getVat() {
  86.         return vat;
  87.     }
  88.  
  89.     /**
  90.      * Sets the vat.
  91.      *
  92.      * @param vat the new vat
  93.      */
  94.     public void setVat(double vat) {
  95.         this.vat = vat;
  96.     }
  97.    
  98.     /* (non-Javadoc)
  99.      * @see java.lang.Object#toString()
  100.      */
  101.     @Override
  102.     public String toString() {
  103.         StringBuilder sb = new StringBuilder();
  104.         sb.append("\t(").append(id).append(")\t").append(name).append("\t").append(price).append("\u20ac\tvat ").append(vat).append("%");
  105.         return sb.toString();
  106.     }
  107. }
PdfInvoicesBasic.java
  1. /*
  2.  * This example was written by Bruno Lowagie in the context of a book.
  3.  * See http://developers.itextpdf.com/content/zugferd-future-invoicing/5-creating-pdf-invoices-basic-profile
  4.  */
  5. package com.itextpdf.zugferd;
  6.  
  7. import java.io.File;
  8. import java.io.FileInputStream;
  9. import java.io.IOException;
  10. import java.sql.SQLException;
  11. import java.text.ParseException;
  12. import java.text.SimpleDateFormat;
  13. import java.util.Date;
  14. import java.util.List;
  15.  
  16. import javax.xml.parsers.ParserConfigurationException;
  17. import javax.xml.transform.TransformerException;
  18.  
  19. import com.itextpdf.kernel.pdf.filespec.PdfFileSpec;
  20. import org.xml.sax.SAXException;
  21.  
  22. import com.itextpdf.kernel.font.PdfFont;
  23. import com.itextpdf.kernel.font.PdfFontFactory;
  24. import com.itextpdf.kernel.pdf.PdfDictionary;
  25. import com.itextpdf.kernel.pdf.PdfName;
  26. import com.itextpdf.kernel.pdf.PdfOutputIntent;
  27. import com.itextpdf.kernel.pdf.PdfWriter;
  28. import com.itextpdf.layout.Document;
  29. import com.itextpdf.layout.borders.Border;
  30. import com.itextpdf.layout.element.Cell;
  31. import com.itextpdf.layout.element.Paragraph;
  32. import com.itextpdf.layout.element.Table;
  33. import com.itextpdf.layout.element.Text;
  34. import com.itextpdf.layout.property.TextAlignment;
  35. import com.itextpdf.layout.property.UnitValue;
  36. import com.itextpdf.licensekey.LicenseKey;
  37. import com.itextpdf.zugferd.data.InvoiceData;
  38. import com.itextpdf.zugferd.exceptions.DataIncompleteException;
  39. import com.itextpdf.zugferd.exceptions.InvalidCodeException;
  40. import com.itextpdf.zugferd.pojo.Invoice;
  41. import com.itextpdf.zugferd.pojo.Item;
  42. import com.itextpdf.zugferd.pojo.PojoFactory;
  43. import com.itextpdf.zugferd.pojo.Product;
  44. import com.itextpdf.zugferd.profiles.IBasicProfile;
  45.  
  46. /**
  47.  * Reads invoice data from a test database and creates ZUGFeRD invoices
  48.  * (Basic profile).
  49.  * @author Bruno Lowagie
  50.  */
  51. public class PdfInvoicesBasic {
  52.    
  53.     /** The pattern of the destination paths. */
  54.     public static final String DEST = "results/zugferd/pdf/basic%05d.pdf";
  55.    
  56.     /** The path to the color profile. */
  57.     public static final String ICC = "resources/color/sRGB_CS_profile.icm";
  58.    
  59.     /** The path to a regular font. */
  60.     public static final String REGULAR = "resources/fonts/OpenSans-Regular.ttf";
  61.    
  62.     /** The path to a bold font. */
  63.     public static final String BOLD = "resources/fonts/OpenSans-Bold.ttf";
  64.    
  65.     /** A <code>String</code> with a newline character. */
  66.     public static final String NEWLINE = "\n";
  67.    
  68.     /**
  69.      * The main method.
  70.      *
  71.      * @param args the arguments
  72.      * @throws IOException Signals that an I/O exception has occurred.
  73.      * @throws ParserConfigurationException the parser configuration exception
  74.      * @throws SQLException the SQL exception
  75.      * @throws SAXException the SAX exception
  76.      * @throws TransformerException the transformer exception
  77.      * @throws ParseException the parse exception
  78.      * @throws DataIncompleteException the data incomplete exception
  79.      * @throws InvalidCodeException the invalid code exception
  80.      */
  81.     public static void main(String[] args) throws IOException, ParserConfigurationException, SQLException, SAXException, TransformerException, ParseException, DataIncompleteException, InvalidCodeException {
  82.         LicenseKey.loadLicenseFile(System.getenv("ITEXT7_LICENSEKEY") + "/itextkey-html2pdf_typography.xml");
  83.         File file = new File(DEST);
  84.         file.getParentFile().mkdirs();
  85.         PdfInvoicesBasic app = new PdfInvoicesBasic();
  86.         PojoFactory factory = PojoFactory.getInstance();
  87.         List<Invoice> invoices = factory.getInvoices();
  88.         for (Invoice invoice : invoices) {
  89.             app.createPdf(invoice);
  90.         }
  91.         factory.close();
  92.     }
  93.    
  94.     /**
  95.      * Creates a PDF file, given a certain invoice.
  96.      *
  97.      * @param invoice the invoice
  98.      * @throws ParserConfigurationException the parser configuration exception
  99.      * @throws SAXException the SAX exception
  100.      * @throws TransformerException the transformer exception
  101.      * @throws IOException Signals that an I/O exception has occurred.
  102.      * @throws ParseException the parse exception
  103.      * @throws DataIncompleteException the data incomplete exception
  104.      * @throws InvalidCodeException the invalid code exception
  105.      */
  106.     public void createPdf(Invoice invoice) throws ParserConfigurationException, SAXException, TransformerException, IOException, ParseException, DataIncompleteException, InvalidCodeException {
  107.        
  108.         String dest = String.format(DEST, invoice.getId());
  109.        
  110.         // Create the XML
  111.         InvoiceData invoiceData = new InvoiceData();
  112.         IBasicProfile basic = invoiceData.createBasicProfileData(invoice);
  113.         InvoiceDOM dom = new InvoiceDOM(basic);
  114.        
  115.         // Create the ZUGFeRD document
  116.         ZugferdDocument pdfDocument = new ZugferdDocument(
  117.                 new PdfWriter(dest), ZugferdConformanceLevel.ZUGFeRDBasic,
  118.                 new PdfOutputIntent("Custom", "", "http://www.color.org",
  119.                         "sRGB IEC61966-2.1", new FileInputStream(ICC)));
  120.         pdfDocument.addFileAttachment("ZUGFeRD invoice", PdfFileSpec.createEmbeddedFileSpec(
  121.                 pdfDocument, dom.toXML(), "ZUGFeRD invoice", "ZUGFeRD-invoice.xml",
  122.                 PdfName.ApplicationXml, new PdfDictionary(), PdfName.Alternative));
  123.        
  124.         // Create the document
  125.         Document document = new Document(pdfDocument);
  126.         document.setFont(PdfFontFactory.createFont(REGULAR, true))
  127.                 .setFontSize(12);
  128.         PdfFont bold = PdfFontFactory.createFont(BOLD, true);
  129.        
  130.         // Add the header
  131.         document.add(
  132.             new Paragraph()
  133.             .   setTextAlignment(TextAlignment.RIGHT)
  134.                 .setMultipliedLeading(1)
  135.                 .add(new Text(String.format("%s %s\n", basic.getName(), basic.getId()))
  136.                         .setFont(bold).setFontSize(14))
  137.                 .add(convertDate(basic.getDateTime(), "MMM dd, yyyy")));
  138.         // Add the seller and buyer address
  139.         document.add(getAddressTable(basic, bold));
  140.         // Add the line items
  141.         document.add(getLineItemTable(invoice, bold));
  142.         // Add the grand totals
  143.         document.add(getTotalsTable(
  144.                 basic.getTaxBasisTotalAmount(), basic.getTaxTotalAmount(), basic.getGrandTotalAmount(), basic.getGrandTotalAmountCurrencyID(),
  145.                 basic.getTaxTypeCode(), basic.getTaxApplicablePercent(),
  146.                 basic.getTaxBasisAmount(), basic.getTaxCalculatedAmount(), basic.getTaxCalculatedAmountCurrencyID(), bold));
  147.         // Add the payment info
  148.         document.add(getPaymentInfo(basic.getPaymentReference(), basic.getPaymentMeansPayeeFinancialInstitutionBIC(), basic.getPaymentMeansPayeeAccountIBAN()));
  149.        
  150.         document.close();
  151.     }
  152.  
  153.     /**
  154.      * Convert a date to a String in a certain format.
  155.      *
  156.      * @param d the date
  157.      * @param newFormat the new format
  158.      * @return the date as a string
  159.      * @throws ParseException the parse exception
  160.      */
  161.     public String convertDate(Date d, String newFormat) throws ParseException {
  162.         SimpleDateFormat sdf = new SimpleDateFormat(newFormat);
  163.         return sdf.format(d);
  164.     }
  165.    
  166.     /**
  167.      * Gets the address table.
  168.      *
  169.      * @param basic the {@link IBasicProfile} instance
  170.      * @param bold a bold font
  171.      * @return the address table
  172.      */
  173.     public Table getAddressTable(IBasicProfile basic, PdfFont bold) {
  174.         Table table = new Table(new UnitValue[]{
  175.                 new UnitValue(UnitValue.PERCENT, 50),
  176.                 new UnitValue(UnitValue.PERCENT, 50)})
  177.                 .setWidth(UnitValue.createPercentValue(100));
  178.         table.addCell(getPartyAddress("From:",
  179.                 basic.getSellerName(),
  180.                 basic.getSellerLineOne(),
  181.                 basic.getSellerLineTwo(),
  182.                 basic.getSellerCountryID(),
  183.                 basic.getSellerPostcode(),
  184.                 basic.getSellerCityName(),
  185.                 bold));
  186.         table.addCell(getPartyAddress("To:",
  187.                 basic.getBuyerName(),
  188.                 basic.getBuyerLineOne(),
  189.                 basic.getBuyerLineTwo(),
  190.                 basic.getBuyerCountryID(),
  191.                 basic.getBuyerPostcode(),
  192.                 basic.getBuyerCityName(),
  193.                 bold));
  194.         table.addCell(getPartyTax(basic.getSellerTaxRegistrationID(),
  195.                 basic.getSellerTaxRegistrationSchemeID(), bold));
  196.         table.addCell(getPartyTax(basic.getBuyerTaxRegistrationID(),
  197.                 basic.getBuyerTaxRegistrationSchemeID(), bold));
  198.         return table;
  199.     }
  200.    
  201.     /**
  202.      * Gets the party address.
  203.      *
  204.      * @param who either "To:" or "From:"
  205.      * @param name the addressee
  206.      * @param line1 line 1 of he address
  207.      * @param line2 line 2 of the address
  208.      * @param countryID the country ID
  209.      * @param postcode the post code
  210.      * @param city the city
  211.      * @param bold a bold font
  212.      * @return a formatted address cell
  213.      */
  214.     public Cell getPartyAddress(String who, String name, String line1, String line2, String countryID, String postcode, String city, PdfFont bold) {
  215.         Paragraph p = new Paragraph()
  216.                 .setMultipliedLeading(1.0f)
  217.                 .add(new Text(who).setFont(bold)).add(NEWLINE)
  218.                 .add(name).add(NEWLINE)
  219.                 .add(line1).add(NEWLINE)
  220.                 .add(line2).add(NEWLINE)
  221.                 .add(String.format("%s-%s %s", countryID, postcode, city));
  222.         Cell cell = new Cell()
  223.                 .setBorder(Border.NO_BORDER)
  224.                 .add(p);
  225.         return cell;
  226.     }
  227.    
  228.     /**
  229.      * Gets the party tax.
  230.      *
  231.      * @param taxId the tax id
  232.      * @param taxSchema the tax schema
  233.      * @param bold a bold font
  234.      * @return a formatted cell
  235.      */
  236.     public Cell getPartyTax(String[] taxId, String[] taxSchema, PdfFont bold) {
  237.         Paragraph p = new Paragraph()
  238.             .setFontSize(10).setMultipliedLeading(1.0f)
  239.             .add(new Text("Tax ID(s):").setFont(bold));
  240.         if (taxId.length == 0) {
  241.             p.add("\nNot applicable");
  242.         }
  243.         else {
  244.             int n = taxId.length;
  245.             for (int i = 0; i < n; i++) {
  246.                 p.add(NEWLINE)
  247.                 .add(String.format("%s: %s", taxSchema[i], taxId[i]));
  248.             }
  249.         }
  250.         return new Cell().setBorder(Border.NO_BORDER).add(p);
  251.     }
  252.    
  253.     /**
  254.      * Gets the line item table.
  255.      *
  256.      * @param invoice the invoice
  257.      * @param bold a bold font
  258.      * @return the line item table
  259.      */
  260.     public Table getLineItemTable(Invoice invoice, PdfFont bold) {
  261.         Table table = new Table(new UnitValue[]{
  262.                 new UnitValue(UnitValue.PERCENT, 43.75f),
  263.                 new UnitValue(UnitValue.PERCENT, 12.5f),
  264.                 new UnitValue(UnitValue.PERCENT, 6.25f),
  265.                 new UnitValue(UnitValue.PERCENT, 12.5f),
  266.                 new UnitValue(UnitValue.PERCENT, 12.5f),
  267.                 new UnitValue(UnitValue.PERCENT, 12.5f)})
  268.                 .setWidth(UnitValue.createPercentValue(100))
  269.                 .setMarginTop(10).setMarginBottom(10);
  270.         table.addHeaderCell(createCell("Item:", bold));
  271.         table.addHeaderCell(createCell("Price:", bold));
  272.         table.addHeaderCell(createCell("Qty:", bold));
  273.         table.addHeaderCell(createCell("Subtotal:", bold));
  274.         table.addHeaderCell(createCell("VAT:", bold));
  275.         table.addHeaderCell(createCell("Total:", bold));
  276.         Product product;
  277.         for (Item item : invoice.getItems()) {
  278.             product = item.getProduct();
  279.             table.addCell(createCell(product.getName()));
  280.             table.addCell(createCell(
  281.                 InvoiceData.format2dec(InvoiceData.round(product.getPrice())))
  282.                 .setTextAlignment(TextAlignment.RIGHT));
  283.             table.addCell(createCell(String.valueOf(item.getQuantity()))
  284.                 .setTextAlignment(TextAlignment.RIGHT));
  285.             table.addCell(createCell(
  286.                 InvoiceData.format2dec(InvoiceData.round(item.getCost())))
  287.                 .setTextAlignment(TextAlignment.RIGHT));
  288.             table.addCell(createCell(
  289.                 InvoiceData.format2dec(InvoiceData.round(product.getVat())))
  290.                 .setTextAlignment(TextAlignment.RIGHT));
  291.             table.addCell(createCell(
  292.                 InvoiceData.format2dec(InvoiceData.round(
  293.                     item.getCost() + ((item.getCost() * product.getVat()) / 100))))
  294.                 .setTextAlignment(TextAlignment.RIGHT));
  295.         }
  296.         return table;
  297.     }
  298.    
  299.     /**
  300.      * Creates a cell with specific properties set.
  301.      *
  302.      * @param text the text that will be in the cell
  303.      * @return the cell
  304.      */
  305.    
  306.     public Cell createCell(String text) {
  307.         return new Cell().setPadding(0.8f)
  308.             .add(new Paragraph(text)
  309.                 .setMultipliedLeading(1));
  310.     }
  311.    
  312.     /**
  313.      * Creates a cell with specific properties set.
  314.      *
  315.      * @param text the text that will be in the cell
  316.      * @param font the font
  317.      * @return the cell
  318.      */
  319.     public Cell createCell(String text, PdfFont font) {
  320.         return new Cell().setPadding(0.8f)
  321.             .add(new Paragraph(text)
  322.                 .setFont(font).setMultipliedLeading(1));
  323.     }
  324.    
  325.     /**
  326.      * Gets the totals table.
  327.      *
  328.      * @param tBase the total tax base
  329.      * @param tTax the total tax amount
  330.      * @param tTotal the total tax
  331.      * @param tCurrency the tax currency
  332.      * @param type the tax types
  333.      * @param percentage the tax percentages
  334.      * @param base the base amounts
  335.      * @param tax the tax amounts
  336.      * @param currency the currencies
  337.      * @param bold a bold font
  338.      * @return the totals table
  339.      */
  340.     public Table getTotalsTable(String tBase, String tTax, String tTotal, String tCurrency,
  341.             String[] type, String[] percentage, String base[], String tax[], String currency[],
  342.             PdfFont bold) {
  343.         Table table = new Table(new UnitValue[]{
  344.                 new UnitValue(UnitValue.PERCENT, 8.33f),
  345.                 new UnitValue(UnitValue.PERCENT, 8.33f),
  346.                 new UnitValue(UnitValue.PERCENT, 25f),
  347.                 new UnitValue(UnitValue.PERCENT, 25f),
  348.                 new UnitValue(UnitValue.PERCENT, 25f),
  349.                 new UnitValue(UnitValue.PERCENT, 8.34f)})
  350.             .setWidth(UnitValue.createPercentValue(100));
  351.         table.addCell(createCell("TAX:", bold));
  352.         table.addCell(createCell("%", bold)
  353.             .setTextAlignment(TextAlignment.RIGHT));
  354.         table.addCell(createCell("Base amount:", bold));
  355.         table.addCell(createCell("Tax amount:", bold));
  356.         table.addCell(createCell("Total:", bold));
  357.         table.addCell(createCell("Curr.:", bold));
  358.         int n = type.length;
  359.         for (int i = 0; i < n; i++) {
  360.             table.addCell(createCell(type[i])
  361.                 .setTextAlignment(TextAlignment.RIGHT));
  362.             table.addCell(createCell(percentage[i])
  363.                 .setTextAlignment(TextAlignment.RIGHT));
  364.             table.addCell(createCell(base[i])
  365.                 .setTextAlignment(TextAlignment.RIGHT));
  366.             table.addCell(createCell(tax[i])
  367.                 .setTextAlignment(TextAlignment.RIGHT));
  368.             double total = Double.parseDouble(base[i]) + Double.parseDouble(tax[i]);
  369.             table.addCell(createCell(
  370.                 InvoiceData.format2dec(InvoiceData.round(total)))
  371.                 .setTextAlignment(TextAlignment.RIGHT));
  372.             table.addCell(createCell(currency[i]));
  373.         }
  374.         table.addCell(new Cell(1, 2).setBorder(Border.NO_BORDER));
  375.         table.addCell(createCell(tBase, bold)
  376.             .setTextAlignment(TextAlignment.RIGHT));
  377.         table.addCell(createCell(tTax, bold)
  378.             .setTextAlignment(TextAlignment.RIGHT));
  379.         table.addCell(createCell(tTotal, bold)
  380.             .setTextAlignment(TextAlignment.RIGHT));
  381.         table.addCell(createCell(tCurrency, bold));
  382.         return table;
  383.     }
  384.    
  385.     /**
  386.      * Gets the payment info.
  387.      *
  388.      * @param ref the reference
  389.      * @param bic the BIC code
  390.      * @param iban the IBAN code
  391.      * @return the payment info
  392.      */
  393.     public Paragraph getPaymentInfo(String ref, String[] bic, String[] iban) {
  394.         Paragraph p = new Paragraph(String.format(
  395.                 "Please wire the amount due to our bank account using the following reference: %s",
  396.                 ref));
  397.         int n = bic.length;
  398.         for (int i = 0; i < n; i++) {
  399.             p.add(NEWLINE).add(String.format("BIC: %s - IBAN: %s", bic[i], iban[i]));
  400.         }
  401.         return p;
  402.     }
  403. }
InvoiceData.java
  1. /*
  2.  * Code written by Bruno Lowagie in the context of an example for the ZUGFeRD book.
  3.  * See http://developers.itextpdf.com/content/zugferd-future-invoicing/
  4.  */
  5. package com.itextpdf.zugferd.data;
  6.  
  7. import java.util.Map;
  8. import java.util.TreeMap;
  9.  
  10. import com.itextpdf.zugferd.pojo.Customer;
  11. import com.itextpdf.zugferd.pojo.Invoice;
  12. import com.itextpdf.zugferd.pojo.Item;
  13. import com.itextpdf.zugferd.profiles.BasicProfileImp;
  14. import com.itextpdf.zugferd.profiles.ComfortProfileImp;
  15. import com.itextpdf.zugferd.profiles.IBasicProfile;
  16. import com.itextpdf.zugferd.profiles.IComfortProfile;
  17. import com.itextpdf.zugferd.validation.basic.DateFormatCode;
  18. import com.itextpdf.zugferd.validation.basic.DocumentTypeCode;
  19. import com.itextpdf.zugferd.validation.basic.TaxIDTypeCode;
  20. import com.itextpdf.zugferd.validation.basic.TaxTypeCode;
  21. import com.itextpdf.zugferd.validation.comfort.FreeTextSubjectCode;
  22. import com.itextpdf.zugferd.validation.comfort.PaymentMeansCode;
  23. import com.itextpdf.zugferd.validation.comfort.TaxCategoryCode;
  24.  
  25. /**
  26.  * Class in which we can store all the data of an {@link Invoice} object.
  27.  *
  28.  * @author Bruno Lowagie (iText Software)
  29.  */
  30. public class InvoiceData {
  31.    
  32.     /**
  33.      * Creates a new {@link InvoiceData} instance.
  34.      */
  35.     public InvoiceData() {
  36.     }
  37.    
  38.     /**
  39.      * Creates a object that implements the {@link IBasicProfile} interface,
  40.      * given a specific {@link Invoice} object.
  41.      *
  42.      * @param invoice the invoice
  43.      * @return the {@link IBasicProfile} implementation
  44.      */
  45.     public IBasicProfile createBasicProfileData(Invoice invoice) {
  46.         BasicProfileImp profileImp = new BasicProfileImp(true);
  47.         importData(profileImp, invoice);
  48.         importBasicData(profileImp, invoice);
  49.         return profileImp;
  50.     }
  51.    
  52.     /**
  53.      * Creates a object that implements the {@link IComfortProfile} interface,
  54.      * given a specific {@link Invoice} object.
  55.      *
  56.      * @param invoice the invoice
  57.      * @return the {@link IComfortProfile} implementation
  58.      */
  59.     public IComfortProfile createComfortProfileData(Invoice invoice) {
  60.         ComfortProfileImp profileImp = new ComfortProfileImp(true);
  61.         importData(profileImp, invoice);
  62.         importComfortData(profileImp, invoice);
  63.         return profileImp;
  64.     }
  65.    
  66.     /**
  67.      * Imports the data from an invoice into a {@link BasicProfileImp} instance.
  68.      *
  69.      * @param profileImp the {IBasicProfile} implementation
  70.      * @param invoice the invoice
  71.      */
  72.     public void importData(BasicProfileImp profileImp, Invoice invoice) {
  73.         profileImp.setTest(true);
  74.         profileImp.setId(String.format("I/%05d", invoice.getId()));
  75.         profileImp.setName("INVOICE");
  76.         profileImp.setTypeCode(DocumentTypeCode.COMMERCIAL_INVOICE);
  77.         profileImp.setDate(invoice.getInvoiceDate(), DateFormatCode.YYYYMMDD);
  78.         profileImp.setSellerName("Das Company");
  79.         profileImp.setSellerLineOne("ZUG Business Center");
  80.         profileImp.setSellerLineTwo("Highway 1");
  81.         profileImp.setSellerPostcode("9000");
  82.         profileImp.setSellerCityName("Ghent");
  83.         profileImp.setSellerCountryID("BE");
  84.         profileImp.addSellerTaxRegistration(TaxIDTypeCode.FISCAL_NUMBER, "201/113/40209");
  85.         profileImp.addSellerTaxRegistration(TaxIDTypeCode.VAT, "BE123456789");
  86.         Customer customer = invoice.getCustomer();
  87.         profileImp.setBuyerName(String.format("%s, %s", customer.getLastName(), customer.getFirstName()));
  88.         profileImp.setBuyerPostcode(customer.getPostalcode());
  89.         profileImp.setBuyerLineOne(customer.getStreet());
  90.         profileImp.setBuyerLineTwo("");
  91.         profileImp.setBuyerCityName(customer.getCity());
  92.         profileImp.setBuyerCountryID(customer.getCountryId());
  93.         profileImp.setPaymentReference(String.format("%09d", invoice.getId()));
  94.         profileImp.setInvoiceCurrencyCode("EUR");
  95.     }
  96.    
  97.     /**
  98.      * Import the basic data into a {@link BasicProfileImp} instance.
  99.      *
  100.      * @param profileImp the {IBasicProfile} implementation
  101.      * @param invoice the invoice
  102.      */
  103.     public void importBasicData(BasicProfileImp profileImp, Invoice invoice) {
  104.         profileImp.addNote(
  105.             new String[]{"This is a test invoice.\nNothing on this invoice is real.\nThis invoice is part of a tutorial."});
  106.         profileImp.addPaymentMeans("", "", "BE 41 7360 0661 9710", "", "", "KREDBEBB", "", "KBC");
  107.         profileImp.addPaymentMeans("", "", "BE 56 0015 4298 7888", "", "", "GEBABEBB", "", "BNP Paribas");
  108.         Map<Double,Double> taxes = new TreeMap<Double, Double>();
  109.         double tax;
  110.         for (Item item : invoice.getItems()) {
  111.             tax = item.getProduct().getVat();
  112.             if (taxes.containsKey(tax)) {
  113.                 taxes.put(tax, taxes.get(tax) + item.getCost());
  114.             }
  115.             else {
  116.                 taxes.put(tax, item.getCost());
  117.             }
  118.             profileImp.addIncludedSupplyChainTradeLineItem(format4dec(item.getQuantity()), "C62", item.getProduct().getName());
  119.         }
  120.         double total, tA;
  121.         double ltN = 0;
  122.         double ttA = 0;
  123.         double gtA = 0;
  124.         for (Map.Entry<Double, Double> t : taxes.entrySet()) {
  125.             tax = t.getKey();
  126.             total = round(t.getValue());
  127.             gtA += total;
  128.             tA = round((100 * total) / (100 + tax));
  129.             ttA += (total - tA);
  130.             ltN += tA;
  131.             profileImp.addApplicableTradeTax(format2dec(total - tA), "EUR", TaxTypeCode.VALUE_ADDED_TAX, format2dec(tA), "EUR", format2dec(tax));
  132.         }
  133.         profileImp.setMonetarySummation(format2dec(ltN), "EUR",
  134.             format2dec(0), "EUR",
  135.             format2dec(0), "EUR",
  136.             format2dec(ltN), "EUR",
  137.             format2dec(ttA), "EUR",
  138.             format2dec(gtA), "EUR");
  139.     }
  140.    
  141.     /**
  142.      * Import comfort data into a {@link ComfortProfileImp} instance.
  143.      *
  144.      * @param profileImp the {IComfortProfile} implementation
  145.      * @param invoice the invoice
  146.      */
  147.     public void importComfortData(ComfortProfileImp profileImp, Invoice invoice) {
  148.         profileImp.addNote(
  149.             new String[]{"This is a test invoice.\nNothing on this invoice is real.\nThis invoice is part of a tutorial."},
  150.             FreeTextSubjectCode.REGULATORY_INFORMATION);
  151.         profileImp.addPaymentMeans(
  152.                 PaymentMeansCode.PAYMENT_TO_BANK_ACCOUNT,
  153.                 new String[]{"This is the preferred bank account."},
  154.                 "", "",
  155.                 "", "",
  156.                 "BE 41 7360 0661 9710", "", "",
  157.                 "", "", "",
  158.                 "KREDBEBB", "", "KBC");
  159.         profileImp.addPaymentMeans(
  160.                 PaymentMeansCode.PAYMENT_TO_BANK_ACCOUNT,
  161.                 new String[]{"Use this as an alternative account."},
  162.                 "", "",
  163.                 "", "",
  164.                 "BE 56 0015 4298 7888", "", "",
  165.                 "", "", "",
  166.                 "GEBABEBB", "", "BNP Paribas");
  167.         Map<Double,Double> taxes = new TreeMap<Double, Double>();
  168.         double tax;
  169.         int counter = 0;
  170.         for (Item item : invoice.getItems()) {
  171.             counter++;
  172.             tax = item.getProduct().getVat();
  173.             if (taxes.containsKey(tax)) {
  174.                 taxes.put(tax, taxes.get(tax) + item.getCost());
  175.             }
  176.             else {
  177.                 taxes.put(tax, item.getCost());
  178.             }
  179.             profileImp.addIncludedSupplyChainTradeLineItem(
  180.                     String.valueOf(counter),
  181.                     null,
  182.                     format4dec(item.getProduct().getPrice()), "EUR", null, null,
  183.                     null, null, null, null,
  184.                     null, null, null, null,
  185.                     format4dec(item.getQuantity()), "C62",
  186.                     new String[]{TaxTypeCode.VALUE_ADDED_TAX},
  187.                     new String[1],
  188.                     new String[]{TaxCategoryCode.STANDARD_RATE},
  189.                     new String[]{format2dec(item.getProduct().getVat())},
  190.                     format2dec(item.getCost()), "EUR",
  191.                     null, null,
  192.                     String.valueOf(item.getProduct().getId()), null,
  193.                     item.getProduct().getName(), null
  194.             );
  195.         }
  196.         double total, tA;
  197.         double ltN = 0;
  198.         double ttA = 0;
  199.         double gtA = 0;
  200.         for (Map.Entry<Double, Double> t : taxes.entrySet()) {
  201.             tax = t.getKey();
  202.             total = round(t.getValue());
  203.             gtA += total;
  204.             tA = round((100 * total) / (100 + tax));
  205.             ttA += (total - tA);
  206.             ltN += tA;
  207.             profileImp.addApplicableTradeTax(
  208.                     format2dec(total - tA), "EUR", TaxTypeCode.VALUE_ADDED_TAX,
  209.                     null, format2dec(tA), "EUR",
  210.                     TaxCategoryCode.STANDARD_RATE, format2dec(tax));
  211.         }
  212.         profileImp.setMonetarySummation(format2dec(ltN), "EUR",
  213.             format2dec(0), "EUR",
  214.             format2dec(0), "EUR",
  215.             format2dec(ltN), "EUR",
  216.             format2dec(ttA), "EUR",
  217.             format2dec(gtA), "EUR");
  218.     }
  219.    
  220.     /**
  221.      * Round a double value.
  222.      *
  223.      * @param d the double value
  224.      * @return the rounded double
  225.      */
  226.     public static double round(double d) {
  227.         d = d * 100;
  228.         long tmp = Math.round(d);
  229.         return (double) tmp / 100;
  230.     }
  231.    
  232.     /**
  233.      * Format a double so that it has 2 decimals.
  234.      *
  235.      * @param d the double value
  236.      * @return a string representation of the double value
  237.      */
  238.     public static String format2dec(double d) {
  239.         return String.format("%.2f", d);
  240.     }
  241.    
  242.     /**
  243.      * Format a double so that it has 4 decimals.
  244.      *
  245.      * @param d the double value
  246.      * @return a string representation of the double value
  247.      */
  248.     public static String format4dec(double d) {
  249.         return String.format("%.4f", d);
  250.     }
  251.    
  252. }
Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now