From 07abcda80b0fc28191910d6ef779d9393f2a32b9 Mon Sep 17 00:00:00 2001 From: 8eth Date: Mon, 8 Dec 2025 10:19:54 -0800 Subject: [PATCH] Adding tax_service_opt_out to Gift Cards --- recurly/__init__.py | 3 +- ...created-with-tax-service-opt-out-false.xml | 82 +++++++++++++++++++ ...eated-with-tax-service-opt-out-invalid.xml | 52 ++++++++++++ ...d-with-tax-service-opt-out-legacy-site.xml | 52 ++++++++++++ .../created-with-tax-service-opt-out-true.xml | 82 +++++++++++++++++++ tests/test_resources.py | 70 ++++++++++++++-- 6 files changed, 333 insertions(+), 8 deletions(-) create mode 100644 tests/fixtures/gift_cards/created-with-tax-service-opt-out-false.xml create mode 100644 tests/fixtures/gift_cards/created-with-tax-service-opt-out-invalid.xml create mode 100644 tests/fixtures/gift_cards/created-with-tax-service-opt-out-legacy-site.xml create mode 100644 tests/fixtures/gift_cards/created-with-tax-service-opt-out-true.xml diff --git a/recurly/__init__.py b/recurly/__init__.py index 6aba554e..45c5d9c9 100644 --- a/recurly/__init__.py +++ b/recurly/__init__.py @@ -792,7 +792,8 @@ class GiftCard(Resource): 'billing_info', 'liability_gl_account_id', 'revenue_gl_account_id', - 'performance_obligation_id' + 'performance_obligation_id', + 'tax_service_opt_out' ) _classes_for_nodename = {'recipient_account': Account,'gifter_account': Account, 'delivery': Delivery} diff --git a/tests/fixtures/gift_cards/created-with-tax-service-opt-out-false.xml b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-false.xml new file mode 100644 index 00000000..0a25e168 --- /dev/null +++ b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-false.xml @@ -0,0 +1,82 @@ +POST https://api.recurly.com/v2/gift_cards HTTP/1.1 +X-Api-Version: {api-version} +Accept: application/xml +Authorization: Basic YXBpa2V5Og== +User-Agent: {user-agent} +Content-Type: application/xml; charset=utf-8 + + + + USD + +
+ 400 Alabama St + San Francisco + US + CA + 94110 +
+ john@email.com + John + Smith + email +
+ + e0004e3c-216c-4254-8767-9be605cd0b03 + verena@example.com + Verena + Example + + US + USD + Verena + Example + 11 + 4111-1111-1111-1111 + 123 + 2019 + + + test_gift_card + false + 2000 +
+ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/gift_cards/2018434791876074812 + + + + + + 2018434791876074812 + 9FC359369CD3892E + test_gift_card + 2000 + USD + + email + john@email.com + + + +
+ 400 Alabama St + + San Francisco + CA + 94110 + US + +
+ + +
+ 2016-08-16T21:49:37Z + 2016-08-16T21:49:37Z + + + + +
diff --git a/tests/fixtures/gift_cards/created-with-tax-service-opt-out-invalid.xml b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-invalid.xml new file mode 100644 index 00000000..5320dbe6 --- /dev/null +++ b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-invalid.xml @@ -0,0 +1,52 @@ +POST https://api.recurly.com/v2/gift_cards HTTP/1.1 +X-Api-Version: {api-version} +Accept: application/xml +Authorization: Basic YXBpa2V5Og== +User-Agent: {user-agent} +Content-Type: application/xml; charset=utf-8 + + + + USD + +
+ 400 Alabama St + San Francisco + US + CA + 94110 +
+ john@email.com + John + Smith + email +
+ + e0004e3c-216c-4254-8767-9be605cd0b03 + verena@example.com + Verena + Example + + US + USD + Verena + Example + 11 + 4111-1111-1111-1111 + 123 + 2019 + + + test_gift_card + invalid + 2000 +
+ +HTTP/1.1 422 Unprocessable Entity +Content-Type: application/xml; charset=utf-8 + + + + tax_service_opt_out + Allowed values: true, false + diff --git a/tests/fixtures/gift_cards/created-with-tax-service-opt-out-legacy-site.xml b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-legacy-site.xml new file mode 100644 index 00000000..d5bce600 --- /dev/null +++ b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-legacy-site.xml @@ -0,0 +1,52 @@ +POST https://api.recurly.com/v2/gift_cards HTTP/1.1 +X-Api-Version: {api-version} +Accept: application/xml +Authorization: Basic YXBpa2V5Og== +User-Agent: {user-agent} +Content-Type: application/xml; charset=utf-8 + + + + USD + +
+ 400 Alabama St + San Francisco + US + CA + 94110 +
+ john@email.com + John + Smith + email +
+ + e0004e3c-216c-4254-8767-9be605cd0b03 + verena@example.com + Verena + Example + + US + USD + Verena + Example + 11 + 4111-1111-1111-1111 + 123 + 2019 + + + test_gift_card + true + 2000 +
+ +HTTP/1.1 422 Unprocessable Entity +Content-Type: application/xml; charset=utf-8 + + + + tax_service_opt_out + Not supported for legacy invoices + diff --git a/tests/fixtures/gift_cards/created-with-tax-service-opt-out-true.xml b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-true.xml new file mode 100644 index 00000000..9cacb387 --- /dev/null +++ b/tests/fixtures/gift_cards/created-with-tax-service-opt-out-true.xml @@ -0,0 +1,82 @@ +POST https://api.recurly.com/v2/gift_cards HTTP/1.1 +X-Api-Version: {api-version} +Accept: application/xml +Authorization: Basic YXBpa2V5Og== +User-Agent: {user-agent} +Content-Type: application/xml; charset=utf-8 + + + + USD + +
+ 400 Alabama St + San Francisco + US + CA + 94110 +
+ john@email.com + John + Smith + email +
+ + e0004e3c-216c-4254-8767-9be605cd0b03 + verena@example.com + Verena + Example + + US + USD + Verena + Example + 11 + 4111-1111-1111-1111 + 123 + 2019 + + + test_gift_card + true + 2000 +
+ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/gift_cards/2018434791876074812 + + + + + + 2018434791876074812 + 9FC359369CD3892E + test_gift_card + 2000 + USD + + email + john@email.com + + + +
+ 400 Alabama St + + San Francisco + CA + 94110 + US + +
+ + +
+ 2016-08-16T21:49:37Z + 2016-08-16T21:49:37Z + + + +
+ diff --git a/tests/test_resources.py b/tests/test_resources.py index 9d28f14d..df5cb392 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -570,16 +570,16 @@ def test_charge_with_vertex_transaction_type(self): type='charge', vertex_transaction_type='sale' ) - + with self.mock_request('adjustment/charged-with-vertex-transaction-type.xml'): account.charge(charge) - + # Verify the charge was created with vertex_transaction_type self.assertEqual(charge.vertex_transaction_type, 'sale') def test_purchase_with_invoice_override_vertex_transaction_type(self): """Test that invoice-level vertex_transaction_type overrides adjustment-level values. - + This demonstrates the override behavior where an invoice can have its own vertex_transaction_type that takes precedence over the individual adjustment values. """ @@ -596,16 +596,16 @@ def test_purchase_with_invoice_override_vertex_transaction_type(self): ], vertex_transaction_type='rental' # Invoice-level value (should override) ) - + with self.mock_request('purchase/invoiced-with-invoice-override-vertex-type.xml'): invoice_collection = purchase.invoice() - + invoice = invoice_collection.charge_invoice adjustments = invoice.line_items - + # Verify the invoice has the invoice-level vertex_transaction_type self.assertEqual(invoice.vertex_transaction_type, 'rental') - + # The adjustment still has its own value (API preserves both) # but the invoice-level value is what gets used for tax calculation self.assertEqual(adjustments[0].vertex_transaction_type, 'sale') @@ -3454,6 +3454,62 @@ def test_gift_cards_purchase(self): self.assertTrue(gift_card.delivery is not None) self.assertTrue(gift_card.canceled_at is None) + def test_gift_cards_purchase_with_tax_service_opt_out_true(self): + gift_card = self._build_gift_card() + gift_card.tax_service_opt_out = True + + self.assertFalse('_url' in gift_card.attributes) + + with self.mock_request('gift_cards/created-with-tax-service-opt-out-true.xml'): + gift_card.save() + + self.assertTrue(gift_card._url is not None) + self.assertTrue(gift_card.delivery is not None) + self.assertTrue(gift_card.canceled_at is None) + + def test_gift_cards_purchase_with_tax_service_opt_out_false(self): + gift_card = self._build_gift_card() + gift_card.tax_service_opt_out = False + + self.assertFalse('_url' in gift_card.attributes) + + with self.mock_request('gift_cards/created-with-tax-service-opt-out-false.xml'): + gift_card.save() + + self.assertTrue(gift_card._url is not None) + self.assertTrue(gift_card.delivery is not None) + self.assertTrue(gift_card.canceled_at is None) + + def test_gift_cards_purchase_with_tax_service_opt_out_invalid(self): + gift_card = self._build_gift_card() + gift_card.tax_service_opt_out = 'invalid' + + self.assertFalse('_url' in gift_card.attributes) + + with self.mock_request('gift_cards/created-with-tax-service-opt-out-invalid.xml'): + try: + gift_card.save() + except ValidationError as exc: + error = exc + else: + self.fail('Creating a gift card with invalid tax_service_opt_out did not raise a ValidationError') + self.assertEqual(error.symbol, 'tax_service_opt_out') + self.assertIn('Allowed values: true, false', error.message) + + def test_gift_cards_purchase_with_tax_service_opt_out_legacy_site(self): + gift_card = self._build_gift_card() + gift_card.tax_service_opt_out = True + + with self.mock_request('gift_cards/created-with-tax-service-opt-out-legacy-site.xml'): + try: + gift_card.save() + except ValidationError as exc: + error = exc + else: + self.fail('Creating a gift card with tax_service_opt_out on legacy site did not raise a ValidationError') + self.assertEqual(error.symbol, 'tax_service_opt_out') + self.assertIn('Not supported for legacy invoices', error.message) + def test_gift_cards_preview(self): gift_card = self._build_gift_card()