You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2009/11/10 15:49:44 UTC

svn commit: r834486 - in /ofbiz/trunk/applications/accounting/webapp/accounting: WEB-INF/actions/invoice/EditInvoice.groovy invoice/invoiceReportItems.fo.ftl

Author: jacopoc
Date: Tue Nov 10 14:49:44 2009
New Revision: 834486

URL: http://svn.apache.org/viewvc?rev=834486&view=rev
Log:
Misc enhancements and cleanups to the invoice PDF report:
1) xsl-fo layout cleanup
2) suppressed the invoiceItemSeqId field from the output document
3) there are now two separate invoice item layouts for the items and and adjustments
4) improved code to retrieve the bill-to-party tax id, required by VAT rules only: now the tax id is retrieved only if in the invoice there are taxes of type VAT_TAX
5) added shipment date if available
6) as required by EU rules for VAT taxes, if there are VAT taxes in the invoice, then a break-down of the VAT amount payable per VAT rate is displayed at the bottom of the invoice

Now most of the mandatory information required by EU/VAT countries as described here:

http://ec.europa.eu/taxation_customs/taxation/vat/traders/invoicing_rules/article_1733_en.htm

are implemented.
Important: the information that are not relevant for "sales tax" invoices (e.g. US invoices) are not rendered if VAT taxes are not available in the invoice.


Modified:
    ofbiz/trunk/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy
    ofbiz/trunk/applications/accounting/webapp/accounting/invoice/invoiceReportItems.fo.ftl

Modified: ofbiz/trunk/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy?rev=834486&r1=834485&r2=834486&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy (original)
+++ ofbiz/trunk/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy Tue Nov 10 14:49:44 2009
@@ -19,6 +19,7 @@
 
 import java.util.*;
 import org.ofbiz.entity.*;
+import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.base.util.*;
 import org.ofbiz.base.util.collections.*;
 import org.ofbiz.accounting.invoice.*;
@@ -28,6 +29,8 @@
 import java.math.MathContext;
 import org.ofbiz.base.util.UtilNumber;
 import javolution.util.FastList;
+import javolution.util.FastMap;
+
 
 
 invoiceId = parameters.get("invoiceId");
