XeroAPI / xero-php-oauth2

Xero PHP SDK for oAuth 2 generated from Xero API OpenAPI Spec 3.0
MIT License
93 stars 65 forks source link

Discount must not be greater than the line total. #288

Closed faisal-alvi closed 2 years ago

faisal-alvi commented 2 years ago

SDK you're using (please complete the following information):

Describe the bug While using a WooCommerce Xero extension, faced an issue where we have passed the same value, "27.8260" to the Unit amount, Line amount, and the Discount amount but we get an error in the response, see the DiscountRate in the response:

SimpleXMLElement Object
(
    [ErrorNumber] => 10
    [Type] => ValidationException
    [Message] => A validation exception occurred
    [Elements] => SimpleXMLElement Object
        (
            [DataContractBase] => SimpleXMLElement Object
                (
                    [ValidationErrors] => SimpleXMLElement Object
                        (
                            [ValidationError] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [Message] => The discount rate '27.83' is invalid. Discount must not be greater than the line total.
                                        )

                                    [1] => SimpleXMLElement Object
                                        (
                                            [Message] => The discount rate '27.83' is invalid. Discount must not be greater than the line total.
                                        )

                                )

                        )

                    [Contact] => SimpleXMLElement Object
                        (
                            [ContactID] => 0e9eb2da-4d05-442a-86f6-cd808a437b5d
                        )

                    [Date] => 2022-06-28T00:00:00
                    [DueDate] => 2022-06-28T00:00:00
                    [Status] => AUTHORISED
                    [LineAmountTypes] => Exclusive
                    [LineItems] => SimpleXMLElement Object
                        (
                            [LineItem] => SimpleXMLElement Object
                                (
                                    [Description] => Xero-269
                                    [UnitAmount] => 27.826087
                                    [TaxType] => NONE
                                    [TaxAmount] => 0.00
                                    [LineAmount] => 0.00
                                    [AccountCode] => 200
                                    [Quantity] => 1.0000
                                    [DiscountRate] => 27.83
                                    [AccountID] => 30b23d64-0dee-4812-9515-63ae4c821219
                                    [DiscountEnteredAsPercent] => false
                                    [DiscountAmount] => 27.826087
                                )

                        )

                    [SubTotal] => 0.00
                    [TotalTax] => 0.00
                    [Total] => 0.00
                    [CurrencyCode] => USD
                    [Type] => ACCREC
                    [InvoiceID] => 00000000-0000-0000-0000-000000000000
                    [InvoiceNumber] => IV-4121
                    [Url] => https://wpne.local/wp-admin/post.php?post=4121&action=edit
                    [ExternalLinkProviderName] => WPNE
                    [TotalDiscount] => 27.83
                    [HasErrors] => true
                )

        )

)

To Reproduce Steps to reproduce the behavior:

  1. Passed the same value, "27.8260" to the Unit amount, Line amount, and Discount amount
  2. See an error in response.

Expected behavior The passed Discount Amount should not be rounded to 2 decimals. That is creating the issue.

Additional context We pass whatever rounded amount in a request, we always get DiscountRate rounded to 2 decimals.

wobinb commented 2 years ago

This appears to be an issue at API level - as opposed to an SDK issue.

4dp are accepted (when the unitdp=4 parameter is passed) on the unit amount and quantity fields but not on the discount field. In this case the discount is being rounded to 27.83 and then failing the validation against the unrounded 27.8260.

To workaround the issue the most reliable method would be to pre-round both values to 2dp and pass these. This will ensure that the validation passes as no rounding is necessary.

faisal-alvi commented 2 years ago

@wobinb thanks for the feedback, I have a couple of questions:

  1. Where can I raise a ticket for API issues, if not here?
  2. Is the discount value always being rounded to 2dp? There's no way to change this behavior?
wobinb commented 2 years ago

You can raise a case either within Xero by clicking the question mark in the top right corner, or by emailing api@xero.com.

There isn't any way of changing the behaviour of the rounding on the discount amount. Changing the unit amount to match would the most reliable workaround.

It is worth noting that from an accounting perspective the line amount gets rounded to 2dp when the journal is posted, so the end result will be the same.

RettBehrens commented 2 years ago

Closing given this is API related and not SDK