Skip to content

Commit 6496f34

Browse files
authored
Merge pull request routablehq#132 from bendavis78/void-invoice
Added support for voiding invoices
2 parents 845b466 + 24a7581 commit 6496f34

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

README.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,16 @@ Attaching a file to customer:
426426
attachment.ContentType = 'application/pdf'
427427
attachment.save(qb=client)
428428
429+
Other operations
430+
----------------
431+
Void an invoice:
432+
433+
.. code-block:: python
434+
435+
invoice = Invoice()
436+
invoice.Id = 7
437+
invoice.void(qb=client)
438+
429439
Working with JSON data
430440
----------------
431441
All objects include ``to_json`` and ``from_json`` methods.

quickbooks/mixins.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,26 @@ def send(self, qb=None, send_to=None):
114114
return results
115115

116116

117+
class VoidMixin(object):
118+
def void(self, qb=None):
119+
if not qb:
120+
qb = QuickBooks()
121+
122+
if not self.Id:
123+
raise QuickbooksException('Cannot void unsaved object')
124+
125+
data = {
126+
'Id': self.Id,
127+
'SyncToken': self.SyncToken,
128+
}
129+
130+
endpoint = self.qbo_object_name.lower()
131+
url = "{0}/company/{1}/{2}".format(qb.api_url, qb.company_id, endpoint)
132+
results = qb.post(url, json.dumps(data), params={'operation': 'void'})
133+
134+
return results
135+
136+
117137
class UpdateMixin(object):
118138
qbo_object_name = ""
119139

quickbooks/objects/invoice.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
QuickbooksTransactionEntity, LinkedTxn, LinkedTxnMixin
44
from .tax import TxnTaxDetail
55
from .detailline import DetailLine, SalesItemLine, SubtotalLine, DiscountLine, GroupLine, DescriptionOnlyLine
6-
from ..mixins import QuickbooksPdfDownloadable, DeleteMixin, SendMixin
6+
from ..mixins import QuickbooksPdfDownloadable, DeleteMixin, SendMixin, VoidMixin
77

88

99
class DeliveryInfo(QuickbooksBaseObject):
@@ -15,7 +15,7 @@ def __init__(self):
1515

1616
@python_2_unicode_compatible
1717
class Invoice(DeleteMixin, QuickbooksPdfDownloadable, QuickbooksManagedObject, QuickbooksTransactionEntity,
18-
LinkedTxnMixin, SendMixin):
18+
LinkedTxnMixin, SendMixin, VoidMixin):
1919
"""
2020
QBO definition: An Invoice represents a sales form where the customer pays for a product or service later.
2121

tests/unit/test_mixins.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,29 @@ def test_send_with_send_to_email(self, mock_misc_op):
425425
invoice.send(qb=self.qb_client, send_to="test@email.com")
426426

427427
mock_misc_op.assert_called_with("invoice/2/send?sendTo=test@email.com", None, 'application/octet-stream')
428+
429+
430+
class VoidMixinTest(unittest.TestCase):
431+
def setUp(self):
432+
self.qb_client = client.QuickBooks(
433+
sandbox=True,
434+
consumer_key="update_consumer_key",
435+
consumer_secret="update_consumer_secret",
436+
access_token="update_access_token",
437+
access_token_secret="update_access_token_secret",
438+
company_id="update_company_id",
439+
callback_url="update_callback_url"
440+
)
441+
442+
@patch('quickbooks.mixins.QuickBooks.post')
443+
def test_void(self, post):
444+
invoice = Invoice()
445+
invoice.Id = 2
446+
invoice.void(qb=self.qb_client)
447+
self.assertTrue(post.called)
448+
449+
def test_delete_unsaved_exception(self):
450+
from quickbooks.exceptions import QuickbooksException
451+
452+
invoice = Invoice()
453+
self.assertRaises(QuickbooksException, invoice.void, qb=self.qb_client)

0 commit comments

Comments
 (0)