@@ -42,6 +45,22 @@
 rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding");
 
 if (invoice) {
+    // each invoice of course has two billing addresses, but the one that is relevant for purchase invoices is the PAYMENT_LOCATION of the invoice
+    // (ie Accounts Payable address for the supplier), while the right one for sales invoices is the BILLING_LOCATION (ie Accounts Receivable or
+    // home of the customer.)
+    if ("PURCHASE_INVOICE".equals(invoice.invoiceTypeId)) {
+        billingAddress = InvoiceWorker.getSendFromAddress(invoice);
+    } else {
+        billingAddress = InvoiceWorker.getBillToAddress(invoice);
+    }
+    if (billingAddress) {
+        context.billingAddress = billingAddress;
+    }
+    billingParty = InvoiceWorker.getBillToParty(invoice);
+    context.billingParty = billingParty;
+    sendingParty = InvoiceWorker.getSendFromParty(invoice);
+    context.sendingParty = sendingParty;
+
     if (currency && !invoice.getString("currencyUomId").equals(currency)) {
         conversionRate = InvoiceWorker.getInvoiceCurrencyConversionRate(invoice);
         invoice.currencyUomId = currency;
@@ -50,11 +69,27 @@
 
     invoiceItems = invoice.getRelatedOrderBy("InvoiceItem", ["invoiceItemSeqId"]);
     invoiceItemsConv = FastList.newInstance();
+    vatTaxesByType = FastMap.newInstance();
     invoiceItems.each { invoiceItem ->
-      invoiceItem.amount = invoiceItem.getBigDecimal("amount").multiply(conversionRate).setScale(decimals, rounding);
-      invoiceItemsConv.add(invoiceItem);
+        invoiceItem.amount = invoiceItem.getBigDecimal("amount").multiply(conversionRate).setScale(decimals, rounding);
+        invoiceItemsConv.add(invoiceItem);
+        // get party tax id for VAT taxes: they are required in invoices by EU
+        // also create a map with tax grand total amount by VAT tax: it is also required in invoices by UE
+        taxRate = invoiceItem.getRelatedOne("TaxAuthorityRateProduct");
+        if (taxRate && "VAT_TAX".equals(taxRate.taxAuthorityRateTypeId)) {
+            taxInfo = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyTaxAuthInfo", UtilMisc.toMap("partyId", billingParty.partyId, "taxAuthGeoId", taxRate.taxAuthGeoId, "taxAuthPartyId", taxRate.taxAuthPartyId)), invoice.invoiceDate));
+            if (taxInfo) {
+                context.billingPartyTaxId = taxInfo.partyTaxId;
+            }
+            vatTaxesByTypeAmount = vatTaxesByType[taxRate.taxAuthorityRateSeqId];
+            if (!vatTaxesByTypeAmount) {
+                vatTaxesByTypeAmount = 0.0;
+            }
+            vatTaxesByType.put(taxRate.taxAuthorityRateSeqId, vatTaxesByTypeAmount + invoiceItem.amount);
+        }
     }
-
+    context.vatTaxesByType = vatTaxesByType;
+    context.vatTaxIds = vatTaxesByType.keySet().asList();
 
     context.invoiceItems = invoiceItemsConv;
 
@@ -63,22 +98,6 @@
     context.invoiceTotal = invoiceTotal;
     context.invoiceNoTaxTotal = invoiceNoTaxTotal;
 
-    // each invoice of course has two billing addresses, but the one that is relevant for purchase invoices is the PAYMENT_LOCATION of the invoice
-    // (ie Accounts Payable address for the supplier), while the right one for sales invoices is the BILLING_LOCATION (ie Accounts Receivable or
-    // home of the customer.)
-    if ("PURCHASE_INVOICE".equals(invoice.invoiceTypeId)) {
-        billingAddress = InvoiceWorker.getSendFromAddress(invoice);
-    } else {
-        billingAddress = InvoiceWorker.getBillToAddress(invoice);
-    }
-    if (billingAddress) {
-        context.billingAddress = billingAddress;
-    }
-    billingParty = InvoiceWorker.getBillToParty(invoice);
-    context.billingParty = billingParty;
-    sendingParty = InvoiceWorker.getSendFromParty(invoice);
-    context.sendingParty = sendingParty;
-
                 //*________________this snippet was added for adding Tax ID in invoice header if needed _________________
 
                sendingTaxInfos = sendingParty.getRelated("PartyTaxAuthInfo");
@@ -101,7 +120,7 @@
                if (sendingPartyTaxId) {
                    context.sendingPartyTaxId = sendingPartyTaxId;
                }
-               if (billingPartyTaxId) {
+               if (billingPartyTaxId && !context.billingPartyTaxId) {
                    context.billingPartyTaxId = billingPartyTaxId;
                }
                //________________this snippet was added for adding Tax ID in invoice header if needed _________________*/

Modified: ofbiz/trunk/applications/accounting/webapp/accounting/invoice/invoiceReportItems.fo.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/webapp/accounting/invoice/invoiceReportItems.fo.ftl?rev=834486&r1=834485&r2=834486&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/webapp/accounting/invoice/invoiceReportItems.fo.ftl (original)
+++ ofbiz/trunk/applications/accounting/webapp/accounting/invoice/invoiceReportItems.fo.ftl Tue Nov 10 14:49:44 2009
@@ -39,8 +39,7 @@
 
     <fo:table>
     <fo:table-column column-width="20mm"/>
-    <fo:table-column column-width="20mm"/>
-    <fo:table-column column-width="65mm"/>
+    <fo:table-column column-width="85mm"/>
     <fo:table-column column-width="15mm"/>
     <fo:table-column column-width="25mm"/>
     <fo:table-column column-width="25mm"/>
@@ -48,22 +47,19 @@
     <fo:table-header height="14px">
       <fo:table-row>
         <fo:table-cell border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
-          <fo:block font-weight="bold">${uiLabelMap.AccountingItemNr}</fo:block>
-        </fo:table-cell>
-        <fo:table-cell border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
           <fo:block font-weight="bold">${uiLabelMap.AccountingProduct}</fo:block>
         </fo:table-cell>
         <fo:table-cell border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
           <fo:block font-weight="bold">${uiLabelMap.CommonDescription}</fo:block>
         </fo:table-cell>
         <fo:table-cell border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
-          <fo:block font-weight="bold" text-align="center">${uiLabelMap.CommonQty}</fo:block>
+          <fo:block font-weight="bold" text-align="right">${uiLabelMap.CommonQty}</fo:block>
         </fo:table-cell>
         <fo:table-cell border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
-          <fo:block font-weight="bold" text-align="center">${uiLabelMap.AccountingUnitPrice}</fo:block>
+          <fo:block font-weight="bold" text-align="right">${uiLabelMap.AccountingUnitPrice}</fo:block>
         </fo:table-cell>
         <fo:table-cell border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
-          <fo:block font-weight="bold" text-align="center">${uiLabelMap.CommonAmount}</fo:block>
+          <fo:block font-weight="bold" text-align="right">${uiLabelMap.CommonAmount}</fo:block>
         </fo:table-cell>
       </fo:table-row>
     </fo:table-header>
@@ -75,6 +71,8 @@
         <#-- if the item has a description, then use its description.  Otherwise, use the description of the invoiceItemType -->
         <#list invoiceItems as invoiceItem>
             <#assign itemType = invoiceItem.getRelatedOne("InvoiceItemType")>
+            <#assign isItemAdjustment = Static["org.ofbiz.common.CommonWorkers"].hasParentType(delegator, "InvoiceItemType", "invoiceItemTypeId", itemType.getString("invoiceItemTypeId"), "parentTypeId", "INVOICE_ADJ")/>
+
             <#assign taxRate = invoiceItem.getRelatedOne("TaxAuthorityRateProduct")?if_exists>
             <#assign itemBillings = invoiceItem.getRelated("OrderItemBilling")?if_exists>
             <#if itemBillings?has_content>
@@ -83,6 +81,7 @@
                     <#assign itemIssuance = itemBilling.getRelatedOne("ItemIssuance")?if_exists>
                     <#if itemIssuance?has_content>
                         <#assign newShipmentId = itemIssuance.shipmentId>
+                        <#assign issuedDateTime = itemIssuance.issuedDateTime/>
                     </#if>
                 </#if>
             </#if>
@@ -99,34 +98,27 @@
                      group of invoice items created for the same shipment
                 -->
                 <fo:table-row height="14px">
-                    <fo:table-cell number-columns-spanned="6">
+                    <fo:table-cell number-columns-spanned="5">
                             <fo:block></fo:block>
                        </fo:table-cell>
                 </fo:table-row>
                 <fo:table-row height="14px">
-                   <fo:table-cell number-columns-spanned="6">
-                        <fo:block font-weight="bold"> ${uiLabelMap.ProductShipmentId}: ${newShipmentId} </fo:block>
+                   <fo:table-cell number-columns-spanned="5">
+                        <fo:block font-weight="bold"> ${uiLabelMap.ProductShipmentId}: ${newShipmentId}<#if issuedDateTime?exists> ${uiLabelMap.CommonDate}: ${Static["org.ofbiz.base.util.UtilDateTime"].toDateString(issuedDateTime)}</#if></fo:block>
                    </fo:table-cell>
                 </fo:table-row>
                 <#assign currentShipmentId = newShipmentId>
             </#if>
-                <fo:table-row height="7px">
-                    <fo:table-cell number-columns-spanned="6">
-                        <fo:block></fo:block>
-                    </fo:table-cell>
-                </fo:table-row>
+            <#if !isItemAdjustment>
                 <fo:table-row height="14px" space-start=".15in">
                     <fo:table-cell>
-                        <fo:block> ${invoiceItem.invoiceItemSeqId} </fo:block>
-                    </fo:table-cell>
-                    <fo:table-cell>
                         <fo:block text-align="left">${invoiceItem.productId?if_exists} </fo:block>
                     </fo:table-cell>
-                    <fo:table-cell>
-                        <fo:block text-align="right">${description?if_exists}</fo:block>
+                    <fo:table-cell border-top-style="solid" border-top-width="thin" border-top-color="black">
+                        <fo:block text-align="left">${description?if_exists}</fo:block>
                     </fo:table-cell>
                       <fo:table-cell>
-                        <fo:block text-align="center"> <#if invoiceItem.quantity?exists>${invoiceItem.quantity?string.number}</#if> </fo:block>
+                        <fo:block text-align="right"> <#if invoiceItem.quantity?exists>${invoiceItem.quantity?string.number}</#if> </fo:block>
                     </fo:table-cell>
                     <fo:table-cell text-align="right">
                         <fo:block> <#if invoiceItem.quantity?exists><@ofbizCurrency amount=invoiceItem.amount?if_exists isoCode=invoice.currencyUomId?if_exists/></#if> </fo:block>
@@ -135,38 +127,55 @@
                         <fo:block> <@ofbizCurrency amount=(Static["org.ofbiz.accounting.invoice.InvoiceWorker"].getInvoiceItemTotal(invoiceItem)) isoCode=invoice.currencyUomId?if_exists/> </fo:block>
                     </fo:table-cell>
                 </fo:table-row>
+            <#else>
+                <#if !(invoiceItem.parentInvoiceId?exists && invoiceItem.parentInvoiceItemSeqId?exists)>
+                    <fo:table-row>
+                        <fo:table-cell><fo:block/></fo:table-cell>
+                        <fo:table-cell border-top-style="solid" border-top-width="thin" border-top-color="black"><fo:block/></fo:table-cell>
+                        <fo:table-cell number-columns-spanned="3"><fo:block/></fo:table-cell>
+                    </fo:table-row>
+                </#if>
+                <fo:table-row height="14px" space-start=".15in">
+                    <fo:table-cell number-columns-spanned="2">
+                        <fo:block text-align="right">${description?if_exists}</fo:block>
+                    </fo:table-cell>
+                    <fo:table-cell text-align="right" number-columns-spanned="3">
+                        <fo:block> <@ofbizCurrency amount=(Static["org.ofbiz.accounting.invoice.InvoiceWorker"].getInvoiceItemTotal(invoiceItem)) isoCode=invoice.currencyUomId?if_exists/> </fo:block>
+                    </fo:table-cell>
+                </fo:table-row>
+            </#if>
         </#list>
 
         <#-- blank line -->
         <fo:table-row height="7px">
-            <fo:table-cell number-columns-spanned="4"><fo:block><#-- blank line --></fo:block></fo:table-cell>
+            <fo:table-cell number-columns-spanned="5"><fo:block><#-- blank line --></fo:block></fo:table-cell>
         </fo:table-row>
 
         <#-- the grand total -->
         <fo:table-row>
-           <fo:table-cell number-columns-spanned="3">
+           <fo:table-cell number-columns-spanned="2">
               <fo:block/>
            </fo:table-cell>
-           <fo:table-cell>
+           <fo:table-cell number-columns-spanned="2">
               <fo:block font-weight="bold">${uiLabelMap.AccountingTotalCapital}</fo:block>
            </fo:table-cell>
-           <fo:table-cell text-align="right" number-columns-spanned="2">
-              <fo:block font-weight="bold"><@ofbizCurrency amount=invoiceTotal isoCode=invoice.currencyUomId?if_exists/></fo:block>
+           <fo:table-cell text-align="right" border-top-style="solid" border-top-width="thin" border-top-color="black">
+              <fo:block><@ofbizCurrency amount=invoiceTotal isoCode=invoice.currencyUomId?if_exists/></fo:block>
            </fo:table-cell>
         </fo:table-row>
         <fo:table-row height="7px">
-           <fo:table-cell>
+           <fo:table-cell number-columns-spanned="5">
               <fo:block/>
            </fo:table-cell>
         </fo:table-row>
         <fo:table-row height="14px">
-           <fo:table-cell number-columns-spanned="3">
+           <fo:table-cell number-columns-spanned="2">
               <fo:block/>
            </fo:table-cell>
            <fo:table-cell number-columns-spanned="2">
               <fo:block>${uiLabelMap.AccountingTotalExclTax}</fo:block>
            </fo:table-cell>
-           <fo:table-cell number-columns-spanned="1" text-align="right">
+           <fo:table-cell text-align="right" border-top-style="solid" border-top-width="thin" border-top-color="black">
               <fo:block>
                  <@ofbizCurrency amount=invoiceNoTaxTotal isoCode=invoice.currencyUomId?if_exists/>
               </fo:block>
@@ -175,6 +184,46 @@
     </fo:table-body>
  </fo:table>
 
+<#if vatTaxIds?has_content>
+ <fo:table>
+    <fo:table-column column-width="105mm"/>
+    <fo:table-column column-width="40mm"/>
+    <fo:table-column column-width="25mm"/>
+
+    <fo:table-header>
+      <fo:table-row>
+        <fo:table-cell>
+          <fo:block/>
+        </fo:table-cell>
+        <fo:table-cell border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
+          <fo:block font-weight="bold">${uiLabelMap.AccountingVat}</fo:block>
+        </fo:table-cell>
+        <fo:table-cell text-align="right" border-bottom-style="solid" border-bottom-width="thin" border-bottom-color="black">
+          <fo:block font-weight="bold">${uiLabelMap.AccountingAmount}</fo:block>
+        </fo:table-cell>
+      </fo:table-row>
+    </fo:table-header>
+
+    <fo:table-body font-size="10pt">
+
+    <#list vatTaxIds as vatTaxId>
+    <#assign taxRate = delegator.findOne("TaxAuthorityRateProduct", Static["org.ofbiz.base.util.UtilMisc"].toMap("taxAuthorityRateSeqId", vatTaxId), true)/>
+    <fo:table-row>
+        <fo:table-cell>
+          <fo:block/>
+        </fo:table-cell>
+        <fo:table-cell number-columns-spanned="1">
+            <fo:block>${taxRate.description}</fo:block>
+        </fo:table-cell>
+        <fo:table-cell number-columns-spanned="1" text-align="right">
+            <fo:block font-weight="bold"><@ofbizCurrency amount=vatTaxesByType[vatTaxId] isoCode=invoice.currencyUomId?if_exists/></fo:block>
+        </fo:table-cell>
+    </fo:table-row>
+    </#list>
+    </fo:table-body>
+ </fo:table>
+</#if>
+
  <#-- a block with the invoice message-->
  <#if invoice.invoiceMessage?has_content><fo:block>${invoice.invoiceMessage}</fo:block></#if>
  <fo:block></fo:block>