OFBiz
  1. OFBiz
  2. OFBIZ-1434 General Ledger
  3. OFBIZ-1599

Issues with tax adjustment precision (3 decimals) and AcctgTransEntry.amount field (2 decimal)

    Details

    • Type: Sub-task Sub-task
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: SVN trunk
    • Component/s: accounting
    • Labels:
      None

      Description

      On Jan 7, 2008, at 10:17 PM, Scott Gray wrote:

      > Perhaps we need to do 2 things:
      > 1. Summarize AcctgTransEntries so that you have one entry per TaxAuthority
      > rather than for each tax adjustment
      > 2. During order/invoice processing, calc and final should be applied on a
      > per TaxAuthority basis, so that we are only ever collecting final rounded
      > amounts for each tax authority.
      >
      > So for example if we have invoice with the following adjustments:
      > (I just made these numbers up, they don't relate to any percentages)
      > UT_TAXMAN - $4.311
      > UT_TAXMAN - $7.397
      > UT_UTAH_TAXMAN - $5.643
      > UT_UTAH_TAXMAN - $16.828
      >
      > Tax final would be calculated like this:
      > UT_TAXMAN - $4.311 + $7.399 = $11.71 (2dp)
      > UT_UTAH_TAXMAN - $5.643 + $16.828 = $22.47 (2dp)
      > Tax Total = $11.71 + $22.47 = $34.18
      >
      > Then the AcctgTransEntries would be:
      > UT_TAXMAN = $11.71
      > UT_UTAH_TAXMAN = $22.47
      >
      > Regards
      > Scott
      >
      >
      > On 08/01/2008, David E Jones <jonesde@hotwaxmedia.com> wrote:
      >>
      >>
      >> On Jan 7, 2008, at 11:04 AM, Scott Gray wrote:
      >>
      >>> Hi Jacopo
      >>>
      >>> My understanding of calc and final:
      >>> calc - adjustment level rounding
      >>> final - the sum of all tax adjustments (tax total) is rounded to this
      >>> precision
      >>>
      >>> Perhaps AcctgTransEntry.amount needs to store to a higher precision
      >>> as well?
      >>
      >> What Scott says above is correct as I understand it, but I'm not sure
      >> this last part is a good idea.
      >>
      >> Accounting/GL transactions are meant to be final and to avoid problems
      >> they are structured in a way where reporting just involves adding
      >> things up and using straight totals with no rounding, etc to avoid any
      >> biasing (with the exception of certain averages and such, but that is
      >> different as precision on those is used in a different way).
      >>
      >> It seems to me that posting anything to an accounting with more than 2
      >> decimals of precision seems like a bad idea to me, except perhaps the
      >> infamous "rounding remainder" accounts. We should probably consult
      >> with an accounting before doing much of that sort of thing, but of
      >> course if we do change the AcctgTransEntry.amount to be higher
      >> precision we can always configure/code around it.
      >>
      >> -David
      >>
      >>
      >>> On 08/01/2008, Jacopo Cappellato <tiz@sastau.it> wrote:
      >>>>
      >>>> While testing the GL accounting transactions I've found something
      >>>> that
      >>>> could be an issue in the procedure that computes the sales tax
      >>>> adjustment for the invoice.
      >>>> I've noticed that the InvoiceItem.amount for sales tax contains
      >>>> sometimes a number with 3 decimals, even if the arithmetic.properties
      >>>> file we have:
      >>>>
      >>>> salestax.calc.decimals = 3
      >>>> salestax.final.decimals = 2
      >>>> salestax.rounding = ROUND_HALF_UP
      >>>>
      >>>> You can recreate this by creating and invoicing a sales order for 3
      >>>> units of GZ-1000.
      >>>>
      >>>> For example, look at this invoice:
      >>>>
      >>>>
      >>>>
      >> https://demo.hotwaxmedia.com/accounting/control/invoiceOverview?invoiceId=CI1
      >>>>
      >>>> Having 3 decimals is an issue for the gl auto posting service for
      >>>> sales
      >>>> invoices because the sales tax item generates an AcctgTransEntry, but
      >>>> the AcctgTransEntry.amount field can only store 2 decimals.
      >>>>
      >>>> I'd appreciate suggestions/hints.
      >>>>
      >>>> Cheers,
      >>>>
      >>>> Jacopo
      >>>>
      >>
      >>
      >>

      1. Issue_1599.patch
        19 kB
        Sumit Pandit
      2. Issue_1599.patch
        19 kB
        Jacques Le Roux
      3. Issue_1599.patch
        19 kB
        Jacques Le Roux
      4. Issue_1599.patch
        19 kB
        Jacques Le Roux
      5. Issue_1599.patch
        21 kB
        Jacques Le Roux

        Issue Links

          Activity

          Hide
          Jacques Le Roux added a comment -

          Thanks Sumit,

          After 2 successful tests I commited your patch in trunk at r818257

          Show
          Jacques Le Roux added a comment - Thanks Sumit, After 2 successful tests I commited your patch in trunk at r818257
          Hide
          Jacques Le Roux added a comment -

          Here a new version of the patch. I have mostly adapted Java code to 1.5. I have also completly rewieved the patch. For me it's ok to be commited. I have not tested though (only complied after my modifcations) since Sumit did it previously and I'm pretty confident, after having read his code, he did it well.

          So now I propose that someone with a better knowlegde than me on the accouting side should also review and then hopefully commit. It's not so huge actually, so I'm wondering a bit why it has been waiting so long, but without any negative comments I guess it's only a miss.

          Thanks

          Show
          Jacques Le Roux added a comment - Here a new version of the patch. I have mostly adapted Java code to 1.5. I have also completly rewieved the patch. For me it's ok to be commited. I have not tested though (only complied after my modifcations) since Sumit did it previously and I'm pretty confident, after having read his code, he did it well. So now I propose that someone with a better knowlegde than me on the accouting side should also review and then hopefully commit. It's not so huge actually, so I'm wondering a bit why it has been waiting so long, but without any negative comments I guess it's only a miss. Thanks
          Hide
          Jacques Le Roux added a comment -

          Last patch (2009/03/30) follows r760010 update

          Show
          Jacques Le Roux added a comment - Last patch (2009/03/30) follows r760010 update
          Hide
          Jacques Le Roux added a comment -

          Replaced new EntityExpr by EntityCondition.makeCondition in last patch

          Show
          Jacques Le Roux added a comment - Replaced new EntityExpr by EntityCondition.makeCondition in last patch
          Hide
          Jacques Le Roux added a comment -

          Patch updated to r757113

          new EntityExpr should be replaced by EntityCondition.makeCondition

          Show
          Jacques Le Roux added a comment - Patch updated to r757113 new EntityExpr should be replaced by EntityCondition.makeCondition
          Hide
          Jacques Le Roux added a comment -

          A reminder for OFBIZ-1579

          Show
          Jacques Le Roux added a comment - A reminder for OFBIZ-1579
          Hide
          Jacques Le Roux added a comment -

          I did not really review nor test this patch (though I compiled, run and created an order and its invoice correctly) but I think it would be a pity to lose it because it would be too old. So here a patch against r707978

          Show
          Jacques Le Roux added a comment - I did not really review nor test this patch (though I compiled, run and created an order and its invoice correctly) but I think it would be a pity to lose it because it would be too old. So here a patch against r707978
          Hide
          Sumit Pandit added a comment -

          Hello All,
          Here is patch for this issue.
          I test it by creating some orders with number of items.
          I verified some entities like the AcctgTransEntry, OrderHeader, OrderItem, OrderAdjustments.

          Show
          Sumit Pandit added a comment - Hello All, Here is patch for this issue. I test it by creating some orders with number of items. I verified some entities like the AcctgTransEntry, OrderHeader, OrderItem, OrderAdjustments.
          Hide
          Jacques Le Roux added a comment -

          Scott, Jacopo, thanks to both of you for clarifying this issue.

          Show
          Jacques Le Roux added a comment - Scott, Jacopo, thanks to both of you for clarifying this issue.
          Hide
          Jacopo Cappellato added a comment -

          That's great.
          To summarize: in order to implement the above solution, we will have to implement a new service that, given an orderId will retrieve all the OrderAdjustments for SALES_TAXES and will sum and approximate them by tax auth/tax geo. The list of amounts will be returned as an OUT parameter together with the total.
          This new service will be used in several places, including:
          1) the service that computes the order grand total: wi will have to change it so that it gets the total for taxes by calling the new service
          2) the gl posting service, to get the (summarized) acctg transaction for sales taxes

          Show
          Jacopo Cappellato added a comment - That's great. To summarize: in order to implement the above solution, we will have to implement a new service that, given an orderId will retrieve all the OrderAdjustments for SALES_TAXES and will sum and approximate them by tax auth/tax geo. The list of amounts will be returned as an OUT parameter together with the total. This new service will be used in several places, including: 1) the service that computes the order grand total: wi will have to change it so that it gets the total for taxes by calling the new service 2) the gl posting service, to get the (summarized) acctg transaction for sales taxes
          Hide
          Scott Gray added a comment -

          yeah thats what i had in mind, happy to help

          Show
          Scott Gray added a comment - yeah thats what i had in mind, happy to help
          Hide
          Jacopo Cappellato added a comment -

          Scott,

          thanks for your valuable answer, now I understand.
          Just to be sure I understand: are you saying that the order grand total (that is, for example, authorized and charged to the Credit Card) is computed using the total item amount + total (non tax) adjustments + tax adjustments as computed by the above formula?

          Show
          Jacopo Cappellato added a comment - Scott, thanks for your valuable answer, now I understand. Just to be sure I understand: are you saying that the order grand total (that is, for example, authorized and charged to the Credit Card) is computed using the total item amount + total (non tax) adjustments + tax adjustments as computed by the above formula?
          Hide
          Scott Gray added a comment -

          Hi Jacopo

          I had planned on the rounded geo/authority taxes to be interim values that would be used for calculation of the order/invoice tax total but not actually stored within the order/invoice entities. They would be stored when posting to the GL though. That way you are always charging the customer for rounded tax per geo/authority and the same amounts are being posted to the ledger.

          So,
          This is the raw data stored with the order invoice:
          Tax Geo and Authority || order item seq id || amount
          =====================================================
          Utah County / Sales Tax || NA || -0.096
          Utah County / Sales Tax || 00001 || 0.960
          Utah State / Sales Tax || 00001 || 45.592
          NA / NA || 00001 || 9.598

          Within the order/invoice these are interim calculation values (not stored within the order/invoice but used to calculate the tax total) but also what we post to the ledger:
          Utah County / Sales Tax || 0.86
          Utah State / Sales Tax || 45.59
          NA / NA || 9.60

          Does that make sense? See any problems?

          Show
          Scott Gray added a comment - Hi Jacopo I had planned on the rounded geo/authority taxes to be interim values that would be used for calculation of the order/invoice tax total but not actually stored within the order/invoice entities. They would be stored when posting to the GL though. That way you are always charging the customer for rounded tax per geo/authority and the same amounts are being posted to the ledger. So, This is the raw data stored with the order invoice: Tax Geo and Authority || order item seq id || amount ===================================================== Utah County / Sales Tax || NA || -0.096 Utah County / Sales Tax || 00001 || 0.960 Utah State / Sales Tax || 00001 || 45.592 NA / NA || 00001 || 9.598 Within the order/invoice these are interim calculation values (not stored within the order/invoice but used to calculate the tax total) but also what we post to the ledger: Utah County / Sales Tax || 0.86 Utah State / Sales Tax || 45.59 NA / NA || 9.60 Does that make sense? See any problems?
          Hide
          Jacopo Cappellato added a comment -

          I have some doubts about the solution suggested by Scott and I'd like to get some feedback.
          I will try to clarify the context with an example

          Enter a sales order for the customer "DemoCustomer" for 20 units of WG-1111.
          Check out the order.

          Go to Webtools>Entity Data Maintenance>OrderAdjustemnt and filter by orderId and orderAdjustmentTypeId="SALES_TAX"

          The sales taxes adjustments will look like the following ones:

          Tax Geo and Authority || order item seq id || amount
          =====================================================
          Utah County / Sales Tax || NA || -0.096
          Utah County / Sales Tax || 00001 || 0.960
          Utah State / Sales Tax || 00001 || 45.592
          NA / NA || 00001 || 9.598

          Apart from the weird taxes, what it is interesting to note is that we have one order header adjustments (the first one) and a few order item adjustments. Also note that taxes are approximated to 3 decimals

          Following Scott's suggestion (if I am interpreting it in the right way) we will have taxes summed up by the same Tax Geo and Authority:

          Utah County / Sales Tax || 0.864
          Utah State / Sales Tax || 45.592
          NA / NA || 9.598

          and then we approximate them to 2 decimals (I'm approximating using round half up, but this is just an example):

          Utah County / Sales Tax || 0.86
          Utah State / Sales Tax || 45.59
          NA / NA || 9.60

          The final result is that, starting from a set of order header and order item tax adjustments we have transformed them in a set of order header tax adjustment, one for each tax geo and authority.

          These are the numbers that will be posted into the GL.

          My main question is: when do we do this calculation? In the service that generates the accounting transaction or in the order/invoice (when the adjustments are stored in the db)?

          If we do this only in the service that generate the accounting transaction the problem is that there will be differences between the amount s in gl and the numbers in orders, invoices and payments.
          If we do this in the order and invoice the problem that I see is that we loose the ability to associate the tax adjustments to the order items (that is a very important feature, in my opinion).

          Show
          Jacopo Cappellato added a comment - I have some doubts about the solution suggested by Scott and I'd like to get some feedback. I will try to clarify the context with an example Enter a sales order for the customer "DemoCustomer" for 20 units of WG-1111. Check out the order. Go to Webtools>Entity Data Maintenance>OrderAdjustemnt and filter by orderId and orderAdjustmentTypeId="SALES_TAX" The sales taxes adjustments will look like the following ones: Tax Geo and Authority || order item seq id || amount ===================================================== Utah County / Sales Tax || NA || -0.096 Utah County / Sales Tax || 00001 || 0.960 Utah State / Sales Tax || 00001 || 45.592 NA / NA || 00001 || 9.598 Apart from the weird taxes, what it is interesting to note is that we have one order header adjustments (the first one) and a few order item adjustments. Also note that taxes are approximated to 3 decimals Following Scott's suggestion (if I am interpreting it in the right way) we will have taxes summed up by the same Tax Geo and Authority: Utah County / Sales Tax || 0.864 Utah State / Sales Tax || 45.592 NA / NA || 9.598 and then we approximate them to 2 decimals (I'm approximating using round half up, but this is just an example): Utah County / Sales Tax || 0.86 Utah State / Sales Tax || 45.59 NA / NA || 9.60 The final result is that, starting from a set of order header and order item tax adjustments we have transformed them in a set of order header tax adjustment, one for each tax geo and authority. These are the numbers that will be posted into the GL. My main question is: when do we do this calculation? In the service that generates the accounting transaction or in the order/invoice (when the adjustments are stored in the db)? If we do this only in the service that generate the accounting transaction the problem is that there will be differences between the amount s in gl and the numbers in orders, invoices and payments. If we do this in the order and invoice the problem that I see is that we loose the ability to associate the tax adjustments to the order items (that is a very important feature, in my opinion).

            People

            • Assignee:
              Jacques Le Roux
              Reporter:
              Jacopo Cappellato
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development