Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the creation of Receipts #6

Open
onevision opened this issue Apr 25, 2015 · 8 comments
Open

Add support for the creation of Receipts #6

onevision opened this issue Apr 25, 2015 · 8 comments

Comments

@onevision
Copy link
Contributor

My company needs a command line tool to create Receipts in Xero, so I thought I would extend xero-java-client to support the creation of invoices.

So have I have made the following change to Receipt.xsd in XeroAPI-Schemas

   <!-- 
   Receipt 
   -->
+  <xs:element name="Receipt" type="Receipt" />
   <xs:complexType name="Receipt">
     <xs:all>
       <xs:element minOccurs="0" maxOccurs="1" name="ValidationErrors" type="ArrayOfValidationError" />

And the following change to XeroClient.java in xero-java-client

    return put("Invoices", objFactory.createInvoice(invoice)).getInvoices();
  }

+  public List<Receipt> createReceipt(Receipt receipt) {
+       return put("Receipts", objFactory.createReceipt(receipt)).getReceipts();
+     }
+

  public List<Invoice> createInvoices(List<Invoice> invoices) {
    ArrayOfInvoice array = new ArrayOfInvoice();
    array.getInvoice().addAll(invoices);

However I an struggling to get Xero to create the Receipt. If I run the following code:

        Receipt receipt = new Receipt();
        receipt.setUser(users.get(0));
        receipt.setContact(contacts.get(0));
        receipt.setTotal(new BigDecimal(10.0));
        receipt.setSubTotal(new BigDecimal(10.0));
        LineItem item = new LineItem();
        item.setDescription("hello");
        item.setAccountCode("760");
        item.setUnitAmount(new BigDecimal(10.0));
        receipt.setLineItems(ImmutableList.of(item));
        client.createReceipt(receipt);

I get the error

Exception in thread "main" com.connectifier.xeroclient.XeroApiException: 400 response: Error number 10. A validation exception occurred, An error occurred in Xero. Check the API Status page http://status.developer.xero.com for current service status. Contact the API support team at [email protected] for more assistance.
    at com.connectifier.xeroclient.XeroClient.newApiException(XeroClient.java:103)
    at com.connectifier.xeroclient.XeroClient.put(XeroClient.java:135)
    at com.connectifier.xeroclient.XeroClient.createReceipt(XeroClient.java:314)
    at com.deepskybluesolutions.expenseimporter.ExpenseImporter.main(ExpenseImporter.java:45)

Is there a way I can see the actual XML being sent to Xero?

thanks

Richard

@benmccann
Copy link
Owner

Line 130 of XeroClient has String contents = marshallRequest(object);. You could add a println there while debugging if you wanted to see the actual XML

@onevision
Copy link
Contributor Author

Hi Ben

I am having a problem where strange schema lines are being added to the XML to be posted to Xero when I don't specify certain non-manatory fields, e.g. TaxAmount. I have tested the XML in the API Previewer and it returns an error. If these lines are removed then all is ok.

Do you have any idea what is causing this?

Thanks

Richard

<?xml version="1.0" encoding="UTF-8"?>
<Receipt>
   <User>
      <UserID>73f0cf2f-ede4-49ea-b93e-6723d9dfca32</UserID>
   </User>
   <Contact>
      <ContactID>e4c9d0e2-c285-4e85-b579-6d28b180c730</ContactID>
   </Contact>
   <Date>2015-01-11Z</Date>
   <LineItems>
      <LineItem>
         <Description>Laptop</Description>
         <UnitAmount>209.99</UnitAmount>
         <TaxAmount xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
         <LineAmount xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
         <AccountCode>720</AccountCode>
         <Quantity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
      </LineItem>
   </LineItems>
</Receipt>
'''

@benmccann
Copy link
Owner

Nope, haven't seen this before. Let me know if you find out though

@onevision
Copy link
Contributor Author

Had to remove nillable=true from fields in LineItem.xsd.

diff --git a/v2.00/LineItem.xsd b/v2.00/LineItem.xsd
index 8718e02..5522479 100644
--- a/v2.00/LineItem.xsd
+++ b/v2.00/LineItem.xsd
@@ -22,12 +22,12 @@
       <xs:element minOccurs="0" maxOccurs="1" name="Description" type="xs:string" />
       <xs:element minOccurs="1" maxOccurs="1" name="UnitAmount" nillable="true" type="itemPrice" />
       <xs:element minOccurs="0" maxOccurs="1" name="TaxType" type="taxType" />
-      <xs:element minOccurs="1" maxOccurs="1" name="TaxAmount" nillable="true" type="itemPrice" />
-      <xs:element minOccurs="1" maxOccurs="1" name="LineAmount" nillable="true" type="itemPrice" />
+      <xs:element minOccurs="1" maxOccurs="1" name="TaxAmount" type="itemPrice" />
+      <xs:element minOccurs="1" maxOccurs="1" name="LineAmount" type="itemPrice" />
       <xs:element minOccurs="0" maxOccurs="1" name="AccountCode" type="accountCode" />
       <xs:element minOccurs="0" maxOccurs="1" name="Tracking" type="ArrayOfTrackingCategory" />
       <xs:element minOccurs="0" maxOccurs="1" name="ItemCode" type="xs:string" />
-      <xs:element minOccurs="1" maxOccurs="1" name="Quantity" nillable="true" type="itemQuantity" />
+      <xs:element minOccurs="1" maxOccurs="1" name="Quantity" type="itemQuantity" />
       <xs:element minOccurs="0" maxOccurs="1" name="DiscountRate" type="itemPrice" />

     </xs:all>
'''

@benmccann
Copy link
Owner

@onevision @andrewsnowden does removing nillable="true" make these fields required? The Xero docs say they should be optional, so this seems suspicious to me. Maybe you also want to set the minOccur to 0 instead or in addition to. See http://www.dimuthu.org/blog/2008/08/18/xml-schema-nillabletrue-vs-minoccurs0/comment-page-1/

Please be sure to test this change with creating and fetching invoices, bank transactions, and receipts

@onevision
Copy link
Contributor Author

No, I removed nillable="true" to stop weird schema lines being added to the posted XML. The fields were still not mandatory

@dtbullock
Copy link

The 'weird schema lines being added to the posted XML' are due to JAXB trying to do the right thing with respect to the nillable attribute on the element definition. From the XSD 1.1 spec:

If {nillable} is true, then an element with no text or element content can be ·valid· despite a {type definition} which would otherwise require content, IF it carries the attribute xsi:nil with the value true

So the effect of 'nillable' in a data-binding situation is to panic the 'XSD processor' into a line of thought like:

  1. I am supposed to provide this element, since it is required (minOccurs > 0)
  2. hmm, but I've been given no data to bind here
  3. probably I'll have to spit the dummy that this unmarshaling effort to be invalid
  4. but wait! the element definition as 'nillable' - I can provide the element, but just leave it empty! saved!
  5. of course, to make use of that trick, I have to mark the element with an attribute ... xsi:nil="true"
  6. and of course, since the xsi namespace isn't in the parent scope, I'll have to toss in xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. shame I couldn't just omit the element altogether
  8. I guess the schema author didn't know what they were doing
  9. oh hang on, here comes another element! ...

So the question becomes whether Xero-the-API would prefer empty elements or no elements when there is nothing to say (and it's allowed).

If it prefers no elements at all, then using 'minOccurs=0' and NOT marking it 'nillable' is the right way to go.

If it prefers empty elements over absent ones, then 'minOccurs>0' and either:

  • permit the element to be empty per its content-model; OR
  • mark it as nillable (and make sure that conformant XML docs to the schema include xsi:nil="true"

Occam's razor says minOccurs=0 wins. Indeed, at the tip of 'master' on XeroAPI-Schema, Receipt.xsd recently has that.

But what we don't need is minOcurrs=0 and nillable. That seems wrong to me. Though at the tip of 'master' on XeroAPI-Schema, there are plenty instances of this. They are not likely to get 'triggered' though ... JAXB is never likely to test if it is nillable if the element is allowed to be absent entirely.

@dtbullock
Copy link

Laid into 'em with XeroAPI/XeroAPI-Schemas#33

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants