Credit Note Allocations cannot be entered
Looking at the code, it seems that Credit Note Allocations cannot be entered, since it's implemented on a separate endpoint:
http://developer.xero.com/documentation/api/credit-notes/#title8
You'll be able to hack this together like so: https://github.com/freakboy3742/pyxero/issues/107
This requires a little more hacking - #107 almost works with CreditNote Allocations, but the endpoint has to look like CreditNotes/{CreditNoteID}/Allocations.
If we re-set the base_url for xero.creditnotes.put then we end up calling CreditNotes/{CreditNoteID}/Allocations/CreditNotes because of how basemanager.py constructs the uri:
uri = '/'.join([self.base_url, self.name])
So we also need to swap out the name and singular like so:
old_base_url = xero.creditnotes.base_url
old_name = xero.creditnotes.name
old_singular = xero.creditnotes.singular
xero.creditnotes.base_url = '{}/CreditNotes/{}'.format(old_base_url, creditnoteid)
xero.creditnotes.name = 'Allocations'
xero.creditnotes.singular = 'Allocation'
Thanks aidanlister and MattHealy. My version of this looks like this:
def allocate_credit_note_payment(credit_note_guid, allocations, xero):
"""
Must pass in xero as it needs credentials if using public method.
allocations should be an array of dictionaries containing amount, invoice:invoice idXero GUIDs for the contacts.
The request should look like:
PUT CreditNotes/a1665e41-719b-400d-ae59-bc92655d8366/Allocations
<Allocations>
<Allocation>
<AppliedAmount>60.50</AppliedAmount>
<Invoice>
<InvoiceID>f5832195-5cd3-4660-ad3f-b73d9c64f263</InvoiceID>
</Invoice>
</Allocation>
</Allocations>
"""
# Store the original endpoint base_url
old_base_url = xero.creditnotes.base_url
old_name = xero.creditnotes.name
old_singular = xero.creditnotes.singular
# Call the API
try:
xero.creditnotes.base_url = '{}/CreditNotes/{}'.format(old_base_url, credit_note_guid)
xero.creditnotes.name = 'Allocations'
xero.creditnotes.singular = 'Allocation'
xero.creditnotes.put(allocations)
except:
raise
finally:
# Reset the base_url
xero.creditnotes.base_url = old_base_url
xero.creditnotes.name = old_name
xero.creditnotes.singular = old_singular
Which I called from something like this:
...
...
def add_to_xero(self, xero):
""" Going to allocate all to a single invoice."""
cn = self.parent.xero_credit_notes(xero)[0]
credit_note_guid = cn['CreditNoteID']
allocations = []
allocation = {}
allocation['AppliedAmount'] = self.parent.gross_amount
allocation['Invoice'] = {}
allocation['Invoice']['InvoiceID'] = self.parent.invoice_id
allocations.append(allocation)
try:
# Now add to Xero
allocate_credit_note_payment(credit_note_guid, allocations, xero)
except XeroBadRequest as e:
print('Problem with add to xero, ? {}'.format(self))
raise e
...
...
The double put method does need a general solution but I don't have one.
Should we be looking for something like:
xero.creditnotes(id={}).allocations.put(new_credit_note_allocations)
Can confirm, @drummonds method is working nicely :ok_hand: