Author: jonesde
Date: Tue Nov  2 19:34:31 2010
New Revision: 1030191

URL: http://svn.apache.org/viewvc?rev=1030191&view=rev
Log:
Added entity and service level support for entering prices with taxes included 
(handy for countries with VAT/etc)

Modified:
    ofbiz/trunk/applications/product/entitydef/entitymodel.xml
    
ofbiz/trunk/applications/product/script/org/ofbiz/product/price/PriceServices.xml
    ofbiz/trunk/applications/product/servicedef/services.xml

Modified: ofbiz/trunk/applications/product/entitydef/entitymodel.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel.xml?rev=1030191&r1=1030190&r2=1030191&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/applications/product/entitydef/entitymodel.xml Tue Nov  2 
19:34:31 2010
@@ -2375,6 +2375,11 @@ under the License.
       <field name="price" type="currency-precise"></field>
       <field name="termUomId" type="id"><description>Mainly used for recurring 
and usage prices to specify a time/freq measure, or a usage unit measure (bits, 
minutes, etc)</description></field>
       <field name="customPriceCalcService" type="id"><description>Points to a 
CustomMethod used to specify a service for the calculation of the unit price of 
the product (NOTE: a better name for this field might be 
priceCalcCustomMethodId)</description></field>
+      <field name="priceWithTax" type="currency-precise"/>
+      <field name="taxAmount" type="currency-precise"/>
+      <field name="taxPercentage" type="fixed-point"/>
+      <field name="taxAuthPartyId" type="id-ne"/>
+      <field name="taxAuthGeoId" type="id-ne"/>
       <field name="createdDate" type="date-time"></field>
       <field name="createdByUserLogin" type="id-vlong"></field>
       <field name="lastModifiedDate" type="date-time"></field>
@@ -2406,6 +2411,12 @@ under the License.
       <relation type="one" fk-name="PROD_PRICE_CMET" 
rel-entity-name="CustomMethod">
         <key-map field-name="customPriceCalcService" 
rel-field-name="customMethodId"/>
       </relation>
+      <relation type="one" fk-name="PROD_PRC_TAXPTY" title="TaxAuthority" 
rel-entity-name="Party">
+        <key-map field-name="taxAuthPartyId" rel-field-name="partyId"/>
+      </relation>
+      <relation type="one" fk-name="PROD_PRC_TAXGEO" title="TaxAuthority" 
rel-entity-name="Geo">
+        <key-map field-name="taxAuthGeoId" rel-field-name="geoId"/>
+      </relation>
       <relation type="one" fk-name="PROD_PRICE_CBUL" title="CreatedBy" 
rel-entity-name="UserLogin">
         <key-map field-name="createdByUserLogin" rel-field-name="userLoginId"/>
       </relation>

Modified: 
ofbiz/trunk/applications/product/script/org/ofbiz/product/price/PriceServices.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/product/price/PriceServices.xml?rev=1030191&r1=1030190&r2=1030191&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/product/script/org/ofbiz/product/price/PriceServices.xml
 (original)
+++ 
ofbiz/trunk/applications/product/script/org/ofbiz/product/price/PriceServices.xml
 Tue Nov  2 19:34:31 2010
@@ -27,18 +27,20 @@ under the License.
         <call-simple-method method-name="checkProductRelatedPermission" 
xml-resource="component://product/script/org/ofbiz/product/product/ProductServices.xml"/>
         <check-permission permission="CATALOG_PRICE_MAINT"><fail-property 
resource="ProductUiLabels" 
property="ProductPriceMaintPermissionError"/></check-permission>
         <check-errors/>
+        
+        <call-simple-method method-name="inlineHandlePriceWithTaxIncuded"/>
 
         <make-value value-field="newEntity" entity-name="ProductPrice"/>
         <set-nonpk-fields map="parameters" value-field="newEntity"/>
         <set-pk-fields map="parameters" value-field="newEntity"/>
-
+        
         <now-timestamp field="nowTimestamp"/>
-
+        
         <if-empty field="newEntity.fromDate">
             <set field="newEntity.fromDate" from-field="nowTimestamp"/>
         </if-empty>
         <field-to-result field="newEntity.fromDate" result-name="fromDate"/>
-
+        
         <set field="newEntity.lastModifiedDate" from-field="nowTimestamp"/>
         <set field="newEntity.createdDate" from-field="nowTimestamp"/>
         <set field="newEntity.lastModifiedByUserLogin" 
from-field="userLogin.userLoginId"/>
@@ -53,6 +55,8 @@ under the License.
         <check-permission permission="CATALOG_PRICE_MAINT"><fail-property 
resource="ProductUiLabels" 
property="ProductPriceMaintPermissionError"/></check-permission>
         <check-errors/>
 
+        <call-simple-method method-name="inlineHandlePriceWithTaxIncuded"/>
+        
         <entity-one entity-name="ProductPrice" value-field="lookedUpValue"/>
 
         <!-- grab the old price value before setting nonpk parameter fields -->
@@ -82,6 +86,71 @@ under the License.
 
         <remove-value value-field="lookedUpValue"/>
     </simple-method>
+    <simple-method method-name="inlineHandlePriceWithTaxIncuded" 
short-description="Inline Handle Price with Tax Included">
+        <if-not-empty field="parameters.taxAuthCombinedId">
+            <set field="taxAuthCombinedId" 
from-field="parameters.taxAuthCombinedId"/>
+            <!-- if passed in value will be split based on: 
"${taxAuthGeoId}::${taxAuthPartyId}" -->
+            <set field="parameters.taxAuthGeoId" 
+                
value="${groovy:taxAuthCombinedId.substring(0,taxAuthCombinedId.indexOf('::'))}"/>
+            <set field="parameters.taxAuthPartyId" 
+                
value="${groovy:taxAuthCombinedId.substring(taxAuthCombinedId.indexOf('::')+2)}"/>
+        </if-not-empty>
+        
+        <!-- handle price with tax included related fields (priceWithTax, 
taxAmount, taxPercentage, taxAuthPartyId, taxAuthGeoId) -->
+        <if>
+            <condition>
+                <and>
+                    <not><if-empty 
field="parameters.taxAuthPartyId"></if-empty></not>
+                    <not><if-empty 
field="parameters.taxAuthGeoId"></if-empty></not>
+                </and>
+            </condition>
+            <then>
+                <set field="parameters.priceWithTax" 
from-field="parameters.price"/>
+                <!-- if taxPercentage not passed in look it up based on 
taxAuthGeoId and taxAuthPartyId -->
+                <if-empty field="parameters.taxPercentage">
+                    <!-- we only have basic data to constrain by here, so 
assume that if it is a VAT tax setup it should be pretty simple -->
+                    <entity-condition entity-name="TaxAuthorityRateProduct" 
list="taxAuthorityRateProductList" filter-by-date="true">
+                        <condition-list combine="and">
+                            <condition-expr field-name="taxAuthGeoId" 
from-field="parameters.taxAuthGeoId"/>
+                            <condition-expr field-name="taxAuthPartyId" 
from-field="parameters.taxAuthPartyId"/>
+                            <condition-list combine="or">
+                                <condition-expr 
field-name="taxAuthorityRateTypeId" value="SALES_TAX"/>
+                                <condition-expr 
field-name="taxAuthorityRateTypeId" value="VAT_TAX"/>
+                            </condition-list>
+                        </condition-list>
+                    </entity-condition>
+                    <set field="parameters.taxPercentage" 
from-field="taxAuthorityRateProductList[0].taxPercentage" type="BigDecimal"/>
+                </if-empty>
+                
+                <if-empty field="parameters.taxPercentage">
+                    <add-error><fail-message message="Tax Authority was 
specified but no Tax Percentage passed in, and could not find one in the Tax 
Authority Rate Product settings, so cannot handle price with tax 
included."/></add-error>
+                    <check-errors/>
+                </if-empty>
+                
+                <calculate field="parameters.taxAmount" type="BigDecimal" 
decimal-scale="3" rounding-mode="HalfEven">
+                    <calcop operator="subtract">
+                        <calcop operator="get" 
field="parameters.priceWithTax"/>
+                        <calcop operator="divide">
+                            <calcop operator="get" 
field="parameters.priceWithTax"/>
+                            <calcop operator="add">
+                                <number value="1"/>
+                                <calcop operator="divide">
+                                    <calcop operator="get" 
field="parameters.taxPercentage"/>
+                                    <number value="100"/>
+                                </calcop>
+                            </calcop>
+                        </calcop>
+                    </calcop>
+                </calculate>
+                <calculate field="parameters.price" type="BigDecimal" 
decimal-scale="3" rounding-mode="HalfEven">
+                    <calcop operator="subtract">
+                        <calcop operator="get" 
field="parameters.priceWithTax"/>
+                        <calcop operator="get" 
field="parameters.taxAmount"></calcop>
+                    </calcop>
+                </calculate>
+            </then>
+        </if>
+    </simple-method>
 
     <simple-method method-name="saveProductPriceChange" 
short-description="Save History of ProductPrice Change">
         <check-permission permission="CATALOG" action="_UPDATE">

Modified: ofbiz/trunk/applications/product/servicedef/services.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/services.xml?rev=1030191&r1=1030190&r2=1030191&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/services.xml Tue Nov  2 
19:34:31 2010
@@ -239,14 +239,23 @@ under the License.
     <!-- Product Price Services -->
     <service name="createProductPrice" default-entity-name="ProductPrice" 
engine="simple"
                 
location="component://product/script/org/ofbiz/product/price/PriceServices.xml" 
invoke="createProductPrice" auth="true">
-        <description>Create an ProductPrice</description>
+        <description>
+            Create an ProductPrice. 
+            Price is always stored without tax. 
+            If a taxAuthGeoId and taxAuthPartyId are (or taxAuthCombinedId is) 
passed in then the price will be considered a price 
+                with tax included and the tax will be removed before storing 
to the database 
+                (the priceWithTax, taxAmount, and taxPercentage fields will 
also be populated).
+        </description>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true">
+            <exclude field-name="priceWithTax"/>
+            <exclude field-name="taxAmount"/>
             <exclude field-name="createdDate"/>
             <exclude field-name="createdByUserLogin"/>
             <exclude field-name="lastModifiedDate"/>
             <exclude field-name="lastModifiedByUserLogin"/>
         </auto-attributes>
+        <attribute name="taxAuthCombinedId" type="String" mode="IN" 
optional="true"><!-- if passed in value will be split based on: 
"${taxAuthGeoId}::${taxAuthPartyId}" --></attribute>
         <override name="fromDate" mode="INOUT" optional="true"/>
         <override name="price" optional="false"/>
     </service>
@@ -255,6 +264,8 @@ under the License.
         <description>Update an ProductPrice</description>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true">
+            <exclude field-name="priceWithTax"/>
+            <exclude field-name="taxAmount"/>
             <exclude field-name="createdDate"/>
             <exclude field-name="createdByUserLogin"/>
             <exclude field-name="lastModifiedDate"/>


Reply via email to