From 03948a52f3ad1c7e21e9747cf5ae9d4b512d86fa Mon Sep 17 00:00:00 2001 From: Volodymyr Spodaryk Date: Mon, 21 Dec 2020 17:27:14 +0200 Subject: [PATCH 001/154] Added Preferences endpoint to be available --- quickbooks/client.py | 2 +- quickbooks/mixins.py | 22 ++ quickbooks/objects/__init__.py | 1 + quickbooks/objects/base.py | 6 +- quickbooks/objects/preferences.py | 121 +++++++++++ tests/integration/test_preferences.py | 34 +++ tests/unit/objects/test_preferences.py | 282 +++++++++++++++++++++++++ 7 files changed, 466 insertions(+), 2 deletions(-) create mode 100644 quickbooks/objects/preferences.py create mode 100644 tests/integration/test_preferences.py create mode 100644 tests/unit/objects/test_preferences.py diff --git a/quickbooks/client.py b/quickbooks/client.py index c882169c..089964fd 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -46,7 +46,7 @@ class QuickBooks(object): "Account", "Attachable", "Bill", "BillPayment", "Class", "CreditMemo", "Customer", "CompanyCurrency", "Department", "Deposit", "Employee", "Estimate", "Invoice", - "Item", "JournalEntry", "Payment", "PaymentMethod", + "Item", "JournalEntry", "Payment", "PaymentMethod", "Preferences", "Purchase", "PurchaseOrder", "RefundReceipt", "SalesReceipt", "TaxAgency", "TaxCode", "TaxService/Taxcode", "TaxRate", "Term", "TimeActivity", "Transfer", "Vendor", "VendorCredit", "CreditCardPayment", diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 791ec69f..77f5c020 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -144,6 +144,28 @@ def void(self, qb=None): return results +class UpdateNoCreateMixin(object): + qbo_object_name = "" + qbo_json_object_name = "" + + def save(self, qb=None): + if not qb: + qb = QuickBooks() + + if self.Id and int(self.Id) > 0: + json_data = qb.update_object(self.qbo_object_name, self.to_json()) + else: + raise QuickbooksException("Update is not allowed for {0} unsaved object".format(self.qbo_object_name)) + + if self.qbo_json_object_name != '': + obj = type(self).from_json(json_data[self.qbo_json_object_name]) + else: + obj = type(self).from_json(json_data[self.qbo_object_name]) + + self.Id = obj.Id + return obj + + class UpdateMixin(object): qbo_object_name = "" qbo_json_object_name = "" diff --git a/quickbooks/objects/__init__.py b/quickbooks/objects/__init__.py index 9ee9f167..ca6d7011 100644 --- a/quickbooks/objects/__init__.py +++ b/quickbooks/objects/__init__.py @@ -36,6 +36,7 @@ ) from .payment import PaymentLine, Payment from .paymentmethod import PaymentMethod +from .preferences import Preferences from .purchase import Purchase from .purchaseorder import PurchaseOrder from .refundreceipt import RefundReceipt diff --git a/quickbooks/objects/base.py b/quickbooks/objects/base.py index b2e2117e..2236b058 100644 --- a/quickbooks/objects/base.py +++ b/quickbooks/objects/base.py @@ -1,5 +1,5 @@ from six import python_2_unicode_compatible -from ..mixins import ToJsonMixin, FromJsonMixin, ReadMixin, ListMixin, UpdateMixin, ToDictMixin +from ..mixins import ToDictMixin, ToJsonMixin, FromJsonMixin, ListMixin, ReadMixin, UpdateMixin, UpdateNoCreateMixin class QuickbooksBaseObject(ToJsonMixin, FromJsonMixin, ToDictMixin): @@ -24,6 +24,10 @@ class QuickbooksReadOnlyObject(QuickbooksBaseObject, ReadMixin, ListMixin): pass +class QuickbooksUpdateOnlyObject(QuickbooksBaseObject, ReadMixin, ListMixin, UpdateNoCreateMixin): + pass + + @python_2_unicode_compatible class MetaData(FromJsonMixin): def __init__(self): diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py new file mode 100644 index 00000000..5854919b --- /dev/null +++ b/quickbooks/objects/preferences.py @@ -0,0 +1,121 @@ +from six import python_2_unicode_compatible +from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, QuickbooksUpdateOnlyObject, Ref + + +class EmailMessageType(QuickbooksBaseObject): + def __init__(self): + super().__init__() + self.Message = "" + self.Subject = "" + + +class EmailMessagesPrefs(QuickbooksBaseObject): + class_dict = { + "InvoiceMessage": EmailMessageType, + "EstimateMessage": EmailMessageType, + "SalesReceiptMessage": EmailMessageType, + "StatementMessage": EmailMessageType, + } + + def __init__(self): + super().__init__() + self.InvoiceMessage = None + self.EstimateMessage = None + self.SalesReceiptMessage = None + self.StatementMessage = None + + +class ProductAndServicesPrefs(QuickbooksBaseObject): + + def __init__(self): + super().__init__() + self.QuantityWithPriceAndRate = True + self.ForPurchase = True + self.QuantityOnHand = True + self.ForSales = True + + +class ReportPrefs(QuickbooksBaseObject): + + def __init__(self): + super().__init__() + self.ReportBasis = "Accrual" # or "Cash" + self.CalcAgingReportFromTxnDate = False # read only + + +class AccountingInfoPrefs(QuickbooksBaseObject): + + def __init__(self): + super().__init__() + self.FirstMonthOfFiscalYear = "January" # read only + self.UseAccountNumbers = True # read only + self.TaxYearMonth = "January" # read only + self.ClassTrackingPerTxn = False + self.TrackDepartments = False + self.TaxForm = "6" + # Possible values include: Clients, Customers, Donors, Guests, Members, Patients, Tenants. + self.CustomerTerminology = "" # Customers + self.BookCloseDate = "" # e.g. "2018-12-31" + # Possible values include: Business, Department, Division, Location, Property, Store, Territory + self.DepartmentTerminology = "" # Location + self.ClassTrackingPerTxnLine = True + + +class ClassTrackingPerTxnLine(QuickbooksBaseObject): + + def __init__(self): + super().__init__() + self.ReportBasis = "Accrual" # or "Cash" + self.CalcAgingReportFromTxnDate = False # read only + + +# class SalesFormsPrefs(QuickbooksBaseObject): # FIXME +# class VendorAndPurchasesPrefs(QuickbooksBaseObject): # FIXME +# class TaxPrefs(QuickbooksBaseObject): # FIXME +# class OtherPrefs(QuickbooksBaseObject): # FIXME +# class TimeTrackingPrefs(QuickbooksBaseObject): # FIXME +# class CurrencyPrefs(QuickbooksBaseObject): # FIXME + + +@python_2_unicode_compatible +class Preferences(QuickbooksUpdateOnlyObject, QuickbooksTransactionEntity): + """ + QBO definition: The Preferences resource represents a set of company preferences that + control application behavior in QuickBooks Online. + They are mostly exposed as read-only through the Preferences endpoint with only a very small subset of them + available as writable. Preferences are not necessarily honored when making requests via the QuickBooks API + because a lot of them control UI behavior in the application and may not be applicable for apps. + """ + + class_dict = { + 'EmailMessagesPrefs': EmailMessagesPrefs, + 'ProductAndServicesPrefs': ProductAndServicesPrefs, + 'ReportPrefs': ReportPrefs, + 'AccountingInfoPrefs': AccountingInfoPrefs, + + # FIXME: add remaining fields to be serializable, otherwise they will remain as dicts + # 'SalesFormsPrefs': SalesFormsPrefs, + # 'VendorAndPurchasesPrefs': VendorAndPurchasesPrefs, + # 'TaxPrefs': TaxPrefs, + # 'OtherPrefs': OtherPrefs, + # 'TimeTrackingPrefs': TimeTrackingPrefs, + # 'CurrencyPrefs': CurrencyPrefs, + } + + qbo_object_name = "Preferences" + + def __init__(self): + super().__init__() + self.EmailMessagesPrefs = None + self.ProductAndServicesPrefs = None + self.ReportPrefs = None + self.AccountingInfoPrefs = None + self.SalesFormsPrefs = None + self.VendorAndPurchasesPrefs = None + self.TaxPrefs = None + self.OtherPrefs = None + self.TimeTrackingPrefs = None + self.CurrencyPrefs = None + + def __str__(self): + return 'Preferences {0}'.format(self.Id) diff --git a/tests/integration/test_preferences.py b/tests/integration/test_preferences.py new file mode 100644 index 00000000..7c69d339 --- /dev/null +++ b/tests/integration/test_preferences.py @@ -0,0 +1,34 @@ +from datetime import datetime +from quickbooks.objects.account import Account +from tests.integration.test_base import QuickbooksTestCase + + +class AccountTest(QuickbooksTestCase): + def setUp(self): + super(AccountTest, self).setUp() + + self.account_number = datetime.now().strftime('%d%H%M') + self.name = "Test Account {0}".format(self.account_number) + + def test_create(self): + account = Account() + account.AcctNum = self.account_number + account.Name = self.name + account.AccountSubType = "CashOnHand" + account.save(qb=self.qb_client) + + self.id = account.Id + query_account = Account.get(account.Id, qb=self.qb_client) + + self.assertEquals(account.Id, query_account.Id) + self.assertEquals(query_account.Name, self.name) + self.assertEquals(query_account.AcctNum, self.account_number) + + def test_update(self): + account = Account.filter(Name=self.name, qb=self.qb_client)[0] + + account.Name = "Updated Name {0}".format(self.account_number) + account.save(qb=self.qb_client) + + query_account = Account.get(account.Id, qb=self.qb_client) + self.assertEquals(query_account.Name, "Updated Name {0}".format(self.account_number)) diff --git a/tests/unit/objects/test_preferences.py b/tests/unit/objects/test_preferences.py new file mode 100644 index 00000000..bfaed000 --- /dev/null +++ b/tests/unit/objects/test_preferences.py @@ -0,0 +1,282 @@ +import unittest + +from quickbooks import QuickBooks +from quickbooks.objects.preferences import Preferences + + +# Taken from here: +# https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/preferences#full-update-preferences +PAYLOAD = { + "Preferences": { + "EmailMessagesPrefs": { + "InvoiceMessage": { + "Message": "Your invoice is attached. Please remit payment at your earliest convenience.\n" + "Thank you for your business - we appreciate it very much.\n\nSincerely,\n" + "Craig's Design and Landscaping Services", + "Subject": "Invoice from Craig's Design and Landscaping Services" + }, + "EstimateMessage": { + "Message": "Please review the estimate below. Feel free to contact us if you have any questions.\n" + "We look forward to working with you.\n\nSincerely,\nCraig's Design and Landscaping Services", + "Subject": "Estimate from Craig's Design and Landscaping Services" + }, + "SalesReceiptMessage": { + "Message": "Your sales receipt is attached.\nThank you for your business - we appreciate it very much.\n\n" + "Sincerely,\nCraig's Design and Landscaping Services", + "Subject": "Sales Receipt from Craig's Design and Landscaping Services" + }, + "StatementMessage": { + "Message": "Your statement is attached. Please remit payment at your earliest convenience.\n" + "Thank you for your business - we appreciate it very much.\n\nSincerely,\n" + "Craig's Design and Landscaping Services", + "Subject": "Statement from Craig's Design and Landscaping Services" + } + }, + "ProductAndServicesPrefs": { + "QuantityWithPriceAndRate": True, + "ForPurchase": True, + "QuantityOnHand": True, + "ForSales": True + }, + "domain": "QBO", + "SyncToken": "6", + "ReportPrefs": { + "ReportBasis": "Accrual", + "CalcAgingReportFromTxnDate": False + }, + "AccountingInfoPrefs": { + "FirstMonthOfFiscalYear": "January", + "UseAccountNumbers": True, + "TaxYearMonth": "January", + "ClassTrackingPerTxn": False, + "TrackDepartments": True, + "TaxForm": "6", + "CustomerTerminology": "Customers", + "BookCloseDate": "2018-12-31", + "DepartmentTerminology": "Location", + "ClassTrackingPerTxnLine": True + }, + "SalesFormsPrefs": { + "ETransactionPaymentEnabled": False, + "CustomTxnNumbers": False, + "AllowShipping": False, + "AllowServiceDate": False, + "ETransactionEnabledStatus": "NotApplicable", + "DefaultCustomerMessage": "Thank you for your business and have a great day!", + "EmailCopyToCompany": False, + "AllowEstimates": True, + "DefaultTerms": { + "value": "3" + }, + "AllowDiscount": True, + "DefaultDiscountAccount": "86", + "AllowDeposit": True, + "AutoApplyPayments": True, + "IPNSupportEnabled": False, + "AutoApplyCredit": True, + "CustomField": [ + { + "CustomField": [ + { + "BooleanValue": False, + "Type": "BooleanType", + "Name": "SalesFormsPrefs.UseSalesCustom3" + }, + { + "BooleanValue": False, + "Type": "BooleanType", + "Name": "SalesFormsPrefs.UseSalesCustom2" + }, + { + "BooleanValue": True, + "Type": "BooleanType", + "Name": "SalesFormsPrefs.UseSalesCustom1" + } + ] + }, + { + "CustomField": [ + { + "StringValue": "Crew #", + "Type": "StringType", + "Name": "SalesFormsPrefs.SalesCustomName1" + } + ] + } + ], + "UsingPriceLevels": False, + "ETransactionAttachPDF": False + }, + "VendorAndPurchasesPrefs": { + "BillableExpenseTracking": True, + "TrackingByCustomer": True, + "POCustomField": [ + { + "CustomField": [ + { + "BooleanValue": False, + "Type": "BooleanType", + "Name": "PurchasePrefs.UsePurchaseCustom3" + }, + { + "BooleanValue": True, + "Type": "BooleanType", + "Name": "PurchasePrefs.UsePurchaseCustom2" + }, + { + "BooleanValue": True, + "Type": "BooleanType", + "Name": "PurchasePrefs.UsePurchaseCustom1" + } + ] + }, + { + "CustomField": [ + { + "StringValue": "Sales Rep", + "Type": "StringType", + "Name": "PurchasePrefs.PurchaseCustomName2" + }, + { + "StringValue": "Crew #", + "Type": "StringType", + "Name": "PurchasePrefs.PurchaseCustomName1" + } + ] + } + ] + }, + "TaxPrefs": { + "TaxGroupCodeRef": { + "value": "2" + }, + "UsingSalesTax": True + }, + "OtherPrefs": { + "NameValue": [ + { + "Name": "SalesFormsPrefs.DefaultCustomerMessage", + "Value": "Thank you for your business and have a great day!" + }, + { + "Name": "SalesFormsPrefs.DefaultItem", + "Value": "1" + }, + { + "Name": "DTXCopyMemo", + "Value": "false" + }, + { + "Name": "UncategorizedAssetAccountId", + "Value": "32" + }, + { + "Name": "UncategorizedIncomeAccountId", + "Value": "30" + }, + { + "Name": "UncategorizedExpenseAccountId", + "Value": "31" + }, + { + "Name": "SFCEnabled", + "Value": "true" + }, + { + "Name": "DataPartner", + "Value": "false" + }, + { + "Name": "Vendor1099Enabled", + "Value": "true" + }, + { + "Name": "TimeTrackingFeatureEnabled", + "Value": "true" + }, + { + "Name": "FDPEnabled", + "Value": "false" + }, + { + "Name": "ProjectsEnabled", + "Value": "false" + }, + { + "Name": "DateFormat", + "Value": "Month Date Year separated by a slash" + }, + { + "Name": "DateFormatMnemonic", + "Value": "MMDDYYYY_SEP_SLASH" + }, + { + "Name": "NumberFormat", + "Value": "US Number Format" + }, + { + "Name": "NumberFormatMnemonic", + "Value": "US_NB" + }, + { + "Name": "WarnDuplicateCheckNumber", + "Value": "true" + }, + { + "Name": "WarnDuplicateBillNumber", + "Value": "false" + }, + { + "Name": "SignoutInactiveMinutes", + "Value": "60" + }, + { + "Name": "AccountingInfoPrefs.ShowAccountNumbers", + "Value": "false" + } + ] + }, + "sparse": False, + "TimeTrackingPrefs": { + "WorkWeekStartDate": "Monday", + "MarkTimeEntriesBillable": True, + "ShowBillRateToAll": False, + "UseServices": True, + "BillCustomers": True + }, + "CurrencyPrefs": { + "HomeCurrency": { + "value": "USD" + }, + "MultiCurrencyEnabled": False + }, + "Id": "1", + "MetaData": { + "CreateTime": "2017-10-25T01:05:43-07:00", + "LastUpdatedTime": "2018-03-08T13:24:26-08:00" + } + }, + "time": "2018-03-12T08:45:52.965-07:00" +} + + +class PreferencesTests(unittest.TestCase): + def test_unicode(self): + preferences = Preferences() + preferences.Id = 137 + + self.assertEquals(str(preferences), "Preferences 137") + + def test_valid_object_name(self): + preferences = Preferences() + client = QuickBooks() + result = client.isvalid_object_name(preferences.qbo_object_name) + + self.assertTrue(result) + + def test_structure(self): + preferences = Preferences.from_json(PAYLOAD['Preferences']) + + print('Expected:', PAYLOAD['Preferences']) + print('Actual:', preferences.to_dict()) + self.assertEquals(PAYLOAD['Preferences'], preferences.to_dict()) From ecbb9fa5cc6e1c695039b544407ab7d2855d2614 Mon Sep 17 00:00:00 2001 From: Volodymyr Spodaryk Date: Tue, 22 Dec 2020 15:45:07 +0200 Subject: [PATCH 002/154] Added better serialization to Preferences --- quickbooks/objects/__init__.py | 7 +- quickbooks/objects/preferences.py | 107 +++++++++++++++++++++++++----- setup.py | 2 +- 3 files changed, 99 insertions(+), 17 deletions(-) diff --git a/quickbooks/objects/__init__.py b/quickbooks/objects/__init__.py index ca6d7011..d1c7a520 100644 --- a/quickbooks/objects/__init__.py +++ b/quickbooks/objects/__init__.py @@ -36,7 +36,12 @@ ) from .payment import PaymentLine, Payment from .paymentmethod import PaymentMethod -from .preferences import Preferences +from .preferences import ( + AccountingInfoPrefs, ClassTrackingPerTxnLine, CurrencyPrefs, + EmailMessageType, EmailMessagesPrefs, OtherPrefs, Preferences, + ProductAndServicesPrefs, ReportPrefs, SalesFormsPrefs, + VendorAndPurchasesPrefs, TaxPrefs, TimeTrackingPrefs, +) from .purchase import Purchase from .purchaseorder import PurchaseOrder from .refundreceipt import RefundReceipt diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py index 5854919b..b401c011 100644 --- a/quickbooks/objects/preferences.py +++ b/quickbooks/objects/preferences.py @@ -1,5 +1,5 @@ from six import python_2_unicode_compatible -from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, QuickbooksUpdateOnlyObject, Ref +from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, QuickbooksUpdateOnlyObject # CustomField, Ref class EmailMessageType(QuickbooksBaseObject): @@ -69,12 +69,91 @@ def __init__(self): self.CalcAgingReportFromTxnDate = False # read only -# class SalesFormsPrefs(QuickbooksBaseObject): # FIXME -# class VendorAndPurchasesPrefs(QuickbooksBaseObject): # FIXME -# class TaxPrefs(QuickbooksBaseObject): # FIXME -# class OtherPrefs(QuickbooksBaseObject): # FIXME -# class TimeTrackingPrefs(QuickbooksBaseObject): # FIXME -# class CurrencyPrefs(QuickbooksBaseObject): # FIXME +class SalesFormsPrefs(QuickbooksBaseObject): + class_dict = { + # 'DefaultTerms': Ref, # FIXME: serialize field properly, not as JSON + } + list_dict = { + # 'CustomField': CustomField, # FIXME: serialize field properly, not as JSON + } + detail_dict = { + # 'CustomField': CustomField, # FIXME: serialize field properly, not as JSON + } + + def __init__(self): + super().__init__() + self.ETransactionPaymentEnabled = False + self.CustomTxnNumbers = False + self.AllowShipping = False + self.AllowServiceDate = False + self.ETransactionEnabledStatus = "" # e.g. "NotApplicable" + self.DefaultCustomerMessage = "" # e.g. "Thank you for your business and have a great day!" + self.EmailCopyToCompany = False + self.AllowEstimates = True + self.DefaultTerms = None + self.AllowDiscount = True + self.DefaultDiscountAccount = "" + self.AllowDeposit = True + self.AutoApplyPayments = True + self.IPNSupportEnabled = False + self.AutoApplyCredit = True + self.CustomField = None + self.UsingPriceLevels = False + self.ETransactionAttachPDF = False + + +class VendorAndPurchasesPrefs(QuickbooksBaseObject): + class_dict = {} + list_dict = { + # 'POCustomField': CustomField, # FIXME: serialize field properly, not as JSON + } + detail_dict = { + # 'POCustomField': CustomField, # FIXME: serialize field properly, not as JSON + } + + def __init__(self): + super().__init__() + self.BillableExpenseTracking = True + self.TrackingByCustomer = True + self.POCustomField = None + + +class TaxPrefs(QuickbooksBaseObject): + class_dict = { + # 'TaxGroupCodeRef': Ref, # FIXME: serialize field properly, not as JSON + } + + def __init__(self): + super().__init__() + self.TaxGroupCodeRef = None + self.UsingSalesTax = True + + +class OtherPrefs(QuickbooksBaseObject): + + def __init__(self): + super().__init__() + + +class TimeTrackingPrefs(QuickbooksBaseObject): + + def __init__(self): + super().__init__() + self.WorkWeekStartDate = "" # e.g. "Monday" + self.MarkTimeEntriesBillable = True + self.ShowBillRateToAll = False + self.UseServices = True + self.BillCustomers = True + + +class CurrencyPrefs(QuickbooksBaseObject): + class_dict = { + # 'HomeCurrency': Ref, # FIXME: serialize field properly, not as JSON + } + + def __init__(self): + super().__init__() + self.HomeCurrency = None @python_2_unicode_compatible @@ -92,14 +171,12 @@ class Preferences(QuickbooksUpdateOnlyObject, QuickbooksTransactionEntity): 'ProductAndServicesPrefs': ProductAndServicesPrefs, 'ReportPrefs': ReportPrefs, 'AccountingInfoPrefs': AccountingInfoPrefs, - - # FIXME: add remaining fields to be serializable, otherwise they will remain as dicts - # 'SalesFormsPrefs': SalesFormsPrefs, - # 'VendorAndPurchasesPrefs': VendorAndPurchasesPrefs, - # 'TaxPrefs': TaxPrefs, - # 'OtherPrefs': OtherPrefs, - # 'TimeTrackingPrefs': TimeTrackingPrefs, - # 'CurrencyPrefs': CurrencyPrefs, + 'SalesFormsPrefs': SalesFormsPrefs, + 'VendorAndPurchasesPrefs': VendorAndPurchasesPrefs, + 'TaxPrefs': TaxPrefs, + 'OtherPrefs': OtherPrefs, + 'TimeTrackingPrefs': TimeTrackingPrefs, + 'CurrencyPrefs': CurrencyPrefs, } qbo_object_name = "Preferences" diff --git a/setup.py b/setup.py index 92d0d9ae..7655928b 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 8, 4) +VERSION = (0, 9, 0) version = '.'.join(map(str, VERSION)) setup( From c55e038ae19bec30a1cba004e2095016c836fa3f Mon Sep 17 00:00:00 2001 From: Volodymyr Spodaryk Date: Tue, 12 Jan 2021 12:36:23 +0200 Subject: [PATCH 003/154] Removed redundant DescriptionLine class. Use DescriptionOnlyLine instead. --- quickbooks/client.py | 19 +++++++++++-------- quickbooks/objects/__init__.py | 4 ++-- quickbooks/objects/creditmemo.py | 4 ++-- quickbooks/objects/detailline.py | 11 ----------- quickbooks/objects/estimate.py | 4 ++-- tests/unit/objects/test_detailline.py | 10 +--------- 6 files changed, 18 insertions(+), 34 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index c882169c..70db4974 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -253,9 +253,12 @@ def get_single_object(self, qbbo, pk): url = "{0}/company/{1}/{2}/{3}/".format(self.api_url, self.company_id, qbbo.lower(), pk) result = self.get(url, {}) - return result - - def handle_exceptions(self, results): + @staticmethod + def handle_exceptions(results): + """ + Error codes with description in documentation: + https://developer.intuit.com/app/developer/qbo/docs/develop/troubleshooting/error-codes#id1 + """ # Needs to handle multiple errors for error in results["Error"]: @@ -269,17 +272,17 @@ def handle_exceptions(self, results): if "code" in error: code = int(error["code"]) - if code > 0 and code <= 499: + if 0 < code <= 499: raise exceptions.AuthorizationException(message, code, detail) - elif code >= 500 and code <= 599: + elif 500 <= code <= 599: raise exceptions.UnsupportedException(message, code, detail) - elif code >= 600 and code <= 1999: + elif 600 <= code <= 1999: if code == 610: raise exceptions.ObjectNotFoundException(message, code, detail) raise exceptions.GeneralException(message, code, detail) - elif code >= 2000 and code <= 4999: + elif 2000 <= code <= 4999: raise exceptions.ValidationException(message, code, detail) - elif code >= 10000: + elif 10000 <= code: raise exceptions.SevereException(message, code, detail) else: raise exceptions.QuickbooksException(message, code, detail) diff --git a/quickbooks/objects/__init__.py b/quickbooks/objects/__init__.py index 9ee9f167..ac175aca 100644 --- a/quickbooks/objects/__init__.py +++ b/quickbooks/objects/__init__.py @@ -21,9 +21,9 @@ ) from .detailline import ( DetailLine, DiscountOverride, DiscountLineDetail, DiscountLine, - SubtotalLineDetail, SubtotalLine, DescriptionLineDetail, DescriptionLine, + SubtotalLineDetail, SubtotalLine, DescriptionLineDetail, DescriptionOnlyLine, SalesItemLineDetail, SalesItemLine, GroupLineDetail, GroupLine, - DescriptionOnlyLine, AccountBasedExpenseLineDetail, AccountBasedExpenseLine, + AccountBasedExpenseLineDetail, AccountBasedExpenseLine, TDSLineDetail, TDSLine, ItemBasedExpenseLineDetail, ItemBasedExpenseLine, ) diff --git a/quickbooks/objects/creditmemo.py b/quickbooks/objects/creditmemo.py index 86db3e23..a92e7f0c 100644 --- a/quickbooks/objects/creditmemo.py +++ b/quickbooks/objects/creditmemo.py @@ -1,6 +1,6 @@ from six import python_2_unicode_compatible -from quickbooks.objects.detailline import SalesItemLine, SubtotalLine, DiscountLine, DescriptionLine, DetailLine +from quickbooks.objects.detailline import SalesItemLine, SubtotalLine, DiscountLine, DescriptionOnlyLine, DetailLine from .base import Address, EmailAddress, Ref, CustomField, CustomerMemo, QuickbooksManagedObject, \ LinkedTxnMixin, QuickbooksTransactionEntity from .tax import TxnTaxDetail @@ -38,7 +38,7 @@ class CreditMemo(DeleteMixin, QuickbooksTransactionEntity, QuickbooksManagedObje "SalesItemLineDetail": SalesItemLine, "SubTotalLineDetail": SubtotalLine, "DiscountLineDetail": DiscountLine, - "DescriptionLineDetail": DescriptionLine + "DescriptionLineDetail": DescriptionOnlyLine } qbo_object_name = "CreditMemo" diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index 4b484bc4..2959fcaa 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -100,17 +100,6 @@ def __init__(self): self.TaxCodeRef = None -class DescriptionLine(DetailLine): - class_dict = { - "DescriptionLineDetail": DescriptionLineDetail - } - - def __init__(self): - super(DescriptionLine, self).__init__() - self.DetailType = "DescriptionOnly" - self.DescriptionLineDetail = None - - @python_2_unicode_compatible class SalesItemLineDetail(QuickbooksBaseObject): class_dict = { diff --git a/quickbooks/objects/estimate.py b/quickbooks/objects/estimate.py index 92096870..32bafa9e 100644 --- a/quickbooks/objects/estimate.py +++ b/quickbooks/objects/estimate.py @@ -2,7 +2,7 @@ from .base import CustomField, Ref, CustomerMemo, Address, EmailAddress, QuickbooksManagedObject, \ LinkedTxnMixin, QuickbooksTransactionEntity, LinkedTxn from .tax import TxnTaxDetail -from .detailline import DetailLine, SalesItemLine, GroupLine, DescriptionLine, DiscountLine, SubtotalLine +from .detailline import DetailLine, SalesItemLine, GroupLine, DescriptionOnlyLine, DiscountLine, SubtotalLine from ..mixins import QuickbooksPdfDownloadable, DeleteMixin, SendMixin @@ -41,7 +41,7 @@ class Estimate(DeleteMixin, detail_dict = { "SalesItemLineDetail": SalesItemLine, "GroupLineDetail": GroupLine, - "DescriptionOnly": DescriptionLine, + "DescriptionOnly": DescriptionOnlyLine, "DiscountLineDetail": DiscountLine, "SubTotalLineDetail": SubtotalLine, } diff --git a/tests/unit/objects/test_detailline.py b/tests/unit/objects/test_detailline.py index 0ef0ed49..c8c06b0a 100644 --- a/tests/unit/objects/test_detailline.py +++ b/tests/unit/objects/test_detailline.py @@ -1,7 +1,7 @@ import unittest from quickbooks.objects.detailline import SalesItemLineDetail, DiscountOverride, DetailLine, SubtotalLineDetail, \ - DiscountLineDetail, SubtotalLine, DescriptionLineDetail, DescriptionLine, SalesItemLine, DiscountLine, GroupLine, \ + DiscountLineDetail, SubtotalLine, DescriptionLineDetail, SalesItemLine, DiscountLine, GroupLine, \ AccountBasedExpenseLineDetail, ItemBasedExpenseLineDetail, DescriptionOnlyLine, ItemBasedExpenseLine @@ -64,14 +64,6 @@ def test_init(self): self.assertEquals(description_detail.TaxCodeRef, None) -class DescriptionLineTest(unittest.TestCase): - def test_init(self): - line = DescriptionLine() - - self.assertEquals(line.DetailType, "DescriptionOnly") - self.assertEquals(line.DescriptionLineDetail, None) - - class SalesItemLineTest(unittest.TestCase): def test_init(self): line = SalesItemLine() From 22abda3ac8e077cddde677074f2eff0bf3c3f741 Mon Sep 17 00:00:00 2001 From: Volodymyr Spodaryk Date: Thu, 14 Jan 2021 15:13:42 +0200 Subject: [PATCH 004/154] Restored line that was removed by accident --- quickbooks/client.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickbooks/client.py b/quickbooks/client.py index 70db4974..e71c3ddd 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -253,6 +253,8 @@ def get_single_object(self, qbbo, pk): url = "{0}/company/{1}/{2}/{3}/".format(self.api_url, self.company_id, qbbo.lower(), pk) result = self.get(url, {}) + return result + @staticmethod def handle_exceptions(results): """ From ea709c63f73f24d399b33eacb06116545d38c4f3 Mon Sep 17 00:00:00 2001 From: Volodymyr Spodaryk Date: Mon, 1 Feb 2021 15:19:23 +0200 Subject: [PATCH 005/154] Added fields: `BillRate` to Vendor and `IsProject` to Customer --- quickbooks/objects/customer.py | 1 + quickbooks/objects/vendor.py | 1 + 2 files changed, 2 insertions(+) diff --git a/quickbooks/objects/customer.py b/quickbooks/objects/customer.py index 0f43bfd9..f2e30d16 100644 --- a/quickbooks/objects/customer.py +++ b/quickbooks/objects/customer.py @@ -48,6 +48,7 @@ def __init__(self): self.PrintOnCheckName = "" self.Notes = "" self.Active = True + self.IsProject = False self.Job = False self.BillWithParent = False self.Taxable = True diff --git a/quickbooks/objects/vendor.py b/quickbooks/objects/vendor.py index 03812e53..a0e2f9e1 100644 --- a/quickbooks/objects/vendor.py +++ b/quickbooks/objects/vendor.py @@ -49,6 +49,7 @@ def __init__(self): self.Active = True self.TaxIdentifier = "" self.Balance = 0 + self.BillRate = 0 self.AcctNum = "" self.Vendor1099 = True self.TaxReportingBasis = "" From 595367b629db2dbcbaeaebada729f00f53a6c472 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Feb 2021 03:07:17 +0000 Subject: [PATCH 006/154] Bump aiohttp from 3.6.2 to 3.7.4 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.6.2 to 3.7.4. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.6.2...v3.7.4) Signed-off-by: dependabot[bot] --- Pipfile.lock | 369 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 247 insertions(+), 122 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 2b562e36..d9727aaf 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -18,37 +18,60 @@ "default": { "aiohttp": { "hashes": [ - "sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", - "sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", - "sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", - "sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", - "sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", - "sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", - "sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", - "sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", - "sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", - "sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", - "sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", - "sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965" - ], - "markers": "python_full_version >= '3.5.3'", - "version": "==3.6.2" + "sha256:119feb2bd551e58d83d1b38bfa4cb921af8ddedec9fad7183132db334c3133e0", + "sha256:16d0683ef8a6d803207f02b899c928223eb219111bd52420ef3d7a8aa76227b6", + "sha256:2eb3efe243e0f4ecbb654b08444ae6ffab37ac0ef8f69d3a2ffb958905379daf", + "sha256:2ffea7904e70350da429568113ae422c88d2234ae776519549513c8f217f58a9", + "sha256:40bd1b101b71a18a528ffce812cc14ff77d4a2a1272dfb8b11b200967489ef3e", + "sha256:418597633b5cd9639e514b1d748f358832c08cd5d9ef0870026535bd5eaefdd0", + "sha256:481d4b96969fbfdcc3ff35eea5305d8565a8300410d3d269ccac69e7256b1329", + "sha256:4c1bdbfdd231a20eee3e56bd0ac1cd88c4ff41b64ab679ed65b75c9c74b6c5c2", + "sha256:5563ad7fde451b1986d42b9bb9140e2599ecf4f8e42241f6da0d3d624b776f40", + "sha256:58c62152c4c8731a3152e7e650b29ace18304d086cb5552d317a54ff2749d32a", + "sha256:5b50e0b9460100fe05d7472264d1975f21ac007b35dcd6fd50279b72925a27f4", + "sha256:5d84ecc73141d0a0d61ece0742bb7ff5751b0657dab8405f899d3ceb104cc7de", + "sha256:5dde6d24bacac480be03f4f864e9a67faac5032e28841b00533cd168ab39cad9", + "sha256:5e91e927003d1ed9283dee9abcb989334fc8e72cf89ebe94dc3e07e3ff0b11e9", + "sha256:62bc216eafac3204877241569209d9ba6226185aa6d561c19159f2e1cbb6abfb", + "sha256:6c8200abc9dc5f27203986100579fc19ccad7a832c07d2bc151ce4ff17190076", + "sha256:6ca56bdfaf825f4439e9e3673775e1032d8b6ea63b8953d3812c71bd6a8b81de", + "sha256:71680321a8a7176a58dfbc230789790639db78dad61a6e120b39f314f43f1907", + "sha256:7c7820099e8b3171e54e7eedc33e9450afe7cd08172632d32128bd527f8cb77d", + "sha256:7dbd087ff2f4046b9b37ba28ed73f15fd0bc9f4fdc8ef6781913da7f808d9536", + "sha256:822bd4fd21abaa7b28d65fc9871ecabaddc42767884a626317ef5b75c20e8a2d", + "sha256:8ec1a38074f68d66ccb467ed9a673a726bb397142c273f90d4ba954666e87d54", + "sha256:950b7ef08b2afdab2488ee2edaff92a03ca500a48f1e1aaa5900e73d6cf992bc", + "sha256:99c5a5bf7135607959441b7d720d96c8e5c46a1f96e9d6d4c9498be8d5f24212", + "sha256:b84ad94868e1e6a5e30d30ec419956042815dfaea1b1df1cef623e4564c374d9", + "sha256:bc3d14bf71a3fb94e5acf5bbf67331ab335467129af6416a437bd6024e4f743d", + "sha256:c2a80fd9a8d7e41b4e38ea9fe149deed0d6aaede255c497e66b8213274d6d61b", + "sha256:c44d3c82a933c6cbc21039326767e778eface44fca55c65719921c4b9661a3f7", + "sha256:cc31e906be1cc121ee201adbdf844522ea3349600dd0a40366611ca18cd40e81", + "sha256:d5d102e945ecca93bcd9801a7bb2fa703e37ad188a2f81b1e65e4abe4b51b00c", + "sha256:dd7936f2a6daa861143e376b3a1fb56e9b802f4980923594edd9ca5670974895", + "sha256:dee68ec462ff10c1d836c0ea2642116aba6151c6880b688e56b4c0246770f297", + "sha256:e76e78863a4eaec3aee5722d85d04dcbd9844bc6cd3bfa6aa880ff46ad16bfcb", + "sha256:eab51036cac2da8a50d7ff0ea30be47750547c9aa1aa2cf1a1b710a1827e7dbe", + "sha256:f4496d8d04da2e98cc9133e238ccebf6a13ef39a93da2e87146c8c8ac9768242", + "sha256:fbd3b5e18d34683decc00d9a360179ac1e7a320a5fee10ab8053ffd6deab76e0", + "sha256:feb24ff1226beeb056e247cf2e24bba5232519efb5645121c4aea5b6ad74c1f2" + ], + "index": "pypi", + "version": "==3.7.4" }, "async-timeout": { "hashes": [ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], - "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { "hashes": [ - "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a", - "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff" + "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", + "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.1.0" + "version": "==20.3.0" }, "authclient": { "hashes": [ @@ -60,18 +83,59 @@ }, "bleach": { "hashes": [ - "sha256:2bce3d8fab545a6528c8fa5d9f9ae8ebc85a56da365c7f85180bfe96a35ef22f", - "sha256:3c4c520fdb9db59ef139915a5db79f8b51bc2a7257ea0389f30c846883430a4b" + "sha256:6123ddc1052673e52bab52cdc955bcb57a015264a1c57d37bea2f6b817af0125", + "sha256:98b3170739e5e83dd9dc19633f074727ad848cbedb6026708c8ac2d3b697a433" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.1.5" + "version": "==3.3.0" }, "certifi": { "hashes": [ - "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", - "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" - ], - "version": "==2020.6.20" + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" + ], + "version": "==2020.12.5" + }, + "cffi": { + "hashes": [ + "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813", + "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06", + "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea", + "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee", + "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396", + "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73", + "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315", + "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1", + "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49", + "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892", + "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482", + "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058", + "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5", + "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53", + "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045", + "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3", + "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5", + "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e", + "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c", + "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369", + "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827", + "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053", + "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa", + "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4", + "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322", + "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132", + "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62", + "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa", + "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0", + "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396", + "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e", + "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991", + "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6", + "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1", + "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406", + "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d", + "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c" + ], + "version": "==1.14.5" }, "chardet": { "hashes": [ @@ -82,11 +146,10 @@ }, "colorama": { "hashes": [ - "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", - "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1" + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.4.3" + "version": "==0.4.4" }, "coverage": { "hashes": [ @@ -128,12 +191,28 @@ "index": "pypi", "version": "==5.2.1" }, + "cryptography": { + "hashes": [ + "sha256:066bc53f052dfeda2f2d7c195cf16fb3e5ff13e1b6b7415b468514b40b381a5b", + "sha256:0923ba600d00718d63a3976f23cab19aef10c1765038945628cd9be047ad0336", + "sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87", + "sha256:4169a27b818de4a1860720108b55a2801f32b6ae79e7f99c00d79f2a2822eeb7", + "sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799", + "sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b", + "sha256:600cf9bfe75e96d965509a4c0b2b183f74a4fa6f5331dcb40fb7b77b7c2484df", + "sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0", + "sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3", + "sha256:9e98b452132963678e3ac6c73f7010fe53adf72209a32854d55690acac3f6724", + "sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2", + "sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964" + ], + "version": "==3.4.6" + }, "docutils": { "hashes": [ "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af", "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.16" }, "ecdsa": { @@ -141,7 +220,6 @@ "sha256:64c613005f13efec6541bb0a33290d0d03c27abab5f15fbab20fb0ee162bdd8e", "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.14.1" }, "enum-compat": { @@ -155,7 +233,6 @@ "hashes": [ "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.18.2" }, "idna": { @@ -163,7 +240,6 @@ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, "intuit-oauth": { @@ -174,36 +250,62 @@ "index": "pypi", "version": "==1.2.3" }, + "jeepney": { + "hashes": [ + "sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657", + "sha256:aec56c0eb1691a841795111e184e13cad504f7703b9a64f63020816afa79a8ae" + ], + "markers": "sys_platform == 'linux'", + "version": "==0.6.0" + }, "keyring": { "hashes": [ - "sha256:182f94fc0381546489e3e4d90384a8c1d43cc09ffe2eb4a826e7312df6e1be7c", - "sha256:cd4d486803d55bdb13e2d453eb61dbbc984773e4f2b98a455aa85b1f4bc421e4" + "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df", + "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0" ], - "markers": "python_version >= '3.6'", - "version": "==21.3.1" + "version": "==22.0.1" }, "multidict": { "hashes": [ - "sha256:1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", - "sha256:275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", - "sha256:3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", - "sha256:4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", - "sha256:5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", - "sha256:51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", - "sha256:5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", - "sha256:6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", - "sha256:7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", - "sha256:9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", - "sha256:c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", - "sha256:d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", - "sha256:e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", - "sha256:f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", - "sha256:fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", - "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", - "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" - ], - "markers": "python_version >= '3.5'", - "version": "==4.7.6" + "sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a", + "sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93", + "sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632", + "sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656", + "sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79", + "sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7", + "sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d", + "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5", + "sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224", + "sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26", + "sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea", + "sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348", + "sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6", + "sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76", + "sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1", + "sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f", + "sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952", + "sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a", + "sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37", + "sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9", + "sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359", + "sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8", + "sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da", + "sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3", + "sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d", + "sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf", + "sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841", + "sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d", + "sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93", + "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f", + "sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647", + "sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635", + "sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456", + "sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda", + "sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5", + "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281", + "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80" + ], + "version": "==5.1.0" }, "nose": { "hashes": [ @@ -219,56 +321,48 @@ "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889", "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.1.0" }, "packaging": { "hashes": [ - "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", - "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" + "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", + "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.4" + "version": "==20.9" }, "pkginfo": { "hashes": [ - "sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb", - "sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32" + "sha256:029a70cb45c6171c329dfc890cde0879f8c52d6f3922794796e06f577bb03db4", + "sha256:9fdbea6495622e022cc72c2e5e1b735218e4ffb2a2a69cde2694a6c1f16afb75" ], - "version": "==1.5.0.1" + "version": "==1.7.0" }, "pyasn1": { "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba" ], "version": "==0.4.8" }, + "pycparser": { + "hashes": [ + "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", + "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" + ], + "version": "==2.20" + }, "pygments": { "hashes": [ - "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44", - "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324" + "sha256:37a13ba168a02ac54cc5891a42b1caec333e59b66addb7fa633ea8a6d73445c0", + "sha256:b21b072d0ccdf29297a82a2363359d99623597b8a265b8081760e4d0f7153c88" ], - "markers": "python_version >= '3.5'", - "version": "==2.6.1" + "version": "==2.8.0" }, "pyparsing": { "hashes": [ "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, "python-jose": { @@ -288,10 +382,10 @@ }, "readme-renderer": { "hashes": [ - "sha256:cbe9db71defedd2428a1589cdc545f9bd98e59297449f69d721ef8f1cfced68d", - "sha256:cc4957a803106e820d05d14f71033092537a22daa4f406dfbdd61177e0936376" + "sha256:63b4075c6698fcfa78e584930f07f39e05d46f3ec97f65006e430b595ca6348c", + "sha256:92fd5ac2bf8677f310f3303aa4bce5b9d5f9f2094ab98c29f13791d7b805a3db" ], - "version": "==26.0" + "version": "==29.0" }, "requests": { "hashes": [ @@ -304,8 +398,7 @@ "requests-oauthlib": { "hashes": [ "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d", - "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a", - "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc" + "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a" ], "version": "==1.3.0" }, @@ -325,11 +418,18 @@ }, "rsa": { "hashes": [ - "sha256:109ea5a66744dd859bf16fe904b8d8b627adafb9408753161e766a92e7d681fa", - "sha256:6166864e23d6b5195a5cfed6cd9fed0fe774e226d8f854fcb23b7bbef0350233" + "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2", + "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9" ], - "markers": "python_version >= '3.5' and python_version < '4'", - "version": "==4.6" + "version": "==4.7.2" + }, + "secretstorage": { + "hashes": [ + "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f", + "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195" + ], + "markers": "sys_platform == 'linux'", + "version": "==3.3.1" }, "simplejson": { "hashes": [ @@ -392,11 +492,10 @@ }, "tqdm": { "hashes": [ - "sha256:1a336d2b829be50e46b84668691e0a2719f26c97c62846298dd5ae2937e4d5cf", - "sha256:564d632ea2b9cb52979f7956e093e831c28d441c11751682f84c86fc46e4fd21" + "sha256:2c44efa73b8914dba7807aefd09653ac63c22b5b4ea34f7a80973f418f1a3089", + "sha256:c23ac707e8e8aabb825e4d91f8e17247f9cc14b0d64dd9e97be0781e9e525bba" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.48.2" + "version": "==4.58.0" }, "twine": { "hashes": [ @@ -406,13 +505,20 @@ "index": "pypi", "version": "==3.2.0" }, + "typing-extensions": { + "hashes": [ + "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", + "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", + "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" + ], + "version": "==3.7.4.3" + }, "urllib3": { "hashes": [ - "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a", - "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461" + "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2", + "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.25.10" + "version": "==1.25.11" }, "webencodings": { "hashes": [ @@ -423,26 +529,45 @@ }, "yarl": { "hashes": [ - "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", - "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593", - "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2", - "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8", - "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d", - "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692", - "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02", - "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a", - "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8", - "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6", - "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511", - "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e", - "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a", - "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb", - "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f", - "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", - "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" - ], - "markers": "python_version >= '3.5'", - "version": "==1.5.1" + "sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e", + "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434", + "sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366", + "sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3", + "sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec", + "sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959", + "sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e", + "sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c", + "sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6", + "sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a", + "sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6", + "sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424", + "sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e", + "sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f", + "sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50", + "sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2", + "sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc", + "sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4", + "sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970", + "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10", + "sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0", + "sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406", + "sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896", + "sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643", + "sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721", + "sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478", + "sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724", + "sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e", + "sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8", + "sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96", + "sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25", + "sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76", + "sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2", + "sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2", + "sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c", + "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a", + "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71" + ], + "version": "==1.6.3" } }, "develop": {} From e1fff9bd1e1899312c75978a790dd0882739a40f Mon Sep 17 00:00:00 2001 From: Varun Bheemaiah Date: Wed, 14 Apr 2021 13:34:42 +0530 Subject: [PATCH 007/154] Added Refresh Token to Client Instance --- quickbooks/client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index c882169c..b59e07fe 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -77,7 +77,8 @@ def __new__(cls, **kwargs): else: instance.sandbox = False - instance._start_session() + refresh_token = instance._start_session() + instance.refresh_token = refresh_token if 'company_id' in kwargs: instance.company_id = kwargs['company_id'] @@ -99,6 +100,7 @@ def _start_session(self): client_secret=self.auth_client.client_secret, access_token=self.auth_client.access_token, ) + return self.auth_client.refresh_token @classmethod def get_instance(cls): From ad5429d82396b624bd9fa032d937352c274bd7b9 Mon Sep 17 00:00:00 2001 From: ej2 Date: Wed, 14 Jul 2021 11:50:28 -0500 Subject: [PATCH 008/154] Updates to requirements and bump version number. --- CHANGELOG.rst | 9 +++++++++ Pipfile | 1 + requirements.txt | 6 +++--- setup.py | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 43ee924e..98261b06 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,15 @@ Changelog ========= +* 0.9.0 (February 2, 2021) + * Added missing TxnDate to Invoice + * Updated requirements + * Added BillRate to Vendor + * Added IsProject to Customer + * Added Refresh Token to Client Instance + * Updated Estimate and CreditMemo to use DescriptionOnlyLine + * Removed unused DescriptionLine object + * 0.8.4 (October 11, 2020) * Added support for the CreditCardPayment entity * Updated readme diff --git a/Pipfile b/Pipfile index eb9fdc15..5178d8db 100644 --- a/Pipfile +++ b/Pipfile @@ -6,6 +6,7 @@ verify_ssl = true [dev-packages] [packages] +bleach = ">=3.3.0" intuit-oauth = "==1.2.3" rauth = ">=0.7.1" requests = ">=2.19.1" diff --git a/requirements.txt b/requirements.txt index e6368351..20edffb8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -intuit-oauth==1.2.3 +intuit-oauth==1.2.4 rauth>=0.7.1 -requests>=2.19.1 +requests>=2.26.0 simplejson>=3.17.0 -six>=1.14.0 +six>=1.14.0 \ No newline at end of file diff --git a/setup.py b/setup.py index 92d0d9ae..7655928b 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 8, 4) +VERSION = (0, 9, 0) version = '.'.join(map(str, VERSION)) setup( From df9936ccc5c844d2136f5a6b905a553bcc77f82d Mon Sep 17 00:00:00 2001 From: ej2 Date: Wed, 14 Jul 2021 17:41:32 -0500 Subject: [PATCH 009/154] Fixed preferences objects. --- README.md | 355 +++++++++++++++--------------- quickbooks/objects/preferences.py | 50 +++-- requirements.txt | 4 +- 3 files changed, 213 insertions(+), 196 deletions(-) diff --git a/README.md b/README.md index 0fb41ca7..e5a74853 100644 --- a/README.md +++ b/README.md @@ -26,115 +26,108 @@ Accessing the API Set up an AuthClient passing in your `CLIENT_ID` and `CLIENT_SECRET`. -```python -from intuitlib.client import AuthClient + from intuitlib.client import AuthClient -auth_client = AuthClient( - client_id='CLIENT_ID', - client_secret='CLIENT_SECRET', - environment='sandbox', - redirect_uri='http://localhost:8000/callback', -) -``` + auth_client = AuthClient( + client_id='CLIENT_ID', + client_secret='CLIENT_SECRET', + environment='sandbox', + redirect_uri='http://localhost:8000/callback', + ) Then create a QuickBooks client object passing in the AuthClient, refresh token, and company id: -```python -from quickbooks import QuickBooks -client = QuickBooks( - auth_client=auth_client, - refresh_token='REFRESH_TOKEN', - company_id='COMPANY_ID', -) -``` + from quickbooks import QuickBooks + + client = QuickBooks( + auth_client=auth_client, + refresh_token='REFRESH_TOKEN', + company_id='COMPANY_ID', + ) If you need to access a minor version (See [Minor versions](https://developer.intuit.com/docs/0100_quickbooks_online/0200_dev_guides/accounting/minor_versions) for details) pass in minorversion when setting up the client: -```python -client = QuickBooks( - auth_client=auth_client, - refresh_token='REFRESH_TOKEN', - company_id='COMPANY_ID', - minorversion=4 -) -``` + client = QuickBooks( + auth_client=auth_client, + refresh_token='REFRESH_TOKEN', + company_id='COMPANY_ID', + minorversion=4 + ) Object Operations ----------------- List of objects: -```python -from quickbooks.objects.customer import Customer -customers = Customer.all(qb=client) -``` + + from quickbooks.objects.customer import Customer + customers = Customer.all(qb=client) **Note:** The maximum number of entities that can be returned in a response is 1000. If the result size is not specified, the default number is 100. (See [Intuit developer guide](https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/querying_data) for details) Filtered list of objects: -```python -customers = Customer.filter(Active=True, FamilyName="Smith", qb=client) -``` + + customers = Customer.filter(Active=True, FamilyName="Smith", qb=client) Filtered list of objects with ordering: -```python -# Get customer invoices ordered by TxnDate -invoices = Invoice.filter(CustomerRef='100', order_by='TxnDate', qb=client) -# Same, but in reverse order -invoices = Invoice.filter(CustomerRef='100', order_by='TxnDate DESC', qb=client) + # Get customer invoices ordered by TxnDate + invoices = Invoice.filter(CustomerRef='100', order_by='TxnDate', qb=client) + + # Same, but in reverse order + invoices = Invoice.filter(CustomerRef='100', order_by='TxnDate DESC', qb=client) + + # Order customers by FamilyName then by GivenName + customers = Customer.all(order_by='FamilyName, GivenName', qb=client) -# Order customers by FamilyName then by GivenName -customers = Customer.all(order_by='FamilyName, GivenName', qb=client) -``` Filtered list of objects with paging: -```python -customers = Customer.filter(start_position=1, max_results=25, Active=True, FamilyName="Smith", qb=client) -``` + + customers = Customer.filter(start_position=1, max_results=25, Active=True, FamilyName="Smith", qb=client) + List Filtered by values in list: -```python -customer_names = ['Customer1', 'Customer2', 'Customer3'] -customers = Customer.choose(customer_names, field="DisplayName", qb=client) -``` + + customer_names = ['Customer1', 'Customer2', 'Customer3'] + customers = Customer.choose(customer_names, field="DisplayName", qb=client) + List with custom Where Clause (do not include the `"WHERE"`): -```python -customers = Customer.where("Active = True AND CompanyName LIKE 'S%'", qb=client) -``` + + customers = Customer.where("Active = True AND CompanyName LIKE 'S%'", qb=client) + List with custom Where and ordering -```python -customers = Customer.where("Active = True AND CompanyName LIKE 'S%'", order_by='DisplayName', qb=client) -``` + + customers = Customer.where("Active = True AND CompanyName LIKE 'S%'", order_by='DisplayName', qb=client) + List with custom Where Clause and paging: -```python -customers = Customer.where("CompanyName LIKE 'S%'", start_position=1, max_results=25, qb=client) -``` + + customers = Customer.where("CompanyName LIKE 'S%'", start_position=1, max_results=25, qb=client) + Filtering a list with a custom query (See [Intuit developer guide](https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/querying_data) for supported SQL statements): -```python -customers = Customer.query("SELECT * FROM Customer WHERE Active = True", qb=client) -``` + + customers = Customer.query("SELECT * FROM Customer WHERE Active = True", qb=client) + Filtering a list with a custom query with paging: -```python -customers = Customer.query("SELECT * FROM Customer WHERE Active = True STARTPOSITION 1 MAXRESULTS 25", qb=client) -``` + + customers = Customer.query("SELECT * FROM Customer WHERE Active = True STARTPOSITION 1 MAXRESULTS 25", qb=client) + Get record count (do not include the ``"WHERE"``): -```python -customer_count = Customer.count("Active = True AND CompanyName LIKE 'S%'", qb=client) -``` + + customer_count = Customer.count("Active = True AND CompanyName LIKE 'S%'", qb=client) + Get single object by Id and update: -```python -customer = Customer.get(1, qb=client) -customer.CompanyName = "New Test Company Name" -customer.save(qb=client) -``` + + customer = Customer.get(1, qb=client) + customer.CompanyName = "New Test Company Name" + customer.save(qb=client) + Create new object: -```python -customer = Customer() -customer.CompanyName = "Test Company" -customer.save(qb=client) -``` + + customer = Customer() + customer.CompanyName = "Test Company" + customer.save(qb=client) + Batch Operations ---------------- @@ -143,162 +136,168 @@ operations in a single request (See [Intuit Batch Operations Guide](https://deve full details). Batch create a list of objects: -```python -from quickbooks.batch import batch_create -customer1 = Customer() -customer1.CompanyName = "Test Company 1" + from quickbooks.batch import batch_create + + customer1 = Customer() + customer1.CompanyName = "Test Company 1" -customer2 = Customer() -customer2.CompanyName = "Test Company 2" + customer2 = Customer() + customer2.CompanyName = "Test Company 2" -customers = [customer1, customer2] + customers = [customer1, customer2] + + results = batch_create(customers, qb=client) -results = batch_create(customers, qb=client) -``` Batch update a list of objects: -```python -from quickbooks.batch import batch_update -customers = Customer.filter(Active=True) -# Update customer records -results = batch_update(customers, qb=client) -``` + from quickbooks.batch import batch_update + customers = Customer.filter(Active=True) + + # Update customer records + + results = batch_update(customers, qb=client) + Batch delete a list of objects: -```python -from quickbooks.batch import batch_delete -customers = Customer.filter(Active=False) -results = batch_delete(customers, qb=client) -``` + from quickbooks.batch import batch_delete + + customers = Customer.filter(Active=False) + results = batch_delete(customers, qb=client) + Review results for batch operation: -```python -# successes is a list of objects that were successfully updated -for obj in results.successes: - print("Updated " + obj.DisplayName) - -# faults contains list of failed operations and associated errors -for fault in results.faults: - print("Operation failed on " + fault.original_object.DisplayName) - - for error in fault.Error: - print("Error " + error.Message) -``` + + # successes is a list of objects that were successfully updated + for obj in results.successes: + print("Updated " + obj.DisplayName) + + # faults contains list of failed operations and associated errors + for fault in results.faults: + print("Operation failed on " + fault.original_object.DisplayName) + + for error in fault.Error: + print("Error " + error.Message) + Change Data Capture ----------------------- Change Data Capture returns a list of objects that have changed since a given time (see [Change data capture](https://developer.intuit.com/docs/api/accounting/changedatacapture) for more details): -```python -from quickbooks.cdc import change_data_capture -from quickbooks.objects import Invoice - -cdc_response = change_data_capture([Invoice], "2017-01-01T00:00:00", qb=client) -for invoice in cdc_response.Invoice: - pass # Do something with the invoice -``` + + from quickbooks.cdc import change_data_capture + from quickbooks.objects import Invoice + + cdc_response = change_data_capture([Invoice], "2017-01-01T00:00:00", qb=client) + for invoice in cdc_response.Invoice: + # Do something with the invoice + Querying muliple entity types at the same time: -```python -from quickbooks.objects import Invoice, Customer -cdc_response = change_data_capture([Invoice, Customer], "2017-01-01T00:00:00", qb=client) -``` + + from quickbooks.objects import Invoice, Customer + cdc_response = change_data_capture([Invoice, Customer], "2017-01-01T00:00:00", qb=client) + If you use a `datetime` object for the timestamp, it is automatically converted to a string: -```python -from datetime import datetime -cdc_response = change_data_capture([Invoice, Customer], datetime(2017, 1, 1, 0, 0, 0), qb=client) -``` + from datetime import datetime + + cdc_response = change_data_capture([Invoice, Customer], datetime(2017, 1, 1, 0, 0, 0), qb=client) + Attachments ---------------- See [Attachable documentation](https://developer.intuit.com/docs/api/accounting/Attachable) for list of valid file types, file size limits and other restrictions. Attaching a note to a customer: -```python -attachment = Attachable() -attachable_ref = AttachableRef() -attachable_ref.EntityRef = customer.to_ref() + attachment = Attachable() + + attachable_ref = AttachableRef() + attachable_ref.EntityRef = customer.to_ref() + + attachment.AttachableRef.append(attachable_ref) -attachment.AttachableRef.append(attachable_ref) + attachment.Note = 'This is a note' + attachment.save(qb=client) -attachment.Note = 'This is a note' -attachment.save(qb=client) -``` Attaching a file to customer: -```python -attachment = Attachable() -attachable_ref = AttachableRef() -attachable_ref.EntityRef = customer.to_ref() + attachment = Attachable() -attachment.AttachableRef.append(attachable_ref) + attachable_ref = AttachableRef() + attachable_ref.EntityRef = customer.to_ref() + + attachment.AttachableRef.append(attachable_ref) + + attachment.FileName = 'Filename' + attachment._FilePath = '/folder/filename' # full path to file + attachment.ContentType = 'application/pdf' + attachment.save(qb=client) -attachment.FileName = 'Filename' -attachment._FilePath = '/folder/filename' # full path to file -attachment.ContentType = 'application/pdf' -attachment.save(qb=client) -``` Other operations ---------------- Void an invoice: -```python -invoice = Invoice() -invoice.Id = 7 -invoice.void(qb=client) -``` + + invoice = Invoice() + invoice.Id = 7 + invoice.void(qb=client) + If your consumer_key never changes you can enable the client to stay running: -```python -QuickBooks.enable_global() -``` + + QuickBooks.enable_global() + You can disable the global client like so: -```python -QuickBooks.disable_global() -``` + + QuickBooks.disable_global() + Working with JSON data ---------------- All objects include `to_json` and `from_json` methods. Converting an object to JSON data: -```python -account = Account.get(1, qb=client) -json_data = account.to_json() -``` + + account = Account.get(1, qb=client) + json_data = account.to_json() + Loading JSON data into a quickbooks object: -```python -account = Account() -account.from_json({ - "AccountType": "Accounts Receivable", - "Name": "MyJobs" -}) -account.save(qb=client) -``` + + account = Account() + account.from_json( + { + "AccountType": "Accounts Receivable", + "Name": "MyJobs" + } + ) + account.save(qb=client) + Date formatting ---------------- When setting date or datetime fields, Quickbooks requires a specific format. Formating helpers are available in helpers.py. Example usage: -```python -date_string = qb_date_format(date(2016, 7, 22)) -date_time_string = qb_datetime_format(datetime(2016, 7, 22, 10, 35, 00)) -date_time_with_utc_string = qb_datetime_utc_offset_format(datetime(2016, 7, 22, 10, 35, 00), '-06:00') -``` + + date_string = qb_date_format(date(2016, 7, 22)) + date_time_string = qb_datetime_format(datetime(2016, 7, 22, 10, 35, 00)) + date_time_with_utc_string = qb_datetime_utc_offset_format(datetime(2016, 7, 22, 10, 35, 00), '-06:00') + Exception Handling ---------------- The QuickbooksException object contains additional [QBO error code](https://developer.intuit.com/app/developer/qbo/docs/develop/troubleshooting/error-codes#id1) information. -```python -from quickbooks.exceptions import QuickbooksException -try: - pass # perform a Quickbooks operation -except QuickbooksException as e: - e.message # contains the error message returned from QBO - e.error_code # contains the - e.detail # contains additional information when available -``` + from quickbooks.exceptions import QuickbooksException + + try: + # perform a Quickbooks operation + except QuickbooksException as e: + e.message # contains the error message returned from QBO + e.error_code # contains the + e.detail # contains additional information when available + **Note:** Objects and object property names match their Quickbooks counterparts and do not follow PEP8. **Note:** This is a work-in-progress made public to help other developers access the QuickBooks API. Built for a Django project. + + + diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py index b401c011..e693c029 100644 --- a/quickbooks/objects/preferences.py +++ b/quickbooks/objects/preferences.py @@ -1,5 +1,26 @@ from six import python_2_unicode_compatible -from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, QuickbooksUpdateOnlyObject # CustomField, Ref +from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, QuickbooksUpdateOnlyObject, Ref + + +@python_2_unicode_compatible +class PreferencesCustomField(QuickbooksBaseObject): + def __init__(self): + self.Type = "" + self.Name = "" + self.StringValue = "" + self.BooleanValue = "" + + def __str__(self): + return self.Name + + +class PreferencesCustomFieldGroup(QuickbooksBaseObject): + list_dict = { + "CustomField": PreferencesCustomField + } + + def __init__(self): + super().__init__() class EmailMessageType(QuickbooksBaseObject): @@ -44,7 +65,6 @@ def __init__(self): class AccountingInfoPrefs(QuickbooksBaseObject): - def __init__(self): super().__init__() self.FirstMonthOfFiscalYear = "January" # read only @@ -62,7 +82,6 @@ def __init__(self): class ClassTrackingPerTxnLine(QuickbooksBaseObject): - def __init__(self): super().__init__() self.ReportBasis = "Accrual" # or "Cash" @@ -71,13 +90,10 @@ def __init__(self): class SalesFormsPrefs(QuickbooksBaseObject): class_dict = { - # 'DefaultTerms': Ref, # FIXME: serialize field properly, not as JSON - } - list_dict = { - # 'CustomField': CustomField, # FIXME: serialize field properly, not as JSON + "DefaultTerms": Ref, } detail_dict = { - # 'CustomField': CustomField, # FIXME: serialize field properly, not as JSON + "CustomField": PreferencesCustomFieldGroup } def __init__(self): @@ -101,14 +117,13 @@ def __init__(self): self.UsingPriceLevels = False self.ETransactionAttachPDF = False + self.DefaultTerms = None + self.CustomField = None + class VendorAndPurchasesPrefs(QuickbooksBaseObject): - class_dict = {} - list_dict = { - # 'POCustomField': CustomField, # FIXME: serialize field properly, not as JSON - } detail_dict = { - # 'POCustomField': CustomField, # FIXME: serialize field properly, not as JSON + "POCustomField": PreferencesCustomFieldGroup } def __init__(self): @@ -120,7 +135,7 @@ def __init__(self): class TaxPrefs(QuickbooksBaseObject): class_dict = { - # 'TaxGroupCodeRef': Ref, # FIXME: serialize field properly, not as JSON + "TaxGroupCodeRef": Ref } def __init__(self): @@ -130,13 +145,16 @@ def __init__(self): class OtherPrefs(QuickbooksBaseObject): + list_dict = { + "NameValue": Ref + } def __init__(self): super().__init__() + self.NameValue = None class TimeTrackingPrefs(QuickbooksBaseObject): - def __init__(self): super().__init__() self.WorkWeekStartDate = "" # e.g. "Monday" @@ -148,7 +166,7 @@ def __init__(self): class CurrencyPrefs(QuickbooksBaseObject): class_dict = { - # 'HomeCurrency': Ref, # FIXME: serialize field properly, not as JSON + "HomeCurrency": Ref } def __init__(self): diff --git a/requirements.txt b/requirements.txt index 20edffb8..9c49b1c3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ intuit-oauth==1.2.4 -rauth>=0.7.1 +rauth>=0.7.3 requests>=2.26.0 simplejson>=3.17.0 -six>=1.14.0 \ No newline at end of file +six>=1.14.0 From 83d11536405fb1265b7648c777a929f26cc48a3d Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 20 Jul 2021 13:41:41 -0500 Subject: [PATCH 010/154] Updated preference object and tests --- quickbooks/mixins.py | 45 ++--- quickbooks/objects/base.py | 6 +- quickbooks/objects/preferences.py | 15 +- tests/integration/test_base.py | 2 +- tests/integration/test_preferences.py | 38 ++-- tests/unit/objects/test_preferences.py | 263 ------------------------- 6 files changed, 55 insertions(+), 314 deletions(-) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 77f5c020..2b52f55b 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -144,28 +144,6 @@ def void(self, qb=None): return results -class UpdateNoCreateMixin(object): - qbo_object_name = "" - qbo_json_object_name = "" - - def save(self, qb=None): - if not qb: - qb = QuickBooks() - - if self.Id and int(self.Id) > 0: - json_data = qb.update_object(self.qbo_object_name, self.to_json()) - else: - raise QuickbooksException("Update is not allowed for {0} unsaved object".format(self.qbo_object_name)) - - if self.qbo_json_object_name != '': - obj = type(self).from_json(json_data[self.qbo_json_object_name]) - else: - obj = type(self).from_json(json_data[self.qbo_object_name]) - - self.Id = obj.Id - return obj - - class UpdateMixin(object): qbo_object_name = "" qbo_json_object_name = "" @@ -363,3 +341,26 @@ def append(self, value): def pop(self, *args, **kwargs): return self._object_list.pop(*args, **kwargs) + + +class PrefMixin(object): + qbo_object_name = "" + qbo_json_object_name = "" + + @classmethod + def get(cls, qb=None): + if not qb: + qb = QuickBooks() + + end_point = "{0}/company/{1}/preferences".format(qb.api_url, qb.company_id) + json_data = qb.get(end_point, {}) + return cls.from_json(json_data[cls.qbo_object_name]) + + def save(self, qb=None): + if not qb: + qb = QuickBooks() + + json_data = qb.update_object(self.qbo_object_name, self.to_json()) + obj = type(self).from_json(json_data[self.qbo_object_name]) + + return obj diff --git a/quickbooks/objects/base.py b/quickbooks/objects/base.py index 2236b058..11c6dd55 100644 --- a/quickbooks/objects/base.py +++ b/quickbooks/objects/base.py @@ -1,5 +1,5 @@ from six import python_2_unicode_compatible -from ..mixins import ToDictMixin, ToJsonMixin, FromJsonMixin, ListMixin, ReadMixin, UpdateMixin, UpdateNoCreateMixin +from ..mixins import ToDictMixin, ToJsonMixin, FromJsonMixin, ListMixin, ReadMixin, UpdateMixin class QuickbooksBaseObject(ToJsonMixin, FromJsonMixin, ToDictMixin): @@ -24,10 +24,6 @@ class QuickbooksReadOnlyObject(QuickbooksBaseObject, ReadMixin, ListMixin): pass -class QuickbooksUpdateOnlyObject(QuickbooksBaseObject, ReadMixin, ListMixin, UpdateNoCreateMixin): - pass - - @python_2_unicode_compatible class MetaData(FromJsonMixin): def __init__(self): diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py index e693c029..3f4cb309 100644 --- a/quickbooks/objects/preferences.py +++ b/quickbooks/objects/preferences.py @@ -1,5 +1,7 @@ from six import python_2_unicode_compatible -from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, QuickbooksUpdateOnlyObject, Ref + +from quickbooks.mixins import PrefMixin +from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, Ref @python_2_unicode_compatible @@ -144,9 +146,16 @@ def __init__(self): self.UsingSalesTax = True +class NameValue(QuickbooksBaseObject): + def __init__(self): + super().__init__() + self.Name = "" + self.Value = "" + + class OtherPrefs(QuickbooksBaseObject): list_dict = { - "NameValue": Ref + "NameValue": NameValue } def __init__(self): @@ -175,7 +184,7 @@ def __init__(self): @python_2_unicode_compatible -class Preferences(QuickbooksUpdateOnlyObject, QuickbooksTransactionEntity): +class Preferences(PrefMixin, QuickbooksTransactionEntity): """ QBO definition: The Preferences resource represents a set of company preferences that control application behavior in QuickBooks Online. diff --git a/tests/integration/test_base.py b/tests/integration/test_base.py index 4eda02fc..09c27027 100644 --- a/tests/integration/test_base.py +++ b/tests/integration/test_base.py @@ -17,7 +17,7 @@ def setUp(self): ) self.qb_client = QuickBooks( - minorversion=54, + minorversion=59, auth_client=self.auth_client, refresh_token=os.environ.get('REFRESH_TOKEN'), company_id=os.environ.get('COMPANY_ID'), diff --git a/tests/integration/test_preferences.py b/tests/integration/test_preferences.py index 7c69d339..5997cff1 100644 --- a/tests/integration/test_preferences.py +++ b/tests/integration/test_preferences.py @@ -1,34 +1,32 @@ from datetime import datetime -from quickbooks.objects.account import Account +from quickbooks.objects.preferences import Preferences from tests.integration.test_base import QuickbooksTestCase -class AccountTest(QuickbooksTestCase): +class PreferencesTest(QuickbooksTestCase): def setUp(self): - super(AccountTest, self).setUp() + super(PreferencesTest, self).setUp() self.account_number = datetime.now().strftime('%d%H%M') self.name = "Test Account {0}".format(self.account_number) - def test_create(self): - account = Account() - account.AcctNum = self.account_number - account.Name = self.name - account.AccountSubType = "CashOnHand" - account.save(qb=self.qb_client) + def test_get(self): + preferences = Preferences.get(qb=self.qb_client) - self.id = account.Id - query_account = Account.get(account.Id, qb=self.qb_client) - - self.assertEquals(account.Id, query_account.Id) - self.assertEquals(query_account.Name, self.name) - self.assertEquals(query_account.AcctNum, self.account_number) + print(preferences.to_json()) + self.assertEquals(preferences.Id, "1") + self.assertEquals(preferences.AccountingInfoPrefs.TaxYearMonth, "January") + self.assertEquals(preferences.ProductAndServicesPrefs.ForPurchase, True) + self.assertEquals(preferences.VendorAndPurchasesPrefs.BillableExpenseTracking, True) + self.assertEquals(preferences.TimeTrackingPrefs.WorkWeekStartDate, "Monday") + self.assertEquals(preferences.OtherPrefs.NameValue[0].Name, "SalesFormsPrefs.DefaultCustomerMessage") def test_update(self): - account = Account.filter(Name=self.name, qb=self.qb_client)[0] + preferences = Preferences.get(qb=self.qb_client) - account.Name = "Updated Name {0}".format(self.account_number) - account.save(qb=self.qb_client) + subject = datetime.now().strftime('%d%H%M%S') + preferences.EmailMessagesPrefs.EstimateMessage.Subject = subject + preferences.save(qb=self.qb_client) - query_account = Account.get(account.Id, qb=self.qb_client) - self.assertEquals(query_account.Name, "Updated Name {0}".format(self.account_number)) + preferences_updated = Preferences.get(qb=self.qb_client) + self.assertEquals(preferences_updated.EmailMessagesPrefs.EstimateMessage.Subject, subject) diff --git a/tests/unit/objects/test_preferences.py b/tests/unit/objects/test_preferences.py index bfaed000..3c567681 100644 --- a/tests/unit/objects/test_preferences.py +++ b/tests/unit/objects/test_preferences.py @@ -4,262 +4,6 @@ from quickbooks.objects.preferences import Preferences -# Taken from here: -# https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/preferences#full-update-preferences -PAYLOAD = { - "Preferences": { - "EmailMessagesPrefs": { - "InvoiceMessage": { - "Message": "Your invoice is attached. Please remit payment at your earliest convenience.\n" - "Thank you for your business - we appreciate it very much.\n\nSincerely,\n" - "Craig's Design and Landscaping Services", - "Subject": "Invoice from Craig's Design and Landscaping Services" - }, - "EstimateMessage": { - "Message": "Please review the estimate below. Feel free to contact us if you have any questions.\n" - "We look forward to working with you.\n\nSincerely,\nCraig's Design and Landscaping Services", - "Subject": "Estimate from Craig's Design and Landscaping Services" - }, - "SalesReceiptMessage": { - "Message": "Your sales receipt is attached.\nThank you for your business - we appreciate it very much.\n\n" - "Sincerely,\nCraig's Design and Landscaping Services", - "Subject": "Sales Receipt from Craig's Design and Landscaping Services" - }, - "StatementMessage": { - "Message": "Your statement is attached. Please remit payment at your earliest convenience.\n" - "Thank you for your business - we appreciate it very much.\n\nSincerely,\n" - "Craig's Design and Landscaping Services", - "Subject": "Statement from Craig's Design and Landscaping Services" - } - }, - "ProductAndServicesPrefs": { - "QuantityWithPriceAndRate": True, - "ForPurchase": True, - "QuantityOnHand": True, - "ForSales": True - }, - "domain": "QBO", - "SyncToken": "6", - "ReportPrefs": { - "ReportBasis": "Accrual", - "CalcAgingReportFromTxnDate": False - }, - "AccountingInfoPrefs": { - "FirstMonthOfFiscalYear": "January", - "UseAccountNumbers": True, - "TaxYearMonth": "January", - "ClassTrackingPerTxn": False, - "TrackDepartments": True, - "TaxForm": "6", - "CustomerTerminology": "Customers", - "BookCloseDate": "2018-12-31", - "DepartmentTerminology": "Location", - "ClassTrackingPerTxnLine": True - }, - "SalesFormsPrefs": { - "ETransactionPaymentEnabled": False, - "CustomTxnNumbers": False, - "AllowShipping": False, - "AllowServiceDate": False, - "ETransactionEnabledStatus": "NotApplicable", - "DefaultCustomerMessage": "Thank you for your business and have a great day!", - "EmailCopyToCompany": False, - "AllowEstimates": True, - "DefaultTerms": { - "value": "3" - }, - "AllowDiscount": True, - "DefaultDiscountAccount": "86", - "AllowDeposit": True, - "AutoApplyPayments": True, - "IPNSupportEnabled": False, - "AutoApplyCredit": True, - "CustomField": [ - { - "CustomField": [ - { - "BooleanValue": False, - "Type": "BooleanType", - "Name": "SalesFormsPrefs.UseSalesCustom3" - }, - { - "BooleanValue": False, - "Type": "BooleanType", - "Name": "SalesFormsPrefs.UseSalesCustom2" - }, - { - "BooleanValue": True, - "Type": "BooleanType", - "Name": "SalesFormsPrefs.UseSalesCustom1" - } - ] - }, - { - "CustomField": [ - { - "StringValue": "Crew #", - "Type": "StringType", - "Name": "SalesFormsPrefs.SalesCustomName1" - } - ] - } - ], - "UsingPriceLevels": False, - "ETransactionAttachPDF": False - }, - "VendorAndPurchasesPrefs": { - "BillableExpenseTracking": True, - "TrackingByCustomer": True, - "POCustomField": [ - { - "CustomField": [ - { - "BooleanValue": False, - "Type": "BooleanType", - "Name": "PurchasePrefs.UsePurchaseCustom3" - }, - { - "BooleanValue": True, - "Type": "BooleanType", - "Name": "PurchasePrefs.UsePurchaseCustom2" - }, - { - "BooleanValue": True, - "Type": "BooleanType", - "Name": "PurchasePrefs.UsePurchaseCustom1" - } - ] - }, - { - "CustomField": [ - { - "StringValue": "Sales Rep", - "Type": "StringType", - "Name": "PurchasePrefs.PurchaseCustomName2" - }, - { - "StringValue": "Crew #", - "Type": "StringType", - "Name": "PurchasePrefs.PurchaseCustomName1" - } - ] - } - ] - }, - "TaxPrefs": { - "TaxGroupCodeRef": { - "value": "2" - }, - "UsingSalesTax": True - }, - "OtherPrefs": { - "NameValue": [ - { - "Name": "SalesFormsPrefs.DefaultCustomerMessage", - "Value": "Thank you for your business and have a great day!" - }, - { - "Name": "SalesFormsPrefs.DefaultItem", - "Value": "1" - }, - { - "Name": "DTXCopyMemo", - "Value": "false" - }, - { - "Name": "UncategorizedAssetAccountId", - "Value": "32" - }, - { - "Name": "UncategorizedIncomeAccountId", - "Value": "30" - }, - { - "Name": "UncategorizedExpenseAccountId", - "Value": "31" - }, - { - "Name": "SFCEnabled", - "Value": "true" - }, - { - "Name": "DataPartner", - "Value": "false" - }, - { - "Name": "Vendor1099Enabled", - "Value": "true" - }, - { - "Name": "TimeTrackingFeatureEnabled", - "Value": "true" - }, - { - "Name": "FDPEnabled", - "Value": "false" - }, - { - "Name": "ProjectsEnabled", - "Value": "false" - }, - { - "Name": "DateFormat", - "Value": "Month Date Year separated by a slash" - }, - { - "Name": "DateFormatMnemonic", - "Value": "MMDDYYYY_SEP_SLASH" - }, - { - "Name": "NumberFormat", - "Value": "US Number Format" - }, - { - "Name": "NumberFormatMnemonic", - "Value": "US_NB" - }, - { - "Name": "WarnDuplicateCheckNumber", - "Value": "true" - }, - { - "Name": "WarnDuplicateBillNumber", - "Value": "false" - }, - { - "Name": "SignoutInactiveMinutes", - "Value": "60" - }, - { - "Name": "AccountingInfoPrefs.ShowAccountNumbers", - "Value": "false" - } - ] - }, - "sparse": False, - "TimeTrackingPrefs": { - "WorkWeekStartDate": "Monday", - "MarkTimeEntriesBillable": True, - "ShowBillRateToAll": False, - "UseServices": True, - "BillCustomers": True - }, - "CurrencyPrefs": { - "HomeCurrency": { - "value": "USD" - }, - "MultiCurrencyEnabled": False - }, - "Id": "1", - "MetaData": { - "CreateTime": "2017-10-25T01:05:43-07:00", - "LastUpdatedTime": "2018-03-08T13:24:26-08:00" - } - }, - "time": "2018-03-12T08:45:52.965-07:00" -} - - class PreferencesTests(unittest.TestCase): def test_unicode(self): preferences = Preferences() @@ -273,10 +17,3 @@ def test_valid_object_name(self): result = client.isvalid_object_name(preferences.qbo_object_name) self.assertTrue(result) - - def test_structure(self): - preferences = Preferences.from_json(PAYLOAD['Preferences']) - - print('Expected:', PAYLOAD['Preferences']) - print('Actual:', preferences.to_dict()) - self.assertEquals(PAYLOAD['Preferences'], preferences.to_dict()) From e097c627a1ae556fe0c505777c35b546e1c9f1f4 Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 20 Jul 2021 14:27:57 -0500 Subject: [PATCH 011/154] Readme update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e5a74853..d8fdfa77 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Set up an AuthClient passing in your `CLIENT_ID` and `CLIENT_SECRET`. auth_client = AuthClient( client_id='CLIENT_ID', client_secret='CLIENT_SECRET', + access_token='ACCESS_TOKEN', # If you do not pass this in, the Quickbooks client will call refresh and get a new access token. environment='sandbox', redirect_uri='http://localhost:8000/callback', ) From 65f7303b788030be8720bef26c7f6aa7be12bf87 Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 20 Jul 2021 16:46:10 -0500 Subject: [PATCH 012/154] Added exchangerate object --- CHANGELOG.rst | 4 ++- README.md | 2 +- quickbooks/client.py | 2 +- quickbooks/mixins.py | 22 ++++++++------ quickbooks/objects/exchangerate.py | 40 +++++++++++++++++++++++++ quickbooks/objects/preferences.py | 4 +-- tests/integration/test_exchangerate.py | 21 +++++++++++++ tests/integration/test_preferences.py | 1 - tests/unit/objects/test_exchangerate.py | 19 ++++++++++++ 9 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 quickbooks/objects/exchangerate.py create mode 100644 tests/integration/test_exchangerate.py create mode 100644 tests/unit/objects/test_exchangerate.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 98261b06..688c4e15 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,7 @@ Changelog ========= -* 0.9.0 (February 2, 2021) +* 0.9.0 (July 20, 2021) * Added missing TxnDate to Invoice * Updated requirements * Added BillRate to Vendor @@ -9,6 +9,8 @@ Changelog * Added Refresh Token to Client Instance * Updated Estimate and CreditMemo to use DescriptionOnlyLine * Removed unused DescriptionLine object + * Added support for Preferences entity + * Added support for ExchangeRate entity * 0.8.4 (October 11, 2020) * Added support for the CreditCardPayment entity diff --git a/README.md b/README.md index d8fdfa77..80e8fdb2 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ details) pass in minorversion when setting up the client: auth_client=auth_client, refresh_token='REFRESH_TOKEN', company_id='COMPANY_ID', - minorversion=4 + minorversion=59 ) Object Operations diff --git a/quickbooks/client.py b/quickbooks/client.py index 089964fd..c1a89a2e 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -45,7 +45,7 @@ class QuickBooks(object): _BUSINESS_OBJECTS = [ "Account", "Attachable", "Bill", "BillPayment", "Class", "CreditMemo", "Customer", "CompanyCurrency", - "Department", "Deposit", "Employee", "Estimate", "Invoice", + "Department", "Deposit", "Employee", "Estimate", "ExchangeRate", "Invoice", "Item", "JournalEntry", "Payment", "PaymentMethod", "Preferences", "Purchase", "PurchaseOrder", "RefundReceipt", "SalesReceipt", "TaxAgency", "TaxCode", "TaxService/Taxcode", "TaxRate", "Term", diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 2b52f55b..2738ad5b 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -166,6 +166,19 @@ def save(self, qb=None): return obj +class UpdateNoIdMixin(object): + qbo_object_name = "" + qbo_json_object_name = "" + + def save(self, qb=None): + if not qb: + qb = QuickBooks() + + json_data = qb.update_object(self.qbo_object_name, self.to_json()) + obj = type(self).from_json(json_data[self.qbo_object_name]) + return obj + + class DeleteMixin(object): qbo_object_name = "" @@ -355,12 +368,3 @@ def get(cls, qb=None): end_point = "{0}/company/{1}/preferences".format(qb.api_url, qb.company_id) json_data = qb.get(end_point, {}) return cls.from_json(json_data[cls.qbo_object_name]) - - def save(self, qb=None): - if not qb: - qb = QuickBooks() - - json_data = qb.update_object(self.qbo_object_name, self.to_json()) - obj = type(self).from_json(json_data[self.qbo_object_name]) - - return obj diff --git a/quickbooks/objects/exchangerate.py b/quickbooks/objects/exchangerate.py new file mode 100644 index 00000000..15d61728 --- /dev/null +++ b/quickbooks/objects/exchangerate.py @@ -0,0 +1,40 @@ +from six import python_2_unicode_compatible + +from quickbooks.mixins import ListMixin, UpdateNoIdMixin, FromJsonMixin +from .base import CustomField, QuickbooksBaseObject + + +@python_2_unicode_compatible +class ExchangeRateMetaData(FromJsonMixin): + def __init__(self): + self.LastUpdatedTime = "" + + +@python_2_unicode_compatible +class ExchangeRate(QuickbooksBaseObject, ListMixin, UpdateNoIdMixin): + """ + QBO definition: Applicable only for those companies that enable multicurrency, + the exchangerate resource provides the ability to query and set exchange rates available to the + QuickBooks Online company. This entity works in combination with the companycurrency entity + and the Currency Center in the QuickBooks Online UI to manage exchange rates for the company. + """ + + class_dict = { + "MetaData": ExchangeRateMetaData, + "CustomField": CustomField, + } + + qbo_object_name = "ExchangeRate" + + def __str__(self): + return self.SourceCurrencyCode + + def __init__(self): + super(ExchangeRate, self).__init__() + + self.AsOfDate = "" + self.SourceCurrencyCode = "" + self.Rate = 0 + self.TargetCurrencyCode = "" + self.MetaData = None + self.CustomField = None diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py index 3f4cb309..c13a4150 100644 --- a/quickbooks/objects/preferences.py +++ b/quickbooks/objects/preferences.py @@ -1,6 +1,6 @@ from six import python_2_unicode_compatible -from quickbooks.mixins import PrefMixin +from quickbooks.mixins import PrefMixin, UpdateNoIdMixin from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, Ref @@ -184,7 +184,7 @@ def __init__(self): @python_2_unicode_compatible -class Preferences(PrefMixin, QuickbooksTransactionEntity): +class Preferences(PrefMixin, UpdateNoIdMixin, QuickbooksTransactionEntity): """ QBO definition: The Preferences resource represents a set of company preferences that control application behavior in QuickBooks Online. diff --git a/tests/integration/test_exchangerate.py b/tests/integration/test_exchangerate.py new file mode 100644 index 00000000..d51406f4 --- /dev/null +++ b/tests/integration/test_exchangerate.py @@ -0,0 +1,21 @@ +from datetime import datetime +from quickbooks.objects.exchangerate import ExchangeRate +from tests.integration.test_base import QuickbooksTestCase + + +class ExchangeRateTest(QuickbooksTestCase): + def test_query(self): + exchange_rate = ExchangeRate.where("SourceCurrencyCode = 'EUR'", qb=self.qb_client)[0] + + self.assertEquals(exchange_rate.SourceCurrencyCode, "EUR") + self.assertEquals(exchange_rate.TargetCurrencyCode, "USD") + + def test_update(self): + exchange_rate = ExchangeRate.where("SourceCurrencyCode = 'EUR'", qb=self.qb_client)[0] + + new_rate = exchange_rate.Rate + 1 + exchange_rate.Rate = new_rate + exchange_rate.save(qb=self.qb_client) + + exchange_rate_updated = ExchangeRate.where("SourceCurrencyCode = 'EUR'", qb=self.qb_client)[0] + self.assertEquals(exchange_rate_updated.Rate, new_rate) diff --git a/tests/integration/test_preferences.py b/tests/integration/test_preferences.py index 5997cff1..c42b79d0 100644 --- a/tests/integration/test_preferences.py +++ b/tests/integration/test_preferences.py @@ -13,7 +13,6 @@ def setUp(self): def test_get(self): preferences = Preferences.get(qb=self.qb_client) - print(preferences.to_json()) self.assertEquals(preferences.Id, "1") self.assertEquals(preferences.AccountingInfoPrefs.TaxYearMonth, "January") self.assertEquals(preferences.ProductAndServicesPrefs.ForPurchase, True) diff --git a/tests/unit/objects/test_exchangerate.py b/tests/unit/objects/test_exchangerate.py new file mode 100644 index 00000000..d016cde7 --- /dev/null +++ b/tests/unit/objects/test_exchangerate.py @@ -0,0 +1,19 @@ +import unittest + +from quickbooks import QuickBooks +from quickbooks.objects.exchangerate import ExchangeRate + + +class ExchangeRateTests(unittest.TestCase): + def test_unicode(self): + exchange_rate = ExchangeRate() + exchange_rate.SourceCurrencyCode = "EUR" + + self.assertEquals(str(exchange_rate), "EUR") + + def test_valid_object_name(self): + obj = ExchangeRate() + client = QuickBooks() + result = client.isvalid_object_name(obj.qbo_object_name) + + self.assertTrue(result) From d1ea91db8f97b42ec10fc29a2fa8f8088b39f119 Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 20 Jul 2021 16:50:31 -0500 Subject: [PATCH 013/154] Update setup --- Pipfile | 6 +++--- setup.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Pipfile b/Pipfile index 5178d8db..e0f6a603 100644 --- a/Pipfile +++ b/Pipfile @@ -7,9 +7,9 @@ verify_ssl = true [packages] bleach = ">=3.3.0" -intuit-oauth = "==1.2.3" -rauth = ">=0.7.1" -requests = ">=2.19.1" +intuit-oauth = "==1.2.4" +rauth = ">=0.7.3" +requests = ">=2.26.0" simplejson = ">=3.17.0" six = ">=1.14.0" nose = "*" diff --git a/setup.py b/setup.py index 7655928b..0e57d0ec 100644 --- a/setup.py +++ b/setup.py @@ -31,10 +31,10 @@ def read(*parts): install_requires=[ 'setuptools', - 'intuit-oauth==1.2.3', - 'rauth>=0.7.1', + 'intuit-oauth==1.2.4', + 'rauth>=0.7.3', 'authclient', - 'requests>=2.19.1', + 'requests>=2.26.0', 'simplejson>=3.17.0', 'six>=1.14.0', 'python-dateutil', From 06110a4a88bb47b2e6349a193908c083d506dde1 Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 20 Jul 2021 16:53:59 -0500 Subject: [PATCH 014/154] Update pipfile --- Pipfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Pipfile b/Pipfile index e0f6a603..921418b8 100644 --- a/Pipfile +++ b/Pipfile @@ -6,6 +6,7 @@ verify_ssl = true [dev-packages] [packages] +urllib3 = ">=1.26.5" bleach = ">=3.3.0" intuit-oauth = "==1.2.4" rauth = ">=0.7.3" From 47d1bfdd84b6c4e93cb4f0d794c348bcb49545b7 Mon Sep 17 00:00:00 2001 From: ej2 Date: Wed, 21 Jul 2021 14:40:46 -0500 Subject: [PATCH 015/154] Added response status code when raising unauthorized exceptions --- quickbooks/client.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index 0a02921f..a93585a3 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -221,7 +221,8 @@ def make_request(self, request_type, url, request_body=None, content_type='appli req = self.process_request(request_type, url, headers=headers, params=params, data=request_body) if req.status_code == httplib.UNAUTHORIZED: - raise exceptions.AuthorizationException("Application authentication failed", detail=req.text) + raise exceptions.AuthorizationException( + "Application authentication failed", error_code=req.status_code, detail=req.text) try: result = req.json() @@ -354,7 +355,8 @@ def download_pdf(self, qbbo, item_id): if response.status_code == httplib.UNAUTHORIZED: # Note that auth errors have different result structure which can't be parsed by handle_exceptions() - raise exceptions.AuthorizationException("Application authentication failed", detail=response.text) + raise exceptions.AuthorizationException( + "Application authentication failed", error_code=response.status_code, detail=response.text) try: result = response.json() From 00f9a5331c24782c50356eaa4d75236a28ee999a Mon Sep 17 00:00:00 2001 From: ej2 Date: Wed, 21 Jul 2021 15:12:18 -0500 Subject: [PATCH 016/154] Added pending deprecation warnings and updated setup. --- CHANGELOG.rst | 4 ++++ README.md | 4 ++-- quickbooks/client.py | 4 ++++ setup.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 688c4e15..9ff87dfd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,10 @@ Changelog ========= +* 0.9.1 (July ??, 2021) + * Added response status code when raising unauthorized exceptions + * Added pending deprecation warnings to enable_global and disable_global + * 0.9.0 (July 20, 2021) * Added missing TxnDate to Invoice * Updated requirements diff --git a/README.md b/README.md index 80e8fdb2..daf59eee 100644 --- a/README.md +++ b/README.md @@ -241,11 +241,11 @@ Void an invoice: invoice.Id = 7 invoice.void(qb=client) -If your consumer_key never changes you can enable the client to stay running: +If your company_id never changes you can enable the client to stay running (deprecation warning: will be removed in next release): QuickBooks.enable_global() -You can disable the global client like so: +You can disable the global client like so (deprecation warning: will be removed in next release): QuickBooks.disable_global() diff --git a/quickbooks/client.py b/quickbooks/client.py index a93585a3..281e52fa 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -1,3 +1,5 @@ +import warnings + try: # Python 3 import http.client as httplib from urllib.parse import parse_qsl @@ -111,6 +113,7 @@ def disable_global(cls): """ Disable use of singleton pattern. """ + warnings.warn("disable_global deprecated", PendingDeprecationWarning) QuickBooks.__use_global = False QuickBooks.__instance = None @@ -119,6 +122,7 @@ def enable_global(cls): """ Allow use of singleton pattern. """ + warnings.warn("enable_global deprecated", PendingDeprecationWarning) QuickBooks.__use_global = True def _drop(self): diff --git a/setup.py b/setup.py index 0e57d0ec..5a9a8930 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 0) +VERSION = (0, 9, 1) version = '.'.join(map(str, VERSION)) setup( From 4aca161ec0db84a46315971d15b15bdde661d924 Mon Sep 17 00:00:00 2001 From: Franklin Ventura Date: Sun, 29 Aug 2021 10:59:41 -0700 Subject: [PATCH 017/154] Add option for invoiceLink on query results closes #241 --- quickbooks/client.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/quickbooks/client.py b/quickbooks/client.py index 0a02921f..e8799907 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -37,6 +37,7 @@ class QuickBooks(object): sandbox = False minorversion = None verifier_token = None + invoice_link = False sandbox_api_url_v3 = "https://sandbox-quickbooks.api.intuit.com/v3" api_url_v3 = "https://quickbooks.api.intuit.com/v3" @@ -86,6 +87,8 @@ def __new__(cls, **kwargs): if 'minorversion' in kwargs: instance.minorversion = kwargs['minorversion'] + instance.invoice_link = kwargs.get('invoice_link', False) + if 'verifier_token' in kwargs: instance.verifier_token = kwargs.get('verifier_token') @@ -171,6 +174,9 @@ def make_request(self, request_type, url, request_body=None, content_type='appli if self.minorversion: params['minorversion'] = self.minorversion + if self.invoice_link: + params['include'] = 'invoiceLink' + if not request_body: request_body = {} From 31bc3e50343f9061bd98fd07d6e72736a2c5643b Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Fri, 17 Sep 2021 21:24:21 +0800 Subject: [PATCH 018/154] #247 void quickbooks payment --- quickbooks/objects/payment.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index 40c37916..ccaa9a90 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -1,8 +1,10 @@ from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, LinkedTxn, \ QuickbooksManagedObject, QuickbooksTransactionEntity +from ..client import QuickBooks from .creditcardpayment import CreditCardPayment from ..mixins import DeleteMixin +import json @python_2_unicode_compatible @@ -77,5 +79,24 @@ def __init__(self): # These fields are for minor version 4 self.TransactionLocationType = None + def void(self, qb=None): + if not qb: + qb = QuickBooks() + + if not self.Id: + raise qb.QuickbooksException('Cannot void unsaved object') + + data = { + 'Id': self.Id, + 'SyncToken': self.SyncToken, + 'sparse': True + } + + endpoint = self.qbo_object_name.lower() + url = "{0}/company/{1}/{2}".format(qb.api_url, qb.company_id, endpoint) + results = qb.post(url, json.dumps(data), params={'operation': 'update', 'include': 'void'}) + + return results + def __str__(self): return str(self.TotalAmt) From c2347e9f88a9758431c49d5a5b1b1ac3eee49075 Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Fri, 17 Sep 2021 21:53:57 +0800 Subject: [PATCH 019/154] #247 void quickbooks payment integration test --- tests/integration/test_payment.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/integration/test_payment.py b/tests/integration/test_payment.py index 19d3c9fb..24ff2e5b 100644 --- a/tests/integration/test_payment.py +++ b/tests/integration/test_payment.py @@ -37,3 +37,24 @@ def test_create(self): self.assertEqual(query_payment.CustomerRef.name, customer.DisplayName) self.assertEqual(query_payment.TotalAmt, 140.0) self.assertEqual(query_payment.PaymentMethodRef.value, payment_method.Id) + + def test_void(self): + payment = Payment() + payment.TotalAmt = 100.0 + + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + payment.CustomerRef = customer.to_ref() + + payment_method = PaymentMethod.all(max_results=1, qb=self.qb_client)[0] + + payment.PaymentMethodRef = payment_method.to_ref() + payment.save(qb=self.qb_client) + + query_payment = Payment.get(payment.Id, qb=self.qb_client) + self.assertEqual(query_payment.TotalAmt, 100.0) + + payment.void(qb=self.qb_client) + query_payment = Payment.get(payment.Id, qb=self.qb_client) + + self.assertEqual(query_payment.TotalAmt, 0.0) + self.assertIn('Voided', query_payment.PrivateNote) From 4b2a47d803643605bd8d21d350011479835a76cd Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 19 Oct 2021 09:56:50 -0500 Subject: [PATCH 020/154] Removed unused requirement authclient --- Pipfile | 1 - Pipfile.lock | 574 ++++++++++-------------------- setup.py | 1 - tests/integration/test_invoice.py | 18 + 4 files changed, 207 insertions(+), 387 deletions(-) diff --git a/Pipfile b/Pipfile index 921418b8..0e568b45 100644 --- a/Pipfile +++ b/Pipfile @@ -14,7 +14,6 @@ requests = ">=2.26.0" simplejson = ">=3.17.0" six = ">=1.14.0" nose = "*" -authclient = "*" coverage = "*" twine = "*" diff --git a/Pipfile.lock b/Pipfile.lock index d9727aaf..0fc83846 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "19d2381be21fa243498ecda6cacf06ad6ba0784c03f7f71afbb208858efd045b" + "sha256": "0dcea13aefe56fd4407fd1616f124a4527372bbc6a4324e6d75ec31027624edd" }, "pipfile-spec": 6, "requires": { @@ -16,211 +16,91 @@ ] }, "default": { - "aiohttp": { - "hashes": [ - "sha256:119feb2bd551e58d83d1b38bfa4cb921af8ddedec9fad7183132db334c3133e0", - "sha256:16d0683ef8a6d803207f02b899c928223eb219111bd52420ef3d7a8aa76227b6", - "sha256:2eb3efe243e0f4ecbb654b08444ae6ffab37ac0ef8f69d3a2ffb958905379daf", - "sha256:2ffea7904e70350da429568113ae422c88d2234ae776519549513c8f217f58a9", - "sha256:40bd1b101b71a18a528ffce812cc14ff77d4a2a1272dfb8b11b200967489ef3e", - "sha256:418597633b5cd9639e514b1d748f358832c08cd5d9ef0870026535bd5eaefdd0", - "sha256:481d4b96969fbfdcc3ff35eea5305d8565a8300410d3d269ccac69e7256b1329", - "sha256:4c1bdbfdd231a20eee3e56bd0ac1cd88c4ff41b64ab679ed65b75c9c74b6c5c2", - "sha256:5563ad7fde451b1986d42b9bb9140e2599ecf4f8e42241f6da0d3d624b776f40", - "sha256:58c62152c4c8731a3152e7e650b29ace18304d086cb5552d317a54ff2749d32a", - "sha256:5b50e0b9460100fe05d7472264d1975f21ac007b35dcd6fd50279b72925a27f4", - "sha256:5d84ecc73141d0a0d61ece0742bb7ff5751b0657dab8405f899d3ceb104cc7de", - "sha256:5dde6d24bacac480be03f4f864e9a67faac5032e28841b00533cd168ab39cad9", - "sha256:5e91e927003d1ed9283dee9abcb989334fc8e72cf89ebe94dc3e07e3ff0b11e9", - "sha256:62bc216eafac3204877241569209d9ba6226185aa6d561c19159f2e1cbb6abfb", - "sha256:6c8200abc9dc5f27203986100579fc19ccad7a832c07d2bc151ce4ff17190076", - "sha256:6ca56bdfaf825f4439e9e3673775e1032d8b6ea63b8953d3812c71bd6a8b81de", - "sha256:71680321a8a7176a58dfbc230789790639db78dad61a6e120b39f314f43f1907", - "sha256:7c7820099e8b3171e54e7eedc33e9450afe7cd08172632d32128bd527f8cb77d", - "sha256:7dbd087ff2f4046b9b37ba28ed73f15fd0bc9f4fdc8ef6781913da7f808d9536", - "sha256:822bd4fd21abaa7b28d65fc9871ecabaddc42767884a626317ef5b75c20e8a2d", - "sha256:8ec1a38074f68d66ccb467ed9a673a726bb397142c273f90d4ba954666e87d54", - "sha256:950b7ef08b2afdab2488ee2edaff92a03ca500a48f1e1aaa5900e73d6cf992bc", - "sha256:99c5a5bf7135607959441b7d720d96c8e5c46a1f96e9d6d4c9498be8d5f24212", - "sha256:b84ad94868e1e6a5e30d30ec419956042815dfaea1b1df1cef623e4564c374d9", - "sha256:bc3d14bf71a3fb94e5acf5bbf67331ab335467129af6416a437bd6024e4f743d", - "sha256:c2a80fd9a8d7e41b4e38ea9fe149deed0d6aaede255c497e66b8213274d6d61b", - "sha256:c44d3c82a933c6cbc21039326767e778eface44fca55c65719921c4b9661a3f7", - "sha256:cc31e906be1cc121ee201adbdf844522ea3349600dd0a40366611ca18cd40e81", - "sha256:d5d102e945ecca93bcd9801a7bb2fa703e37ad188a2f81b1e65e4abe4b51b00c", - "sha256:dd7936f2a6daa861143e376b3a1fb56e9b802f4980923594edd9ca5670974895", - "sha256:dee68ec462ff10c1d836c0ea2642116aba6151c6880b688e56b4c0246770f297", - "sha256:e76e78863a4eaec3aee5722d85d04dcbd9844bc6cd3bfa6aa880ff46ad16bfcb", - "sha256:eab51036cac2da8a50d7ff0ea30be47750547c9aa1aa2cf1a1b710a1827e7dbe", - "sha256:f4496d8d04da2e98cc9133e238ccebf6a13ef39a93da2e87146c8c8ac9768242", - "sha256:fbd3b5e18d34683decc00d9a360179ac1e7a320a5fee10ab8053ffd6deab76e0", - "sha256:feb24ff1226beeb056e247cf2e24bba5232519efb5645121c4aea5b6ad74c1f2" - ], - "index": "pypi", - "version": "==3.7.4" - }, - "async-timeout": { - "hashes": [ - "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", - "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" - ], - "version": "==3.0.1" - }, - "attrs": { - "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" - ], - "version": "==20.3.0" - }, - "authclient": { + "bleach": { "hashes": [ - "sha256:77fe31eb7b8b7c8cf947fc449ef06d48576bae675299ea612c508c2f7eae9d9f", - "sha256:f56a63107c7cf26a84274ba6f10eae509d76fa5f391fee0a80af44d2cea00481" + "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da", + "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994" ], "index": "pypi", - "version": "==1.0" + "version": "==4.1.0" }, - "bleach": { + "certifi": { "hashes": [ - "sha256:6123ddc1052673e52bab52cdc955bcb57a015264a1c57d37bea2f6b817af0125", - "sha256:98b3170739e5e83dd9dc19633f074727ad848cbedb6026708c8ac2d3b697a433" + "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", + "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" ], - "version": "==3.3.0" + "version": "==2021.10.8" }, - "certifi": { + "charset-normalizer": { "hashes": [ - "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", - "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" - ], - "version": "==2020.12.5" - }, - "cffi": { - "hashes": [ - "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813", - "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06", - "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea", - "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee", - "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396", - "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73", - "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315", - "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1", - "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49", - "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892", - "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482", - "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058", - "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5", - "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53", - "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045", - "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3", - "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5", - "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e", - "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c", - "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369", - "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827", - "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053", - "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa", - "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4", - "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322", - "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132", - "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62", - "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa", - "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0", - "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396", - "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e", - "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991", - "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6", - "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1", - "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406", - "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d", - "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c" - ], - "version": "==1.14.5" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" + "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0", + "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b" + ], + "markers": "python_version >= '3'", + "version": "==2.0.7" }, "colorama": { "hashes": [ "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.4.4" }, "coverage": { "hashes": [ - "sha256:098a703d913be6fbd146a8c50cc76513d726b022d170e5e98dc56d958fd592fb", - "sha256:16042dc7f8e632e0dcd5206a5095ebd18cb1d005f4c89694f7f8aafd96dd43a3", - "sha256:1adb6be0dcef0cf9434619d3b892772fdb48e793300f9d762e480e043bd8e716", - "sha256:27ca5a2bc04d68f0776f2cdcb8bbd508bbe430a7bf9c02315cd05fb1d86d0034", - "sha256:28f42dc5172ebdc32622a2c3f7ead1b836cdbf253569ae5673f499e35db0bac3", - "sha256:2fcc8b58953d74d199a1a4d633df8146f0ac36c4e720b4a1997e9b6327af43a8", - "sha256:304fbe451698373dc6653772c72c5d5e883a4aadaf20343592a7abb2e643dae0", - "sha256:30bc103587e0d3df9e52cd9da1dd915265a22fad0b72afe54daf840c984b564f", - "sha256:40f70f81be4d34f8d491e55936904db5c527b0711b2a46513641a5729783c2e4", - "sha256:4186fc95c9febeab5681bc3248553d5ec8c2999b8424d4fc3a39c9cba5796962", - "sha256:46794c815e56f1431c66d81943fa90721bb858375fb36e5903697d5eef88627d", - "sha256:4869ab1c1ed33953bb2433ce7b894a28d724b7aa76c19b11e2878034a4e4680b", - "sha256:4f6428b55d2916a69f8d6453e48a505c07b2245653b0aa9f0dee38785939f5e4", - "sha256:52f185ffd3291196dc1aae506b42e178a592b0b60a8610b108e6ad892cfc1bb3", - "sha256:538f2fd5eb64366f37c97fdb3077d665fa946d2b6d95447622292f38407f9258", - "sha256:64c4f340338c68c463f1b56e3f2f0423f7b17ba6c3febae80b81f0e093077f59", - "sha256:675192fca634f0df69af3493a48224f211f8db4e84452b08d5fcebb9167adb01", - "sha256:700997b77cfab016533b3e7dbc03b71d33ee4df1d79f2463a318ca0263fc29dd", - "sha256:8505e614c983834239f865da2dd336dcf9d72776b951d5dfa5ac36b987726e1b", - "sha256:962c44070c281d86398aeb8f64e1bf37816a4dfc6f4c0f114756b14fc575621d", - "sha256:9e536783a5acee79a9b308be97d3952b662748c4037b6a24cbb339dc7ed8eb89", - "sha256:9ea749fd447ce7fb1ac71f7616371f04054d969d412d37611716721931e36efd", - "sha256:a34cb28e0747ea15e82d13e14de606747e9e484fb28d63c999483f5d5188e89b", - "sha256:a3ee9c793ffefe2944d3a2bd928a0e436cd0ac2d9e3723152d6fd5398838ce7d", - "sha256:aab75d99f3f2874733946a7648ce87a50019eb90baef931698f96b76b6769a46", - "sha256:b1ed2bdb27b4c9fc87058a1cb751c4df8752002143ed393899edb82b131e0546", - "sha256:b360d8fd88d2bad01cb953d81fd2edd4be539df7bfec41e8753fe9f4456a5082", - "sha256:b8f58c7db64d8f27078cbf2a4391af6aa4e4767cc08b37555c4ae064b8558d9b", - "sha256:c1bbb628ed5192124889b51204de27c575b3ffc05a5a91307e7640eff1d48da4", - "sha256:c2ff24df02a125b7b346c4c9078c8936da06964cc2d276292c357d64378158f8", - "sha256:c890728a93fffd0407d7d37c1e6083ff3f9f211c83b4316fae3778417eab9811", - "sha256:c96472b8ca5dc135fb0aa62f79b033f02aa434fb03a8b190600a5ae4102df1fd", - "sha256:ce7866f29d3025b5b34c2e944e66ebef0d92e4a4f2463f7266daa03a1332a651", - "sha256:e26c993bd4b220429d4ec8c1468eca445a4064a61c74ca08da7429af9bc53bb0" + "sha256:04560539c19ec26995ecfb3d9307ff154fbb9a172cb57e3b3cfc4ced673103d1", + "sha256:1549e1d08ce38259de2bc3e9a0d5f3642ff4a8f500ffc1b2df73fd621a6cdfc0", + "sha256:1db67c497688fd4ba85b373b37cc52c50d437fd7267520ecd77bddbd89ea22c9", + "sha256:30922626ce6f7a5a30bdba984ad21021529d3d05a68b4f71ea3b16bda35b8895", + "sha256:36e9040a43d2017f2787b28d365a4bb33fcd792c7ff46a047a04094dc0e2a30d", + "sha256:381d773d896cc7f8ba4ff3b92dee4ed740fb88dfe33b6e42efc5e8ab6dfa1cfe", + "sha256:3bbda1b550e70fa6ac40533d3f23acd4f4e9cb4e6e77251ce77fdf41b3309fb2", + "sha256:3be1206dc09fb6298de3fce70593e27436862331a85daee36270b6d0e1c251c4", + "sha256:424c44f65e8be58b54e2b0bd1515e434b940679624b1b72726147cfc6a9fc7ce", + "sha256:4b34ae4f51bbfa5f96b758b55a163d502be3dcb24f505d0227858c2b3f94f5b9", + "sha256:4e28d2a195c533b58fc94a12826f4431726d8eb029ac21d874345f943530c122", + "sha256:53a294dc53cfb39c74758edaa6305193fb4258a30b1f6af24b360a6c8bd0ffa7", + "sha256:60e51a3dd55540bec686d7fff61b05048ca31e804c1f32cbb44533e6372d9cc3", + "sha256:61b598cbdbaae22d9e34e3f675997194342f866bb1d781da5d0be54783dce1ff", + "sha256:6807947a09510dc31fa86f43595bf3a14017cd60bf633cc746d52141bfa6b149", + "sha256:6a6a9409223a27d5ef3cca57dd7cd4dfcb64aadf2fad5c3b787830ac9223e01a", + "sha256:7092eab374346121805fb637572483270324407bf150c30a3b161fc0c4ca5164", + "sha256:77b1da5767ed2f44611bc9bc019bc93c03fa495728ec389759b6e9e5039ac6b1", + "sha256:8251b37be1f2cd9c0e5ccd9ae0380909c24d2a5ed2162a41fcdbafaf59a85ebd", + "sha256:9f1627e162e3864a596486774876415a7410021f4b67fd2d9efdf93ade681afc", + "sha256:a1b73c7c4d2a42b9d37dd43199c5711d91424ff3c6c22681bc132db4a4afec6f", + "sha256:a82d79586a0a4f5fd1cf153e647464ced402938fbccb3ffc358c7babd4da1dd9", + "sha256:abbff240f77347d17306d3201e14431519bf64495648ca5a49571f988f88dee9", + "sha256:ad9b8c1206ae41d46ec7380b78ba735ebb77758a650643e841dd3894966c31d0", + "sha256:bbffde2a68398682623d9dd8c0ca3f46fda074709b26fcf08ae7a4c431a6ab2d", + "sha256:bcae10fccb27ca2a5f456bf64d84110a5a74144be3136a5e598f9d9fb48c0caa", + "sha256:c9cd3828bbe1a40070c11fe16a51df733fd2f0cb0d745fb83b7b5c1f05967df7", + "sha256:cd1cf1deb3d5544bd942356364a2fdc8959bad2b6cf6eb17f47d301ea34ae822", + "sha256:d036dc1ed8e1388e995833c62325df3f996675779541f682677efc6af71e96cc", + "sha256:db42baa892cba723326284490283a68d4de516bfb5aaba369b4e3b2787a778b7", + "sha256:e4fb7ced4d9dec77d6cf533acfbf8e1415fe799430366affb18d69ee8a3c6330", + "sha256:e7a0b42db2a47ecb488cde14e0f6c7679a2c5a9f44814393b162ff6397fcdfbb", + "sha256:f2f184bf38e74f152eed7f87e345b51f3ab0b703842f447c22efe35e59942c24" ], "index": "pypi", - "version": "==5.2.1" - }, - "cryptography": { - "hashes": [ - "sha256:066bc53f052dfeda2f2d7c195cf16fb3e5ff13e1b6b7415b468514b40b381a5b", - "sha256:0923ba600d00718d63a3976f23cab19aef10c1765038945628cd9be047ad0336", - "sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87", - "sha256:4169a27b818de4a1860720108b55a2801f32b6ae79e7f99c00d79f2a2822eeb7", - "sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799", - "sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b", - "sha256:600cf9bfe75e96d965509a4c0b2b183f74a4fa6f5331dcb40fb7b77b7c2484df", - "sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0", - "sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3", - "sha256:9e98b452132963678e3ac6c73f7010fe53adf72209a32854d55690acac3f6724", - "sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2", - "sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964" - ], - "version": "==3.4.6" + "version": "==6.0.2" }, "docutils": { "hashes": [ - "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af", - "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc" + "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125", + "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61" ], - "version": "==0.16" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.17.1" }, "ecdsa": { "hashes": [ - "sha256:64c613005f13efec6541bb0a33290d0d03c27abab5f15fbab20fb0ee162bdd8e", - "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe" + "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676", + "sha256:b9f500bb439e4153d0330610f5d26baaf18d17b8ced1bc54410d189385ea68aa" ], - "version": "==0.14.1" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.17.0" }, "enum-compat": { "hashes": [ @@ -233,79 +113,40 @@ "hashes": [ "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.18.2" }, "idna": { "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "version": "==2.10" + "markers": "python_version >= '3'", + "version": "==3.3" }, - "intuit-oauth": { + "importlib-metadata": { "hashes": [ - "sha256:004a83d9904ed5e4ef0582ce39717108351b59f5a26e20283405ba4881738dbf", - "sha256:f245c550f7601174eb55f8bdec50b0e64072fa6b017e2aebb4951e41e5f78b21" + "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15", + "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1" ], - "index": "pypi", - "version": "==1.2.3" + "markers": "python_version >= '3.6'", + "version": "==4.8.1" }, - "jeepney": { + "intuit-oauth": { "hashes": [ - "sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657", - "sha256:aec56c0eb1691a841795111e184e13cad504f7703b9a64f63020816afa79a8ae" + "sha256:14a1a8ed73f24369ba209f0e581eb30698571fd7bcbe05ca5bed65d2ff9df8b1", + "sha256:dd09ef833a26e12e0fbe96d0e7694cdae2c9179776f763ea00e328f8cbd4464e" ], - "markers": "sys_platform == 'linux'", - "version": "==0.6.0" + "index": "pypi", + "version": "==1.2.4" }, "keyring": { "hashes": [ - "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df", - "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0" - ], - "version": "==22.0.1" - }, - "multidict": { - "hashes": [ - "sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a", - "sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93", - "sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632", - "sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656", - "sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79", - "sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7", - "sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d", - "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5", - "sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224", - "sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26", - "sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea", - "sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348", - "sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6", - "sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76", - "sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1", - "sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f", - "sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952", - "sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a", - "sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37", - "sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9", - "sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359", - "sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8", - "sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da", - "sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3", - "sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d", - "sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf", - "sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841", - "sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d", - "sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93", - "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f", - "sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647", - "sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635", - "sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456", - "sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda", - "sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5", - "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281", - "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80" - ], - "version": "==5.1.0" + "sha256:6334aee6073db2fb1f30892697b1730105b5e9a77ce7e61fca6b435225493efe", + "sha256:bd2145a237ed70c8ce72978b497619ddfcae640b6dcf494402d5143e37755c6e" + ], + "markers": "python_version >= '3.6'", + "version": "==23.2.1" }, "nose": { "hashes": [ @@ -318,59 +159,67 @@ }, "oauthlib": { "hashes": [ - "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889", - "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea" + "sha256:42bf6354c2ed8c6acb54d971fce6f88193d97297e18602a3a886603f9d7730cc", + "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3" ], - "version": "==3.1.0" + "markers": "python_version >= '3.6'", + "version": "==3.1.1" }, "packaging": { "hashes": [ - "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", - "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" + "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7", + "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14" ], - "version": "==20.9" + "markers": "python_version >= '3.6'", + "version": "==21.0" }, "pkginfo": { "hashes": [ - "sha256:029a70cb45c6171c329dfc890cde0879f8c52d6f3922794796e06f577bb03db4", - "sha256:9fdbea6495622e022cc72c2e5e1b735218e4ffb2a2a69cde2694a6c1f16afb75" + "sha256:37ecd857b47e5f55949c41ed061eb51a0bee97a87c969219d144c0e023982779", + "sha256:e7432f81d08adec7297633191bbf0bd47faf13cd8724c3a13250e51d542635bd" ], - "version": "==1.7.0" + "version": "==1.7.1" }, "pyasn1": { "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba" + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" ], "version": "==0.4.8" }, - "pycparser": { - "hashes": [ - "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", - "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" - ], - "version": "==2.20" - }, "pygments": { "hashes": [ - "sha256:37a13ba168a02ac54cc5891a42b1caec333e59b66addb7fa633ea8a6d73445c0", - "sha256:b21b072d0ccdf29297a82a2363359d99623597b8a265b8081760e4d0f7153c88" + "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380", + "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6" ], - "version": "==2.8.0" + "markers": "python_version >= '3.5'", + "version": "==2.10.0" }, "pyparsing": { "hashes": [ "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, "python-jose": { "hashes": [ - "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b", - "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be" + "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", + "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a" ], - "version": "==3.2.0" + "version": "==3.3.0" }, "rauth": { "hashes": [ @@ -382,23 +231,24 @@ }, "readme-renderer": { "hashes": [ - "sha256:63b4075c6698fcfa78e584930f07f39e05d46f3ec97f65006e430b595ca6348c", - "sha256:92fd5ac2bf8677f310f3303aa4bce5b9d5f9f2094ab98c29f13791d7b805a3db" + "sha256:3286806450d9961d6e3b5f8a59f77e61503799aca5155c8d8d40359b4e1e1adc", + "sha256:8299700d7a910c304072a7601eafada6712a5b011a20139417e1b1e9f04645d8" ], - "version": "==29.0" + "version": "==30.0" }, "requests": { "hashes": [ - "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b", - "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898" + "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", + "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" ], "index": "pypi", - "version": "==2.24.0" + "version": "==2.26.0" }, "requests-oauthlib": { "hashes": [ "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d", - "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a" + "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a", + "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc" ], "version": "==1.3.0" }, @@ -411,114 +261,102 @@ }, "rfc3986": { "hashes": [ - "sha256:112398da31a3344dc25dbf477d8df6cb34f9278a94fee2625d89e4514be8bb9d", - "sha256:af9147e9aceda37c91a05f4deb128d4b4b49d6b199775fd2d2927768abdc8f50" + "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835", + "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97" ], - "version": "==1.4.0" + "version": "==1.5.0" }, "rsa": { "hashes": [ "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2", "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9" ], + "markers": "python_version >= '3.5' and python_version < '4'", "version": "==4.7.2" }, - "secretstorage": { - "hashes": [ - "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f", - "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195" - ], - "markers": "sys_platform == 'linux'", - "version": "==3.3.1" - }, "simplejson": { "hashes": [ - "sha256:034550078a11664d77bc1a8364c90bb7eef0e44c2dbb1fd0a4d92e3997088667", - "sha256:05b43d568300c1cd43f95ff4bfcff984bc658aa001be91efb3bb21df9d6288d3", - "sha256:0dd9d9c738cb008bfc0862c9b8fa6743495c03a0ed543884bf92fb7d30f8d043", - "sha256:10fc250c3edea4abc15d930d77274ddb8df4803453dde7ad50c2f5565a18a4bb", - "sha256:2862beabfb9097a745a961426fe7daf66e1714151da8bb9a0c430dde3d59c7c0", - "sha256:292c2e3f53be314cc59853bd20a35bf1f965f3bc121e007ab6fd526ed412a85d", - "sha256:2d3eab2c3fe52007d703a26f71cf649a8c771fcdd949a3ae73041ba6797cfcf8", - "sha256:2e7b57c2c146f8e4dadf84977a83f7ee50da17c8861fd7faf694d55e3274784f", - "sha256:311f5dc2af07361725033b13cc3d0351de3da8bede3397d45650784c3f21fbcf", - "sha256:344e2d920a7f27b4023c087ab539877a1e39ce8e3e90b867e0bfa97829824748", - "sha256:3fabde09af43e0cbdee407555383063f8b45bfb52c361bc5da83fcffdb4fd278", - "sha256:42b8b8dd0799f78e067e2aaae97e60d58a8f63582939af60abce4c48631a0aa4", - "sha256:4b3442249d5e3893b90cb9f72c7d6ce4d2ea144d2c0d9f75b9ae1e5460f3121a", - "sha256:55d65f9cc1b733d85ef95ab11f559cce55c7649a2160da2ac7a078534da676c8", - "sha256:5c659a0efc80aaaba57fcd878855c8534ecb655a28ac8508885c50648e6e659d", - "sha256:72d8a3ffca19a901002d6b068cf746be85747571c6a7ba12cbcf427bfb4ed971", - "sha256:75ecc79f26d99222a084fbdd1ce5aad3ac3a8bd535cd9059528452da38b68841", - "sha256:76ac9605bf2f6d9b56abf6f9da9047a8782574ad3531c82eae774947ae99cc3f", - "sha256:7d276f69bfc8c7ba6c717ba8deaf28f9d3c8450ff0aa8713f5a3280e232be16b", - "sha256:7f10f8ba9c1b1430addc7dd385fc322e221559d3ae49b812aebf57470ce8de45", - "sha256:8042040af86a494a23c189b5aa0ea9433769cc029707833f261a79c98e3375f9", - "sha256:813846738277729d7db71b82176204abc7fdae2f566e2d9fcf874f9b6472e3e6", - "sha256:845a14f6deb124a3bcb98a62def067a67462a000e0508f256f9c18eff5847efc", - "sha256:869a183c8e44bc03be1b2bbcc9ec4338e37fa8557fc506bf6115887c1d3bb956", - "sha256:8acf76443cfb5c949b6e781c154278c059b09ac717d2757a830c869ba000cf8d", - "sha256:8f713ea65958ef40049b6c45c40c206ab363db9591ff5a49d89b448933fa5746", - "sha256:934115642c8ba9659b402c8bdbdedb48651fb94b576e3b3efd1ccb079609b04a", - "sha256:9551f23e09300a9a528f7af20e35c9f79686d46d646152a0c8fc41d2d074d9b0", - "sha256:9a2b7543559f8a1c9ed72724b549d8cc3515da7daf3e79813a15bdc4a769de25", - "sha256:a55c76254d7cf8d4494bc508e7abb993a82a192d0db4552421e5139235604625", - "sha256:ad8f41c2357b73bc9e8606d2fa226233bf4d55d85a8982ecdfd55823a6959995", - "sha256:af4868da7dd53296cd7630687161d53a7ebe2e63814234631445697bd7c29f46", - "sha256:afebfc3dd3520d37056f641969ce320b071bc7a0800639c71877b90d053e087f", - "sha256:b59aa298137ca74a744c1e6e22cfc0bf9dca3a2f41f51bc92eb05695155d905a", - "sha256:bc00d1210567a4cdd215ac6e17dc00cb9893ee521cee701adfd0fa43f7c73139", - "sha256:c1cb29b1fced01f97e6d5631c3edc2dadb424d1f4421dad079cb13fc97acb42f", - "sha256:c94dc64b1a389a416fc4218cd4799aa3756f25940cae33530a4f7f2f54f166da", - "sha256:ceaa28a5bce8a46a130cd223e895080e258a88d51bf6e8de2fc54a6ef7e38c34", - "sha256:cff6453e25204d3369c47b97dd34783ca820611bd334779d22192da23784194b", - "sha256:d0b64409df09edb4c365d95004775c988259efe9be39697d7315c42b7a5e7e94", - "sha256:d4813b30cb62d3b63ccc60dd12f2121780c7a3068db692daeb90f989877aaf04", - "sha256:da3c55cdc66cfc3fffb607db49a42448785ea2732f055ac1549b69dcb392663b", - "sha256:e058c7656c44fb494a11443191e381355388443d543f6fc1a245d5d238544396", - "sha256:fed0f22bf1313ff79c7fc318f7199d6c2f96d4de3234b2f12a1eab350e597c06", - "sha256:ffd4e4877a78c84d693e491b223385e0271278f5f4e1476a4962dca6824ecfeb" + "sha256:065230b9659ac38c8021fa512802562d122afb0cf8d4b89e257014dcddb5730a", + "sha256:07707ba69324eaf58f0c6f59d289acc3e0ed9ec528dae5b0d4219c0d6da27dc5", + "sha256:10defa88dd10a0a4763f16c1b5504e96ae6dc68953cfe5fc572b4a8fcaf9409b", + "sha256:140eb58809f24d843736edb8080b220417e22c82ac07a3dfa473f57e78216b5f", + "sha256:188f2c78a8ac1eb7a70a4b2b7b9ad11f52181044957bf981fb3e399c719e30ee", + "sha256:1c2688365743b0f190392e674af5e313ebe9d621813d15f9332e874b7c1f2d04", + "sha256:24e413bd845bd17d4d72063d64e053898543fb7abc81afeae13e5c43cef9c171", + "sha256:2b59acd09b02da97728d0bae8ff48876d7efcbbb08e569c55e2d0c2e018324f5", + "sha256:2df15814529a4625ea6f7b354a083609b3944c269b954ece0d0e7455872e1b2a", + "sha256:352c11582aa1e49a2f0f7f7d8fd5ec5311da890d1354287e83c63ab6af857cf5", + "sha256:36b08b886027eac67e7a0e822e3a5bf419429efad7612e69501669d6252a21f2", + "sha256:376023f51edaf7290332dacfb055bc00ce864cb013c0338d0dea48731f37e42f", + "sha256:3ba82f8b421886f4a2311c43fb98faaf36c581976192349fef2a89ed0fcdbdef", + "sha256:3d72aa9e73134dacd049a2d6f9bd219f7be9c004d03d52395831611d66cedb71", + "sha256:40ece8fa730d1a947bff792bcc7824bd02d3ce6105432798e9a04a360c8c07b0", + "sha256:417b7e119d66085dc45bdd563dcb2c575ee10a3b1c492dd3502a029448d4be1c", + "sha256:42b7c7264229860fe879be961877f7466d9f7173bd6427b3ba98144a031d49fb", + "sha256:457d9cfe7ece1571770381edccdad7fc255b12cd7b5b813219441146d4f47595", + "sha256:4a6943816e10028eeed512ea03be52b54ea83108b408d1049b999f58a760089b", + "sha256:5b94df70bd34a3b946c0eb272022fb0f8a9eb27cad76e7f313fedbee2ebe4317", + "sha256:5f5051a13e7d53430a990604b532c9124253c5f348857e2d5106d45fc8533860", + "sha256:5f7f53b1edd4b23fb112b89208377480c0bcee45d43a03ffacf30f3290e0ed85", + "sha256:5fe8c6dcb9e6f7066bdc07d3c410a2fca78c0d0b4e0e72510ffd20a60a20eb8e", + "sha256:71a54815ec0212b0cba23adc1b2a731bdd2df7b9e4432718b2ed20e8aaf7f01a", + "sha256:7332f7b06d42153255f7bfeb10266141c08d48cc1a022a35473c95238ff2aebc", + "sha256:78c6f0ed72b440ebe1892d273c1e5f91e55e6861bea611d3b904e673152a7a4c", + "sha256:7c9b30a2524ae6983b708f12741a31fbc2fb8d6fecd0b6c8584a62fd59f59e09", + "sha256:86fcffc06f1125cb443e2bed812805739d64ceb78597ac3c1b2d439471a09717", + "sha256:87572213965fd8a4fb7a97f837221e01d8fddcfb558363c671b8aa93477fb6a2", + "sha256:8e595de17178dd3bbeb2c5b8ea97536341c63b7278639cb8ee2681a84c0ef037", + "sha256:917f01db71d5e720b731effa3ff4a2c702a1b6dacad9bcdc580d86a018dfc3ca", + "sha256:91cfb43fb91ff6d1e4258be04eee84b51a4ef40a28d899679b9ea2556322fb50", + "sha256:aa86cfdeb118795875855589934013e32895715ec2d9e8eb7a59be3e7e07a7e1", + "sha256:ade09aa3c284d11f39640aebdcbb748e1996f0c60504f8c4a0c5a9fec821e67a", + "sha256:b2a5688606dffbe95e1347a05b77eb90489fe337edde888e23bbb7fd81b0d93b", + "sha256:b92fbc2bc549c5045c8233d954f3260ccf99e0f3ec9edfd2372b74b350917752", + "sha256:c2d5334d935af711f6d6dfeec2d34e071cdf73ec0df8e8bd35ac435b26d8da97", + "sha256:cb0afc3bad49eb89a579103616574a54b523856d20fc539a4f7a513a0a8ba4b2", + "sha256:ce66f730031b9b3683b2fc6ad4160a18db86557c004c3d490a29bf8d450d7ab9", + "sha256:e29b9cea4216ec130df85d8c36efb9985fda1c9039e4706fb30e0fb6a67602ff", + "sha256:e2cc4b68e59319e3de778325e34fbff487bfdb2225530e89995402989898d681", + "sha256:e90d2e219c3dce1500dda95f5b893c293c4d53c4e330c968afbd4e7a90ff4a5b", + "sha256:f13c48cc4363829bdfecc0c181b6ddf28008931de54908a492dc8ccd0066cd60", + "sha256:f550730d18edec4ff9d4252784b62adfe885d4542946b6d5a54c8a6521b56afd", + "sha256:fa843ee0d34c7193f5a816e79df8142faff851549cab31e84b526f04878ac778", + "sha256:fe1c33f78d2060719d52ea9459d97d7ae3a5b707ec02548575c4fbed1d1d345b" ], "index": "pypi", - "version": "==3.17.2" + "version": "==3.17.5" }, "six": { "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], "index": "pypi", - "version": "==1.15.0" + "version": "==1.16.0" }, "tqdm": { "hashes": [ - "sha256:2c44efa73b8914dba7807aefd09653ac63c22b5b4ea34f7a80973f418f1a3089", - "sha256:c23ac707e8e8aabb825e4d91f8e17247f9cc14b0d64dd9e97be0781e9e525bba" + "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", + "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" ], - "version": "==4.58.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.62.3" }, "twine": { "hashes": [ - "sha256:34352fd52ec3b9d29837e6072d5a2a7c6fe4290e97bba46bb8d478b5c598f7ab", - "sha256:ba9ff477b8d6de0c89dd450e70b2185da190514e91c42cc62f96850025c10472" + "sha256:087328e9bb405e7ce18527a2dca4042a84c7918658f951110b38bc135acab218", + "sha256:4caec0f1ed78dc4c9b83ad537e453d03ce485725f2aea57f1bb3fdde78dae936" ], "index": "pypi", - "version": "==3.2.0" - }, - "typing-extensions": { - "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" - ], - "version": "==3.7.4.3" + "version": "==3.4.2" }, "urllib3": { "hashes": [ - "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2", - "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e" + "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", + "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" ], - "version": "==1.25.11" + "index": "pypi", + "version": "==1.26.7" }, "webencodings": { "hashes": [ @@ -527,47 +365,13 @@ ], "version": "==0.5.1" }, - "yarl": { - "hashes": [ - "sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e", - "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434", - "sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366", - "sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3", - "sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec", - "sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959", - "sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e", - "sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c", - "sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6", - "sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a", - "sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6", - "sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424", - "sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e", - "sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f", - "sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50", - "sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2", - "sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc", - "sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4", - "sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970", - "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10", - "sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0", - "sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406", - "sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896", - "sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643", - "sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721", - "sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478", - "sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724", - "sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e", - "sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8", - "sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96", - "sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25", - "sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76", - "sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2", - "sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2", - "sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c", - "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a", - "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71" - ], - "version": "==1.6.3" + "zipp": { + "hashes": [ + "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", + "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" + ], + "markers": "python_version >= '3.6'", + "version": "==3.6.0" } }, "develop": {} diff --git a/setup.py b/setup.py index 5a9a8930..105caaba 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,6 @@ def read(*parts): 'setuptools', 'intuit-oauth==1.2.4', 'rauth>=0.7.3', - 'authclient', 'requests>=2.26.0', 'simplejson>=3.17.0', 'six>=1.14.0', diff --git a/tests/integration/test_invoice.py b/tests/integration/test_invoice.py index e0b5a197..8ba724d0 100644 --- a/tests/integration/test_invoice.py +++ b/tests/integration/test_invoice.py @@ -7,6 +7,24 @@ class InvoiceTest(QuickbooksTestCase): + def test_query_by_customer_ref(self): + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + invoice = Invoice.query( + "select * from Invoice where CustomerRef = '{0}'".format(customer.Id), qb=self.qb_client) + + print(invoice[0].Line[0].LineNum) + print(invoice[0].Line[0].Amount) + self.assertEquals(invoice[0].CustomerRef.name, customer.DisplayName) + + def test_where(self): + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + + invoice = Invoice.where( + "CustomerRef = '{0}'".format(customer.Id), qb=self.qb_client) + + print(invoice[0]) + self.assertEquals(invoice[0].CustomerRef.name, customer.DisplayName) + def test_create(self): invoice = Invoice() From 978c2c27e43cd0ff98ec2a55ff36a1c3569c9b04 Mon Sep 17 00:00:00 2001 From: Kshitij Grover Date: Mon, 8 Nov 2021 21:53:35 -0800 Subject: [PATCH 021/154] allow passing in request_id for create, update, and delete requests --- quickbooks/client.py | 17 +++++++++------ quickbooks/mixins.py | 15 +++++++------ tests/integration/test_invoice.py | 36 +++++++++++++------------------ tests/unit/test_client.py | 10 +++++++++ 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index 0a02921f..91751cce 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -164,12 +164,15 @@ def change_data_capture(self, entity_string, changed_since): return result def make_request(self, request_type, url, request_body=None, content_type='application/json', - params=None, file_path=None): + params=None, file_path=None, request_id=None): if not params: params = {} if self.minorversion: params['minorversion'] = self.minorversion + + if request_id: + params['requestid'] = request_id if not request_body: request_body = {} @@ -291,11 +294,11 @@ def handle_exceptions(results): else: raise exceptions.QuickbooksException(message, code, detail) - def create_object(self, qbbo, request_body, _file_path=None): + def create_object(self, qbbo, request_body, _file_path=None, request_id=None): self.isvalid_object_name(qbbo) url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - results = self.post(url, request_body, file_path=_file_path) + results = self.post(url, request_body, file_path=_file_path, request_id=request_id) return results @@ -311,15 +314,15 @@ def isvalid_object_name(self, object_name): return True - def update_object(self, qbbo, request_body, _file_path=None): + def update_object(self, qbbo, request_body, _file_path=None, request_id=None): url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - result = self.post(url, request_body, file_path=_file_path) + result = self.post(url, request_body, file_path=_file_path, request_id=request_id) return result - def delete_object(self, qbbo, request_body, _file_path=None): + def delete_object(self, qbbo, request_body, _file_path=None, request_id=None): url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - result = self.post(url, request_body, params={'operation': 'delete'}, file_path=_file_path) + result = self.post(url, request_body, params={'operation': 'delete'}, file_path=_file_path, request_id=request_id) return result diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 2738ad5b..7a17de8d 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -1,4 +1,5 @@ from future.moves.urllib.parse import quote +from requests.api import request try: import simplejson as json except ImportError: import json @@ -148,14 +149,14 @@ class UpdateMixin(object): qbo_object_name = "" qbo_json_object_name = "" - def save(self, qb=None): + def save(self, qb=None, request_id=None): if not qb: qb = QuickBooks() if self.Id and int(self.Id) > 0: - json_data = qb.update_object(self.qbo_object_name, self.to_json()) + json_data = qb.update_object(self.qbo_object_name, self.to_json(), request_id=request_id) else: - json_data = qb.create_object(self.qbo_object_name, self.to_json()) + json_data = qb.create_object(self.qbo_object_name, self.to_json(), request_id=request_id) if self.qbo_json_object_name != '': obj = type(self).from_json(json_data[self.qbo_json_object_name]) @@ -170,11 +171,11 @@ class UpdateNoIdMixin(object): qbo_object_name = "" qbo_json_object_name = "" - def save(self, qb=None): + def save(self, qb=None, request_id=None): if not qb: qb = QuickBooks() - json_data = qb.update_object(self.qbo_object_name, self.to_json()) + json_data = qb.update_object(self.qbo_object_name, self.to_json(), request_id=request_id) obj = type(self).from_json(json_data[self.qbo_object_name]) return obj @@ -182,7 +183,7 @@ def save(self, qb=None): class DeleteMixin(object): qbo_object_name = "" - def delete(self, qb=None): + def delete(self, qb=None, request_id=None): if not qb: qb = QuickBooks() @@ -193,7 +194,7 @@ def delete(self, qb=None): 'Id': self.Id, 'SyncToken': self.SyncToken, } - return qb.delete_object(self.qbo_object_name, json.dumps(data)) + return qb.delete_object(self.qbo_object_name, json.dumps(data), request_id=request_id) class ListMixin(object): diff --git a/tests/integration/test_invoice.py b/tests/integration/test_invoice.py index e0b5a197..b134c21d 100644 --- a/tests/integration/test_invoice.py +++ b/tests/integration/test_invoice.py @@ -4,10 +4,11 @@ from quickbooks.objects.invoice import Invoice from quickbooks.objects.item import Item from tests.integration.test_base import QuickbooksTestCase - +import uuid class InvoiceTest(QuickbooksTestCase): - def test_create(self): + + def create_invoice(self, request_id=None): invoice = Invoice() line = SalesItemLine() @@ -25,35 +26,28 @@ def test_create(self): invoice.CustomerMemo = CustomerMemo() invoice.CustomerMemo.value = "Customer Memo" - invoice.save(qb=self.qb_client) + invoice.save(qb=self.qb_client, request_id=request_id) + def test_create(self): + invoice = self.create_invoice() query_invoice = Invoice.get(invoice.Id, qb=self.qb_client) self.assertEquals(query_invoice.CustomerRef.name, customer.DisplayName) self.assertEquals(query_invoice.CustomerMemo.value, "Customer Memo") self.assertEquals(query_invoice.Line[0].Description, "description") self.assertEquals(query_invoice.Line[0].Amount, 100.0) + + def test_create_idempotence(self): + sample_request_id = str(uuid.uuid4()) + invoice = self.create_invoice(request_id=sample_request_id) + duplicate_invoice = self.create_invoice(request_id=sample_request_id) + + # Assert that both returned invoices have the same id + self.assertEquals(invoice.Id, duplicate_invoice.Id) def test_delete(self): # First create an invoice - invoice = Invoice() - - line = SalesItemLine() - line.LineNum = 1 - line.Description = "description" - line.Amount = 100 - line.SalesItemLineDetail = SalesItemLineDetail() - item = Item.all(max_results=1, qb=self.qb_client)[0] - - line.SalesItemLineDetail.ItemRef = item.to_ref() - invoice.Line.append(line) - - customer = Customer.all(max_results=1, qb=self.qb_client)[0] - invoice.CustomerRef = customer.to_ref() - - invoice.CustomerMemo = CustomerMemo() - invoice.CustomerMemo.value = "Customer Memo" - invoice.save(qb=self.qb_client) + invoice = self.create_invoice() # Then delete invoice_id = invoice.Id diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 69547366..8fc77058 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -117,6 +117,15 @@ def test_update_object(self, post): self.assertTrue(post.called) + @patch('quickbooks.client.QuickBooks.make_request') + def test_update_object_with_request_id(self, make_req): + qb_client = client.QuickBooks() + qb_client.company_id = "1234" + qb_client.update_object("Customer", "request_body", request_id="123") + + url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/customer" + make_req.assert_called_with("POST", url, request_id="123") + @patch('quickbooks.client.QuickBooks.get') def test_get_current_user(self, get): qb_client = client.QuickBooks() @@ -163,6 +172,7 @@ def test_make_request(self, process_request): "GET", url, data={}, headers={'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': 'python-quickbooks V3 library'}, params={}) + def test_handle_exceptions(self): qb_client = client.QuickBooks() error_data = { From 7a3e96041dd391fd900a112a96380f4b8ce3c8a6 Mon Sep 17 00:00:00 2001 From: Kshitij Grover Date: Thu, 11 Nov 2021 14:58:42 -0800 Subject: [PATCH 022/154] Fix unit tests --- tests/integration/test_invoice.py | 15 +++++++++------ tests/unit/test_client.py | 2 +- tests/unit/test_mixins.py | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/integration/test_invoice.py b/tests/integration/test_invoice.py index b134c21d..8e05dd56 100644 --- a/tests/integration/test_invoice.py +++ b/tests/integration/test_invoice.py @@ -8,7 +8,7 @@ class InvoiceTest(QuickbooksTestCase): - def create_invoice(self, request_id=None): + def create_invoice(self, customer, request_id=None): invoice = Invoice() line = SalesItemLine() @@ -21,15 +21,16 @@ def create_invoice(self, request_id=None): line.SalesItemLineDetail.ItemRef = item.to_ref() invoice.Line.append(line) - customer = Customer.all(max_results=1, qb=self.qb_client)[0] invoice.CustomerRef = customer.to_ref() invoice.CustomerMemo = CustomerMemo() invoice.CustomerMemo.value = "Customer Memo" invoice.save(qb=self.qb_client, request_id=request_id) + return invoice def test_create(self): - invoice = self.create_invoice() + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + invoice = self.create_invoice(customer) query_invoice = Invoice.get(invoice.Id, qb=self.qb_client) self.assertEquals(query_invoice.CustomerRef.name, customer.DisplayName) @@ -38,16 +39,18 @@ def test_create(self): self.assertEquals(query_invoice.Line[0].Amount, 100.0) def test_create_idempotence(self): + customer = Customer.all(max_results=1, qb=self.qb_client)[0] sample_request_id = str(uuid.uuid4()) - invoice = self.create_invoice(request_id=sample_request_id) - duplicate_invoice = self.create_invoice(request_id=sample_request_id) + invoice = self.create_invoice(customer, request_id=sample_request_id) + duplicate_invoice = self.create_invoice(customer, request_id=sample_request_id) # Assert that both returned invoices have the same id self.assertEquals(invoice.Id, duplicate_invoice.Id) def test_delete(self): + customer = Customer.all(max_results=1, qb=self.qb_client)[0] # First create an invoice - invoice = self.create_invoice() + invoice = self.create_invoice(customer) # Then delete invoice_id = invoice.Id diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 8fc77058..3ec7f397 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -124,7 +124,7 @@ def test_update_object_with_request_id(self, make_req): qb_client.update_object("Customer", "request_body", request_id="123") url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/customer" - make_req.assert_called_with("POST", url, request_id="123") + make_req.assert_called_with("POST", url, "request_body", file_path = None, request_id="123") @patch('quickbooks.client.QuickBooks.get') def test_get_current_user(self, get): diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index 42765538..9a61afe1 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -227,7 +227,7 @@ class UpdateMixinTest(QuickbooksUnitTestCase): def test_save_create(self, create_object): department = Department() department.save(qb=self.qb_client) - create_object.assert_called_once_with("Department", department.to_json()) + create_object.assert_called_once_with("Department", department.to_json(), request_id=None) def test_save_create_with_qb(self): with patch.object(self.qb_client, 'create_object') as create_object: @@ -242,7 +242,7 @@ def test_save_update(self, update_object): json = department.to_json() department.save(qb=self.qb_client) - update_object.assert_called_once_with("Department", json) + update_object.assert_called_once_with("Department", json, request_id=None) def test_save_update_with_qb(self): with patch.object(self.qb_client, 'update_object') as update_object: From 53a146085157ac40ac9818c400c9448ce9c5195d Mon Sep 17 00:00:00 2001 From: Kshitij Grover Date: Thu, 11 Nov 2021 15:02:21 -0800 Subject: [PATCH 023/154] Remove unused import --- quickbooks/mixins.py | 1 - 1 file changed, 1 deletion(-) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 7a17de8d..0cda656c 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -1,5 +1,4 @@ from future.moves.urllib.parse import quote -from requests.api import request try: import simplejson as json except ImportError: import json From ad18e9b5b4cb0d7c2358a6726e135dcf5a57b751 Mon Sep 17 00:00:00 2001 From: varun-bheemaiah Date: Wed, 24 Nov 2021 16:32:10 +0530 Subject: [PATCH 024/154] Added more detailed messages in case of an exception --- quickbooks/exceptions.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/quickbooks/exceptions.py b/quickbooks/exceptions.py index 1469e550..60b636b8 100644 --- a/quickbooks/exceptions.py +++ b/quickbooks/exceptions.py @@ -21,33 +21,38 @@ class UnsupportedException(QuickbooksException): """ Quickbooks Error Codes from 500 to 599 """ - pass + def __str__(self): + return "QB Unsupported Exception: " + self.message + " \n\n" + self.detail class GeneralException(QuickbooksException): """ Quickbooks Error Codes from 600 to 1999 """ - pass + def __str__(self): + return "QB General Exception: " + self.message + " \n\n" + self.detail class ValidationException(QuickbooksException): """ Quickbooks Error Codes from 2000 to 4999 """ - pass + def __str__(self): + return "QB Validation Exception: " + self.message + " \n\n" + self.detail class SevereException(QuickbooksException): """ Quickbooks Error Codes greater than 10000 """ - pass + def __str__(self): + return "QB Severe Exception: " + self.message + " \n\n" + self.detail class ObjectNotFoundException(QuickbooksException): """ Quickbooks Error Code 610 """ - pass + def __str__(self): + return "QB Object Not Found Exception: " + self.message + " \n\n" + self.detail From c82935bd07d9901d0e8d10765a7fcb06ad2ef53d Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 30 Nov 2021 10:40:45 -0600 Subject: [PATCH 025/154] Updated change log --- CHANGELOG.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9ff87dfd..10d7e8c3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,9 +1,13 @@ Changelog ========= -* 0.9.1 (July ??, 2021) +* 0.9.1 (November 30, 2021) * Added response status code when raising unauthorized exceptions * Added pending deprecation warnings to enable_global and disable_global + * Added more detailed messages in raised exceptions + * Added void method to Payment object + * Added option for invoice link + * Added support for idempotent behavior using Request ID parameter * 0.9.0 (July 20, 2021) * Added missing TxnDate to Invoice From 28888cb70312cb1efb9e41639438cbcbbf5ef4c2 Mon Sep 17 00:00:00 2001 From: ej2 Date: Tue, 30 Nov 2021 10:56:23 -0600 Subject: [PATCH 026/154] Fixed issue with AccountBasedExpenseLineDetail in detaillne.py --- quickbooks/objects/detailline.py | 1 + 1 file changed, 1 insertion(+) diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index 2959fcaa..c12b31e1 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -183,6 +183,7 @@ def __init__(self): self.CustomerRef = None self.AccountRef = None self.TaxCodeRef = None + self.ClassRef = None def __str__(self): return self.BillableStatus From f5459a07619ae220e24099c6e0c8e8db890bb66b Mon Sep 17 00:00:00 2001 From: varun-bheemaiah Date: Tue, 28 Dec 2021 21:02:27 +0530 Subject: [PATCH 027/154] Added error code to exception message and implemented a dict function --- quickbooks/exceptions.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/quickbooks/exceptions.py b/quickbooks/exceptions.py index 60b636b8..b002c4f0 100644 --- a/quickbooks/exceptions.py +++ b/quickbooks/exceptions.py @@ -7,14 +7,19 @@ def __init__(self, message, error_code=0, detail=""): self.error_code = error_code self.detail = detail self.message = message - + def __str__(self) -> str: + return f"QB Exception {self.error_code}: {self.message}\n{self.detail}" + def __iter__(self): + yield "error_code", self.error_code + yield "detail", self.detail + yield "message", self.message class AuthorizationException(QuickbooksException): """ Quickbooks Error Codes from 1 to 499 """ def __str__(self): - return "QB Auth Exception: " + self.message + " \n\n" + self.detail + return f"QB Auth Exception {self.error_code}: {self.message}\n{self.detail}" class UnsupportedException(QuickbooksException): @@ -22,7 +27,7 @@ class UnsupportedException(QuickbooksException): Quickbooks Error Codes from 500 to 599 """ def __str__(self): - return "QB Unsupported Exception: " + self.message + " \n\n" + self.detail + return f"QB Unsupported Exception {self.error_code}: {self.message}\n{self.detail}" class GeneralException(QuickbooksException): @@ -30,7 +35,7 @@ class GeneralException(QuickbooksException): Quickbooks Error Codes from 600 to 1999 """ def __str__(self): - return "QB General Exception: " + self.message + " \n\n" + self.detail + return f"QB General Exception {self.error_code}: {self.message}\n{self.detail}" class ValidationException(QuickbooksException): @@ -38,7 +43,7 @@ class ValidationException(QuickbooksException): Quickbooks Error Codes from 2000 to 4999 """ def __str__(self): - return "QB Validation Exception: " + self.message + " \n\n" + self.detail + return f"QB Validation Exception {self.error_code}: {self.message}\n{self.detail}" class SevereException(QuickbooksException): @@ -46,7 +51,7 @@ class SevereException(QuickbooksException): Quickbooks Error Codes greater than 10000 """ def __str__(self): - return "QB Severe Exception: " + self.message + " \n\n" + self.detail + return f"QB Severe Exception {self.error_code}: {self.message}\n{self.detail}" class ObjectNotFoundException(QuickbooksException): @@ -54,5 +59,5 @@ class ObjectNotFoundException(QuickbooksException): Quickbooks Error Code 610 """ def __str__(self): - return "QB Object Not Found Exception: " + self.message + " \n\n" + self.detail + return f"QB Object Not Found Exception {self.error_code}: {self.message}\n{self.detail}" From e4088acb0ed964dbfe9d8e1720838b67f5e3f11d Mon Sep 17 00:00:00 2001 From: Anurag Kumar Date: Wed, 5 Jan 2022 22:56:04 +0530 Subject: [PATCH 028/154] updated classifiers added support for python 3.9 and 3.10 --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 105caaba..bb0b5d45 100644 --- a/setup.py +++ b/setup.py @@ -50,6 +50,8 @@ def read(*parts): 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', ], packages=find_packages(), ) From cadce434af56972dadbc5cbca8e957ce2ba318e8 Mon Sep 17 00:00:00 2001 From: "Jared M. Smith" Date: Sun, 16 Jan 2022 01:02:13 -0500 Subject: [PATCH 029/154] Add ClassRef Initialization for AccountBasedExpenseDetailLine --- quickbooks/objects/detailline.py | 1 + 1 file changed, 1 insertion(+) diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index 2959fcaa..c12b31e1 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -183,6 +183,7 @@ def __init__(self): self.CustomerRef = None self.AccountRef = None self.TaxCodeRef = None + self.ClassRef = None def __str__(self): return self.BillableStatus From c4914bcafe06c4db548779c2bfaaf79c8608d189 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Tue, 25 Jan 2022 19:15:04 -0500 Subject: [PATCH 030/154] chore(deps): remove unused pycparser The pin to `pycparser==2.18` was brought about when the package was still supporting Python 2.6. See https://github.com/ej2/python-quickbooks/pull/126 Python 2.6 (and 2.7) support were dropped in versions 0.7.5 and 0.8.1 respectively. (from `CHANGELOG.rst`) The `authlib` library that depended on `pycparser` was removed in version 0.9.1 See https://github.com/ej2/python-quickbooks/pull/258 We can now safely remove `pycparser` from the project scope, and thus any other dependencies that rely on `pycparser` can now advance past version 2.18 without conflict. --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 105caaba..f6403a11 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,6 @@ def read(*parts): 'simplejson>=3.17.0', 'six>=1.14.0', 'python-dateutil', - 'pycparser==2.18' ], classifiers=[ From cf720aeef8d52f7dde20bbe3a245a5dfb066ba3c Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Wed, 3 Aug 2022 12:41:06 +0200 Subject: [PATCH 031/154] Add LinkedTxnMixin Payments --- quickbooks/objects/payment.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index ccaa9a90..f38334d3 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -1,6 +1,7 @@ from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, LinkedTxn, \ - QuickbooksManagedObject, QuickbooksTransactionEntity + QuickbooksManagedObject, QuickbooksTransactionEntity \ + LinkedTxnMixin from ..client import QuickBooks from .creditcardpayment import CreditCardPayment from ..mixins import DeleteMixin @@ -23,7 +24,7 @@ def __str__(self): @python_2_unicode_compatible -class Payment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity): +class Payment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: A Payment entity records a payment in QuickBooks. The payment can be applied for a particular customer against multiple Invoices and Credit Memos. It can also From 358375c4494b57682683b1329a4cd77fb4970d16 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Wed, 3 Aug 2022 12:47:11 +0200 Subject: [PATCH 032/154] fix lint --- quickbooks/objects/payment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index f38334d3..fe58b1bf 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -1,6 +1,6 @@ from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, LinkedTxn, \ - QuickbooksManagedObject, QuickbooksTransactionEntity \ + QuickbooksManagedObject, QuickbooksTransactionEntity, \ LinkedTxnMixin from ..client import QuickBooks from .creditcardpayment import CreditCardPayment From 90325db3af0d70e54ac6867048852b3be295d5db Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 08:27:40 -0500 Subject: [PATCH 033/154] Added new fields to CreditCardPayment object --- CHANGELOG.rst | 4 ++++ quickbooks/objects/creditcardpayment_entity.py | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 10d7e8c3..7f022a27 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,10 @@ Changelog ========= +* 0.9.2 (August ??, 2022) + * Removed pycparser dependency + * Added new fields to CreditCardPayment object + * 0.9.1 (November 30, 2021) * Added response status code when raising unauthorized exceptions * Added pending deprecation warnings to enable_global and disable_global diff --git a/quickbooks/objects/creditcardpayment_entity.py b/quickbooks/objects/creditcardpayment_entity.py index d7b83a93..7d62ded5 100644 --- a/quickbooks/objects/creditcardpayment_entity.py +++ b/quickbooks/objects/creditcardpayment_entity.py @@ -1,5 +1,5 @@ from six import python_2_unicode_compatible -from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin +from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, MetaData from ..mixins import DeleteMixin @@ -17,6 +17,8 @@ class CreditCardPayment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransact class_dict = { "BankAccountRef": Ref, "CreditCardAccountRef": Ref, + "VendorRef": Ref, + "MetaData": MetaData, } qbo_object_name = "CreditCardPayment" @@ -27,9 +29,14 @@ def __init__(self): self.TxnDate = None self.Amount = 0 self.PrivateNote = None + self.Memo = None + self.PrintStatus = None + self.CheckNum = None self.BankAccountRef = None self.CreditCardAccountRef = None + self.VendorRef = None + self.MetaData = None def __str__(self): return str(self.Amount) From b9fdda6e84a82c052b9bdbd01e7f2593d1bcd07e Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 11:34:04 -0500 Subject: [PATCH 034/154] Added new fields to Invoice object --- CHANGELOG.rst | 1 + quickbooks/objects/invoice.py | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7f022a27..3d06911c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,7 @@ Changelog * 0.9.2 (August ??, 2022) * Removed pycparser dependency * Added new fields to CreditCardPayment object + * Added new fields to Invoice object * 0.9.1 (November 30, 2021) * Added response status code when raising unauthorized exceptions diff --git a/quickbooks/objects/invoice.py b/quickbooks/objects/invoice.py index c4ce710e..166ba499 100644 --- a/quickbooks/objects/invoice.py +++ b/quickbooks/objects/invoice.py @@ -1,6 +1,6 @@ from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, CustomField, Address, EmailAddress, CustomerMemo, QuickbooksManagedObject, \ - QuickbooksTransactionEntity, LinkedTxn, LinkedTxnMixin + QuickbooksTransactionEntity, LinkedTxn, LinkedTxnMixin, MetaData from .tax import TxnTaxDetail from .detailline import DetailLine, SalesItemLine, SubtotalLine, DiscountLine, GroupLine, DescriptionOnlyLine from ..mixins import QuickbooksPdfDownloadable, DeleteMixin, SendMixin, VoidMixin @@ -33,8 +33,13 @@ class Invoice(DeleteMixin, QuickbooksPdfDownloadable, QuickbooksManagedObject, Q "ShipAddr": Address, "TxnTaxDetail": TxnTaxDetail, "BillEmail": EmailAddress, + "BillEmailCc": EmailAddress, + "BillEmailBcc": EmailAddress, "CustomerMemo": CustomerMemo, - "DeliveryInfo": DeliveryInfo + "DeliveryInfo": DeliveryInfo, + "RecurDataRef": Ref, + "TaxExemptionRef": Ref, + "MetaData": MetaData } list_dict = { @@ -74,18 +79,26 @@ def __init__(self): self.ExchangeRate = 1 self.GlobalTaxCalculation = "TaxExcluded" self.InvoiceLink = "" + self.HomeBalance = 0 + self.HomeTotalAmt = 0 + self.FreeFormAddress = False self.EInvoiceStatus = None self.BillAddr = None self.ShipAddr = None self.BillEmail = None + self.BillEmailCc = None + self.BillEmailBcc = None self.CustomerRef = None self.CurrencyRef = None self.CustomerMemo = None self.DepartmentRef = None self.TxnTaxDetail = None self.DeliveryInfo = None + self.RecurDataRef = None + self.TaxExemptionRef = None + self.MetaData = None self.CustomField = [] self.Line = [] From e7c3f02cd597db6b9461ba40bd76eedd0e72bf95 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 11:44:20 -0500 Subject: [PATCH 035/154] Added new fields to Payment object --- CHANGELOG.rst | 2 ++ quickbooks/objects/payment.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3d06911c..9307e2a2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,8 @@ Changelog * Removed pycparser dependency * Added new fields to CreditCardPayment object * Added new fields to Invoice object + * Added new fields to Payment object + * Fixed issue with Paymentline LinkedTxn * 0.9.1 (November 30, 2021) * Added response status code when raising unauthorized exceptions diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index ccaa9a90..f0bbdf48 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -49,6 +49,8 @@ class Payment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity) "DepositToAccountRef": Ref, "CurrencyRef": Ref, "CreditCardPayment": CreditCardPayment, + "TaxExemptionRef": Ref, + "MetaData": MetaData } list_dict = { @@ -74,6 +76,8 @@ def __init__(self): self.CurrencyRef = None # Readonly self.PaymentMethodRef = None self.DepositToAccountRef = None + self.TaxExemptionRef = None + self.MetaData = None self.Line = [] # These fields are for minor version 4 From eaa7274eb22f9b9acafcb4d3fdeb30b1ab6d245f Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 12:17:32 -0500 Subject: [PATCH 036/154] Added new object CustomerType --- CHANGELOG.rst | 2 ++ quickbooks/client.py | 2 +- quickbooks/objects/customertype.py | 28 +++++++++++++++++++++++++ tests/unit/objects/test_customertype.py | 19 +++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 quickbooks/objects/customertype.py create mode 100644 tests/unit/objects/test_customertype.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9307e2a2..8182add7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,8 @@ Changelog * Added new fields to Invoice object * Added new fields to Payment object * Fixed issue with Paymentline LinkedTxn + * Added new object CustomerType + * 0.9.1 (November 30, 2021) * Added response status code when raising unauthorized exceptions diff --git a/quickbooks/client.py b/quickbooks/client.py index dd7da2e8..7e4ae291 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -47,7 +47,7 @@ class QuickBooks(object): _BUSINESS_OBJECTS = [ "Account", "Attachable", "Bill", "BillPayment", - "Class", "CreditMemo", "Customer", "CompanyCurrency", + "Class", "CreditMemo", "Customer", "CustomerType", "CompanyCurrency", "Department", "Deposit", "Employee", "Estimate", "ExchangeRate", "Invoice", "Item", "JournalEntry", "Payment", "PaymentMethod", "Preferences", "Purchase", "PurchaseOrder", "RefundReceipt", diff --git a/quickbooks/objects/customertype.py b/quickbooks/objects/customertype.py new file mode 100644 index 00000000..f45bcc2f --- /dev/null +++ b/quickbooks/objects/customertype.py @@ -0,0 +1,28 @@ +from six import python_2_unicode_compatible +from .base import Address, PhoneNumber, EmailAddress, WebAddress, MetaData, QuickbooksReadOnlyObject, \ + QuickbooksTransactionEntity + + +@python_2_unicode_compatible +class CustomerType(QuickbooksReadOnlyObject, QuickbooksTransactionEntity): + """ + QBO definition: Customer types allow categorizing customers in ways that are meaningful to the business. + For example, one could set up customer types so that they indicate which industry a customer represents, + a customer's geographic location, or how a customer first heard about the business. The categorization + then can be used for reporting or mailings. + """ + + class_dict = { + "MetaData": MetaData + } + + qbo_object_name = "CustomerType" + + def __init__(self): + super(CustomerType, self).__init__() + self.Name = "" + self.Active = False + self.MetaData = None + + def __str__(self): + return self.Name diff --git a/tests/unit/objects/test_customertype.py b/tests/unit/objects/test_customertype.py new file mode 100644 index 00000000..ec845373 --- /dev/null +++ b/tests/unit/objects/test_customertype.py @@ -0,0 +1,19 @@ +import unittest + +from quickbooks import QuickBooks +from quickbooks.objects.customerType import CustomerType + + +class CustomerTypeTests(unittest.TestCase): + def test_unicode(self): + customer_type = CustomerType() + customer_type.Name = "test" + + self.assertEquals(str(customer_type), "test") + + def test_valid_object_name(self): + obj = CustomerType() + client = QuickBooks() + result = client.isvalid_object_name(obj.qbo_object_name) + + self.assertTrue(result) From 192aee62c61f3ac2621b31ebd7d7d89ebc245d75 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 12:25:50 -0500 Subject: [PATCH 037/154] Updated CompanyInfo object --- CHANGELOG.rst | 2 ++ quickbooks/objects/company_info.py | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8182add7..f06e9fcb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,8 @@ Changelog * Added new fields to Payment object * Fixed issue with Paymentline LinkedTxn * Added new object CustomerType + * Added MetaData to CompanyInfo + * Added update support to CompanyInfo * 0.9.1 (November 30, 2021) diff --git a/quickbooks/objects/company_info.py b/quickbooks/objects/company_info.py index 8f6027da..23194315 100644 --- a/quickbooks/objects/company_info.py +++ b/quickbooks/objects/company_info.py @@ -1,10 +1,10 @@ from six import python_2_unicode_compatible from .base import Address, PhoneNumber, EmailAddress, WebAddress, \ - QuickbooksReadOnlyObject, Ref + QuickbooksManagedObject, Ref, MetaData @python_2_unicode_compatible -class CompanyInfo(QuickbooksReadOnlyObject): +class CompanyInfo(QuickbooksManagedObject): """ QBO definition: The CompanyInfo entity contains basic company information. In QuickBooks Online, company info and preferences are displayed in the @@ -21,7 +21,8 @@ class CompanyInfo(QuickbooksReadOnlyObject): "LegalAddr": Address, "PrimaryPhone": PhoneNumber, "Email": EmailAddress, - "WebAddr": WebAddress + "WebAddr": WebAddress, + "MetaData": MetaData } qbo_object_name = "CompanyInfo" @@ -43,6 +44,7 @@ def __init__(self): self.PrimaryPhone = None self.Email = None self.WebAddr = None + self.MetaData = None def __str__(self): return self.CompanyName From 05c10cb02387687ce4bb87544d09f36b9ab0a3fe Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 12:59:11 -0500 Subject: [PATCH 038/154] Added new fields to Preferences object --- CHANGELOG.rst | 4 ++-- quickbooks/objects/preferences.py | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f06e9fcb..61239a5b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,11 +6,11 @@ Changelog * Added new fields to CreditCardPayment object * Added new fields to Invoice object * Added new fields to Payment object - * Fixed issue with Paymentline LinkedTxn + * Added to_linked_txn method to Payment object * Added new object CustomerType * Added MetaData to CompanyInfo * Added update support to CompanyInfo - + * Added new fields to Preferences object * 0.9.1 (November 30, 2021) * Added response status code when raising unauthorized exceptions diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py index c13a4150..6fbe971c 100644 --- a/quickbooks/objects/preferences.py +++ b/quickbooks/objects/preferences.py @@ -1,7 +1,7 @@ from six import python_2_unicode_compatible from quickbooks.mixins import PrefMixin, UpdateNoIdMixin -from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, Ref +from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, Ref, EmailAddress @python_2_unicode_compatible @@ -56,6 +56,8 @@ def __init__(self): self.ForPurchase = True self.QuantityOnHand = True self.ForSales = True + self.RevenueRecognitionEnabled = True + self.RecognitionFrequencyType = True class ReportPrefs(QuickbooksBaseObject): @@ -93,6 +95,8 @@ def __init__(self): class SalesFormsPrefs(QuickbooksBaseObject): class_dict = { "DefaultTerms": Ref, + "SalesEmailBcc": EmailAddress, + "SalesEmailCc": EmailAddress } detail_dict = { "CustomField": PreferencesCustomFieldGroup @@ -111,6 +115,7 @@ def __init__(self): self.DefaultTerms = None self.AllowDiscount = True self.DefaultDiscountAccount = "" + self.DefaultShippingAccount = False self.AllowDeposit = True self.AutoApplyPayments = True self.IPNSupportEnabled = False @@ -118,12 +123,20 @@ def __init__(self): self.CustomField = None self.UsingPriceLevels = False self.ETransactionAttachPDF = False + self.UsingProgressInvoicing = False + self.EstimateMessage = "" self.DefaultTerms = None self.CustomField = None + self.SalesEmailBcc = None + self.SalesEmailCc = None class VendorAndPurchasesPrefs(QuickbooksBaseObject): + class_dict = { + "DefaultTerms": Ref, + "DefaultMarkupAccount": Ref + } detail_dict = { "POCustomField": PreferencesCustomFieldGroup } @@ -132,7 +145,11 @@ def __init__(self): super().__init__() self.BillableExpenseTracking = True self.TrackingByCustomer = True + self.TPAREnabled = True + self.POCustomField = None + self.DefaultMarkupAccount = None + self.DefaultTerms = None class TaxPrefs(QuickbooksBaseObject): @@ -144,6 +161,7 @@ def __init__(self): super().__init__() self.TaxGroupCodeRef = None self.UsingSalesTax = True + self.PartnerTaxEnabled = True class NameValue(QuickbooksBaseObject): @@ -169,6 +187,7 @@ def __init__(self): self.WorkWeekStartDate = "" # e.g. "Monday" self.MarkTimeEntriesBillable = True self.ShowBillRateToAll = False + self.UsingSalesTax = False self.UseServices = True self.BillCustomers = True @@ -181,6 +200,7 @@ class CurrencyPrefs(QuickbooksBaseObject): def __init__(self): super().__init__() self.HomeCurrency = None + self.MultiCurrencyEnabled = False @python_2_unicode_compatible From a721303209bd81492b0e0dd306de7b7e526beedd Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 13:20:58 -0500 Subject: [PATCH 039/154] Change log update --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 61239a5b..32e40e98 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,7 @@ Changelog * Added MetaData to CompanyInfo * Added update support to CompanyInfo * Added new fields to Preferences object + * Improved exception object * 0.9.1 (November 30, 2021) * Added response status code when raising unauthorized exceptions From cce549871b33071a9b8b9f0898554e7b4a9aff4c Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 14:55:31 -0500 Subject: [PATCH 040/154] Updated tests and fixed bugs --- dev_requirements.txt | 4 ++-- quickbooks/objects/payment.py | 2 +- quickbooks/objects/preferences.py | 5 ++--- setup.py | 2 +- tests/integration/test_base.py | 2 +- tests/unit/objects/test_customertype.py | 2 +- tests/unit/test_exception.py | 2 +- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/dev_requirements.txt b/dev_requirements.txt index 65190a33..2becb719 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,4 +1,4 @@ -coverage==4.5.1 -ipdb==0.11 +coverage==6.4.2 +ipdb==0.13.9 mock==2.0.0 nose==1.3.7 \ No newline at end of file diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index a668c1ff..f82ce744 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -1,7 +1,7 @@ from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, LinkedTxn, \ QuickbooksManagedObject, QuickbooksTransactionEntity, \ - LinkedTxnMixin + LinkedTxnMixin, MetaData from ..client import QuickBooks from .creditcardpayment import CreditCardPayment from ..mixins import DeleteMixin diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py index 6fbe971c..d7e7e5bc 100644 --- a/quickbooks/objects/preferences.py +++ b/quickbooks/objects/preferences.py @@ -56,8 +56,8 @@ def __init__(self): self.ForPurchase = True self.QuantityOnHand = True self.ForSales = True - self.RevenueRecognitionEnabled = True - self.RecognitionFrequencyType = True + self.RevenueRecognition = True + self.RevenueRecognitionFrequency = "" class ReportPrefs(QuickbooksBaseObject): @@ -187,7 +187,6 @@ def __init__(self): self.WorkWeekStartDate = "" # e.g. "Monday" self.MarkTimeEntriesBillable = True self.ShowBillRateToAll = False - self.UsingSalesTax = False self.UseServices = True self.BillCustomers = True diff --git a/setup.py b/setup.py index c0de040b..afc330a7 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 1) +VERSION = (0, 9, 2) version = '.'.join(map(str, VERSION)) setup( diff --git a/tests/integration/test_base.py b/tests/integration/test_base.py index 09c27027..9b4b7083 100644 --- a/tests/integration/test_base.py +++ b/tests/integration/test_base.py @@ -17,7 +17,7 @@ def setUp(self): ) self.qb_client = QuickBooks( - minorversion=59, + minorversion=65, auth_client=self.auth_client, refresh_token=os.environ.get('REFRESH_TOKEN'), company_id=os.environ.get('COMPANY_ID'), diff --git a/tests/unit/objects/test_customertype.py b/tests/unit/objects/test_customertype.py index ec845373..a7639c53 100644 --- a/tests/unit/objects/test_customertype.py +++ b/tests/unit/objects/test_customertype.py @@ -1,7 +1,7 @@ import unittest from quickbooks import QuickBooks -from quickbooks.objects.customerType import CustomerType +from quickbooks.objects.customertype import CustomerType class CustomerTypeTests(unittest.TestCase): diff --git a/tests/unit/test_exception.py b/tests/unit/test_exception.py index 25b2fd8a..38fadae3 100644 --- a/tests/unit/test_exception.py +++ b/tests/unit/test_exception.py @@ -17,4 +17,4 @@ class AuthorizationExceptionTests(unittest.TestCase): def test_unicode(self): exception = AuthorizationException("message", detail="detail") - self.assertEquals(str(exception), "QB Auth Exception: message \n\ndetail") + self.assertEquals(str(exception), "QB Auth Exception 0: message\ndetail") From 9a73937802dadead2d0088c04908c12d5501938d Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 15:01:00 -0500 Subject: [PATCH 041/154] Add python 3.9 and 3.10 to travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index fb9de727..b8124441 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ python: - 3.6 - 3.7 - 3.8 + - 3.9 + - 3.10 before_install: - pip install coveralls install: From 28d99eab256542fb6ca18b44d9518584741249da Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Aug 2022 15:05:06 -0500 Subject: [PATCH 042/154] Updated CHANGELOG --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 32e40e98..df92a3f4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,7 @@ Changelog ========= -* 0.9.2 (August ??, 2022) +* 0.9.2 (August 3, 2022) * Removed pycparser dependency * Added new fields to CreditCardPayment object * Added new fields to Invoice object From 355e9a85172362de33178be4bcd4f420379e3f08 Mon Sep 17 00:00:00 2001 From: Chris Nicholls Date: Wed, 30 Nov 2022 19:25:54 -0400 Subject: [PATCH 043/154] Add support for RecurringTransaction --- quickbooks/client.py | 1 + quickbooks/mixins.py | 10 ++ quickbooks/objects/recurringtransaction.py | 132 ++++++++++++++ .../integration/test_recurringtransaction.py | 169 ++++++++++++++++++ .../unit/objects/test_recurringtransaction.py | 12 ++ tests/unit/test_mixins.py | 11 ++ 6 files changed, 335 insertions(+) create mode 100644 quickbooks/objects/recurringtransaction.py create mode 100644 tests/integration/test_recurringtransaction.py create mode 100644 tests/unit/objects/test_recurringtransaction.py diff --git a/quickbooks/client.py b/quickbooks/client.py index 7e4ae291..7b41d9be 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -53,6 +53,7 @@ class QuickBooks(object): "Purchase", "PurchaseOrder", "RefundReceipt", "SalesReceipt", "TaxAgency", "TaxCode", "TaxService/Taxcode", "TaxRate", "Term", "TimeActivity", "Transfer", "Vendor", "VendorCredit", "CreditCardPayment", + "RecurringTransaction" ] __instance = None diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 0cda656c..2b58c28b 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -196,6 +196,16 @@ def delete(self, qb=None, request_id=None): return qb.delete_object(self.qbo_object_name, json.dumps(data), request_id=request_id) +class DeleteNoIdMixin(object): + qbo_object_name = "" + + def delete(self, qb=None, request_id=None): + if not qb: + qb = QuickBooks() + + return qb.delete_object(self.qbo_object_name, self.to_json(), request_id=request_id) + + class ListMixin(object): qbo_object_name = "" qbo_json_object_name = "" diff --git a/quickbooks/objects/recurringtransaction.py b/quickbooks/objects/recurringtransaction.py new file mode 100644 index 00000000..0845d18e --- /dev/null +++ b/quickbooks/objects/recurringtransaction.py @@ -0,0 +1,132 @@ +from six import python_2_unicode_compatible + +from .bill import Bill +from .creditmemo import CreditMemo +from .deposit import Deposit +from .estimate import Estimate +from .invoice import Invoice +from .journalentry import JournalEntry +from .purchase import Purchase +from .purchaseorder import PurchaseOrder +from .refundreceipt import RefundReceipt +from .salesreceipt import SalesReceipt +from .transfer import Transfer +from .vendorcredit import VendorCredit +from .base import Ref, QuickbooksBaseObject +from ..mixins import UpdateNoIdMixin, ListMixin, ReadMixin, DeleteNoIdMixin + +class ScheduleInfo(QuickbooksBaseObject): + def __init__(self): + super(ScheduleInfo, self).__init__() + + self.StartDate = None + self.EndDate = None + self.DaysBefore = None + self.MaxOccurrences = None + + self.RemindDays = None + self.IntervalType = None + self.NumInterval = None + + self.DayOfMonth = None + self.DayOfWeek = None + self.MonthOfYear = None + self.WeekOfMonth = None + + self.NextDate = None + self.PreviousDate = None + + +class RecurringInfo(QuickbooksBaseObject): + class_dict = { + "ScheduleInfo": ScheduleInfo + } + + qbo_object_name = "RecurringInfo" + + def __init__(self): + super(RecurringInfo, self).__init__() + + self.RecurType = "Automated" + self.Name = "" + self.Active = False + + +class Recurring(): + class_dict = { + "RecurringInfo": RecurringInfo, + "RecurDataRef": Ref + } + + +class RecurringBill(Bill): + class_dict = {**Bill.class_dict, **Recurring.class_dict} + + +class RecurringPurchase(Purchase): + class_dict = {**Purchase.class_dict, **Recurring.class_dict} + + +class RecurringCreditMemo(CreditMemo): + class_dict = {**CreditMemo.class_dict, **Recurring.class_dict} + + +class RecurringDeposit(Deposit): + class_dict = {**Deposit.class_dict, **Recurring.class_dict} + + +class RecurringEstimate(Estimate): + class_dict = {**Estimate.class_dict, **Recurring.class_dict} + + +class RecurringInvoice(Invoice): + class_dict = {**Invoice.class_dict, **Recurring.class_dict} + + +class RecurringJournalEntry(JournalEntry): + class_dict = {**JournalEntry.class_dict, **Recurring.class_dict} + + +class RecurringRefundReceipt(RefundReceipt): + class_dict = {**RefundReceipt.class_dict, **Recurring.class_dict} + + +class RecurringSalesReceipt(SalesReceipt): + class_dict = {**SalesReceipt.class_dict, **Recurring.class_dict} + + +class RecurringTransfer(Transfer): + class_dict = {**Transfer.class_dict, **Recurring.class_dict} + + +class RecurringVendorCredit(VendorCredit): + class_dict = {**VendorCredit.class_dict, **Recurring.class_dict} + + +class RecurringPurchaseOrder(PurchaseOrder): + class_dict = {**PurchaseOrder.class_dict, **Recurring.class_dict} + + +@python_2_unicode_compatible +class RecurringTransaction(QuickbooksBaseObject, ReadMixin, UpdateNoIdMixin, ListMixin, DeleteNoIdMixin): + """ + QBO definition: A RecurringTransaction object refers to scheduling creation of transactions, + set up reminders and create transaction template for later use. + This feature is available in QuickBooks Essentials and Plus SKU. + """ + class_dict = { + "Bill": RecurringBill, + "Purchase": RecurringPurchase, + "CreditMemo": RecurringCreditMemo, + "Deposit": RecurringDeposit, + "Estimate": RecurringEstimate, + "Invoice": RecurringInvoice, + "JournalEntry": RecurringJournalEntry, + "RefundReceipt": RecurringRefundReceipt, + "SalesReceipt": RecurringSalesReceipt, + "Transfer": RecurringTransfer, + "VendorCredit": RecurringVendorCredit, + "PurchaseOrder": RecurringPurchaseOrder + } + + qbo_object_name = "RecurringTransaction" \ No newline at end of file diff --git a/tests/integration/test_recurringtransaction.py b/tests/integration/test_recurringtransaction.py new file mode 100644 index 00000000..4dc2d5db --- /dev/null +++ b/tests/integration/test_recurringtransaction.py @@ -0,0 +1,169 @@ +from datetime import datetime, timedelta +from quickbooks.objects.base import Ref +from quickbooks.objects.customer import Customer +from quickbooks.objects.detailline import SalesItemLine, SalesItemLineDetail, AccountBasedExpenseLine, AccountBasedExpenseLineDetail +from quickbooks.objects.recurringtransaction import RecurringTransaction, RecurringInfo, ScheduleInfo, RecurringInvoice, RecurringBill +from quickbooks.objects.item import Item +from quickbooks.objects.vendor import Vendor +from tests.integration.test_base import QuickbooksTestCase + +class RecurringTransactionTest(QuickbooksTestCase): + def setUp(self): + super(RecurringTransactionTest, self).setUp() + self.now = datetime.now() + + def create_recurring_invoice(self, t): + # Regular Invoice stuff except use a RecurringInvoice + line = SalesItemLine() + line.LineNum = 1 + line.Description = "description" + line.Amount = 100 + + line.SalesItemLineDetail = SalesItemLineDetail() + item = Item.all(max_results=1, qb=self.qb_client)[0] + line.SalesItemLineDetail.ItemRef = item.to_ref() + + invoice = RecurringInvoice() + + invoice.Line.append(line) + + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + invoice.CustomerRef = customer.to_ref() + + # Now the recurring bits + info = RecurringInfo() + info.Active = True + info.RecurType = "Automated" + info.Name = "Test Recurring Invoice {}".format(t.strftime('%d%H%M%S')) + + info.ScheduleInfo = ScheduleInfo() + info.ScheduleInfo.StartDate = t.strftime("%Y-%m-%d") + info.ScheduleInfo.MaxOccurrences = 6 + info.ScheduleInfo.IntervalType = "Monthly" + info.ScheduleInfo.DayOfMonth = 1 + info.ScheduleInfo.NumInterval = 1 + invoice.RecurringInfo = info + + rt = RecurringTransaction() + rt.Invoice = invoice + + return rt.save(qb=self.qb_client) + + + def test_create_recurring_invoice(self): + actual_rt = self.create_recurring_invoice(self.now) + + self.assertTrue(hasattr(actual_rt, "Invoice")) + self.assertEquals(actual_rt.Invoice.Line[0].Description, "description") + self.assertEquals(actual_rt.Invoice.Line[0].Amount, 100.0) + + actual_info = actual_rt.Invoice.RecurringInfo + self.assertEqual(actual_info.ScheduleInfo.MaxOccurrences, 6) + self.assertEqual(actual_info.ScheduleInfo.IntervalType, "Monthly") + self.assertEqual(actual_info.ScheduleInfo.DayOfMonth, 1) + self.assertEqual(actual_info.ScheduleInfo.NumInterval, 1) + + + def test_create_recurring_bill(self): + bill = RecurringBill() + + line = AccountBasedExpenseLine() + line.Amount = 500 + line.DetailType = "AccountBasedExpenseLineDetail" + + account_ref = Ref() + account_ref.type = "Account" + account_ref.value = 1 + line.AccountBasedExpenseLineDetail = AccountBasedExpenseLineDetail() + line.AccountBasedExpenseLineDetail.AccountRef = account_ref + bill.Line.append(line) + + vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] + bill.VendorRef = vendor.to_ref() + + recurring_info = RecurringInfo() + recurring_info.Active = True + recurring_info.RecurType = "Automated" + recurring_info.Name = "Test Recurring Bill {}".format(datetime.now().strftime('%d%H%M%S')) + + recurring_info.ScheduleInfo = ScheduleInfo() + recurring_info.ScheduleInfo.StartDate = self.now.strftime("%Y-%m-%d") + + end_date = self.now + timedelta(weeks=12) + recurring_info.ScheduleInfo.EndDate = end_date.strftime("%Y-%m-%d") + + recurring_info.ScheduleInfo.NumInterval = 1 + recurring_info.ScheduleInfo.DaysBefore = 3 + recurring_info.ScheduleInfo.IntervalType = "Weekly" + recurring_info.ScheduleInfo.DayOfWeek = "Friday" + + bill.RecurringInfo = recurring_info + + recurring_txn = RecurringTransaction() + recurring_txn.Bill = bill + + saved = recurring_txn.save(qb=self.qb_client) + + actual_rt = RecurringTransaction.get(saved.Bill.Id, qb=self.qb_client) + + self.assertTrue(hasattr(actual_rt, "Bill")) + actual_info = actual_rt.Bill.RecurringInfo + self.assertEqual(actual_info.ScheduleInfo.EndDate, end_date.strftime("%Y-%m-%d")) + self.assertEqual(actual_info.ScheduleInfo.IntervalType, "Weekly") + self.assertEqual(actual_info.ScheduleInfo.DayOfWeek, "Friday") + self.assertEqual(actual_info.ScheduleInfo.NumInterval, 1) + + + def test_update_recurring_invoice(self): + saved = self.create_recurring_invoice(self.now + timedelta(seconds=+1)) # add a second to not conflict with the other test + recurring_txn = RecurringTransaction.get(saved.Invoice.Id, qb=self.qb_client) + + recurring_txn.Invoice.RecurringInfo.ScheduleInfo.DayOfMonth = 15 + recurring_txn.Invoice.Line[0].Amount = 250 + + # QBO api returns this to us as 0 but if you send it back you get an error + recurring_txn.Invoice.Deposit = None + + recurring_txn.save(qb=self.qb_client) + + actual = RecurringTransaction.get(saved.Invoice.Id, qb=self.qb_client) + self.assertEquals(actual.Invoice.RecurringInfo.ScheduleInfo.DayOfMonth, 15) + self.assertEquals(actual.Invoice.Line[0].Amount, 250) + + + def test_filter_by_type(self): + recurring_txns = RecurringTransaction.where("Type = 'Bill'", qb=self.qb_client) + + for recurring_txn in recurring_txns: + self.assertTrue(hasattr(recurring_txn, "Bill")) + + + # this one is mostly to demostrate how to use this + def test_get_all(self): + recurring_txns = RecurringTransaction.all(qb=self.qb_client) + + self.assertGreater(len(recurring_txns), 1) + + types = set() + + for recurring_txn in recurring_txns: + if hasattr(recurring_txn, "Invoice"): + types.add("Invoice") + elif hasattr(recurring_txn, "Bill"): + types.add("Bill") + elif hasattr(recurring_txn, "Purchase"): + types.add("Purchase") + # etc... + + self.assertIn("Bill", types) + self.assertIn("Invoice", types) + + + def test_delete_recurring_invoice(self): + # add a second to not conflict with the other test + saved = self.create_recurring_invoice(self.now + timedelta(seconds=+1)) + recurring_txn = RecurringTransaction.get(saved.Invoice.Id, qb=self.qb_client) + + recurring_txn.delete(qb=self.qb_client) + + diff --git a/tests/unit/objects/test_recurringtransaction.py b/tests/unit/objects/test_recurringtransaction.py new file mode 100644 index 00000000..a9b766b3 --- /dev/null +++ b/tests/unit/objects/test_recurringtransaction.py @@ -0,0 +1,12 @@ +import unittest + +from quickbooks import QuickBooks +from quickbooks.objects.recurringtransaction import RecurringTransaction + +class RecurringTransactionTests(unittest.TestCase): + def test_valid_object_name(self): + obj = RecurringTransaction() + client = QuickBooks() + result = client.isvalid_object_name(obj.qbo_object_name) + + self.assertTrue(result) \ No newline at end of file diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index 9a61afe1..db920308 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -19,6 +19,7 @@ from quickbooks.objects.department import Department from quickbooks.objects.customer import Customer from quickbooks.objects.journalentry import JournalEntry, JournalEntryLine +from quickbooks.objects.recurringtransaction import RecurringTransaction from quickbooks.objects.salesreceipt import SalesReceipt from quickbooks.mixins import ObjectListMixin @@ -347,6 +348,16 @@ def test_delete(self, delete_object): self.assertTrue(delete_object.called) +class DeleteNoIdMixinTest(QuickbooksUnitTestCase): + @patch('quickbooks.mixins.QuickBooks.delete_object') + def test_delete(self, delete_object): + recurring_txn = RecurringTransaction() + recurring_txn.Bill = Bill() + recurring_txn.delete(qb=self.qb_client) + + self.assertTrue(delete_object.called) + + class SendMixinTest(QuickbooksUnitTestCase): @patch('quickbooks.mixins.QuickBooks.misc_operation') def test_send(self, mock_misc_op): From ac356dc368a4855f636ba4826220c319feb0d53e Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 6 Mar 2023 12:34:25 -0600 Subject: [PATCH 044/154] Update readme --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index daf59eee..ecbebabd 100644 --- a/README.md +++ b/README.md @@ -235,20 +235,17 @@ Attaching a file to customer: Other operations ---------------- +Add Sharable link for an invoice sent to external customers (minorversion must be set to 36 or greater): + + invoice.invoice_link = true + + Void an invoice: invoice = Invoice() invoice.Id = 7 invoice.void(qb=client) -If your company_id never changes you can enable the client to stay running (deprecation warning: will be removed in next release): - - QuickBooks.enable_global() - -You can disable the global client like so (deprecation warning: will be removed in next release): - - QuickBooks.disable_global() - Working with JSON data ---------------- From cbd5bdae231fe3aeb5d82ebfab17bc36558688de Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 7 Mar 2023 09:55:39 -0600 Subject: [PATCH 045/154] Update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ecbebabd..231e9311 100644 --- a/README.md +++ b/README.md @@ -159,12 +159,12 @@ Batch update a list of objects: results = batch_update(customers, qb=client) -Batch delete a list of objects: +Batch delete a list of objects (only entities that support delete can use batch delete): from quickbooks.batch import batch_delete - customers = Customer.filter(Active=False) - results = batch_delete(customers, qb=client) + payments = Payment.filter(TxnDate=date.today()) + results = batch_delete(payments, qb=client) Review results for batch operation: From f0d0a939ed92e4f118d08b6236294b88ac9217eb Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 7 Mar 2023 11:19:12 -0600 Subject: [PATCH 046/154] Add python 3.11 to CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b8124441..e2658f62 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: - 3.8 - 3.9 - 3.10 + - 3.11 before_install: - pip install coveralls install: From 98d896d8a5a84df44138dd7ae603af5c5a50f14f Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 7 Mar 2023 11:24:51 -0600 Subject: [PATCH 047/154] Update Pipfile.lock --- Pipfile.lock | 515 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 331 insertions(+), 184 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 0fc83846..31478d1f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -18,89 +18,173 @@ "default": { "bleach": { "hashes": [ - "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da", - "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994" + "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414", + "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4" ], "index": "pypi", - "version": "==4.1.0" + "version": "==6.0.0" }, "certifi": { "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" ], - "version": "==2021.10.8" + "markers": "python_version >= '3.6'", + "version": "==2022.12.7" }, "charset-normalizer": { "hashes": [ - "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0", - "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b" - ], - "markers": "python_version >= '3'", - "version": "==2.0.7" - }, - "colorama": { - "hashes": [ - "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.4.4" + "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", + "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", + "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", + "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", + "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", + "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", + "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", + "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", + "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", + "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", + "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", + "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", + "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", + "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", + "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", + "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", + "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", + "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", + "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", + "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", + "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", + "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", + "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", + "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", + "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", + "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", + "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", + "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", + "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", + "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", + "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", + "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", + "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", + "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", + "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", + "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", + "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", + "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", + "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", + "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", + "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", + "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", + "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", + "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", + "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", + "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", + "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", + "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", + "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", + "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", + "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", + "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", + "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", + "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", + "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", + "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", + "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", + "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", + "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", + "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", + "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", + "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", + "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", + "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", + "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", + "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", + "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", + "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", + "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", + "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", + "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", + "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", + "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", + "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", + "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.0" }, "coverage": { "hashes": [ - "sha256:04560539c19ec26995ecfb3d9307ff154fbb9a172cb57e3b3cfc4ced673103d1", - "sha256:1549e1d08ce38259de2bc3e9a0d5f3642ff4a8f500ffc1b2df73fd621a6cdfc0", - "sha256:1db67c497688fd4ba85b373b37cc52c50d437fd7267520ecd77bddbd89ea22c9", - "sha256:30922626ce6f7a5a30bdba984ad21021529d3d05a68b4f71ea3b16bda35b8895", - "sha256:36e9040a43d2017f2787b28d365a4bb33fcd792c7ff46a047a04094dc0e2a30d", - "sha256:381d773d896cc7f8ba4ff3b92dee4ed740fb88dfe33b6e42efc5e8ab6dfa1cfe", - "sha256:3bbda1b550e70fa6ac40533d3f23acd4f4e9cb4e6e77251ce77fdf41b3309fb2", - "sha256:3be1206dc09fb6298de3fce70593e27436862331a85daee36270b6d0e1c251c4", - "sha256:424c44f65e8be58b54e2b0bd1515e434b940679624b1b72726147cfc6a9fc7ce", - "sha256:4b34ae4f51bbfa5f96b758b55a163d502be3dcb24f505d0227858c2b3f94f5b9", - "sha256:4e28d2a195c533b58fc94a12826f4431726d8eb029ac21d874345f943530c122", - "sha256:53a294dc53cfb39c74758edaa6305193fb4258a30b1f6af24b360a6c8bd0ffa7", - "sha256:60e51a3dd55540bec686d7fff61b05048ca31e804c1f32cbb44533e6372d9cc3", - "sha256:61b598cbdbaae22d9e34e3f675997194342f866bb1d781da5d0be54783dce1ff", - "sha256:6807947a09510dc31fa86f43595bf3a14017cd60bf633cc746d52141bfa6b149", - "sha256:6a6a9409223a27d5ef3cca57dd7cd4dfcb64aadf2fad5c3b787830ac9223e01a", - "sha256:7092eab374346121805fb637572483270324407bf150c30a3b161fc0c4ca5164", - "sha256:77b1da5767ed2f44611bc9bc019bc93c03fa495728ec389759b6e9e5039ac6b1", - "sha256:8251b37be1f2cd9c0e5ccd9ae0380909c24d2a5ed2162a41fcdbafaf59a85ebd", - "sha256:9f1627e162e3864a596486774876415a7410021f4b67fd2d9efdf93ade681afc", - "sha256:a1b73c7c4d2a42b9d37dd43199c5711d91424ff3c6c22681bc132db4a4afec6f", - "sha256:a82d79586a0a4f5fd1cf153e647464ced402938fbccb3ffc358c7babd4da1dd9", - "sha256:abbff240f77347d17306d3201e14431519bf64495648ca5a49571f988f88dee9", - "sha256:ad9b8c1206ae41d46ec7380b78ba735ebb77758a650643e841dd3894966c31d0", - "sha256:bbffde2a68398682623d9dd8c0ca3f46fda074709b26fcf08ae7a4c431a6ab2d", - "sha256:bcae10fccb27ca2a5f456bf64d84110a5a74144be3136a5e598f9d9fb48c0caa", - "sha256:c9cd3828bbe1a40070c11fe16a51df733fd2f0cb0d745fb83b7b5c1f05967df7", - "sha256:cd1cf1deb3d5544bd942356364a2fdc8959bad2b6cf6eb17f47d301ea34ae822", - "sha256:d036dc1ed8e1388e995833c62325df3f996675779541f682677efc6af71e96cc", - "sha256:db42baa892cba723326284490283a68d4de516bfb5aaba369b4e3b2787a778b7", - "sha256:e4fb7ced4d9dec77d6cf533acfbf8e1415fe799430366affb18d69ee8a3c6330", - "sha256:e7a0b42db2a47ecb488cde14e0f6c7679a2c5a9f44814393b162ff6397fcdfbb", - "sha256:f2f184bf38e74f152eed7f87e345b51f3ab0b703842f447c22efe35e59942c24" + "sha256:0339dc3237c0d31c3b574f19c57985fcbe494280153bbcad33f2cdf469f4ac3e", + "sha256:09643fb0df8e29f7417adc3f40aaf379d071ee8f0350ab290517c7004f05360b", + "sha256:0bd7e628f6c3ec4e7d2d24ec0e50aae4e5ae95ea644e849d92ae4805650b4c4e", + "sha256:0cf557827be7eca1c38a2480484d706693e7bb1929e129785fe59ec155a59de6", + "sha256:0f8318ed0f3c376cfad8d3520f496946977abde080439d6689d7799791457454", + "sha256:1b7fb13850ecb29b62a447ac3516c777b0e7a09ecb0f4bb6718a8654c87dfc80", + "sha256:22c308bc508372576ffa3d2dbc4824bb70d28eeb4fcd79d4d1aed663a06630d0", + "sha256:3004765bca3acd9e015794e5c2f0c9a05587f5e698127ff95e9cfba0d3f29339", + "sha256:3a209d512d157379cc9ab697cbdbb4cfd18daa3e7eebaa84c3d20b6af0037384", + "sha256:436313d129db7cf5b4ac355dd2bd3f7c7e5294af077b090b85de75f8458b8616", + "sha256:49567ec91fc5e0b15356da07a2feabb421d62f52a9fff4b1ec40e9e19772f5f8", + "sha256:4dd34a935de268a133e4741827ae951283a28c0125ddcdbcbba41c4b98f2dfef", + "sha256:570c21a29493b350f591a4b04c158ce1601e8d18bdcd21db136fbb135d75efa6", + "sha256:5928b85416a388dd557ddc006425b0c37e8468bd1c3dc118c1a3de42f59e2a54", + "sha256:5d2b9b5e70a21474c105a133ba227c61bc95f2ac3b66861143ce39a5ea4b3f84", + "sha256:617a94ada56bbfe547aa8d1b1a2b8299e2ec1ba14aac1d4b26a9f7d6158e1273", + "sha256:6a034480e9ebd4e83d1aa0453fd78986414b5d237aea89a8fdc35d330aa13bae", + "sha256:6fce673f79a0e017a4dc35e18dc7bb90bf6d307c67a11ad5e61ca8d42b87cbff", + "sha256:78d2c3dde4c0b9be4b02067185136b7ee4681978228ad5ec1278fa74f5ca3e99", + "sha256:7f099da6958ddfa2ed84bddea7515cb248583292e16bb9231d151cd528eab657", + "sha256:80559eaf6c15ce3da10edb7977a1548b393db36cbc6cf417633eca05d84dd1ed", + "sha256:834c2172edff5a08d78e2f53cf5e7164aacabeb66b369f76e7bb367ca4e2d993", + "sha256:861cc85dfbf55a7a768443d90a07e0ac5207704a9f97a8eb753292a7fcbdfcfc", + "sha256:8649371570551d2fd7dee22cfbf0b61f1747cdfb2b7587bb551e4beaaa44cb97", + "sha256:87dc37f16fb5e3a28429e094145bf7c1753e32bb50f662722e378c5851f7fdc6", + "sha256:8a6450da4c7afc4534305b2b7d8650131e130610cea448ff240b6ab73d7eab63", + "sha256:8d3843ca645f62c426c3d272902b9de90558e9886f15ddf5efe757b12dd376f5", + "sha256:8dca3c1706670297851bca1acff9618455122246bdae623be31eca744ade05ec", + "sha256:97a3189e019d27e914ecf5c5247ea9f13261d22c3bb0cfcfd2a9b179bb36f8b1", + "sha256:99f4dd81b2bb8fc67c3da68b1f5ee1650aca06faa585cbc6818dbf67893c6d58", + "sha256:9e872b082b32065ac2834149dc0adc2a2e6d8203080501e1e3c3c77851b466f9", + "sha256:a81dbcf6c6c877986083d00b834ac1e84b375220207a059ad45d12f6e518a4e3", + "sha256:abacd0a738e71b20e224861bc87e819ef46fedba2fb01bc1af83dfd122e9c319", + "sha256:ae82c988954722fa07ec5045c57b6d55bc1a0890defb57cf4a712ced65b26ddd", + "sha256:b0c0d46de5dd97f6c2d1b560bf0fcf0215658097b604f1840365296302a9d1fb", + "sha256:b1991a6d64231a3e5bbe3099fb0dd7c9aeaa4275ad0e0aeff4cb9ef885c62ba2", + "sha256:b2167d116309f564af56f9aa5e75ef710ef871c5f9b313a83050035097b56820", + "sha256:bd5a12239c0006252244f94863f1c518ac256160cd316ea5c47fb1a11b25889a", + "sha256:bdd3f2f285ddcf2e75174248b2406189261a79e7fedee2ceeadc76219b6faa0e", + "sha256:c77f2a9093ccf329dd523a9b2b3c854c20d2a3d968b6def3b820272ca6732242", + "sha256:cb5f152fb14857cbe7f3e8c9a5d98979c4c66319a33cad6e617f0067c9accdc4", + "sha256:cca7c0b7f5881dfe0291ef09ba7bb1582cb92ab0aeffd8afb00c700bf692415a", + "sha256:d2ef6cae70168815ed91388948b5f4fcc69681480a0061114db737f957719f03", + "sha256:d9256d4c60c4bbfec92721b51579c50f9e5062c21c12bec56b55292464873508", + "sha256:e191a63a05851f8bce77bc875e75457f9b01d42843f8bd7feed2fc26bbe60833", + "sha256:e2b50ebc2b6121edf352336d503357321b9d8738bb7a72d06fc56153fd3f4cd8", + "sha256:e3ea04b23b114572b98a88c85379e9e9ae031272ba1fb9b532aa934c621626d4", + "sha256:e4d70c853f0546855f027890b77854508bdb4d6a81242a9d804482e667fff6e6", + "sha256:f29351393eb05e6326f044a7b45ed8e38cb4dcc38570d12791f271399dc41431", + "sha256:f3d07edb912a978915576a776756069dede66d012baa503022d3a0adba1b6afa", + "sha256:fac6343bae03b176e9b58104a9810df3cdccd5cfed19f99adfa807ffbf43cf9b" ], "index": "pypi", - "version": "==6.0.2" + "version": "==7.2.1" }, "docutils": { "hashes": [ - "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125", - "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61" + "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", + "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.17.1" + "markers": "python_version >= '3.7'", + "version": "==0.19" }, "ecdsa": { "hashes": [ - "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676", - "sha256:b9f500bb439e4153d0330610f5d26baaf18d17b8ced1bc54410d189385ea68aa" + "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", + "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" ], "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.17.0" + "version": "==0.18.0" }, "enum-compat": { "hashes": [ @@ -111,26 +195,34 @@ }, "future": { "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" + "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307" ], "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.2" + "version": "==0.18.3" }, "idna": { "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" ], - "markers": "python_version >= '3'", - "version": "==3.3" + "markers": "python_version >= '3.5'", + "version": "==3.4" }, "importlib-metadata": { "hashes": [ - "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15", - "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1" + "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", + "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" ], - "markers": "python_version >= '3.6'", - "version": "==4.8.1" + "markers": "python_version >= '3.7'", + "version": "==6.0.0" + }, + "importlib-resources": { + "hashes": [ + "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6", + "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a" + ], + "markers": "python_version < '3.9'", + "version": "==5.12.0" }, "intuit-oauth": { "hashes": [ @@ -140,13 +232,45 @@ "index": "pypi", "version": "==1.2.4" }, + "jaraco.classes": { + "hashes": [ + "sha256:2353de3288bc6b82120752201c6b1c1a14b058267fa424ed5ce5984e3b922158", + "sha256:89559fa5c1d3c34eff6f631ad80bb21f378dbcbb35dd161fd2c6b93f5be2f98a" + ], + "markers": "python_version >= '3.7'", + "version": "==3.2.3" + }, "keyring": { "hashes": [ - "sha256:6334aee6073db2fb1f30892697b1730105b5e9a77ce7e61fca6b435225493efe", - "sha256:bd2145a237ed70c8ce72978b497619ddfcae640b6dcf494402d5143e37755c6e" + "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd", + "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678" ], - "markers": "python_version >= '3.6'", - "version": "==23.2.1" + "markers": "python_version >= '3.7'", + "version": "==23.13.1" + }, + "markdown-it-py": { + "hashes": [ + "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30", + "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.2.0" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "more-itertools": { + "hashes": [ + "sha256:cabaa341ad0389ea83c17a94566a53ae4c9d07349861ecb14dc6d0345cf9ac5d", + "sha256:d2bc7f02446e86a68911e58ded76d6561eea00cddfb2a91e7019bbb586c799f3" + ], + "markers": "python_version >= '3.7'", + "version": "==9.1.0" }, "nose": { "hashes": [ @@ -159,26 +283,19 @@ }, "oauthlib": { "hashes": [ - "sha256:42bf6354c2ed8c6acb54d971fce6f88193d97297e18602a3a886603f9d7730cc", - "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3" + "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", + "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" ], "markers": "python_version >= '3.6'", - "version": "==3.1.1" - }, - "packaging": { - "hashes": [ - "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7", - "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14" - ], - "markers": "python_version >= '3.6'", - "version": "==21.0" + "version": "==3.2.2" }, "pkginfo": { "hashes": [ - "sha256:37ecd857b47e5f55949c41ed061eb51a0bee97a87c969219d144c0e023982779", - "sha256:e7432f81d08adec7297633191bbf0bd47faf13cd8724c3a13250e51d542635bd" + "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546", + "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046" ], - "version": "==1.7.1" + "markers": "python_version >= '3.6'", + "version": "==1.9.6" }, "pyasn1": { "hashes": [ @@ -200,19 +317,11 @@ }, "pygments": { "hashes": [ - "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380", - "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6" + "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", + "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" ], - "markers": "python_version >= '3.5'", - "version": "==2.10.0" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.4.7" + "markers": "python_version >= '3.6'", + "version": "==2.14.0" }, "python-jose": { "hashes": [ @@ -231,100 +340,138 @@ }, "readme-renderer": { "hashes": [ - "sha256:3286806450d9961d6e3b5f8a59f77e61503799aca5155c8d8d40359b4e1e1adc", - "sha256:8299700d7a910c304072a7601eafada6712a5b011a20139417e1b1e9f04645d8" + "sha256:cd653186dfc73055656f090f227f5cb22a046d7f71a841dfa305f55c9a513273", + "sha256:f67a16caedfa71eef48a31b39708637a6f4664c4394801a7b0d6432d13907343" ], - "version": "==30.0" + "markers": "python_version >= '3.7'", + "version": "==37.3" }, "requests": { "hashes": [ - "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", - "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" + "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", + "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" ], "index": "pypi", - "version": "==2.26.0" + "version": "==2.28.2" }, "requests-oauthlib": { "hashes": [ - "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d", - "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a", - "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc" + "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", + "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" ], - "version": "==1.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.3.1" }, "requests-toolbelt": { "hashes": [ - "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", - "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0" + "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7", + "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d" ], - "version": "==0.9.1" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.10.1" }, "rfc3986": { "hashes": [ - "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835", - "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97" + "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "rich": { + "hashes": [ + "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001", + "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f" ], - "version": "==1.5.0" + "markers": "python_version >= '3.7'", + "version": "==13.3.2" }, "rsa": { "hashes": [ - "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2", - "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9" + "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", + "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" ], - "markers": "python_version >= '3.5' and python_version < '4'", - "version": "==4.7.2" + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==4.9" }, "simplejson": { "hashes": [ - "sha256:065230b9659ac38c8021fa512802562d122afb0cf8d4b89e257014dcddb5730a", - "sha256:07707ba69324eaf58f0c6f59d289acc3e0ed9ec528dae5b0d4219c0d6da27dc5", - "sha256:10defa88dd10a0a4763f16c1b5504e96ae6dc68953cfe5fc572b4a8fcaf9409b", - "sha256:140eb58809f24d843736edb8080b220417e22c82ac07a3dfa473f57e78216b5f", - "sha256:188f2c78a8ac1eb7a70a4b2b7b9ad11f52181044957bf981fb3e399c719e30ee", - "sha256:1c2688365743b0f190392e674af5e313ebe9d621813d15f9332e874b7c1f2d04", - "sha256:24e413bd845bd17d4d72063d64e053898543fb7abc81afeae13e5c43cef9c171", - "sha256:2b59acd09b02da97728d0bae8ff48876d7efcbbb08e569c55e2d0c2e018324f5", - "sha256:2df15814529a4625ea6f7b354a083609b3944c269b954ece0d0e7455872e1b2a", - "sha256:352c11582aa1e49a2f0f7f7d8fd5ec5311da890d1354287e83c63ab6af857cf5", - "sha256:36b08b886027eac67e7a0e822e3a5bf419429efad7612e69501669d6252a21f2", - "sha256:376023f51edaf7290332dacfb055bc00ce864cb013c0338d0dea48731f37e42f", - "sha256:3ba82f8b421886f4a2311c43fb98faaf36c581976192349fef2a89ed0fcdbdef", - "sha256:3d72aa9e73134dacd049a2d6f9bd219f7be9c004d03d52395831611d66cedb71", - "sha256:40ece8fa730d1a947bff792bcc7824bd02d3ce6105432798e9a04a360c8c07b0", - "sha256:417b7e119d66085dc45bdd563dcb2c575ee10a3b1c492dd3502a029448d4be1c", - "sha256:42b7c7264229860fe879be961877f7466d9f7173bd6427b3ba98144a031d49fb", - "sha256:457d9cfe7ece1571770381edccdad7fc255b12cd7b5b813219441146d4f47595", - "sha256:4a6943816e10028eeed512ea03be52b54ea83108b408d1049b999f58a760089b", - "sha256:5b94df70bd34a3b946c0eb272022fb0f8a9eb27cad76e7f313fedbee2ebe4317", - "sha256:5f5051a13e7d53430a990604b532c9124253c5f348857e2d5106d45fc8533860", - "sha256:5f7f53b1edd4b23fb112b89208377480c0bcee45d43a03ffacf30f3290e0ed85", - "sha256:5fe8c6dcb9e6f7066bdc07d3c410a2fca78c0d0b4e0e72510ffd20a60a20eb8e", - "sha256:71a54815ec0212b0cba23adc1b2a731bdd2df7b9e4432718b2ed20e8aaf7f01a", - "sha256:7332f7b06d42153255f7bfeb10266141c08d48cc1a022a35473c95238ff2aebc", - "sha256:78c6f0ed72b440ebe1892d273c1e5f91e55e6861bea611d3b904e673152a7a4c", - "sha256:7c9b30a2524ae6983b708f12741a31fbc2fb8d6fecd0b6c8584a62fd59f59e09", - "sha256:86fcffc06f1125cb443e2bed812805739d64ceb78597ac3c1b2d439471a09717", - "sha256:87572213965fd8a4fb7a97f837221e01d8fddcfb558363c671b8aa93477fb6a2", - "sha256:8e595de17178dd3bbeb2c5b8ea97536341c63b7278639cb8ee2681a84c0ef037", - "sha256:917f01db71d5e720b731effa3ff4a2c702a1b6dacad9bcdc580d86a018dfc3ca", - "sha256:91cfb43fb91ff6d1e4258be04eee84b51a4ef40a28d899679b9ea2556322fb50", - "sha256:aa86cfdeb118795875855589934013e32895715ec2d9e8eb7a59be3e7e07a7e1", - "sha256:ade09aa3c284d11f39640aebdcbb748e1996f0c60504f8c4a0c5a9fec821e67a", - "sha256:b2a5688606dffbe95e1347a05b77eb90489fe337edde888e23bbb7fd81b0d93b", - "sha256:b92fbc2bc549c5045c8233d954f3260ccf99e0f3ec9edfd2372b74b350917752", - "sha256:c2d5334d935af711f6d6dfeec2d34e071cdf73ec0df8e8bd35ac435b26d8da97", - "sha256:cb0afc3bad49eb89a579103616574a54b523856d20fc539a4f7a513a0a8ba4b2", - "sha256:ce66f730031b9b3683b2fc6ad4160a18db86557c004c3d490a29bf8d450d7ab9", - "sha256:e29b9cea4216ec130df85d8c36efb9985fda1c9039e4706fb30e0fb6a67602ff", - "sha256:e2cc4b68e59319e3de778325e34fbff487bfdb2225530e89995402989898d681", - "sha256:e90d2e219c3dce1500dda95f5b893c293c4d53c4e330c968afbd4e7a90ff4a5b", - "sha256:f13c48cc4363829bdfecc0c181b6ddf28008931de54908a492dc8ccd0066cd60", - "sha256:f550730d18edec4ff9d4252784b62adfe885d4542946b6d5a54c8a6521b56afd", - "sha256:fa843ee0d34c7193f5a816e79df8142faff851549cab31e84b526f04878ac778", - "sha256:fe1c33f78d2060719d52ea9459d97d7ae3a5b707ec02548575c4fbed1d1d345b" + "sha256:04a4b9a297cccbc9e1d66fe652fbffd55b36d6579c43132e821d315957302194", + "sha256:063db62a9251e61ea0c17e49c3e7bed465bfcc5359655abcb8c0bc6130a4e0d4", + "sha256:070ab073ce72f1624107dfd6d095c87ac32aafe7ba54a5c5055a3dd83cb06e51", + "sha256:099bbd3b5b4ea83159a980348cd481a34984dee5fe1b9fac31a9137158f46960", + "sha256:0baf8c60efef74944ed4adb034d14bcf737731576f0e4c3c56fb875ea256af69", + "sha256:0e7c3fae6c9540064e06a653780b4f263675cd69ca6841345029fee3e27e9bb5", + "sha256:141782a0a25c1792627575b37b4951583358ccc7137623aa45947f8425ee8d96", + "sha256:14b35fb90083218e59df5dba733c7086655f2938f3fcabe36ad849623941d660", + "sha256:169c2c7446ef33439c304a6aa5b7b5a2dbc938c9c2dd882dd3f2553f9518ebf6", + "sha256:16cc750d19852fa5ebafd55da86fa357f87991e07b4e2afb37a5975dfdde0153", + "sha256:1907d49d70c75530976119c13785db91168d2599288debaca7d25da9cd2f3747", + "sha256:1b79e2607ac5ba98381c2e068727acc1e4dd385a6d216914c0613f8f568a06a5", + "sha256:1e49c84df6e71e3c23169d3df481565dd607cbee4aa1e0af15c493cccad7c745", + "sha256:23fce984045804194f513a2739dcd82be350198470d5ade5058da019a48cf3f8", + "sha256:24823364fee93bab141621b3a2e10612e31be7ca58788bf9b2cd2b1ce37ab07d", + "sha256:290bbcdcbb37af3f7e43378f592ab7a9168fca640da6af63d42cdb535f96bbf2", + "sha256:2a1b3222bc8f6ac91b5ebe3263111c7dc4dc4b01c52f0153f5bb1f3ef3bf0023", + "sha256:2b0f6de11f5ce4b80f51bc49d08b898602e190547f8efe4e44af8ae3cda7779d", + "sha256:2be75f4cb9951efeb2616e16f944ee4f9a09768475a3f5c40a6ac4dc5ee68dfd", + "sha256:2c7ee643ee93684bf76196e2d84a2090c6df8f01737a016e869b579593827b6e", + "sha256:37bdef13412c0bc338db2993a38f3911d5bd2a0ba8d00b3bc66d1063edd7c33e", + "sha256:3bab9ea49ff477c926c5787f79ec47cf51c7ffb15c9d8dd0f09e728807d44f4b", + "sha256:44d6c52d4f5c0c087a6e88a92bf9f94234321d21be32c6471ba39856e304bbe3", + "sha256:4b8d4d958c5ab3489d1174917a7fad82da642560c39ce559a624e63deaaa36b1", + "sha256:4de9fed1166aeedee44150fa83bc059aca6b612940281f8b5a39374781f16196", + "sha256:502d86fbfe914263642479b87ed61af3b27b9e039df77acd2416cfccfc892e68", + "sha256:508342d7227ed66beecfbba7a38b46e1a713faeb034216f43f03ec5c175e0622", + "sha256:50f4b6d52f3a2d1cffd11834a1fe7f9516f0e3f20cbe78027aa88ff990fad7d6", + "sha256:52465a5578cfc2c5e374a574df14dfb75e04c6cb6a100b7abc8bf6c89bea8f5e", + "sha256:55aa983575b0aef143845f5bfbb35075475eccaebf7d4b30f4037a2fe8414666", + "sha256:55df3dfd8777bf134e1078d2f195352432a77f23ccb90b92b08218123d56adc9", + "sha256:56f186d44a9f625b5e5d9ba4b9551e263604000a7df60cb373b3e789ca603b2a", + "sha256:5780e3929435a8d39671537174f8ce0ccafb4f6e0c748ffe139916ffbdca39d3", + "sha256:59a629240cfbc5b4f390a8578dca74ae77ab617de971862acb946822d2eb1b11", + "sha256:5b009342e712026ffabe8a471d5b4a4ff2a038687387e74eae601574c04dae33", + "sha256:62628ea5df8c830d00a7417d5ecd949a1b24a8d0a5063a2a77f7ec7522110a0f", + "sha256:694332fd6fd10fe8868c2508583220d1a1a7be9ff049dab5bd6b9aedfb9edc50", + "sha256:6a49665169c18f27a0fc10935466332ee7406ee14ced8dc0a1b4d465547299aa", + "sha256:6b997739fdbc9b7030ff490fc8e5f8c144b8ec80f3605eff643983672bb8cfde", + "sha256:6bd81d10cb3384f64242316da8a2b2f88618776bc1ef38bcc79f1afe8ad36616", + "sha256:6c4c56c5abb82e22877b913186e5c0fd7d9eef0c930719e28fa451d3f11defb4", + "sha256:6fe1173b4146641c872bafa6f9a21f3a2012f502d54fbb523a76e6320024fae9", + "sha256:75eb555dc349d0cbe2c95ea2be665b306c6ac6d5b64e3a3920af9b805ecdb5f7", + "sha256:7c26fe63755ecc59c502ddde8e58ce8b765bf4fdd3f5858d2b7c8ab28bc2a9c8", + "sha256:7e73d9d6af3c29b60a92e28b3144d951110f59a3d05fc402c3f6c5248b883400", + "sha256:7ff65b475091084e5bdb7f26e9c555956be7355b573ce494fa96f9f8e34541ac", + "sha256:8209c40279ed9b2cd5fbe2d617a29a074e90ea97fce7c07a0128a01cb3e8afc5", + "sha256:88f59a07873dc1f06fd9e6712dd71286f1b297a066ad2fd9110ad080d3cb011c", + "sha256:96ade36640734b54176c4765d00a60767bd7fae5b7a5b3574accc055ac18e34c", + "sha256:9cf299fbb7d476676dfea372a3262654af98694bd1df35b060ce0fe1b68087f1", + "sha256:a2960b95f3ba822d077d1afa7e1fea9799cfb2990028cf010e666f64195ecb5a", + "sha256:a80bd9a3db88a76a401155c64e3499376c702307c2206cb381cc2a8dd9cc4f1f", + "sha256:aad323e92cb1bd3b1db6f57c007dca964d13c52247ad844203ce381e94066601", + "sha256:ab5bdf0b8d07f7fd603b2d0c1982412cd9f8ade997088ddced251f7e656c7fd4", + "sha256:b0352428b35da859a98770949e7353866ae65463026f1c8e4c89a6395d4b5fd7", + "sha256:b2c4e8b65987f3c6529149495d28e23efe213e94dc3659176c4ab22d18a9ee4a", + "sha256:bcd9eac304a133ee4af58e68c5ded4c5ba663d3ee4602e8613359b776a1f8c8f", + "sha256:c3b696770b504f881f271f97b94a687487ec1ef20bfbd5f20d92bbab7a85952d", + "sha256:c4514675f6571da8190fea52a110bca686fa844972e8b2b3bc07ace9e632ee4f", + "sha256:c98fddc374468158778a8afb3fd7296412a2b2fc34cebba64212ac3e018e7382", + "sha256:cde5a3ff5e0bd5d6da676314dfae86c9e99bff77bca03d30223c9718a58f9e83", + "sha256:cf7168b2046db0eceb83d8ed2ee31c0847ce18b2d8baf3e93de9560f3921a8c3", + "sha256:d774782159347d66563cd7ac18b9dd37010438a825160cde4818caa18110a746", + "sha256:d990ea42ba908cb57a3df97d283aa26c1822f10a0a60e250b54ee21cd08c48d0", + "sha256:e762e9d8556fa9f3a99f8a278eeba50a35b5f554b82deeb282ddbdd85816e638", + "sha256:e8a4750e8db92109e6f1f7783a7faae4254d6d5dc28a41ff7eff7d2265f0586b", + "sha256:eb81cfef0c0039010f0212f4e5eb6909641b8a54c761584054ac97fd7bd0c21a", + "sha256:ebb53837c5ffcb6100646018565d3f1afed6f4b185b14b2c9cbccf874fe40157", + "sha256:efa70fd9b6c7b57b048ecadb909683acd535cddebc5b22f3c05ba3b369739caf", + "sha256:f73bae5e315adf7bc8cb7f0a13a1e9e33bead42e8ce174be83ac9ecc2513c86a", + "sha256:f89f078114cacedb9a3392615cc099cf02a51efa7507f90e2006bf7ec38c880d", + "sha256:f9f72d2b539512f382a48cc9ad6cea2d3a572e71e92c40e03d2140041eeaa233", + "sha256:fc8df5831b645e96a318ea51a66ce6e2bb869eebc3fa9a860bbf67aecd270055" ], "index": "pypi", - "version": "==3.17.5" + "version": "==3.18.3" }, "six": { "hashes": [ @@ -334,29 +481,29 @@ "index": "pypi", "version": "==1.16.0" }, - "tqdm": { + "twine": { "hashes": [ - "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", - "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" + "sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8", + "sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.62.3" + "index": "pypi", + "version": "==4.0.2" }, - "twine": { + "typing-extensions": { "hashes": [ - "sha256:087328e9bb405e7ce18527a2dca4042a84c7918658f951110b38bc135acab218", - "sha256:4caec0f1ed78dc4c9b83ad537e453d03ce485725f2aea57f1bb3fdde78dae936" + "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", + "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" ], - "index": "pypi", - "version": "==3.4.2" + "markers": "python_version < '3.9'", + "version": "==4.5.0" }, "urllib3": { "hashes": [ - "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", - "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" + "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", + "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" ], "index": "pypi", - "version": "==1.26.7" + "version": "==1.26.14" }, "webencodings": { "hashes": [ @@ -367,11 +514,11 @@ }, "zipp": { "hashes": [ - "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", - "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" + "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", + "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556" ], - "markers": "python_version >= '3.6'", - "version": "==3.6.0" + "markers": "python_version >= '3.7'", + "version": "==3.15.0" } }, "develop": {} From 6309e21c63cb87d8dab5b3d91dc48c5047686190 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 7 Mar 2023 14:28:17 -0600 Subject: [PATCH 048/154] Added optional query string params --- README.md | 7 ++++ quickbooks/client.py | 13 +++---- quickbooks/mixins.py | 6 ++-- quickbooks/objects/purchase.py | 2 +- tests/integration/test_purchase.py | 56 ++++++++++++++++++++++++++++++ tests/unit/test_client.py | 2 +- 6 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 tests/integration/test_purchase.py diff --git a/README.md b/README.md index 231e9311..2bbef167 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,13 @@ Attaching a file to customer: attachment.ContentType = 'application/pdf' attachment.save(qb=client) +Passing in optional params +---------------- +Some QBO objects have options that need to be set on the query string of an API call. +One example is `include=allowduplicatedocnum` on the Purchase object. You can add these params when calling save: + + purchase.save(qb=self.qb_client, params={'include': 'allowduplicatedocnum'}) + Other operations ---------------- Add Sharable link for an invoice sent to external customers (minorversion must be set to 36 or greater): diff --git a/quickbooks/client.py b/quickbooks/client.py index 7e4ae291..d8bfe5ba 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -172,6 +172,7 @@ def change_data_capture(self, entity_string, changed_since): def make_request(self, request_type, url, request_body=None, content_type='application/json', params=None, file_path=None, request_id=None): + print(params) if not params: params = {} @@ -305,17 +306,17 @@ def handle_exceptions(results): else: raise exceptions.QuickbooksException(message, code, detail) - def create_object(self, qbbo, request_body, _file_path=None, request_id=None): + def create_object(self, qbbo, request_body, _file_path=None, request_id=None, params=None): self.isvalid_object_name(qbbo) url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - results = self.post(url, request_body, file_path=_file_path, request_id=request_id) + results = self.post(url, request_body, file_path=_file_path, request_id=request_id, params=params) return results - def query(self, select): + def query(self, select, params=None): url = "{0}/company/{1}/query".format(self.api_url, self.company_id) - result = self.post(url, select, content_type='application/text') + result = self.post(url, select, content_type='application/text', params=params) return result @@ -325,9 +326,9 @@ def isvalid_object_name(self, object_name): return True - def update_object(self, qbbo, request_body, _file_path=None, request_id=None): + def update_object(self, qbbo, request_body, _file_path=None, request_id=None, params=None): url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - result = self.post(url, request_body, file_path=_file_path, request_id=request_id) + result = self.post(url, request_body, file_path=_file_path, request_id=request_id, params=params) return result diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 0cda656c..e907757a 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -148,14 +148,14 @@ class UpdateMixin(object): qbo_object_name = "" qbo_json_object_name = "" - def save(self, qb=None, request_id=None): + def save(self, qb=None, request_id=None, params=None): if not qb: qb = QuickBooks() if self.Id and int(self.Id) > 0: - json_data = qb.update_object(self.qbo_object_name, self.to_json(), request_id=request_id) + json_data = qb.update_object(self.qbo_object_name, self.to_json(), request_id=request_id, params=params) else: - json_data = qb.create_object(self.qbo_object_name, self.to_json(), request_id=request_id) + json_data = qb.create_object(self.qbo_object_name, self.to_json(), request_id=request_id, params=params) if self.qbo_json_object_name != '': obj = type(self).from_json(json_data[self.qbo_json_object_name]) diff --git a/quickbooks/objects/purchase.py b/quickbooks/objects/purchase.py index 59d10251..49264e22 100644 --- a/quickbooks/objects/purchase.py +++ b/quickbooks/objects/purchase.py @@ -22,7 +22,7 @@ class Purchase(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity For example, to create a transaction that sends a check to a vendor, create a Purchase object with PaymentType set to Check. To query Purchase transactions of a certain type, for example Check, submit the following to the query endpoint: SELECT * from Purchase where PaymentType='Check' You must specify an AccountRef for all purchases. - The TotalAmtattribute must add up to sum of Line.Amount attributes. + The TotalAmt attribute must add up to sum of Line.Amount attributes. """ class_dict = { "AccountRef": Ref, diff --git a/tests/integration/test_purchase.py b/tests/integration/test_purchase.py new file mode 100644 index 00000000..6d7fd629 --- /dev/null +++ b/tests/integration/test_purchase.py @@ -0,0 +1,56 @@ +from quickbooks.objects.account import Account +from quickbooks.objects.customer import Customer +from quickbooks.objects.detailline import ItemBasedExpenseLine, ItemBasedExpenseLineDetail +from quickbooks.objects.item import Item +from quickbooks.objects.purchase import Purchase +from quickbooks.objects.taxcode import TaxCode +from tests.integration.test_base import QuickbooksTestCase + + +class PurchaseOrderTest(QuickbooksTestCase): + def test_create(self): + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + taxcode = TaxCode.all(max_results=1, qb=self.qb_client)[0] + item = Item.filter(Type='Inventory', max_results=1, qb=self.qb_client)[0] + + credit_account = Account() + credit_account.FullyQualifiedName = 'Visa' + credit_account.Id = "42" + + purchase = Purchase() + purchase.DocNumber = "Doc123" + purchase.PaymentType = "CreditCard" + purchase.AccountRef = credit_account.to_ref() + purchase.TotalAmt = 100 + + detail_line = ItemBasedExpenseLine() + detail_line.Amount = 100 + detail_line.ItemBasedExpenseLineDetail = ItemBasedExpenseLineDetail() + detail_line.ItemBasedExpenseLineDetail.BillableStatus = "NotBillable" + detail_line.ItemBasedExpenseLineDetail.UnitPrice = 100 + detail_line.ItemBasedExpenseLineDetail.Qty = 1 + detail_line.ItemBasedExpenseLineDetail.CustomerRef = customer.to_ref() + detail_line.ItemBasedExpenseLineDetail.TaxCodeRef = taxcode.to_ref() + detail_line.ItemBasedExpenseLineDetail.ItemRef = item.to_ref() + + purchase.Line.append(detail_line) + + print(purchase.to_json()) + purchase.save(qb=self.qb_client, params={'include': 'allowduplicatedocnum'}) + + query_purchase = Purchase.get(purchase.Id, qb=self.qb_client) + + self.assertEquals(query_purchase.AccountRef.value, credit_account.Id) + self.assertEquals(query_purchase.DocNumber, "Doc123") + self.assertEquals(query_purchase.TotalAmt, 100) + + query_detail_line = query_purchase.Line[0] + + self.assertEquals(query_detail_line.Amount, 100) + self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.UnitPrice, 100) + self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.Qty, 1) + self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.CustomerRef.value, customer.Id) + self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.TaxCodeRef.value, taxcode.Name) + self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.ItemRef.value, item.Id) + + diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 3ec7f397..bb551a1e 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -124,7 +124,7 @@ def test_update_object_with_request_id(self, make_req): qb_client.update_object("Customer", "request_body", request_id="123") url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/customer" - make_req.assert_called_with("POST", url, "request_body", file_path = None, request_id="123") + make_req.assert_called_with("POST", url, "request_body", file_path=None, params=None, request_id="123") @patch('quickbooks.client.QuickBooks.get') def test_get_current_user(self, get): From 4e5c5c1427204248ac4b46a7f041ca26f84d69a9 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 7 Mar 2023 16:19:08 -0600 Subject: [PATCH 049/154] Update changelog --- CHANGELOG.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index df92a3f4..4179061e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,9 @@ Changelog ========= +* 0.9.3 (March 7, 2023) + * Added support for Recurring Transaction + * Added support for optional query params + * Fixed errors in example code on the readme * 0.9.2 (August 3, 2022) * Removed pycparser dependency From a73517136380a005fec8e063580a27b03d26a37c Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 08:08:16 -0600 Subject: [PATCH 050/154] Create pylint.yml --- .github/workflows/pylint.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/pylint.yml diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 00000000..383e65cd --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,23 @@ +name: Pylint + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10"] + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + - name: Analysing the code with pylint + run: | + pylint $(git ls-files '*.py') From f7dcbea5da330eb8558334cf14f07cec9544cd57 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 08:14:40 -0600 Subject: [PATCH 051/154] Create python-package.yml --- .github/workflows/python-package.yml | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/python-package.yml diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 00000000..e303fda3 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,40 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python package + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pytest From 5acaa36709696939cef96f3c15e2322ace709e23 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 08:23:14 -0600 Subject: [PATCH 052/154] Update python-package.yml --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index e303fda3..41f71120 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -37,4 +37,4 @@ jobs: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | - pytest + pytest tests/unit From d4b9b267e1e042488dfb918566b756c35d1a0ee3 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 09:27:10 -0600 Subject: [PATCH 053/154] Fixed tests and removed deprecations --- CHANGELOG.rst | 1 + quickbooks/client.py | 21 ------ tests/integration/test_account.py | 8 +-- tests/integration/test_attachable.py | 8 +-- tests/integration/test_base.py | 4 +- tests/integration/test_bill.py | 6 +- tests/integration/test_billpayment.py | 10 +-- .../test_creditcardpayment_entity.py | 10 +-- tests/integration/test_creditmemo.py | 16 ++--- tests/integration/test_customer.py | 2 +- tests/integration/test_exchangerate.py | 6 +- tests/integration/test_invoice.py | 14 ++-- tests/integration/test_item.py | 18 ++--- tests/integration/test_preferences.py | 14 ++-- tests/integration/test_purchase.py | 18 ++--- tests/integration/test_purchaseorder.py | 18 ++--- .../integration/test_recurringtransaction.py | 8 +-- tests/integration/test_taxagency.py | 6 +- tests/integration/test_taxcode.py | 2 +- tests/integration/test_taxrate.py | 2 +- tests/integration/test_taxservice.py | 10 +-- tests/integration/test_term.py | 10 +-- tests/integration/test_timeactivity.py | 14 ++-- tests/integration/test_trackingclass.py | 8 +-- tests/integration/test_transfer.py | 10 +-- tests/integration/test_vendor.py | 44 ++++++------ tests/unit/objects/test_account.py | 8 +-- tests/unit/objects/test_attachable.py | 8 +-- tests/unit/objects/test_base.py | 42 +++++------ tests/unit/objects/test_batchrequest.py | 18 ++--- tests/unit/objects/test_bill.py | 14 ++-- tests/unit/objects/test_billpayment.py | 8 +-- tests/unit/objects/test_budget.py | 4 +- tests/unit/objects/test_company_info.py | 8 +-- tests/unit/objects/test_companycurrency.py | 8 +-- tests/unit/objects/test_creditcardpayment.py | 28 ++++---- .../objects/test_creditcardpayment_entity.py | 2 +- tests/unit/objects/test_creditmemo.py | 24 +++---- tests/unit/objects/test_customer.py | 8 +-- tests/unit/objects/test_customertype.py | 2 +- tests/unit/objects/test_department.py | 8 +-- tests/unit/objects/test_deposit.py | 22 +++--- tests/unit/objects/test_detailline.py | 68 +++++++++--------- tests/unit/objects/test_employee.py | 8 +-- tests/unit/objects/test_estimate.py | 2 +- tests/unit/objects/test_exchangerate.py | 2 +- tests/unit/objects/test_invoice.py | 18 ++--- tests/unit/objects/test_item.py | 8 +-- tests/unit/objects/test_journalentry.py | 28 ++++---- tests/unit/objects/test_payment.py | 4 +- tests/unit/objects/test_paymentmethod.py | 8 +-- tests/unit/objects/test_preferences.py | 2 +- tests/unit/objects/test_purchase.py | 2 +- tests/unit/objects/test_purchaseorder.py | 2 +- tests/unit/objects/test_refundreceipt.py | 2 +- tests/unit/objects/test_salesreceipt.py | 2 +- tests/unit/objects/test_tax.py | 6 +- tests/unit/objects/test_taxagency.py | 2 +- tests/unit/objects/test_taxcode.py | 14 ++-- tests/unit/objects/test_taxrate.py | 2 +- tests/unit/objects/test_taxservice.py | 4 +- tests/unit/objects/test_term.py | 8 +-- tests/unit/objects/test_timeactivity.py | 20 +++--- tests/unit/objects/test_trackingclass.py | 8 +-- tests/unit/objects/test_transfer.py | 2 +- tests/unit/objects/test_vendor.py | 12 ++-- tests/unit/objects/test_vendorcredit.py | 2 +- tests/unit/test_batch.py | 10 +-- tests/unit/test_cdc.py | 8 +-- tests/unit/test_client.py | 69 ++++++++----------- tests/unit/test_exception.py | 8 +-- tests/unit/test_helpers.py | 6 +- tests/unit/test_mixins.py | 62 ++++++++--------- 73 files changed, 434 insertions(+), 465 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4179061e..60e8d37a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,7 @@ Changelog * Added support for Recurring Transaction * Added support for optional query params * Fixed errors in example code on the readme + * Removed enable_global and disable_global * 0.9.2 (August 3, 2022) * Removed pycparser dependency diff --git a/quickbooks/client.py b/quickbooks/client.py index db75c053..28c7b753 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -108,27 +108,6 @@ def _start_session(self): ) return self.auth_client.refresh_token - @classmethod - def get_instance(cls): - return cls.__instance - - @classmethod - def disable_global(cls): - """ - Disable use of singleton pattern. - """ - warnings.warn("disable_global deprecated", PendingDeprecationWarning) - QuickBooks.__use_global = False - QuickBooks.__instance = None - - @classmethod - def enable_global(cls): - """ - Allow use of singleton pattern. - """ - warnings.warn("enable_global deprecated", PendingDeprecationWarning) - QuickBooks.__use_global = True - def _drop(self): QuickBooks.__instance = None diff --git a/tests/integration/test_account.py b/tests/integration/test_account.py index 7c69d339..4efde66a 100644 --- a/tests/integration/test_account.py +++ b/tests/integration/test_account.py @@ -20,9 +20,9 @@ def test_create(self): self.id = account.Id query_account = Account.get(account.Id, qb=self.qb_client) - self.assertEquals(account.Id, query_account.Id) - self.assertEquals(query_account.Name, self.name) - self.assertEquals(query_account.AcctNum, self.account_number) + self.assertEqual(account.Id, query_account.Id) + self.assertEqual(query_account.Name, self.name) + self.assertEqual(query_account.AcctNum, self.account_number) def test_update(self): account = Account.filter(Name=self.name, qb=self.qb_client)[0] @@ -31,4 +31,4 @@ def test_update(self): account.save(qb=self.qb_client) query_account = Account.get(account.Id, qb=self.qb_client) - self.assertEquals(query_account.Name, "Updated Name {0}".format(self.account_number)) + self.assertEqual(query_account.Name, "Updated Name {0}".format(self.account_number)) diff --git a/tests/integration/test_attachable.py b/tests/integration/test_attachable.py index e690acfe..eec05931 100644 --- a/tests/integration/test_attachable.py +++ b/tests/integration/test_attachable.py @@ -27,8 +27,8 @@ def test_create_note(self): attachable.save(qb=self.qb_client) query_attachable = Attachable.get(attachable.Id, qb=self.qb_client) - self.assertEquals(query_attachable.AttachableRef[0].EntityRef.value, vendor.Id) - self.assertEquals(query_attachable.Note, "Test note added on {}".format(self.time.strftime("%Y-%m-%d %H:%M:%S"))) + self.assertEqual(query_attachable.AttachableRef[0].EntityRef.value, vendor.Id) + self.assertEqual(query_attachable.Note, "Test note added on {}".format(self.time.strftime("%Y-%m-%d %H:%M:%S"))) def test_update_note(self): attachable = Attachable.all(max_results=1, qb=self.qb_client)[0] @@ -37,7 +37,7 @@ def test_update_note(self): attachable.save(qb=self.qb_client) query_attachable = Attachable.get(attachable.Id, qb=self.qb_client) - self.assertEquals(query_attachable.Note, "Note updated on {}".format(self.time.strftime("%Y-%m-%d %H:%M:%S"))) + self.assertEqual(query_attachable.Note, "Note updated on {}".format(self.time.strftime("%Y-%m-%d %H:%M:%S"))) def test_create_file(self): attachable = Attachable() @@ -57,4 +57,4 @@ def test_create_file(self): query_attachable = Attachable.get(attachable.Id, qb=self.qb_client) - self.assertEquals(query_attachable.AttachableRef[0].EntityRef.value, vendor.Id) + self.assertEqual(query_attachable.AttachableRef[0].EntityRef.value, vendor.Id) diff --git a/tests/integration/test_base.py b/tests/integration/test_base.py index 9b4b7083..a4df0828 100644 --- a/tests/integration/test_base.py +++ b/tests/integration/test_base.py @@ -33,12 +33,12 @@ def setUp(self): self.auth_client = AuthClient( client_id='CLIENTID', client_secret='CLIENT_SECRET', - environment=Environments.SANDBOX, + environment='sandbox', redirect_uri='http://localhost:8000/callback', ) self.qb_client = QuickBooks( - #auth_client=self.auth_client, + # auth_client=self.auth_client, refresh_token='REFRESH_TOKEN', company_id='COMPANY_ID', ) diff --git a/tests/integration/test_bill.py b/tests/integration/test_bill.py index 631b4474..45b351b7 100644 --- a/tests/integration/test_bill.py +++ b/tests/integration/test_bill.py @@ -34,6 +34,6 @@ def test_create(self): query_bill = Bill.get(bill.Id, qb=self.qb_client) - self.assertEquals(query_bill.Id, bill.Id) - self.assertEquals(len(query_bill.Line), 1) - self.assertEquals(query_bill.Line[0].Amount, 200.0) + self.assertEqual(query_bill.Id, bill.Id) + self.assertEqual(len(query_bill.Line), 1) + self.assertEqual(query_bill.Line[0].Amount, 200.0) diff --git a/tests/integration/test_billpayment.py b/tests/integration/test_billpayment.py index 0d300493..fab990c0 100644 --- a/tests/integration/test_billpayment.py +++ b/tests/integration/test_billpayment.py @@ -42,9 +42,9 @@ def test_create(self): query_bill_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) - self.assertEquals(query_bill_payment.PayType, "Check") - self.assertEquals(query_bill_payment.TotalAmt, 200.0) - self.assertEquals(query_bill_payment.PrivateNote, "Private Note") + self.assertEqual(query_bill_payment.PayType, "Check") + self.assertEqual(query_bill_payment.TotalAmt, 200.0) + self.assertEqual(query_bill_payment.PrivateNote, "Private Note") - self.assertEquals(len(query_bill_payment.Line), 1) - self.assertEquals(query_bill_payment.Line[0].Amount, 200.0) + self.assertEqual(len(query_bill_payment.Line), 1) + self.assertEqual(query_bill_payment.Line[0].Amount, 200.0) diff --git a/tests/integration/test_creditcardpayment_entity.py b/tests/integration/test_creditcardpayment_entity.py index 13c49ddf..245ff81c 100644 --- a/tests/integration/test_creditcardpayment_entity.py +++ b/tests/integration/test_creditcardpayment_entity.py @@ -38,10 +38,10 @@ def test_create(self): query_credit_card_payment = CreditCardPayment.get(credit_card_payment.Id, qb=self.qb_client) - self.assertEquals(query_credit_card_payment.Id, credit_card_payment.Id) - self.assertEquals(query_credit_card_payment.Amount, 100) - self.assertEquals(query_credit_card_payment.BankAccountRef.value, from_account.Id) - self.assertEquals(query_credit_card_payment.CreditCardAccountRef.value, to_account.Id) + self.assertEqual(query_credit_card_payment.Id, credit_card_payment.Id) + self.assertEqual(query_credit_card_payment.Amount, 100) + self.assertEqual(query_credit_card_payment.BankAccountRef.value, from_account.Id) + self.assertEqual(query_credit_card_payment.CreditCardAccountRef.value, to_account.Id) # reset transfer (so the from_account doesn't run out of cash) # I wonder if we can do a transfer from credit_card_account to a bank_account @@ -59,4 +59,4 @@ def test_update(self): query_credit_card_payment = CreditCardPayment.get(credit_card_payment.Id, qb=self.qb_client) - self.assertEquals(query_credit_card_payment.Amount, credit_card_payment.Amount) + self.assertEqual(query_credit_card_payment.Amount, credit_card_payment.Amount) diff --git a/tests/integration/test_creditmemo.py b/tests/integration/test_creditmemo.py index 7505688b..d86df5d0 100644 --- a/tests/integration/test_creditmemo.py +++ b/tests/integration/test_creditmemo.py @@ -26,15 +26,15 @@ def test_create(self): query_credit_memo = CreditMemo.get(credit_memo.Id, qb=self.qb_client) - self.assertEquals(credit_memo.Id, query_credit_memo.Id) - self.assertEquals(query_credit_memo.CustomerRef.value, customer.Id) + self.assertEqual(credit_memo.Id, query_credit_memo.Id) + self.assertEqual(query_credit_memo.CustomerRef.value, customer.Id) line = query_credit_memo.Line[0] - self.assertEquals(line.LineNum, 1) - self.assertEquals(line.Description, "Test Description") - self.assertEquals(line.Amount, 100) - self.assertEquals(line.DetailType, "SalesItemLineDetail") - self.assertEquals(line.SalesItemLineDetail.ItemRef.value, item.Id) + self.assertEqual(line.LineNum, 1) + self.assertEqual(line.Description, "Test Description") + self.assertEqual(line.Amount, 100) + self.assertEqual(line.DetailType, "SalesItemLineDetail") + self.assertEqual(line.SalesItemLineDetail.ItemRef.value, item.Id) def test_update(self): credit_memo = CreditMemo.all(max_results=1, qb=self.qb_client)[0] @@ -42,6 +42,6 @@ def test_update(self): credit_memo.save(qb=self.qb_client) query_credit_memo = CreditMemo.get(credit_memo.Id, qb=self.qb_client) - self.assertEquals(query_credit_memo.PrivateNote, "Test") + self.assertEqual(query_credit_memo.PrivateNote, "Test") diff --git a/tests/integration/test_customer.py b/tests/integration/test_customer.py index fbbd4a8f..c1781c46 100644 --- a/tests/integration/test_customer.py +++ b/tests/integration/test_customer.py @@ -47,7 +47,7 @@ def test_create(self): query_customer = Customer.get(customer.Id, qb=self.qb_client) - self.assertEquals(customer.Id, query_customer.Id) + self.assertEqual(customer.Id, query_customer.Id) self.assertEqual(query_customer.Title, self.title) self.assertEqual(query_customer.GivenName, self.given_name) self.assertEqual(query_customer.MiddleName, self.middle_name) diff --git a/tests/integration/test_exchangerate.py b/tests/integration/test_exchangerate.py index d51406f4..bc563a7c 100644 --- a/tests/integration/test_exchangerate.py +++ b/tests/integration/test_exchangerate.py @@ -7,8 +7,8 @@ class ExchangeRateTest(QuickbooksTestCase): def test_query(self): exchange_rate = ExchangeRate.where("SourceCurrencyCode = 'EUR'", qb=self.qb_client)[0] - self.assertEquals(exchange_rate.SourceCurrencyCode, "EUR") - self.assertEquals(exchange_rate.TargetCurrencyCode, "USD") + self.assertEqual(exchange_rate.SourceCurrencyCode, "EUR") + self.assertEqual(exchange_rate.TargetCurrencyCode, "USD") def test_update(self): exchange_rate = ExchangeRate.where("SourceCurrencyCode = 'EUR'", qb=self.qb_client)[0] @@ -18,4 +18,4 @@ def test_update(self): exchange_rate.save(qb=self.qb_client) exchange_rate_updated = ExchangeRate.where("SourceCurrencyCode = 'EUR'", qb=self.qb_client)[0] - self.assertEquals(exchange_rate_updated.Rate, new_rate) + self.assertEqual(exchange_rate_updated.Rate, new_rate) diff --git a/tests/integration/test_invoice.py b/tests/integration/test_invoice.py index 9a82a529..4a686a53 100644 --- a/tests/integration/test_invoice.py +++ b/tests/integration/test_invoice.py @@ -34,7 +34,7 @@ def test_query_by_customer_ref(self): print(invoice[0].Line[0].LineNum) print(invoice[0].Line[0].Amount) - self.assertEquals(invoice[0].CustomerRef.name, customer.DisplayName) + self.assertEqual(invoice[0].CustomerRef.name, customer.DisplayName) def test_where(self): customer = Customer.all(max_results=1, qb=self.qb_client)[0] @@ -43,17 +43,17 @@ def test_where(self): "CustomerRef = '{0}'".format(customer.Id), qb=self.qb_client) print(invoice[0]) - self.assertEquals(invoice[0].CustomerRef.name, customer.DisplayName) + self.assertEqual(invoice[0].CustomerRef.name, customer.DisplayName) def test_create(self): customer = Customer.all(max_results=1, qb=self.qb_client)[0] invoice = self.create_invoice(customer) query_invoice = Invoice.get(invoice.Id, qb=self.qb_client) - self.assertEquals(query_invoice.CustomerRef.name, customer.DisplayName) - self.assertEquals(query_invoice.CustomerMemo.value, "Customer Memo") - self.assertEquals(query_invoice.Line[0].Description, "description") - self.assertEquals(query_invoice.Line[0].Amount, 100.0) + self.assertEqual(query_invoice.CustomerRef.name, customer.DisplayName) + self.assertEqual(query_invoice.CustomerMemo.value, "Customer Memo") + self.assertEqual(query_invoice.Line[0].Description, "description") + self.assertEqual(query_invoice.Line[0].Amount, 100.0) def test_create_idempotence(self): customer = Customer.all(max_results=1, qb=self.qb_client)[0] @@ -62,7 +62,7 @@ def test_create_idempotence(self): duplicate_invoice = self.create_invoice(customer, request_id=sample_request_id) # Assert that both returned invoices have the same id - self.assertEquals(invoice.Id, duplicate_invoice.Id) + self.assertEqual(invoice.Id, duplicate_invoice.Id) def test_delete(self): customer = Customer.all(max_results=1, qb=self.qb_client)[0] diff --git a/tests/integration/test_item.py b/tests/integration/test_item.py index fe8a80ff..ee12c686 100644 --- a/tests/integration/test_item.py +++ b/tests/integration/test_item.py @@ -36,12 +36,12 @@ def test_create(self): query_item = Item.get(item.Id, qb=self.qb_client) - self.assertEquals(query_item.Id, item.Id) - self.assertEquals(query_item.Name, self.name) - self.assertEquals(query_item.Type, "Inventory") - self.assertEquals(query_item.Sku, "SKU123123") - self.assertEquals(query_item.TrackQtyOnHand, True) - self.assertEquals(query_item.QtyOnHand, 10) - self.assertEquals(query_item.IncomeAccountRef.value, self.income_account.Id) - self.assertEquals(query_item.ExpenseAccountRef.value, self.expense_account.Id) - self.assertEquals(query_item.AssetAccountRef.value, self.asset_account.Id) + self.assertEqual(query_item.Id, item.Id) + self.assertEqual(query_item.Name, self.name) + self.assertEqual(query_item.Type, "Inventory") + self.assertEqual(query_item.Sku, "SKU123123") + self.assertEqual(query_item.TrackQtyOnHand, True) + self.assertEqual(query_item.QtyOnHand, 10) + self.assertEqual(query_item.IncomeAccountRef.value, self.income_account.Id) + self.assertEqual(query_item.ExpenseAccountRef.value, self.expense_account.Id) + self.assertEqual(query_item.AssetAccountRef.value, self.asset_account.Id) diff --git a/tests/integration/test_preferences.py b/tests/integration/test_preferences.py index c42b79d0..8e41c0d9 100644 --- a/tests/integration/test_preferences.py +++ b/tests/integration/test_preferences.py @@ -13,12 +13,12 @@ def setUp(self): def test_get(self): preferences = Preferences.get(qb=self.qb_client) - self.assertEquals(preferences.Id, "1") - self.assertEquals(preferences.AccountingInfoPrefs.TaxYearMonth, "January") - self.assertEquals(preferences.ProductAndServicesPrefs.ForPurchase, True) - self.assertEquals(preferences.VendorAndPurchasesPrefs.BillableExpenseTracking, True) - self.assertEquals(preferences.TimeTrackingPrefs.WorkWeekStartDate, "Monday") - self.assertEquals(preferences.OtherPrefs.NameValue[0].Name, "SalesFormsPrefs.DefaultCustomerMessage") + self.assertEqual(preferences.Id, "1") + self.assertEqual(preferences.AccountingInfoPrefs.TaxYearMonth, "January") + self.assertEqual(preferences.ProductAndServicesPrefs.ForPurchase, True) + self.assertEqual(preferences.VendorAndPurchasesPrefs.BillableExpenseTracking, True) + self.assertEqual(preferences.TimeTrackingPrefs.WorkWeekStartDate, "Monday") + self.assertEqual(preferences.OtherPrefs.NameValue[0].Name, "SalesFormsPrefs.DefaultCustomerMessage") def test_update(self): preferences = Preferences.get(qb=self.qb_client) @@ -28,4 +28,4 @@ def test_update(self): preferences.save(qb=self.qb_client) preferences_updated = Preferences.get(qb=self.qb_client) - self.assertEquals(preferences_updated.EmailMessagesPrefs.EstimateMessage.Subject, subject) + self.assertEqual(preferences_updated.EmailMessagesPrefs.EstimateMessage.Subject, subject) diff --git a/tests/integration/test_purchase.py b/tests/integration/test_purchase.py index 6d7fd629..3c9c6e03 100644 --- a/tests/integration/test_purchase.py +++ b/tests/integration/test_purchase.py @@ -40,17 +40,17 @@ def test_create(self): query_purchase = Purchase.get(purchase.Id, qb=self.qb_client) - self.assertEquals(query_purchase.AccountRef.value, credit_account.Id) - self.assertEquals(query_purchase.DocNumber, "Doc123") - self.assertEquals(query_purchase.TotalAmt, 100) + self.assertEqual(query_purchase.AccountRef.value, credit_account.Id) + self.assertEqual(query_purchase.DocNumber, "Doc123") + self.assertEqual(query_purchase.TotalAmt, 100) query_detail_line = query_purchase.Line[0] - self.assertEquals(query_detail_line.Amount, 100) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.UnitPrice, 100) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.Qty, 1) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.CustomerRef.value, customer.Id) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.TaxCodeRef.value, taxcode.Name) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.ItemRef.value, item.Id) + self.assertEqual(query_detail_line.Amount, 100) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.UnitPrice, 100) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.Qty, 1) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.CustomerRef.value, customer.Id) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.TaxCodeRef.value, taxcode.Name) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.ItemRef.value, item.Id) diff --git a/tests/integration/test_purchaseorder.py b/tests/integration/test_purchaseorder.py index 6f4bbb55..bd9b3657 100644 --- a/tests/integration/test_purchaseorder.py +++ b/tests/integration/test_purchaseorder.py @@ -38,17 +38,17 @@ def test_create(self): query_purchaseorder = PurchaseOrder.get(purchaseorder.Id, qb=self.qb_client) - self.assertEquals(query_purchaseorder.VendorRef.value, vendor.Id) - self.assertEquals(query_purchaseorder.APAccountRef.value, account.Id) - self.assertEquals(query_purchaseorder.TotalAmt, 100) + self.assertEqual(query_purchaseorder.VendorRef.value, vendor.Id) + self.assertEqual(query_purchaseorder.APAccountRef.value, account.Id) + self.assertEqual(query_purchaseorder.TotalAmt, 100) query_detail_line = query_purchaseorder.Line[0] - self.assertEquals(query_detail_line.Amount, 100) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.UnitPrice, 100) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.Qty, 1) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.CustomerRef.value, customer.Id) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.TaxCodeRef.value, taxcode.Name) - self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.ItemRef.value, item.Id) + self.assertEqual(query_detail_line.Amount, 100) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.UnitPrice, 100) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.Qty, 1) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.CustomerRef.value, customer.Id) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.TaxCodeRef.value, taxcode.Name) + self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.ItemRef.value, item.Id) diff --git a/tests/integration/test_recurringtransaction.py b/tests/integration/test_recurringtransaction.py index 4dc2d5db..b4c93eaa 100644 --- a/tests/integration/test_recurringtransaction.py +++ b/tests/integration/test_recurringtransaction.py @@ -54,8 +54,8 @@ def test_create_recurring_invoice(self): actual_rt = self.create_recurring_invoice(self.now) self.assertTrue(hasattr(actual_rt, "Invoice")) - self.assertEquals(actual_rt.Invoice.Line[0].Description, "description") - self.assertEquals(actual_rt.Invoice.Line[0].Amount, 100.0) + self.assertEqual(actual_rt.Invoice.Line[0].Description, "description") + self.assertEqual(actual_rt.Invoice.Line[0].Amount, 100.0) actual_info = actual_rt.Invoice.RecurringInfo self.assertEqual(actual_info.ScheduleInfo.MaxOccurrences, 6) @@ -127,8 +127,8 @@ def test_update_recurring_invoice(self): recurring_txn.save(qb=self.qb_client) actual = RecurringTransaction.get(saved.Invoice.Id, qb=self.qb_client) - self.assertEquals(actual.Invoice.RecurringInfo.ScheduleInfo.DayOfMonth, 15) - self.assertEquals(actual.Invoice.Line[0].Amount, 250) + self.assertEqual(actual.Invoice.RecurringInfo.ScheduleInfo.DayOfMonth, 15) + self.assertEqual(actual.Invoice.Line[0].Amount, 250) def test_filter_by_type(self): diff --git a/tests/integration/test_taxagency.py b/tests/integration/test_taxagency.py index 630cc8f6..c99fb0c4 100644 --- a/tests/integration/test_taxagency.py +++ b/tests/integration/test_taxagency.py @@ -8,7 +8,7 @@ class TaxAgencyTest(QuickbooksTestCase): def test_read(self): tax_agencies = TaxAgency.all(max_results=1, qb=self.qb_client) - self.assertEquals(len(tax_agencies), 1) + self.assertEqual(len(tax_agencies), 1) def test_create(self): tax_agency = TaxAgency() @@ -20,5 +20,5 @@ def test_create(self): query_tax_agency = TaxAgency.get(tax_agency.Id, qb=self.qb_client) - self.assertEquals(query_tax_agency.Id, tax_agency.Id) - self.assertEquals(query_tax_agency.DisplayName, name) \ No newline at end of file + self.assertEqual(query_tax_agency.Id, tax_agency.Id) + self.assertEqual(query_tax_agency.DisplayName, name) \ No newline at end of file diff --git a/tests/integration/test_taxcode.py b/tests/integration/test_taxcode.py index c9001e13..6bb1838d 100644 --- a/tests/integration/test_taxcode.py +++ b/tests/integration/test_taxcode.py @@ -9,5 +9,5 @@ def test_get_all(self): # KNOWN Quickbooks bug - TaxCode query returns 3 extra items: # https://intuitdeveloper.lc.intuit.com/questions/1398164-setting-maxresults-on-taxcode-query-returns-incorrect-number-of-records - self.assertEquals(len(tax_codes), 4) + self.assertEqual(len(tax_codes), 4) diff --git a/tests/integration/test_taxrate.py b/tests/integration/test_taxrate.py index 239fdab6..d00599c8 100644 --- a/tests/integration/test_taxrate.py +++ b/tests/integration/test_taxrate.py @@ -6,5 +6,5 @@ class TaxRateTest(QuickbooksTestCase): def test_read(self): tax_rates = TaxRate.all(max_results=1, qb=self.qb_client) - self.assertEquals(len(tax_rates), 1) + self.assertEqual(len(tax_rates), 1) diff --git a/tests/integration/test_taxservice.py b/tests/integration/test_taxservice.py index 07d98baf..73c0c50f 100644 --- a/tests/integration/test_taxservice.py +++ b/tests/integration/test_taxservice.py @@ -24,10 +24,10 @@ def test_create(self): created_taxservice = taxservice.save(qb=self.qb_client) - self.assertEquals(created_taxservice.TaxCode, self.name) + self.assertEqual(created_taxservice.TaxCode, self.name) detail = created_taxservice.TaxRateDetails[0] - self.assertEquals(detail.TaxRateName, self.name) - self.assertEquals(detail.RateValue, 10) - self.assertEquals(detail.TaxAgencyId, '1') - self.assertEquals(detail.TaxApplicableOn, "Sales") + self.assertEqual(detail.TaxRateName, self.name) + self.assertEqual(detail.RateValue, 10) + self.assertEqual(detail.TaxAgencyId, '1') + self.assertEqual(detail.TaxApplicableOn, "Sales") diff --git a/tests/integration/test_term.py b/tests/integration/test_term.py index e3c7fd63..9c3ff510 100644 --- a/tests/integration/test_term.py +++ b/tests/integration/test_term.py @@ -18,9 +18,9 @@ def test_create(self): query_term = Term.get(term.Id, qb=self.qb_client) - self.assertEquals(query_term.Id, term.Id) - self.assertEquals(query_term.Name, self.name) - self.assertEquals(query_term.DueDays, 10) + self.assertEqual(query_term.Id, term.Id) + self.assertEqual(query_term.Name, self.name) + self.assertEqual(query_term.DueDays, 10) def test_update(self): term = Term.all(max_results=1, qb=self.qb_client)[0] @@ -29,5 +29,5 @@ def test_update(self): query_term = Term.get(term.Id, qb=self.qb_client) - self.assertEquals(query_term.Id, term.Id) - self.assertEquals(query_term.DueDays, 60) + self.assertEqual(query_term.Id, term.Id) + self.assertEqual(query_term.DueDays, 60) diff --git a/tests/integration/test_timeactivity.py b/tests/integration/test_timeactivity.py index 5f908810..707d65de 100644 --- a/tests/integration/test_timeactivity.py +++ b/tests/integration/test_timeactivity.py @@ -26,14 +26,14 @@ def test_create(self): query_time_activity = TimeActivity.get(time_activity.Id, qb=self.qb_client) - self.assertEquals(query_time_activity.Id, time_activity.Id) - self.assertEquals(query_time_activity.NameOf, "Employee") - self.assertEquals(query_time_activity.Description, "Test description") - self.assertEquals(query_time_activity.EmployeeRef.value, employee.Id) + self.assertEqual(query_time_activity.Id, time_activity.Id) + self.assertEqual(query_time_activity.NameOf, "Employee") + self.assertEqual(query_time_activity.Description, "Test description") + self.assertEqual(query_time_activity.EmployeeRef.value, employee.Id) # Quickbooks has issues with returning the correct StartTime and EndTime - #self.assertEquals(query_time_activity.StartTime, '2016-07-22T10:00:00-07:00') - #self.assertEquals(query_time_activity.EndTime, '2016-07-22T11:00:00-07:00') + #self.assertEqual(query_time_activity.StartTime, '2016-07-22T10:00:00-07:00') + #self.assertEqual(query_time_activity.EndTime, '2016-07-22T11:00:00-07:00') def test_update(self): time_activity = TimeActivity.all(max_results=1, qb=self.qb_client)[0] @@ -42,4 +42,4 @@ def test_update(self): query_time_activity = TimeActivity.get(time_activity.Id, qb=self.qb_client) - self.assertEquals(query_time_activity.Description, "Updated test description") + self.assertEqual(query_time_activity.Description, "Updated test description") diff --git a/tests/integration/test_trackingclass.py b/tests/integration/test_trackingclass.py index 8cd40473..ec7d796a 100644 --- a/tests/integration/test_trackingclass.py +++ b/tests/integration/test_trackingclass.py @@ -17,8 +17,8 @@ def test_create(self): query_tracking_class = Class.get(tracking_class.Id, qb=self.qb_client) - self.assertEquals(query_tracking_class.Id, tracking_class.Id) - self.assertEquals(query_tracking_class.Name, self.name) + self.assertEqual(query_tracking_class.Id, tracking_class.Id) + self.assertEqual(query_tracking_class.Name, self.name) def test_update(self): updated_name = "Updated {}".format(self.name) @@ -29,5 +29,5 @@ def test_update(self): query_tracking_class = Class.get(tracking_class.Id, qb=self.qb_client) - self.assertEquals(query_tracking_class.Id, tracking_class.Id) - self.assertEquals(query_tracking_class.Name, updated_name) + self.assertEqual(query_tracking_class.Id, tracking_class.Id) + self.assertEqual(query_tracking_class.Name, updated_name) diff --git a/tests/integration/test_transfer.py b/tests/integration/test_transfer.py index 86ec58f1..8eddb31f 100644 --- a/tests/integration/test_transfer.py +++ b/tests/integration/test_transfer.py @@ -31,10 +31,10 @@ def test_create(self): query_transfer = Transfer.get(transfer.Id, qb=self.qb_client) - self.assertEquals(query_transfer.Id, transfer.Id) - self.assertEquals(query_transfer.Amount, 100) - self.assertEquals(query_transfer.FromAccountRef.value, from_account.Id) - self.assertEquals(query_transfer.ToAccountRef.value, to_account.Id) + self.assertEqual(query_transfer.Id, transfer.Id) + self.assertEqual(query_transfer.Amount, 100) + self.assertEqual(query_transfer.FromAccountRef.value, from_account.Id) + self.assertEqual(query_transfer.ToAccountRef.value, to_account.Id) # reset transfer (so the from_account doesn't run out of cash) transfer = Transfer() @@ -51,4 +51,4 @@ def test_update(self): query_transfer = Transfer.get(transfer.Id, qb=self.qb_client) - self.assertEquals(query_transfer.Amount, transfer.Amount) + self.assertEqual(query_transfer.Amount, transfer.Amount) diff --git a/tests/integration/test_vendor.py b/tests/integration/test_vendor.py index 679e1f2f..a1b8d631 100644 --- a/tests/integration/test_vendor.py +++ b/tests/integration/test_vendor.py @@ -46,26 +46,26 @@ def test_create(self): query_vendor = Vendor.get(vendor.Id, qb=self.qb_client) - self.assertEquals(query_vendor.Id, vendor.Id) - - self.assertEquals(query_vendor.AcctNum, self.account_number) - self.assertEquals(query_vendor.Title, 'Ms.') - self.assertEquals(query_vendor.GivenName, 'First') - self.assertEquals(query_vendor.FamilyName, 'Last') - self.assertEquals(query_vendor.Suffix, 'Sr.') - self.assertEquals(query_vendor.CompanyName, self.name) - self.assertEquals(query_vendor.DisplayName, self.name) - self.assertEquals(query_vendor.PrintOnCheckName, self.name) - - self.assertEquals(query_vendor.BillAddr.Line1, "123 Main") - self.assertEquals(query_vendor.BillAddr.Line2, "Apartment 1") - self.assertEquals(query_vendor.BillAddr.City, "City") - self.assertEquals(query_vendor.BillAddr.Country, "U.S.A") - self.assertEquals(query_vendor.BillAddr.CountrySubDivisionCode, "CA") - self.assertEquals(query_vendor.BillAddr.PostalCode, "94030") - self.assertEquals(query_vendor.PrimaryPhone.FreeFormNumber, '555-555-5555') - self.assertEquals(query_vendor.PrimaryEmailAddr.Address, 'test@email.com') - self.assertEquals(query_vendor.WebAddr.URI, 'http://testurl.com/') + self.assertEqual(query_vendor.Id, vendor.Id) + + self.assertEqual(query_vendor.AcctNum, self.account_number) + self.assertEqual(query_vendor.Title, 'Ms.') + self.assertEqual(query_vendor.GivenName, 'First') + self.assertEqual(query_vendor.FamilyName, 'Last') + self.assertEqual(query_vendor.Suffix, 'Sr.') + self.assertEqual(query_vendor.CompanyName, self.name) + self.assertEqual(query_vendor.DisplayName, self.name) + self.assertEqual(query_vendor.PrintOnCheckName, self.name) + + self.assertEqual(query_vendor.BillAddr.Line1, "123 Main") + self.assertEqual(query_vendor.BillAddr.Line2, "Apartment 1") + self.assertEqual(query_vendor.BillAddr.City, "City") + self.assertEqual(query_vendor.BillAddr.Country, "U.S.A") + self.assertEqual(query_vendor.BillAddr.CountrySubDivisionCode, "CA") + self.assertEqual(query_vendor.BillAddr.PostalCode, "94030") + self.assertEqual(query_vendor.PrimaryPhone.FreeFormNumber, '555-555-5555') + self.assertEqual(query_vendor.PrimaryEmailAddr.Address, 'test@email.com') + self.assertEqual(query_vendor.WebAddr.URI, 'http://testurl.com/') def update_vendor(self): vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] @@ -76,5 +76,5 @@ def update_vendor(self): vendor.save(qb=self.qb_client) query_vendor = Vendor.get(vendor.Id, qb=self.qb_client) - self.assertEquals(query_vendor.GivenName, 'Updated Name') - self.assertEquals(query_vendor.FamilyName, 'Updated Lastname') + self.assertEqual(query_vendor.GivenName, 'Updated Name') + self.assertEqual(query_vendor.FamilyName, 'Updated Lastname') diff --git a/tests/unit/objects/test_account.py b/tests/unit/objects/test_account.py index b9d38c47..6da0a1bd 100644 --- a/tests/unit/objects/test_account.py +++ b/tests/unit/objects/test_account.py @@ -9,7 +9,7 @@ def test_unicode(self): account = Account() account.FullyQualifiedName = "test" - self.assertEquals(str(account), "test") + self.assertEqual(str(account), "test") def test_to_ref(self): account = Account() @@ -18,9 +18,9 @@ def test_to_ref(self): ref = account.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Account") - self.assertEquals(ref.value, 12) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Account") + self.assertEqual(ref.value, 12) def test_valid_object_name(self): account = Account() diff --git a/tests/unit/objects/test_attachable.py b/tests/unit/objects/test_attachable.py index e50e7221..26080f62 100644 --- a/tests/unit/objects/test_attachable.py +++ b/tests/unit/objects/test_attachable.py @@ -9,7 +9,7 @@ def test_unicode(self): attachable = Attachable() attachable.FileName = "test" - self.assertEquals(str(attachable), "test") + self.assertEqual(str(attachable), "test") def test_to_ref(self): attachable = Attachable() @@ -18,9 +18,9 @@ def test_to_ref(self): ref = attachable.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Attachable") - self.assertEquals(ref.value, 12) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Attachable") + self.assertEqual(ref.value, 12) def test_valid_object_name(self): attachable = Attachable() diff --git a/tests/unit/objects/test_base.py b/tests/unit/objects/test_base.py index 128aa086..d13e8c76 100644 --- a/tests/unit/objects/test_base.py +++ b/tests/unit/objects/test_base.py @@ -14,7 +14,7 @@ def test_unicode(self): address.CountrySubDivisionCode = "MO" address.PostalCode = "12345" - self.assertEquals(str(address), "123 Main Joplin, MO 12345") + self.assertEqual(str(address), "123 Main Joplin, MO 12345") class PhoneNumberTests(unittest.TestCase): @@ -22,7 +22,7 @@ def test_unicode(self): number = PhoneNumber() number.FreeFormNumber = "555-555-5555" - self.assertEquals(str(number), "555-555-5555") + self.assertEqual(str(number), "555-555-5555") class EmailAddressTests(unittest.TestCase): @@ -30,7 +30,7 @@ def test_unicode(self): email = EmailAddress() email.Address = "email@gmail.com" - self.assertEquals(str(email), "email@gmail.com") + self.assertEqual(str(email), "email@gmail.com") class WebAddressTests(unittest.TestCase): @@ -38,7 +38,7 @@ def test_unicode(self): url = WebAddress() url.URI = "www.website.com" - self.assertEquals(str(url), "www.website.com") + self.assertEqual(str(url), "www.website.com") class RefTests(unittest.TestCase): @@ -48,7 +48,7 @@ def test_unicode(self): ref.name = "test" ref.value = 1 - self.assertEquals(str(ref), "test") + self.assertEqual(str(ref), "test") class CustomFieldTests(unittest.TestCase): @@ -56,7 +56,7 @@ def test_unicode(self): custom = CustomField() custom.Name = "name" - self.assertEquals(str(custom), "name") + self.assertEqual(str(custom), "name") class CustomerMemoTests(unittest.TestCase): @@ -64,7 +64,7 @@ def test_unicode(self): memo = CustomerMemo() memo.value = "value" - self.assertEquals(str(memo), "value") + self.assertEqual(str(memo), "value") class LinkedTxnTests(unittest.TestCase): @@ -72,7 +72,7 @@ def test_unicode(self): linked = LinkedTxn() linked.TxnId = 1 - self.assertEquals(str(linked), "1") + self.assertEqual(str(linked), "1") class MetaDataTests(unittest.TestCase): @@ -80,17 +80,17 @@ def test_unicode(self): meta = MetaData() meta.CreateTime = "1/1/2000" - self.assertEquals(str(meta), "Created 1/1/2000") + self.assertEqual(str(meta), "Created 1/1/2000") class MarkupInfoTests(unittest.TestCase): def test_init(self): markup = MarkupInfo() - self.assertEquals(markup.PercentBased, False) - self.assertEquals(markup.Value, 0) - self.assertEquals(markup.Percent, 0) - self.assertEquals(markup.PriceLevelRef, None) + self.assertEqual(markup.PercentBased, False) + self.assertEqual(markup.Value, 0) + self.assertEqual(markup.Percent, 0) + self.assertEqual(markup.PriceLevelRef, None) class AttachableRefTests(unittest.TestCase): @@ -101,11 +101,11 @@ def test_init(self): attachable.Inactive = False attachable.NoRefOnly = False - self.assertEquals(attachable.LineInfo, None) - self.assertEquals(attachable.IncludeOnSend, False) - self.assertEquals(attachable.Inactive, False) - self.assertEquals(attachable.NoRefOnly, False) - self.assertEquals(attachable.EntityRef, None) + self.assertEqual(attachable.LineInfo, None) + self.assertEqual(attachable.IncludeOnSend, False) + self.assertEqual(attachable.Inactive, False) + self.assertEqual(attachable.NoRefOnly, False) + self.assertEqual(attachable.EntityRef, None) class LinkedTxnMixinTests(unittest.TestCase): @@ -116,6 +116,6 @@ def test_to_linked_txn(self): linked_txn = deposit.to_linked_txn() - self.assertEquals(linked_txn.TxnId, 100) - self.assertEquals(linked_txn.TxnType, "Deposit") - self.assertEquals(linked_txn.TxnLineId, 1) + self.assertEqual(linked_txn.TxnId, 100) + self.assertEqual(linked_txn.TxnType, "Deposit") + self.assertEqual(linked_txn.TxnLineId, 1) diff --git a/tests/unit/objects/test_batchrequest.py b/tests/unit/objects/test_batchrequest.py index 8a83727f..cb68ef50 100644 --- a/tests/unit/objects/test_batchrequest.py +++ b/tests/unit/objects/test_batchrequest.py @@ -10,7 +10,7 @@ def test__repr__(self): fault.original_object = 100 fault.Error.append("error") - self.assertEquals(str(fault.__repr__()), "1 Errors") + self.assertEqual(str(fault.__repr__()), "1 Errors") class FaultErrorTests(unittest.TestCase): @@ -20,7 +20,7 @@ def test_unicode(self): fault_error.code = 100 fault_error.Detail = "detail" - self.assertEquals(str(fault_error), "Code: 100 Message: test Detail: detail") + self.assertEqual(str(fault_error), "Code: 100 Message: test Detail: detail") def test__repr__(self): fault_error = FaultError() @@ -28,7 +28,7 @@ def test__repr__(self): fault_error.code = 100 fault_error.Detail = "detail" - self.assertEquals(fault_error.__repr__(), "Code: 100 Message: test Detail: detail") + self.assertEqual(fault_error.__repr__(), "Code: 100 Message: test Detail: detail") class BatchItemResponseTests(unittest.TestCase): @@ -37,15 +37,15 @@ def test_set_object(self): batch_item = BatchItemResponse() batch_item.set_object(obj) - self.assertEquals(batch_item._original_object, obj) - self.assertEquals(batch_item.Error, obj) + self.assertEqual(batch_item._original_object, obj) + self.assertEqual(batch_item.Error, obj) def test_get_object(self): obj = Fault() batch_item = BatchItemResponse() batch_item.set_object(obj) - self.assertEquals(batch_item.get_object(), obj) + self.assertEqual(batch_item.get_object(), obj) class BatchItemRequestTests(unittest.TestCase): @@ -54,12 +54,12 @@ def test_set_object(self): batch_item = BatchItemRequest() batch_item.set_object(obj) - self.assertEquals(batch_item._original_object, obj) - self.assertEquals(batch_item.Error, obj) + self.assertEqual(batch_item._original_object, obj) + self.assertEqual(batch_item.Error, obj) def test_get_object(self): obj = Fault() batch_item = BatchItemRequest() batch_item.set_object(obj) - self.assertEquals(batch_item.get_object(), obj) + self.assertEqual(batch_item.get_object(), obj) diff --git a/tests/unit/objects/test_bill.py b/tests/unit/objects/test_bill.py index 383dca05..91c983f2 100644 --- a/tests/unit/objects/test_bill.py +++ b/tests/unit/objects/test_bill.py @@ -9,7 +9,7 @@ def test_unicode(self): bill = Bill() bill.Balance = 1000 - self.assertEquals(str(bill), "1000") + self.assertEqual(str(bill), "1000") def test_to_LinkedTxn(self): bill = Bill() @@ -17,9 +17,9 @@ def test_to_LinkedTxn(self): linked_txn = bill.to_linked_txn() - self.assertEquals(linked_txn.TxnId, bill.Id) - self.assertEquals(linked_txn.TxnType, "Bill") - self.assertEquals(linked_txn.TxnLineId, 1) + self.assertEqual(linked_txn.TxnId, bill.Id) + self.assertEqual(linked_txn.TxnType, "Bill") + self.assertEqual(linked_txn.TxnLineId, 1) def test_valid_object_name(self): obj = Bill() @@ -35,7 +35,7 @@ def test_to_ref(self): ref = bill.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Bill") - self.assertEquals(ref.value, 100) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Bill") + self.assertEqual(ref.value, 100) diff --git a/tests/unit/objects/test_billpayment.py b/tests/unit/objects/test_billpayment.py index b71b3b81..994f6294 100644 --- a/tests/unit/objects/test_billpayment.py +++ b/tests/unit/objects/test_billpayment.py @@ -9,7 +9,7 @@ def test_unicode(self): checkpayment = CheckPayment() checkpayment.PrintStatus = "test" - self.assertEquals(str(checkpayment), "test") + self.assertEqual(str(checkpayment), "test") class BillPaymentLineTests(unittest.TestCase): @@ -17,7 +17,7 @@ def test_unicode(self): bill = BillPaymentLine() bill.Amount = 1000 - self.assertEquals(str(bill), "1000") + self.assertEqual(str(bill), "1000") class BillPaymentTests(unittest.TestCase): @@ -25,7 +25,7 @@ def test_unicode(self): bill_payment = BillPayment() bill_payment.TotalAmt = 1000 - self.assertEquals(str(bill_payment), "1000") + self.assertEqual(str(bill_payment), "1000") def test_valid_object_name(self): obj = BillPayment() @@ -39,4 +39,4 @@ class BillPaymentCreditCardTests(unittest.TestCase): def test_init(self): bill_payment_cc = BillPaymentCreditCard() - self.assertEquals(bill_payment_cc.CCAccountRef, None) + self.assertEqual(bill_payment_cc.CCAccountRef, None) diff --git a/tests/unit/objects/test_budget.py b/tests/unit/objects/test_budget.py index fc363d2c..7fc5aee5 100644 --- a/tests/unit/objects/test_budget.py +++ b/tests/unit/objects/test_budget.py @@ -8,7 +8,7 @@ def test_unicode(self): budget_detail = BudgetDetail() budget_detail.Amount = 10 - self.assertEquals(str(budget_detail), "10") + self.assertEqual(str(budget_detail), "10") class BudgetTests(unittest.TestCase): @@ -16,4 +16,4 @@ def test_unicode(self): budget = Budget() budget.Name = "test" - self.assertEquals(str(budget), "test") + self.assertEqual(str(budget), "test") diff --git a/tests/unit/objects/test_company_info.py b/tests/unit/objects/test_company_info.py index e8f02b79..bb99992c 100644 --- a/tests/unit/objects/test_company_info.py +++ b/tests/unit/objects/test_company_info.py @@ -9,7 +9,7 @@ def test_unicode(self): company_info = CompanyInfo() company_info.CompanyName = "test" - self.assertEquals(str(company_info), "test") + self.assertEqual(str(company_info), "test") def test_to_ref(self): company_info = CompanyInfo() @@ -18,6 +18,6 @@ def test_to_ref(self): ref = company_info.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "CompanyInfo") - self.assertEquals(ref.value, 100) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "CompanyInfo") + self.assertEqual(ref.value, 100) diff --git a/tests/unit/objects/test_companycurrency.py b/tests/unit/objects/test_companycurrency.py index fec2f401..adb217d6 100644 --- a/tests/unit/objects/test_companycurrency.py +++ b/tests/unit/objects/test_companycurrency.py @@ -10,7 +10,7 @@ def test_unicode(self): company_currency.Name = "test" company_currency.Code = "USD" - self.assertEquals(str(company_currency), "test") + self.assertEqual(str(company_currency), "test") def test_to_ref(self): company_currency = CompanyCurrency() @@ -19,6 +19,6 @@ def test_to_ref(self): ref = company_currency.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "CompanyCurrency") - self.assertEquals(ref.value, 23) \ No newline at end of file + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "CompanyCurrency") + self.assertEqual(ref.value, 23) \ No newline at end of file diff --git a/tests/unit/objects/test_creditcardpayment.py b/tests/unit/objects/test_creditcardpayment.py index 723c624d..5591a616 100644 --- a/tests/unit/objects/test_creditcardpayment.py +++ b/tests/unit/objects/test_creditcardpayment.py @@ -7,29 +7,29 @@ class CreditCardPaymentTests(unittest.TestCase): def test_init(self): payment = CreditCardPayment() - self.assertEquals(payment.CreditChargeInfo, None) - self.assertEquals(payment.CreditChargeResponse, None) + self.assertEqual(payment.CreditChargeInfo, None) + self.assertEqual(payment.CreditChargeResponse, None) class CreditChargeResponseTests(unittest.TestCase): def test_init(self): response = CreditChargeResponse() - self.assertEquals(response.CCTransId, "") - self.assertEquals(response.AuthCode, "") - self.assertEquals(response.TxnAuthorizationTime, "") - self.assertEquals(response.Status, "") + self.assertEqual(response.CCTransId, "") + self.assertEqual(response.AuthCode, "") + self.assertEqual(response.TxnAuthorizationTime, "") + self.assertEqual(response.Status, "") class CreditChargeInfoTests(unittest.TestCase): def test_init(self): info = CreditChargeInfo() - self.assertEquals(info.Type, "") - self.assertEquals(info.NameOnAcct, "") - self.assertEquals(info.CcExpiryMonth, 0) - self.assertEquals(info.CcExpiryYear, 0) - self.assertEquals(info.BillAddrStreet, "") - self.assertEquals(info.PostalCode, "") - self.assertEquals(info.Amount, 0) - self.assertEquals(info.ProcessPayment, False) + self.assertEqual(info.Type, "") + self.assertEqual(info.NameOnAcct, "") + self.assertEqual(info.CcExpiryMonth, 0) + self.assertEqual(info.CcExpiryYear, 0) + self.assertEqual(info.BillAddrStreet, "") + self.assertEqual(info.PostalCode, "") + self.assertEqual(info.Amount, 0) + self.assertEqual(info.ProcessPayment, False) diff --git a/tests/unit/objects/test_creditcardpayment_entity.py b/tests/unit/objects/test_creditcardpayment_entity.py index 2a99a255..1e7be666 100644 --- a/tests/unit/objects/test_creditcardpayment_entity.py +++ b/tests/unit/objects/test_creditcardpayment_entity.py @@ -9,7 +9,7 @@ def test_unicode(self): credit_card_payment = CreditCardPayment() credit_card_payment.Amount = 100 - self.assertEquals(str(credit_card_payment), "100") + self.assertEqual(str(credit_card_payment), "100") def test_valid_object_name(self): obj = CreditCardPayment() diff --git a/tests/unit/objects/test_creditmemo.py b/tests/unit/objects/test_creditmemo.py index 932f71c7..87de54e5 100644 --- a/tests/unit/objects/test_creditmemo.py +++ b/tests/unit/objects/test_creditmemo.py @@ -11,7 +11,7 @@ def test_unicode(self): detail = SalesItemLineDetail() detail.UnitPrice = 10 - self.assertEquals(str(detail), "10") + self.assertEqual(str(detail), "10") class CreditMemoTests(unittest.TestCase): @@ -19,7 +19,7 @@ def test_unicode(self): credit_memo = CreditMemo() credit_memo.TotalAmt = 1000 - self.assertEquals(str(credit_memo), "1000") + self.assertEqual(str(credit_memo), "1000") def test_valid_object_name(self): obj = CreditMemo() @@ -33,31 +33,31 @@ class DiscountLineDetailTests(unittest.TestCase): def test_init(self): discount_detail = DiscountLineDetail() - self.assertEquals(discount_detail.ClassRef, None) - self.assertEquals(discount_detail.TaxCodeRef, None) - self.assertEquals(discount_detail.Discount, None) + self.assertEqual(discount_detail.ClassRef, None) + self.assertEqual(discount_detail.TaxCodeRef, None) + self.assertEqual(discount_detail.Discount, None) class SubtotalLineDetailTests(unittest.TestCase): def test_init(self): detail = SubtotalLineDetail() - self.assertEquals(detail.ItemRef, None) + self.assertEqual(detail.ItemRef, None) class DiscountOverrideTests(unittest.TestCase): def test_init(self): discount_detail = DiscountOverride() - self.assertEquals(discount_detail.PercentBased, False) - self.assertEquals(discount_detail.DiscountPercent, 0) - self.assertEquals(discount_detail.DiscountAccountRef, None) - self.assertEquals(discount_detail.DiscountRef, None) + self.assertEqual(discount_detail.PercentBased, False) + self.assertEqual(discount_detail.DiscountPercent, 0) + self.assertEqual(discount_detail.DiscountAccountRef, None) + self.assertEqual(discount_detail.DiscountRef, None) class DescriptionLineDetailTests(unittest.TestCase): def test_init(self): detail = DescriptionLineDetail() - self.assertEquals(detail.ServiceDate, "") - self.assertEquals(detail.TaxCodeRef, None) + self.assertEqual(detail.ServiceDate, "") + self.assertEqual(detail.TaxCodeRef, None) diff --git a/tests/unit/objects/test_customer.py b/tests/unit/objects/test_customer.py index 4902b863..e0780f56 100644 --- a/tests/unit/objects/test_customer.py +++ b/tests/unit/objects/test_customer.py @@ -9,7 +9,7 @@ def test_unicode(self): customer = Customer() customer.DisplayName = "test" - self.assertEquals(str(customer), "test") + self.assertEqual(str(customer), "test") def test_to_ref(self): customer = Customer() @@ -18,9 +18,9 @@ def test_to_ref(self): ref = customer.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Customer") - self.assertEquals(ref.value, 100) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Customer") + self.assertEqual(ref.value, 100) def test_valid_object_name(self): obj = Customer() diff --git a/tests/unit/objects/test_customertype.py b/tests/unit/objects/test_customertype.py index a7639c53..c459d22d 100644 --- a/tests/unit/objects/test_customertype.py +++ b/tests/unit/objects/test_customertype.py @@ -9,7 +9,7 @@ def test_unicode(self): customer_type = CustomerType() customer_type.Name = "test" - self.assertEquals(str(customer_type), "test") + self.assertEqual(str(customer_type), "test") def test_valid_object_name(self): obj = CustomerType() diff --git a/tests/unit/objects/test_department.py b/tests/unit/objects/test_department.py index 152cc70d..90d130f6 100644 --- a/tests/unit/objects/test_department.py +++ b/tests/unit/objects/test_department.py @@ -9,7 +9,7 @@ def test_unicode(self): department = Department() department.Name = "test" - self.assertEquals(str(department), "test") + self.assertEqual(str(department), "test") def test_to_ref(self): department = Department() @@ -18,9 +18,9 @@ def test_to_ref(self): dept_ref = department.to_ref() - self.assertEquals(dept_ref.name, "test") - self.assertEquals(dept_ref.type, "Department") - self.assertEquals(dept_ref.value, 100) + self.assertEqual(dept_ref.name, "test") + self.assertEqual(dept_ref.type, "Department") + self.assertEqual(dept_ref.value, 100) def test_valid_object_name(self): obj = Department() diff --git a/tests/unit/objects/test_deposit.py b/tests/unit/objects/test_deposit.py index ac74273d..65d7a5bc 100644 --- a/tests/unit/objects/test_deposit.py +++ b/tests/unit/objects/test_deposit.py @@ -9,7 +9,7 @@ def test_unicode(self): deposit = Deposit() deposit.TotalAmt = 100 - self.assertEquals(str(deposit), "100") + self.assertEqual(str(deposit), "100") def test_valid_object_name(self): obj = Deposit() @@ -24,25 +24,25 @@ def test_unicode(self): deposit = DepositLine() deposit.Amount = 100 - self.assertEquals(str(deposit), "100") + self.assertEqual(str(deposit), "100") class CashBackInfoTests(unittest.TestCase): def test_init(self): cash_back_info = CashBackInfo() - self.assertEquals(cash_back_info.Amount, 0) - self.assertEquals(cash_back_info.Memo, "") - self.assertEquals(cash_back_info.AccountRef, None) + self.assertEqual(cash_back_info.Amount, 0) + self.assertEqual(cash_back_info.Memo, "") + self.assertEqual(cash_back_info.AccountRef, None) class DepositLineDetailTests(unittest.TestCase): def test_init(self): detail = DepositLineDetail() - self.assertEquals(detail.Entity, None) - self.assertEquals(detail.ClassRef, None) - self.assertEquals(detail.AccountRef, None) - self.assertEquals(detail.PaymentMethodRef, None) - self.assertEquals(detail.CheckNum, "") - self.assertEquals(detail.TxnType, None) + self.assertEqual(detail.Entity, None) + self.assertEqual(detail.ClassRef, None) + self.assertEqual(detail.AccountRef, None) + self.assertEqual(detail.PaymentMethodRef, None) + self.assertEqual(detail.CheckNum, "") + self.assertEqual(detail.TxnType, None) diff --git a/tests/unit/objects/test_detailline.py b/tests/unit/objects/test_detailline.py index c8c06b0a..298994fe 100644 --- a/tests/unit/objects/test_detailline.py +++ b/tests/unit/objects/test_detailline.py @@ -12,7 +12,7 @@ def test_unicode(self): detail.Description = "Product Description" detail.Amount = 100 - self.assertEquals(str(detail), "[1] Product Description 100") + self.assertEqual(str(detail), "[1] Product Description 100") class SalesItemLineDetailTests(unittest.TestCase): @@ -20,16 +20,16 @@ def test_unicode(self): sales_detail = SalesItemLineDetail() sales_detail.UnitPrice = 10 - self.assertEquals(str(sales_detail), "10") + self.assertEqual(str(sales_detail), "10") class DiscountOverrideTests(unittest.TestCase): def test_init(self): discount_override = DiscountOverride() - self.assertEquals(discount_override.DiscountPercent, 0) - self.assertEquals(discount_override.DiscountRef, None) - self.assertEquals(discount_override.DiscountAccountRef, None) + self.assertEqual(discount_override.DiscountPercent, 0) + self.assertEqual(discount_override.DiscountRef, None) + self.assertEqual(discount_override.DiscountAccountRef, None) self.assertFalse(discount_override.PercentBased) @@ -37,79 +37,79 @@ class DiscountLineDetailTesets(unittest.TestCase): def test_init(self): discount_detail = DiscountLineDetail() - self.assertEquals(discount_detail.Discount, None) - self.assertEquals(discount_detail.ClassRef, None) - self.assertEquals(discount_detail.TaxCodeRef, None) + self.assertEqual(discount_detail.Discount, None) + self.assertEqual(discount_detail.ClassRef, None) + self.assertEqual(discount_detail.TaxCodeRef, None) class SubtotalLineDetailTest(unittest.TestCase): def test_init(self): detail = SubtotalLineDetail() - self.assertEquals(detail.ItemRef, None) + self.assertEqual(detail.ItemRef, None) class SubtotalLineTest(unittest.TestCase): def test_init(self): subtotal_line = SubtotalLine() - self.assertEquals(subtotal_line.DetailType, "SubTotalLineDetail") - self.assertEquals(subtotal_line.SubtotalLineDetail, None) + self.assertEqual(subtotal_line.DetailType, "SubTotalLineDetail") + self.assertEqual(subtotal_line.SubtotalLineDetail, None) class DescriptionLineDetailTest(unittest.TestCase): def test_init(self): description_detail = DescriptionLineDetail() - self.assertEquals(description_detail.ServiceDate, "") - self.assertEquals(description_detail.TaxCodeRef, None) + self.assertEqual(description_detail.ServiceDate, "") + self.assertEqual(description_detail.TaxCodeRef, None) class SalesItemLineTest(unittest.TestCase): def test_init(self): line = SalesItemLine() - self.assertEquals(line.DetailType, "SalesItemLineDetail") - self.assertEquals(line.SalesItemLineDetail, None) + self.assertEqual(line.DetailType, "SalesItemLineDetail") + self.assertEqual(line.SalesItemLineDetail, None) class DiscountLineTest(unittest.TestCase): def test_init(self): line = DiscountLine() - self.assertEquals(line.DetailType, "DiscountLineDetail") - self.assertEquals(line.DiscountLineDetail, None) + self.assertEqual(line.DetailType, "DiscountLineDetail") + self.assertEqual(line.DiscountLineDetail, None) class GroupLineTest(unittest.TestCase): def test_init(self): line = GroupLine() - self.assertEquals(line.DetailType, "GroupLineDetail") - self.assertEquals(line.GroupLineDetail, None) + self.assertEqual(line.DetailType, "GroupLineDetail") + self.assertEqual(line.GroupLineDetail, None) class ItemBasedExpenseLineDetailTest(unittest.TestCase): def test_init(self): detail = ItemBasedExpenseLineDetail() - self.assertEquals(detail.BillableStatus, None) - self.assertEquals(detail.UnitPrice, 0) - self.assertEquals(detail.TaxInclusiveAmt, 0) - self.assertEquals(detail.Qty, 0) - self.assertEquals(detail.ItemRef, None) - self.assertEquals(detail.ClassRef, None) - self.assertEquals(detail.PriceLevelRef, None) - self.assertEquals(detail.TaxCodeRef, None) - self.assertEquals(detail.MarkupInfo, None) - self.assertEquals(detail.CustomerRef, None) + self.assertEqual(detail.BillableStatus, None) + self.assertEqual(detail.UnitPrice, 0) + self.assertEqual(detail.TaxInclusiveAmt, 0) + self.assertEqual(detail.Qty, 0) + self.assertEqual(detail.ItemRef, None) + self.assertEqual(detail.ClassRef, None) + self.assertEqual(detail.PriceLevelRef, None) + self.assertEqual(detail.TaxCodeRef, None) + self.assertEqual(detail.MarkupInfo, None) + self.assertEqual(detail.CustomerRef, None) class ItemBasedExpenseLineTests(unittest.TestCase): def test_unicode(self): line = ItemBasedExpenseLine() - self.assertEquals(line.DetailType, "ItemBasedExpenseLineDetail") - self.assertEquals(line.ItemBasedExpenseLineDetail, None) + self.assertEqual(line.DetailType, "ItemBasedExpenseLineDetail") + self.assertEqual(line.ItemBasedExpenseLineDetail, None) class AccountBasedExpenseLineDetailTests(unittest.TestCase): @@ -117,12 +117,12 @@ def test_unicode(self): acct_detail = AccountBasedExpenseLineDetail() acct_detail.BillableStatus = "test" - self.assertEquals(str(acct_detail), "test") + self.assertEqual(str(acct_detail), "test") class DescriptionOnlyLineTests(unittest.TestCase): def test_unicode(self): line = DescriptionOnlyLine() - self.assertEquals(line.DetailType, "DescriptionOnly") - self.assertEquals(line.DescriptionLineDetail, None) + self.assertEqual(line.DetailType, "DescriptionOnly") + self.assertEqual(line.DescriptionLineDetail, None) diff --git a/tests/unit/objects/test_employee.py b/tests/unit/objects/test_employee.py index 9b1db4d3..cf2f540f 100644 --- a/tests/unit/objects/test_employee.py +++ b/tests/unit/objects/test_employee.py @@ -9,7 +9,7 @@ def test_unicode(self): employee = Employee() employee.DisplayName = "test" - self.assertEquals(str(employee), "test") + self.assertEqual(str(employee), "test") def test_to_ref(self): employee = Employee() @@ -18,9 +18,9 @@ def test_to_ref(self): ref = employee.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Employee") - self.assertEquals(ref.value, 100) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Employee") + self.assertEqual(ref.value, 100) def test_valid_object_name(self): obj = Employee() diff --git a/tests/unit/objects/test_estimate.py b/tests/unit/objects/test_estimate.py index 6794acd7..f88be666 100644 --- a/tests/unit/objects/test_estimate.py +++ b/tests/unit/objects/test_estimate.py @@ -9,7 +9,7 @@ def test_unicode(self): estimate = Estimate() estimate.TotalAmt = 10 - self.assertEquals(str(estimate), "10") + self.assertEqual(str(estimate), "10") def test_valid_object_name(self): obj = Estimate() diff --git a/tests/unit/objects/test_exchangerate.py b/tests/unit/objects/test_exchangerate.py index d016cde7..6e00bd2a 100644 --- a/tests/unit/objects/test_exchangerate.py +++ b/tests/unit/objects/test_exchangerate.py @@ -9,7 +9,7 @@ def test_unicode(self): exchange_rate = ExchangeRate() exchange_rate.SourceCurrencyCode = "EUR" - self.assertEquals(str(exchange_rate), "EUR") + self.assertEqual(str(exchange_rate), "EUR") def test_valid_object_name(self): obj = ExchangeRate() diff --git a/tests/unit/objects/test_invoice.py b/tests/unit/objects/test_invoice.py index 27b75a3c..1536fa35 100644 --- a/tests/unit/objects/test_invoice.py +++ b/tests/unit/objects/test_invoice.py @@ -10,7 +10,7 @@ def test_unicode(self): invoice = Invoice() invoice.TotalAmt = 10 - self.assertEquals(str(invoice), "10") + self.assertEqual(str(invoice), "10") def test_to_LinkedTxn(self): invoice = Invoice() @@ -19,9 +19,9 @@ def test_to_LinkedTxn(self): linked_txn = invoice.to_linked_txn() - self.assertEquals(linked_txn.TxnId, invoice.Id) - self.assertEquals(linked_txn.TxnType, "Invoice") - self.assertEquals(linked_txn.TxnLineId, 1) + self.assertEqual(linked_txn.TxnId, invoice.Id) + self.assertEqual(linked_txn.TxnType, "Invoice") + self.assertEqual(linked_txn.TxnLineId, 1) def test_email_sent_true(self): invoice = Invoice() @@ -47,14 +47,14 @@ def test_to_ref(self): ref = invoice.to_ref() self.assertIsInstance(ref, Ref) - self.assertEquals(ref.type, "Invoice") - self.assertEquals(ref.name, 1) # should be DocNumber - self.assertEquals(ref.value, 2) # should be Id + self.assertEqual(ref.type, "Invoice") + self.assertEqual(ref.name, 1) # should be DocNumber + self.assertEqual(ref.value, 2) # should be Id class DeliveryInfoTests(unittest.TestCase): def test_init(self): info = DeliveryInfo() - self.assertEquals(info.DeliveryType, "") - self.assertEquals(info.DeliveryTime, "") + self.assertEqual(info.DeliveryType, "") + self.assertEqual(info.DeliveryTime, "") diff --git a/tests/unit/objects/test_item.py b/tests/unit/objects/test_item.py index c4734d89..cba055f7 100644 --- a/tests/unit/objects/test_item.py +++ b/tests/unit/objects/test_item.py @@ -9,7 +9,7 @@ def test_unicode(self): item = Item() item.Name = "test" - self.assertEquals(str(item), "test") + self.assertEqual(str(item), "test") def test_to_ref(self): item = Item() @@ -18,9 +18,9 @@ def test_to_ref(self): ref = item.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Item") - self.assertEquals(ref.value, 100) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Item") + self.assertEqual(ref.value, 100) def test_valid_object_name(self): obj = Item() diff --git a/tests/unit/objects/test_journalentry.py b/tests/unit/objects/test_journalentry.py index cd1e9d47..7f32b300 100644 --- a/tests/unit/objects/test_journalentry.py +++ b/tests/unit/objects/test_journalentry.py @@ -9,7 +9,7 @@ def test_unicode(self): journalentry = JournalEntry() journalentry.TotalAmt = 1000 - self.assertEquals(str(journalentry), '1000') + self.assertEqual(str(journalentry), '1000') def test_valid_object_name(self): obj = JournalEntry() @@ -23,28 +23,28 @@ class JournalEntryLineTests(unittest.TestCase): def test_init(self): journalentry = JournalEntryLine() - self.assertEquals(journalentry.DetailType, "JournalEntryLineDetail") - self.assertEquals(journalentry.JournalEntryLineDetail, None) + self.assertEqual(journalentry.DetailType, "JournalEntryLineDetail") + self.assertEqual(journalentry.JournalEntryLineDetail, None) class JournalEntryLineDetailTests(unittest.TestCase): def test_init(self): journalentry = JournalEntryLineDetail() - self.assertEquals(journalentry.PostingType, "") - self.assertEquals(journalentry.TaxApplicableOn, "Sales") - self.assertEquals(journalentry.TaxAmount, 0) - self.assertEquals(journalentry.BillableStatus, None) - self.assertEquals(journalentry.Entity, None) - self.assertEquals(journalentry.AccountRef, None) - self.assertEquals(journalentry.ClassRef, None) - self.assertEquals(journalentry.DepartmentRef, None) - self.assertEquals(journalentry.TaxCodeRef, None) + self.assertEqual(journalentry.PostingType, "") + self.assertEqual(journalentry.TaxApplicableOn, "Sales") + self.assertEqual(journalentry.TaxAmount, 0) + self.assertEqual(journalentry.BillableStatus, None) + self.assertEqual(journalentry.Entity, None) + self.assertEqual(journalentry.AccountRef, None) + self.assertEqual(journalentry.ClassRef, None) + self.assertEqual(journalentry.DepartmentRef, None) + self.assertEqual(journalentry.TaxCodeRef, None) class EntityTests(unittest.TestCase): def test_init(self): entity = Entity() - self.assertEquals(entity.Type, "") - self.assertEquals(entity.EntityRef, None) + self.assertEqual(entity.Type, "") + self.assertEqual(entity.EntityRef, None) diff --git a/tests/unit/objects/test_payment.py b/tests/unit/objects/test_payment.py index d8be81c3..d397da4b 100644 --- a/tests/unit/objects/test_payment.py +++ b/tests/unit/objects/test_payment.py @@ -9,7 +9,7 @@ def test_unicode(self): payment_line = PaymentLine() payment_line.Amount = 100 - self.assertEquals(str(payment_line), "100") + self.assertEqual(str(payment_line), "100") class PaymentTests(unittest.TestCase): @@ -17,7 +17,7 @@ def test_unicode(self): payment = Payment() payment.TotalAmt = 1000 - self.assertEquals(str(payment), '1000') + self.assertEqual(str(payment), '1000') def test_valid_object_name(self): obj = Payment() diff --git a/tests/unit/objects/test_paymentmethod.py b/tests/unit/objects/test_paymentmethod.py index 59788088..d8aabb8b 100644 --- a/tests/unit/objects/test_paymentmethod.py +++ b/tests/unit/objects/test_paymentmethod.py @@ -9,7 +9,7 @@ def test_unicode(self): payment_method = PaymentMethod() payment_method.Name = "test" - self.assertEquals(str(payment_method), "test") + self.assertEqual(str(payment_method), "test") def test_valid_object_name(self): obj = PaymentMethod() @@ -25,6 +25,6 @@ def test_to_ref(self): ref = obj.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "PaymentMethod") - self.assertEquals(ref.value, 12) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "PaymentMethod") + self.assertEqual(ref.value, 12) diff --git a/tests/unit/objects/test_preferences.py b/tests/unit/objects/test_preferences.py index 3c567681..85adb1ba 100644 --- a/tests/unit/objects/test_preferences.py +++ b/tests/unit/objects/test_preferences.py @@ -9,7 +9,7 @@ def test_unicode(self): preferences = Preferences() preferences.Id = 137 - self.assertEquals(str(preferences), "Preferences 137") + self.assertEqual(str(preferences), "Preferences 137") def test_valid_object_name(self): preferences = Preferences() diff --git a/tests/unit/objects/test_purchase.py b/tests/unit/objects/test_purchase.py index 5ab8766c..5a9dc80f 100644 --- a/tests/unit/objects/test_purchase.py +++ b/tests/unit/objects/test_purchase.py @@ -9,7 +9,7 @@ def test_unicode(self): purchase = Purchase() purchase.TotalAmt = 1000 - self.assertEquals(str(purchase), "1000") + self.assertEqual(str(purchase), "1000") def test_valid_object_name(self): obj = Purchase() diff --git a/tests/unit/objects/test_purchaseorder.py b/tests/unit/objects/test_purchaseorder.py index 102ae393..4e63296b 100644 --- a/tests/unit/objects/test_purchaseorder.py +++ b/tests/unit/objects/test_purchaseorder.py @@ -9,7 +9,7 @@ def test_unicode(self): purchase_order = PurchaseOrder() purchase_order.TotalAmt = 1000 - self.assertEquals(str(purchase_order), '1000') + self.assertEqual(str(purchase_order), '1000') def test_valid_object_name(self): obj = PurchaseOrder() diff --git a/tests/unit/objects/test_refundreceipt.py b/tests/unit/objects/test_refundreceipt.py index c7da7f91..32fef70f 100644 --- a/tests/unit/objects/test_refundreceipt.py +++ b/tests/unit/objects/test_refundreceipt.py @@ -9,7 +9,7 @@ def test_unicode(self): deposit = RefundReceipt() deposit.TotalAmt = 100 - self.assertEquals(str(deposit), "100") + self.assertEqual(str(deposit), "100") def test_valid_object_name(self): obj = RefundReceipt() diff --git a/tests/unit/objects/test_salesreceipt.py b/tests/unit/objects/test_salesreceipt.py index 141dc48f..cdba115e 100644 --- a/tests/unit/objects/test_salesreceipt.py +++ b/tests/unit/objects/test_salesreceipt.py @@ -9,7 +9,7 @@ def test_unicode(self): sales_receipt = SalesReceipt() sales_receipt.TotalAmt = 100 - self.assertEquals(str(sales_receipt), "100") + self.assertEqual(str(sales_receipt), "100") def test_valid_object_name(self): obj = SalesReceipt() diff --git a/tests/unit/objects/test_tax.py b/tests/unit/objects/test_tax.py index 6acb7ef2..6f3f84f8 100644 --- a/tests/unit/objects/test_tax.py +++ b/tests/unit/objects/test_tax.py @@ -8,7 +8,7 @@ def test_unicode(self): detail = TaxLineDetail() detail.TaxPercent = 10 - self.assertEquals(str(detail), "10") + self.assertEqual(str(detail), "10") class TaxLineTests(unittest.TestCase): @@ -16,7 +16,7 @@ def test_unicode(self): line = TaxLine() line.Amount = 100 - self.assertEquals(str(line), "100") + self.assertEqual(str(line), "100") class TxnTaxDetailTests(unittest.TestCase): @@ -24,4 +24,4 @@ def test_unicode(self): detail = TxnTaxDetail() detail.TotalTax = 100 - self.assertEquals(str(detail), "100") + self.assertEqual(str(detail), "100") diff --git a/tests/unit/objects/test_taxagency.py b/tests/unit/objects/test_taxagency.py index 12bf32a3..4b5f3d51 100644 --- a/tests/unit/objects/test_taxagency.py +++ b/tests/unit/objects/test_taxagency.py @@ -8,4 +8,4 @@ def test_unicode(self): deposit = TaxAgency() deposit.DisplayName = "test" - self.assertEquals(str(deposit), "test") + self.assertEqual(str(deposit), "test") diff --git a/tests/unit/objects/test_taxcode.py b/tests/unit/objects/test_taxcode.py index 89828f23..371ce7f5 100644 --- a/tests/unit/objects/test_taxcode.py +++ b/tests/unit/objects/test_taxcode.py @@ -9,7 +9,7 @@ def test_unicode(self): taxcode = TaxCode() taxcode.Name = "test" - self.assertEquals(str(taxcode), "test") + self.assertEqual(str(taxcode), "test") def test_valid_object_name(self): obj = TaxCode() @@ -24,21 +24,21 @@ def test_to_ref(self): taxcode.Name = "test" ref = taxcode.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "TaxCode") - self.assertEquals(ref.value, 2) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "TaxCode") + self.assertEqual(ref.value, 2) class TaxRateDetailTests(unittest.TestCase): def test_init(self): tax_rate = TaxRateDetail() - self.assertEquals(tax_rate.TaxOrder, 0) - self.assertEquals(tax_rate.TaxTypeApplicable, "") + self.assertEqual(tax_rate.TaxOrder, 0) + self.assertEqual(tax_rate.TaxTypeApplicable, "") class TaxRateListTests(unittest.TestCase): def test_init(self): tax_rate_list = TaxRateList() - self.assertEquals(tax_rate_list.TaxRateDetail, []) + self.assertEqual(tax_rate_list.TaxRateDetail, []) diff --git a/tests/unit/objects/test_taxrate.py b/tests/unit/objects/test_taxrate.py index 50a7a91c..91dfc295 100644 --- a/tests/unit/objects/test_taxrate.py +++ b/tests/unit/objects/test_taxrate.py @@ -9,7 +9,7 @@ def test_unicode(self): tax = TaxRate() tax.Name = "test" - self.assertEquals(str(tax), "test") + self.assertEqual(str(tax), "test") def test_valid_object_name(self): obj = TaxRate() diff --git a/tests/unit/objects/test_taxservice.py b/tests/unit/objects/test_taxservice.py index 7a8f3efd..9ec56402 100644 --- a/tests/unit/objects/test_taxservice.py +++ b/tests/unit/objects/test_taxservice.py @@ -8,7 +8,7 @@ def test_unicode(self): tax = TaxService() tax.TaxCode = "test" - self.assertEquals(str(tax), "test") + self.assertEqual(str(tax), "test") class TaxRateDetailsTests(unittest.TestCase): @@ -16,4 +16,4 @@ def test_unicode(self): tax = TaxRateDetails() tax.TaxRateName = "test" - self.assertEquals(str(tax), "test") \ No newline at end of file + self.assertEqual(str(tax), "test") \ No newline at end of file diff --git a/tests/unit/objects/test_term.py b/tests/unit/objects/test_term.py index 57c9f7b1..31d98779 100644 --- a/tests/unit/objects/test_term.py +++ b/tests/unit/objects/test_term.py @@ -9,7 +9,7 @@ def test_unicode(self): term = Term() term.Name = "test" - self.assertEquals(str(term), "test") + self.assertEqual(str(term), "test") def test_valid_object_name(self): obj = Term() @@ -25,6 +25,6 @@ def test_to_ref(self): ref = term.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Term") - self.assertEquals(ref.value, 100) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Term") + self.assertEqual(ref.value, 100) diff --git a/tests/unit/objects/test_timeactivity.py b/tests/unit/objects/test_timeactivity.py index 9663de21..fa9f870b 100644 --- a/tests/unit/objects/test_timeactivity.py +++ b/tests/unit/objects/test_timeactivity.py @@ -19,16 +19,16 @@ def test_unicode(self): time_activity.BreakMinutes = 60 time_activity.Description = "test" - self.assertEquals(str(time_activity), "test") - self.assertEquals(time_activity.TimeZone, "CST") - self.assertEquals(time_activity.BillableStatus, "test") - self.assertEquals(time_activity.Taxable, False) - self.assertEquals(time_activity.HourlyRate, 0) - self.assertEquals(time_activity.Hours, 1) - self.assertEquals(time_activity.Minutes, 60) - self.assertEquals(time_activity.BreakHours, 1) - self.assertEquals(time_activity.BreakMinutes, 60) - self.assertEquals(time_activity.Description, "test") + self.assertEqual(str(time_activity), "test") + self.assertEqual(time_activity.TimeZone, "CST") + self.assertEqual(time_activity.BillableStatus, "test") + self.assertEqual(time_activity.Taxable, False) + self.assertEqual(time_activity.HourlyRate, 0) + self.assertEqual(time_activity.Hours, 1) + self.assertEqual(time_activity.Minutes, 60) + self.assertEqual(time_activity.BreakHours, 1) + self.assertEqual(time_activity.BreakMinutes, 60) + self.assertEqual(time_activity.Description, "test") def test_valid_object_name(self): obj = TimeActivity() diff --git a/tests/unit/objects/test_trackingclass.py b/tests/unit/objects/test_trackingclass.py index 4b351d70..b397e08a 100644 --- a/tests/unit/objects/test_trackingclass.py +++ b/tests/unit/objects/test_trackingclass.py @@ -8,7 +8,7 @@ def test_unicode(self): cls = Class() cls.Name = "test" - self.assertEquals(str(cls), "test") + self.assertEqual(str(cls), "test") def test_to_ref(self): cls = Class() @@ -17,6 +17,6 @@ def test_to_ref(self): dept_ref = cls.to_ref() - self.assertEquals(dept_ref.name, "test") - self.assertEquals(dept_ref.type, "Class") - self.assertEquals(dept_ref.value, 100) + self.assertEqual(dept_ref.name, "test") + self.assertEqual(dept_ref.type, "Class") + self.assertEqual(dept_ref.value, 100) diff --git a/tests/unit/objects/test_transfer.py b/tests/unit/objects/test_transfer.py index f93bc56e..9ce2da1f 100644 --- a/tests/unit/objects/test_transfer.py +++ b/tests/unit/objects/test_transfer.py @@ -9,7 +9,7 @@ def test_unicode(self): transfer = Transfer() transfer.Amount = 100 - self.assertEquals(str(transfer), "100") + self.assertEqual(str(transfer), "100") def test_valid_object_name(self): obj = Transfer() diff --git a/tests/unit/objects/test_vendor.py b/tests/unit/objects/test_vendor.py index db7864d3..d4678420 100644 --- a/tests/unit/objects/test_vendor.py +++ b/tests/unit/objects/test_vendor.py @@ -9,7 +9,7 @@ def test_unicode(self): vendor = Vendor() vendor.DisplayName = "test" - self.assertEquals(str(vendor), "test") + self.assertEqual(str(vendor), "test") def test_to_ref(self): vendor = Vendor() @@ -18,9 +18,9 @@ def test_to_ref(self): ref = vendor.to_ref() - self.assertEquals(ref.name, "test") - self.assertEquals(ref.type, "Vendor") - self.assertEquals(ref.value, 100) + self.assertEqual(ref.name, "test") + self.assertEqual(ref.type, "Vendor") + self.assertEqual(ref.value, 100) def test_valid_object_name(self): obj = Vendor() @@ -34,5 +34,5 @@ class ContactInfoTests(unittest.TestCase): def test_init(self): contact_info = ContactInfo() - self.assertEquals(contact_info.Type, "") - self.assertEquals(contact_info.Telephone, None) + self.assertEqual(contact_info.Type, "") + self.assertEqual(contact_info.Telephone, None) diff --git a/tests/unit/objects/test_vendorcredit.py b/tests/unit/objects/test_vendorcredit.py index c3631e12..cabaed54 100644 --- a/tests/unit/objects/test_vendorcredit.py +++ b/tests/unit/objects/test_vendorcredit.py @@ -9,7 +9,7 @@ def test_unicode(self): vendor_credit = VendorCredit() vendor_credit.TotalAmt = 1000 - self.assertEquals(str(vendor_credit), "1000") + self.assertEqual(str(vendor_credit), "1000") def test_valid_object_name(self): obj = VendorCredit() diff --git a/tests/unit/test_batch.py b/tests/unit/test_batch.py index d8b762f0..e3bacd8f 100644 --- a/tests/unit/test_batch.py +++ b/tests/unit/test_batch.py @@ -49,13 +49,13 @@ def test_list_to_batch_request(self): obj_list = [self.object1, self.object2] batch_request = batch_mgr.list_to_batch_request(obj_list) - self.assertEquals(len(batch_request.BatchItemRequest), 2) + self.assertEqual(len(batch_request.BatchItemRequest), 2) batch_item = batch_request.BatchItemRequest[0] self.assertTrue(batch_item.bId) self.assertTrue(len(batch_item.bId) < 50) - self.assertEquals(batch_item.operation, "create") - self.assertEquals(batch_item.get_object(), self.object1) + self.assertEqual(batch_item.operation, "create") + self.assertEqual(batch_item.get_object(), self.object1) def test_batch_results_to_list(self): batch_mgr = batch.BatchManager("create") @@ -72,5 +72,5 @@ def test_batch_results_to_list(self): results = batch_mgr.batch_results_to_list(json_data, batch_request, self.obj_list) - self.assertEquals(len(results.faults), 1) - self.assertEquals(len(results.successes), 1) + self.assertEqual(len(results.faults), 1) + self.assertEqual(len(results.successes), 1) diff --git a/tests/unit/test_cdc.py b/tests/unit/test_cdc.py index df3d122c..d115177a 100644 --- a/tests/unit/test_cdc.py +++ b/tests/unit/test_cdc.py @@ -89,16 +89,16 @@ def setUp(self): def test_change_data_capture(self, make_request): make_request.return_value = self.cdc_json_response.copy() cdc_response = change_data_capture([Invoice, Customer], "2017-01-01T00:00:00") - self.assertEquals(1, len(cdc_response.Customer)) - self.assertEquals(2, len(cdc_response.Invoice)) + self.assertEqual(1, len(cdc_response.Customer)) + self.assertEqual(2, len(cdc_response.Invoice)) @patch('quickbooks.client.QuickBooks.make_request') def test_change_data_capture_with_timestamp(self, make_request): make_request.return_value = self.cdc_json_response.copy() cdc_response_with_datetime = change_data_capture([Invoice, Customer], datetime(2017, 1, 1, 0, 0, 0)) - self.assertEquals(1, len(cdc_response_with_datetime.Customer)) - self.assertEquals(2, len(cdc_response_with_datetime.Invoice)) + self.assertEqual(1, len(cdc_response_with_datetime.Customer)) + self.assertEqual(2, len(cdc_response_with_datetime.Invoice)) @patch('quickbooks.client.QuickBooks.make_request') def test_change_data_capture_with_empty_response(self, make_request): diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index bb551a1e..6b4fe93a 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -8,6 +8,7 @@ from quickbooks.exceptions import QuickbooksException, SevereException, AuthorizationException from quickbooks import client from quickbooks.objects.salesreceipt import SalesReceipt +from intuitlib.client import AuthClient TEST_SIGNATURE = 'nfPLN16u3vMvv08ghDs+dOkLuirEVDy5wAeG/lmM2OA=' @@ -17,8 +18,20 @@ class ClientTest(QuickbooksUnitTestCase): + def setUp(self): + super(ClientTest, self).setUp() + + self.auth_client = AuthClient( + client_id='CLIENTID', + client_secret='CLIENT_SECRET', + environment='sandbox', + redirect_uri='http://localhost:8000/callback', + ) + + self.auth_client.access_token = 'ACCESS_TOKEN' + + def tearDown(self): - client.QuickBooks.enable_global() self.qb_client = client.QuickBooks() self.qb_client._drop() @@ -30,33 +43,8 @@ def test_client_new(self): verifier_token=TEST_VERIFIER_TOKEN, ) - self.assertEquals(self.qb_client.company_id, "company_id") - self.assertEquals(self.qb_client.minorversion, 4) - - def test_client_updated(self): - self.qb_client = client.QuickBooks( - sandbox=False, - company_id="company_id", - ) - - self.qb_client2 = client.QuickBooks( - sandbox=True, - company_id="update_company_id", - ) - - self.assertEquals(self.qb_client.sandbox, True) - self.assertEquals(self.qb_client.company_id, "update_company_id") - - self.assertEquals(self.qb_client2.sandbox, True) - self.assertEquals(self.qb_client2.company_id, "update_company_id") - - def test_disable_global(self): - client.QuickBooks.disable_global() - self.qb_client = client.QuickBooks() - - self.assertFalse(self.qb_client.sandbox) - self.assertFalse(self.qb_client.company_id) - self.assertFalse(self.qb_client.minorversion) + self.assertEqual(self.qb_client.company_id, "company_id") + self.assertEqual(self.qb_client.minorversion, 4) def test_api_url(http://github.com/self): qb_client = client.QuickBooks(sandbox=False) @@ -65,8 +53,14 @@ def test_api_url(http://github.com/self): self.assertFalse("sandbox" in api_url) def test_api_url_sandbox(self): - qb_client = client.QuickBooks(sandbox=True) + qb_client = client.QuickBooks( + auth_client=self.auth_client, + refresh_token='REFRESH_TOKEN', + company_id='COMPANY_ID', + ) + api_url = qb_client.api_url + print(api_url) self.assertTrue("sandbox" in api_url) @@ -74,7 +68,7 @@ def test_isvalid_object_name_valid(self): qb_client = client.QuickBooks() result = qb_client.isvalid_object_name("Customer") - self.assertEquals(result, True) + self.assertEqual(result, True) def test_isvalid_object_name_invalid(self): qb_client = client.QuickBooks() @@ -90,7 +84,8 @@ def test_batch_operation(self, make_req): @patch('quickbooks.client.QuickBooks.post') def test_misc_operation(self, post): - qb_client = client.QuickBooks() + qb_client = client.QuickBooks(company_id='COMPANY_ID', auth_client=self.auth_client) + qb_client.misc_operation("end_point", "request_body") url = "https://sandbox-quickbooks.api.intuit.com/v3/company/COMPANY_ID/end_point" @@ -119,7 +114,7 @@ def test_update_object(self, post): @patch('quickbooks.client.QuickBooks.make_request') def test_update_object_with_request_id(self, make_req): - qb_client = client.QuickBooks() + qb_client = client.QuickBooks(auth_client=self.auth_client) qb_client.company_id = "1234" qb_client.update_object("Customer", "request_body", request_id="123") @@ -137,22 +132,16 @@ def test_get_current_user(self, get): @patch('quickbooks.client.QuickBooks.make_request') def test_get_report(self, make_req): - qb_client = client.QuickBooks() + qb_client = client.QuickBooks(auth_client=self.auth_client) qb_client.company_id = "1234" qb_client.get_report("profitandloss", {1: 2}) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/reports/profitandloss" make_req.assert_called_with("GET", url, params={1: 2}) - def test_get_instance(self): - qb_client = client.QuickBooks() - - instance = qb_client.get_instance() - self.assertEquals(qb_client, instance) - @patch('quickbooks.client.QuickBooks.make_request') def test_get_single_object(self, make_req): - qb_client = client.QuickBooks() + qb_client = client.QuickBooks(auth_client=self.auth_client) qb_client.company_id = "1234" qb_client.get_single_object("test", 1) diff --git a/tests/unit/test_exception.py b/tests/unit/test_exception.py index 38fadae3..393d6a2c 100644 --- a/tests/unit/test_exception.py +++ b/tests/unit/test_exception.py @@ -8,13 +8,13 @@ class QuickbooksExceptionTests(unittest.TestCase): def test_init(self): exception = QuickbooksException("message", 100, "detail") - self.assertEquals(exception.message, "message") - self.assertEquals(exception.error_code, 100) - self.assertEquals(exception.detail, "detail") + self.assertEqual(exception.message, "message") + self.assertEqual(exception.error_code, 100) + self.assertEqual(exception.detail, "detail") class AuthorizationExceptionTests(unittest.TestCase): def test_unicode(self): exception = AuthorizationException("message", detail="detail") - self.assertEquals(str(exception), "QB Auth Exception 0: message\ndetail") + self.assertEqual(str(exception), "QB Auth Exception 0: message\ndetail") diff --git a/tests/unit/test_helpers.py b/tests/unit/test_helpers.py index 90459864..e90fc47a 100644 --- a/tests/unit/test_helpers.py +++ b/tests/unit/test_helpers.py @@ -7,12 +7,12 @@ class HelpersTests(unittest.TestCase): def test_qb_date_format(self): result = qb_date_format(date(2016, 7, 22)) - self.assertEquals(result, '2016-07-22') + self.assertEqual(result, '2016-07-22') def test_qb_datetime_format(self): result = qb_datetime_format(datetime(2016, 7, 22, 10, 35, 00)) - self.assertEquals(result, '2016-07-22T10:35:00') + self.assertEqual(result, '2016-07-22T10:35:00') def test_qb_datetime_utc_offset_format(self): result = qb_datetime_utc_offset_format(datetime(2016, 7, 22, 10, 35, 00), '-06:00') - self.assertEquals(result, '2016-07-22T10:35:00-06:00') + self.assertEqual(result, '2016-07-22T10:35:00-06:00') diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index db920308..613543a5 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -31,7 +31,7 @@ def test_to_json(self): json = phone.to_json() - self.assertEquals(json, '{\n "FreeFormNumber": "555-555-5555"\n}') + self.assertEqual(json, '{\n "FreeFormNumber": "555-555-5555"\n}') class FromJsonMixinTest(unittest.TestCase): @@ -56,25 +56,25 @@ def test_from_json(self): entry = JournalEntry() new_obj = entry.from_json(self.json_data) - self.assertEquals(type(new_obj), JournalEntry) - self.assertEquals(new_obj.DocNumber, "123") - self.assertEquals(new_obj.TotalAmt, 100) + self.assertEqual(type(new_obj), JournalEntry) + self.assertEqual(new_obj.DocNumber, "123") + self.assertEqual(new_obj.TotalAmt, 100) line = new_obj.Line[0] - self.assertEquals(type(line), JournalEntryLine) - self.assertEquals(line.Description, "Test") - self.assertEquals(line.Amount, 25.54) - self.assertEquals(line.DetailType, "JournalEntryLineDetail") - self.assertEquals(line.JournalEntryLineDetail.PostingType, "Debit") + self.assertEqual(type(line), JournalEntryLine) + self.assertEqual(line.Description, "Test") + self.assertEqual(line.Amount, 25.54) + self.assertEqual(line.DetailType, "JournalEntryLineDetail") + self.assertEqual(line.JournalEntryLineDetail.PostingType, "Debit") def test_from_json_missing_detail_object(self): test_obj = QuickbooksBaseObject() new_obj = test_obj.from_json(self.json_data) - self.assertEquals(type(new_obj), QuickbooksBaseObject) - self.assertEquals(new_obj.DocNumber, "123") - self.assertEquals(new_obj.TotalAmt, 100) + self.assertEqual(type(new_obj), QuickbooksBaseObject) + self.assertEqual(new_obj.DocNumber, "123") + self.assertEqual(new_obj.TotalAmt, 100) class ToDictMixinTest(unittest.TestCase): @@ -131,7 +131,7 @@ def test_to_dict(self): 'TxnTaxDetail': None, } - self.assertEquals(expected, entry.to_dict()) + self.assertEqual(expected, entry.to_dict()) class ListMixinTest(QuickbooksUnitTestCase): @@ -228,7 +228,7 @@ class UpdateMixinTest(QuickbooksUnitTestCase): def test_save_create(self, create_object): department = Department() department.save(qb=self.qb_client) - create_object.assert_called_once_with("Department", department.to_json(), request_id=None) + create_object.assert_called_once_with("Department", department.to_json(), request_id=None, params=None) def test_save_create_with_qb(self): with patch.object(self.qb_client, 'create_object') as create_object: @@ -243,7 +243,7 @@ def test_save_update(self, update_object): json = department.to_json() department.save(qb=self.qb_client) - update_object.assert_called_once_with("Department", json, request_id=None) + update_object.assert_called_once_with("Department", json, request_id=None, params=None) def test_save_update_with_qb(self): with patch.object(self.qb_client, 'update_object') as update_object: @@ -286,50 +286,50 @@ def test_object_list_mixin_with_primitives(self): test_primitive_list = [1, 2, 3] test_subclass_primitive_obj = self.TestSubclass(test_primitive_list) - self.assertEquals(test_primitive_list, test_subclass_primitive_obj[:]) + self.assertEqual(test_primitive_list, test_subclass_primitive_obj[:]) for index in range(0, len(test_subclass_primitive_obj)): - self.assertEquals(test_primitive_list[index], test_subclass_primitive_obj[index]) + self.assertEqual(test_primitive_list[index], test_subclass_primitive_obj[index]) for prim in test_subclass_primitive_obj: - self.assertEquals(True, prim in test_subclass_primitive_obj) + self.assertEqual(True, prim in test_subclass_primitive_obj) - self.assertEquals(3, test_subclass_primitive_obj.pop()) + self.assertEqual(3, test_subclass_primitive_obj.pop()) test_subclass_primitive_obj.append(4) - self.assertEquals([1, 2, 4], test_subclass_primitive_obj[:]) + self.assertEqual([1, 2, 4], test_subclass_primitive_obj[:]) test_subclass_primitive_obj[0] = 5 - self.assertEquals([5, 2, 4], test_subclass_primitive_obj[:]) + self.assertEqual([5, 2, 4], test_subclass_primitive_obj[:]) del test_subclass_primitive_obj[0] - self.assertEquals([2, 4], test_subclass_primitive_obj[:]) + self.assertEqual([2, 4], test_subclass_primitive_obj[:]) - self.assertEquals([4, 2], list(reversed(test_subclass_primitive_obj))) + self.assertEqual([4, 2], list(reversed(test_subclass_primitive_obj))) def test_object_list_mixin_with_qb_objects(self): pn1, pn2, pn3, pn4, pn5 = PhoneNumber(), PhoneNumber(), PhoneNumber(), PhoneNumber(), PhoneNumber() test_object_list = [pn1, pn2, pn3] test_subclass_object_obj = self.TestSubclass(test_object_list) - self.assertEquals(test_object_list, test_subclass_object_obj[:]) + self.assertEqual(test_object_list, test_subclass_object_obj[:]) for index in range (0, len(test_subclass_object_obj)): - self.assertEquals(test_object_list[index], test_subclass_object_obj[index]) + self.assertEqual(test_object_list[index], test_subclass_object_obj[index]) for obj in test_subclass_object_obj: - self.assertEquals(True, obj in test_subclass_object_obj) + self.assertEqual(True, obj in test_subclass_object_obj) - self.assertEquals(pn3, test_subclass_object_obj.pop()) + self.assertEqual(pn3, test_subclass_object_obj.pop()) test_subclass_object_obj.append(pn4) - self.assertEquals([pn1, pn2, pn4], test_subclass_object_obj[:]) + self.assertEqual([pn1, pn2, pn4], test_subclass_object_obj[:]) test_subclass_object_obj[0] = pn5 - self.assertEquals([pn5, pn2, pn4], test_subclass_object_obj[:]) + self.assertEqual([pn5, pn2, pn4], test_subclass_object_obj[:]) del test_subclass_object_obj[0] - self.assertEquals([pn2, pn4], test_subclass_object_obj[:]) + self.assertEqual([pn2, pn4], test_subclass_object_obj[:]) - self.assertEquals([pn4, pn2], list(reversed(test_subclass_object_obj))) + self.assertEqual([pn4, pn2], list(reversed(test_subclass_object_obj))) class DeleteMixinTest(QuickbooksUnitTestCase): From 218af9f45fc4f482ed7485362e016a4b82844453 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 09:35:10 -0600 Subject: [PATCH 054/154] Remove travis-ci --- .travis.yml | 17 ----------------- README.md | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e2658f62..00000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: python -python: - - 3.5 - - 3.6 - - 3.7 - - 3.8 - - 3.9 - - 3.10 - - 3.11 -before_install: - - pip install coveralls -install: - - pip install -e . - -script: nosetests -w tests/unit --with-coverage --cover-package=quickbooks -after_success: - - coveralls diff --git a/README.md b/README.md index 2bbef167..13b58473 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ python-quickbooks ================= -[![](https://travis-ci.org/ej2/python-quickbooks.svg?branch=master)](https://travis-ci.org/ej2/python-quickbooks) +![](https://github.com/ej2/python-quickbooks/blob/master/.github/workflows/python-package.yml/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/ej2/python-quickbooks/badge.svg?branch=master)](https://coveralls.io/github/ej2/python-quickbooks?branch=master) [![](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/ej2/python-quickbooks/blob/master/LICENSE) From 5147a43f965af4fc893fe57f101532ba49b01894 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 09:55:16 -0600 Subject: [PATCH 055/154] readme update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 13b58473..802a9af1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ python-quickbooks ================= -![](https://github.com/ej2/python-quickbooks/blob/master/.github/workflows/python-package.yml/badge.svg) +[build](https://github.com/ej2/python-quickbooks/blob/master/.github/workflows/python-package.yml/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/ej2/python-quickbooks/badge.svg?branch=master)](https://coveralls.io/github/ej2/python-quickbooks?branch=master) [![](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/ej2/python-quickbooks/blob/master/LICENSE) From a5c38a95f65123df544c6cf4c5053437b7570c85 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 09:57:53 -0600 Subject: [PATCH 056/154] build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 802a9af1..261c7fc0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ python-quickbooks ================= -[build](https://github.com/ej2/python-quickbooks/blob/master/.github/workflows/python-package.yml/badge.svg) +[![Python package](https://github.com/ej2/python-quickbooks/actions/workflows/python-package.yml/badge.svg)](https://github.com/ej2/python-quickbooks/actions/workflows/python-package.yml) [![Coverage Status](https://coveralls.io/repos/github/ej2/python-quickbooks/badge.svg?branch=master)](https://coveralls.io/github/ej2/python-quickbooks?branch=master) [![](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/ej2/python-quickbooks/blob/master/LICENSE) From 1b96b237799163b299784b270063ca5b5eb3c9e9 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 10:38:15 -0600 Subject: [PATCH 057/154] pytest setup change --- setup.cfg | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/setup.cfg b/setup.cfg index 493746f0..c5f4a61f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,3 +7,11 @@ max-complexity = 10 filename = *.py format = default exclude =/quickbooks/objects/__init__.py + +[coverage:run] +branch = True +omit = src/db/env.py,src/db/versions/* # define paths to omit + +[coverage:report] +show_missing = True +skip_covered = True \ No newline at end of file From 205a8b3c206da64d967df097e339a6dd2af0a946 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 11:13:56 -0600 Subject: [PATCH 058/154] clean up --- quickbooks/client.py | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index 28c7b753..22b9edeb 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -152,7 +152,7 @@ def change_data_capture(self, entity_string, changed_since): def make_request(self, request_type, url, request_body=None, content_type='application/json', params=None, file_path=None, request_id=None): - print(params) + if not params: params = {} diff --git a/setup.cfg b/setup.cfg index c5f4a61f..4f71077b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,4 +14,4 @@ omit = src/db/env.py,src/db/versions/* # define paths to omit [coverage:report] show_missing = True -skip_covered = True \ No newline at end of file +skip_covered = True From 9d7e4a5379b06c395e12791a50e6f2f23c3fd271 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 8 Mar 2023 11:14:46 -0600 Subject: [PATCH 059/154] Update version number --- quickbooks/client.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index 22b9edeb..156530ac 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -152,7 +152,7 @@ def change_data_capture(self, entity_string, changed_since): def make_request(self, request_type, url, request_body=None, content_type='application/json', params=None, file_path=None, request_id=None): - + if not params: params = {} diff --git a/setup.py b/setup.py index afc330a7..a52279b6 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 2) +VERSION = (0, 9, 3) version = '.'.join(map(str, VERSION)) setup( From 0028961e0e7ca7b6f61919520ffee1152f796f49 Mon Sep 17 00:00:00 2001 From: "Nicholas Nadeau, Ph.D., P.Eng" <6395915+engnadeau@users.noreply.github.com> Date: Sun, 28 May 2023 10:35:44 -0400 Subject: [PATCH 060/154] docs: added pypi link and installation section --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 261c7fc0..ea09ef75 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ python-quickbooks [![Python package](https://github.com/ej2/python-quickbooks/actions/workflows/python-package.yml/badge.svg)](https://github.com/ej2/python-quickbooks/actions/workflows/python-package.yml) [![Coverage Status](https://coveralls.io/repos/github/ej2/python-quickbooks/badge.svg?branch=master)](https://coveralls.io/github/ej2/python-quickbooks?branch=master) [![](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/ej2/python-quickbooks/blob/master/LICENSE) +[![PyPI](https://img.shields.io/pypi/v/python-quickbooks)](https://pypi.org/project/python-quickbooks/) A Python 3 library for accessing the Quickbooks API. Complete rework of [quickbooks-python](https://github.com/troolee/quickbooks-python). @@ -14,6 +15,13 @@ You can find additional examples of usage in [Integration tests folder](https:// For information about contributing, see the [Contributing Page](https://github.com/ej2/python-quickbooks/blob/master/contributing.md). +Installation +------------ + +```bash +pip install python-quickbooks +``` + QuickBooks OAuth ------------------------------------------------ From 10c47a95c829a4bb2dcf978e6f2f355fc5ebc6ae Mon Sep 17 00:00:00 2001 From: "Jared M. Smith" Date: Fri, 28 Jul 2023 17:50:03 -0500 Subject: [PATCH 061/154] Update detailline.py --- quickbooks/objects/detailline.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index c12b31e1..094287ee 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -115,7 +115,6 @@ def __init__(self): self.UnitPrice = 0 self.Qty = 0 self.ServiceDate = "" - self.TaxInclusiveAmt = 0 self.MarkupInfo = None self.ItemRef = None @@ -177,8 +176,6 @@ class AccountBasedExpenseLineDetail(QuickbooksBaseObject): def __init__(self): super(AccountBasedExpenseLineDetail, self).__init__() self.BillableStatus = None - self.TaxAmount = 0 - self.TaxInclusiveAmt = 0 self.CustomerRef = None self.AccountRef = None @@ -237,7 +234,6 @@ def __init__(self): super(ItemBasedExpenseLineDetail, self).__init__() self.BillableStatus = None self.UnitPrice = 0 - self.TaxInclusiveAmt = 0 self.Qty = 0 self.ItemRef = None self.ClassRef = None From 4335643532922b2ba9811aa941e4422c326cda1c Mon Sep 17 00:00:00 2001 From: "Jared M. Smith" Date: Fri, 28 Jul 2023 17:53:31 -0500 Subject: [PATCH 062/154] Update test_detailline.py --- tests/unit/objects/test_detailline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/objects/test_detailline.py b/tests/unit/objects/test_detailline.py index 298994fe..a0bf19df 100644 --- a/tests/unit/objects/test_detailline.py +++ b/tests/unit/objects/test_detailline.py @@ -94,7 +94,6 @@ def test_init(self): self.assertEqual(detail.BillableStatus, None) self.assertEqual(detail.UnitPrice, 0) - self.assertEqual(detail.TaxInclusiveAmt, 0) self.assertEqual(detail.Qty, 0) self.assertEqual(detail.ItemRef, None) self.assertEqual(detail.ClassRef, None) From 8dbbb55a1e9033c1ce3cbdb685d27d0030fea511 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 28 Aug 2023 11:32:56 -0500 Subject: [PATCH 063/154] Remove six --- Pipfile | 1 - quickbooks/mixins.py | 12 +++------- quickbooks/objects/account.py | 2 -- quickbooks/objects/attachable.py | 2 -- quickbooks/objects/base.py | 10 --------- quickbooks/objects/batchrequest.py | 2 -- quickbooks/objects/bill.py | 4 ---- quickbooks/objects/billpayment.py | 4 ---- quickbooks/objects/budget.py | 4 ---- quickbooks/objects/changedatacapture.py | 12 +++++----- quickbooks/objects/company_info.py | 2 -- quickbooks/objects/companycurrency.py | 2 -- .../objects/creditcardpayment_entity.py | 2 -- quickbooks/objects/creditmemo.py | 3 --- quickbooks/objects/customer.py | 2 -- quickbooks/objects/customertype.py | 2 -- quickbooks/objects/department.py | 2 -- quickbooks/objects/deposit.py | 3 --- quickbooks/objects/detailline.py | 5 ----- quickbooks/objects/employee.py | 2 -- quickbooks/objects/estimate.py | 2 -- quickbooks/objects/exchangerate.py | 4 ---- quickbooks/objects/invoice.py | 2 -- quickbooks/objects/item.py | 2 -- quickbooks/objects/journalentry.py | 4 +--- quickbooks/objects/payment.py | 3 --- quickbooks/objects/paymentmethod.py | 3 --- quickbooks/objects/preferences.py | 4 ---- quickbooks/objects/purchase.py | 3 --- quickbooks/objects/purchaseorder.py | 3 --- quickbooks/objects/recurringtransaction.py | 16 ++++++-------- quickbooks/objects/refundreceipt.py | 8 ++----- quickbooks/objects/salesreceipt.py | 2 -- quickbooks/objects/tax.py | 4 ---- quickbooks/objects/taxagency.py | 2 -- quickbooks/objects/taxcode.py | 2 -- quickbooks/objects/taxrate.py | 5 ----- quickbooks/objects/taxservice.py | 3 --- quickbooks/objects/term.py | 3 --- quickbooks/objects/timeactivity.py | 2 -- quickbooks/objects/trackingclass.py | 2 -- quickbooks/objects/transfer.py | 2 -- quickbooks/objects/vendor.py | 2 -- quickbooks/objects/vendorcredit.py | 5 +---- quickbooks/utils.py | 22 ++----------------- requirements.txt | 5 ++--- setup.py | 7 +++--- 47 files changed, 27 insertions(+), 173 deletions(-) diff --git a/Pipfile b/Pipfile index 0e568b45..e1c60e62 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,6 @@ intuit-oauth = "==1.2.4" rauth = ">=0.7.3" requests = ">=2.26.0" simplejson = ">=3.17.0" -six = ">=1.14.0" nose = "*" coverage = "*" twine = "*" diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index c22ef309..22c66728 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -3,7 +3,6 @@ try: import simplejson as json except ImportError: import json -import six from .utils import build_where_clause, build_choose_clause from .client import QuickBooks from .exceptions import QuickbooksException @@ -70,14 +69,9 @@ def to_dict(obj, classkey=None): elif hasattr(obj, "__iter__") and not isinstance(obj, str): return [to_dict(v, classkey) for v in obj] elif hasattr(obj, "__dict__"): - if six.PY2: - data = dict([(key, to_dict(value, classkey)) - for key, value in obj.__dict__.iteritems() - if not callable(value) and not key.startswith('_')]) - else: - data = dict([(key, to_dict(value, classkey)) - for key, value in obj.__dict__.items() - if not callable(value) and not key.startswith('_')]) + data = dict([(key, to_dict(value, classkey)) + for key, value in obj.__dict__.items() + if not callable(value) and not key.startswith('_')]) if classkey is not None and hasattr(obj, "__class__"): data[classkey] = obj.__class__.__name__ diff --git a/quickbooks/objects/account.py b/quickbooks/objects/account.py index 5f30eb25..1c7f7e9f 100644 --- a/quickbooks/objects/account.py +++ b/quickbooks/objects/account.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity -@python_2_unicode_compatible class Account(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: Account is a component of a Chart Of Accounts, and is part of a Ledger. Used to record a total diff --git a/quickbooks/objects/attachable.py b/quickbooks/objects/attachable.py index a45625cd..e7d23d05 100644 --- a/quickbooks/objects/attachable.py +++ b/quickbooks/objects/attachable.py @@ -1,10 +1,8 @@ -from six import python_2_unicode_compatible from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, AttachableRef from ..client import QuickBooks from ..mixins import DeleteMixin -@python_2_unicode_compatible class Attachable(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: This page covers the Attachable, Upload, and Download resources used for attachment management. Attachments are supplemental information linked to a transaction or Item object. They can be files, notes, or a combination of both. diff --git a/quickbooks/objects/base.py b/quickbooks/objects/base.py index 11c6dd55..c6b1afd2 100644 --- a/quickbooks/objects/base.py +++ b/quickbooks/objects/base.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from ..mixins import ToDictMixin, ToJsonMixin, FromJsonMixin, ListMixin, ReadMixin, UpdateMixin @@ -24,7 +23,6 @@ class QuickbooksReadOnlyObject(QuickbooksBaseObject, ReadMixin, ListMixin): pass -@python_2_unicode_compatible class MetaData(FromJsonMixin): def __init__(self): self.CreateTime = "" @@ -44,7 +42,6 @@ def to_linked_txn(self): return linked_txn -@python_2_unicode_compatible class Address(QuickbooksBaseObject): def __init__(self): self.Id = None @@ -65,7 +62,6 @@ def __str__(self): return "{0} {1}, {2} {3}".format(self.Line1, self.City, self.CountrySubDivisionCode, self.PostalCode) -@python_2_unicode_compatible class PhoneNumber(ToJsonMixin, FromJsonMixin, ToDictMixin): def __init__(self): self.FreeFormNumber = "" @@ -74,7 +70,6 @@ def __str__(self): return self.FreeFormNumber -@python_2_unicode_compatible class EmailAddress(QuickbooksBaseObject): def __init__(self): self.Address = "" @@ -83,7 +78,6 @@ def __str__(self): return self.Address -@python_2_unicode_compatible class WebAddress(QuickbooksBaseObject): def __init__(self): self.URI = "" @@ -92,7 +86,6 @@ def __str__(self): return self.URI -@python_2_unicode_compatible class Ref(QuickbooksBaseObject): def __init__(self): self.value = "" @@ -103,7 +96,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class CustomField(QuickbooksBaseObject): def __init__(self): self.DefinitionId = "" @@ -115,7 +107,6 @@ def __str__(self): return self.Name -@python_2_unicode_compatible class LinkedTxn(QuickbooksBaseObject): qbo_object_name = "LinkedTxn" @@ -129,7 +120,6 @@ def __str__(self): return str(self.TxnId) -@python_2_unicode_compatible class CustomerMemo(QuickbooksBaseObject): def __init__(self): super(CustomerMemo, self).__init__() diff --git a/quickbooks/objects/batchrequest.py b/quickbooks/objects/batchrequest.py index 520419b3..2f7aecbc 100644 --- a/quickbooks/objects/batchrequest.py +++ b/quickbooks/objects/batchrequest.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from ..mixins import ToJsonMixin, FromJsonMixin @@ -8,7 +7,6 @@ class BatchOperation(object): DELETE = "delete" -@python_2_unicode_compatible class FaultError(FromJsonMixin): qbo_object_name = "Error" diff --git a/quickbooks/objects/bill.py b/quickbooks/objects/bill.py index 013ac92b..834da6a4 100644 --- a/quickbooks/objects/bill.py +++ b/quickbooks/objects/bill.py @@ -1,5 +1,3 @@ -from six import python_2_unicode_compatible - from quickbooks.objects.detailline import DetailLine, ItemBasedExpenseLine, AccountBasedExpenseLine, \ TDSLine from .base import Ref, LinkedTxn, QuickbooksManagedObject, QuickbooksTransactionEntity, \ @@ -8,7 +6,6 @@ from ..mixins import DeleteMixin -@python_2_unicode_compatible class Bill(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: A Bill entity is an AP transaction representing a request-for-payment from a third party for @@ -79,4 +76,3 @@ def to_ref(self): ref.value = self.Id return ref - diff --git a/quickbooks/objects/billpayment.py b/quickbooks/objects/billpayment.py index 6fd1e460..3f175d95 100644 --- a/quickbooks/objects/billpayment.py +++ b/quickbooks/objects/billpayment.py @@ -1,10 +1,8 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, LinkedTxn, QuickbooksManagedObject, LinkedTxnMixin, \ QuickbooksTransactionEntity from ..mixins import DeleteMixin -@python_2_unicode_compatible class CheckPayment(QuickbooksBaseObject): class_dict = { "BankAccountRef": Ref @@ -33,7 +31,6 @@ def __init__(self): self.CCAccountRef = None -@python_2_unicode_compatible class BillPaymentLine(QuickbooksBaseObject): list_dict = { "LinkedTxn": LinkedTxn @@ -50,7 +47,6 @@ def __str__(self): return str(self.Amount) -@python_2_unicode_compatible class BillPayment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: A BillPayment entity represents the financial transaction of payment diff --git a/quickbooks/objects/budget.py b/quickbooks/objects/budget.py index 17cc6a53..442bd845 100644 --- a/quickbooks/objects/budget.py +++ b/quickbooks/objects/budget.py @@ -1,9 +1,7 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, QuickbooksTransactionEntity, \ QuickbooksReadOnlyObject -@python_2_unicode_compatible class BudgetDetail(QuickbooksBaseObject): class_dict = { "AccountRef": Ref, @@ -26,7 +24,6 @@ def __str__(self): return str(self.Amount) -@python_2_unicode_compatible class Budget(QuickbooksReadOnlyObject, QuickbooksTransactionEntity): """ QBO definition: The Budget endpoint allows you to retrieve the current state of budgets already set up in the user's @@ -56,4 +53,3 @@ def __init__(self): def __str__(self): return self.Name - diff --git a/quickbooks/objects/changedatacapture.py b/quickbooks/objects/changedatacapture.py index ee628dac..d11a527a 100644 --- a/quickbooks/objects/changedatacapture.py +++ b/quickbooks/objects/changedatacapture.py @@ -2,14 +2,14 @@ class CDCResponse(FromJsonMixin): - qbo_object_name = "CDCResponse" + qbo_object_name = "CDCResponse" - def __init__(self): - super(CDCResponse, self).__init__() + def __init__(self): + super(CDCResponse, self).__init__() class QueryResponse(FromJsonMixin, ObjectListMixin): - qbo_object_name = "QueryResponse" + qbo_object_name = "QueryResponse" - def __init__(self): - super(QueryResponse, self).__init__() + def __init__(self): + super(QueryResponse, self).__init__() diff --git a/quickbooks/objects/company_info.py b/quickbooks/objects/company_info.py index 23194315..87ddb60d 100644 --- a/quickbooks/objects/company_info.py +++ b/quickbooks/objects/company_info.py @@ -1,9 +1,7 @@ -from six import python_2_unicode_compatible from .base import Address, PhoneNumber, EmailAddress, WebAddress, \ QuickbooksManagedObject, Ref, MetaData -@python_2_unicode_compatible class CompanyInfo(QuickbooksManagedObject): """ QBO definition: The CompanyInfo entity contains basic company information. diff --git a/quickbooks/objects/companycurrency.py b/quickbooks/objects/companycurrency.py index 90d0ff66..b4f788ea 100644 --- a/quickbooks/objects/companycurrency.py +++ b/quickbooks/objects/companycurrency.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksManagedObject, QuickbooksTransactionEntity, Ref, CustomField, MetaData -@python_2_unicode_compatible class CompanyCurrency(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: Applicable only for those companies that enable multicurrency, a companycurrency object diff --git a/quickbooks/objects/creditcardpayment_entity.py b/quickbooks/objects/creditcardpayment_entity.py index 7d62ded5..9b4b2877 100644 --- a/quickbooks/objects/creditcardpayment_entity.py +++ b/quickbooks/objects/creditcardpayment_entity.py @@ -1,9 +1,7 @@ -from six import python_2_unicode_compatible from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, MetaData from ..mixins import DeleteMixin -@python_2_unicode_compatible class CreditCardPayment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: A Represents a financial transaction to record a Credit Card balance payment diff --git a/quickbooks/objects/creditmemo.py b/quickbooks/objects/creditmemo.py index a92e7f0c..9cfcc876 100644 --- a/quickbooks/objects/creditmemo.py +++ b/quickbooks/objects/creditmemo.py @@ -1,5 +1,3 @@ -from six import python_2_unicode_compatible - from quickbooks.objects.detailline import SalesItemLine, SubtotalLine, DiscountLine, DescriptionOnlyLine, DetailLine from .base import Address, EmailAddress, Ref, CustomField, CustomerMemo, QuickbooksManagedObject, \ LinkedTxnMixin, QuickbooksTransactionEntity @@ -7,7 +5,6 @@ from ..mixins import DeleteMixin -@python_2_unicode_compatible class CreditMemo(DeleteMixin, QuickbooksTransactionEntity, QuickbooksManagedObject, LinkedTxnMixin): """ QBO definition: The CreditMemo is a financial transaction representing a refund or credit of payment or part diff --git a/quickbooks/objects/customer.py b/quickbooks/objects/customer.py index f2e30d16..2bf0f19b 100644 --- a/quickbooks/objects/customer.py +++ b/quickbooks/objects/customer.py @@ -1,9 +1,7 @@ -from six import python_2_unicode_compatible from .base import Address, PhoneNumber, EmailAddress, WebAddress, Ref, QuickbooksManagedObject, \ QuickbooksTransactionEntity -@python_2_unicode_compatible class Customer(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: A customer is a consumer of the service or product that your business offers. The Customer object diff --git a/quickbooks/objects/customertype.py b/quickbooks/objects/customertype.py index f45bcc2f..af41b3a1 100644 --- a/quickbooks/objects/customertype.py +++ b/quickbooks/objects/customertype.py @@ -1,9 +1,7 @@ -from six import python_2_unicode_compatible from .base import Address, PhoneNumber, EmailAddress, WebAddress, MetaData, QuickbooksReadOnlyObject, \ QuickbooksTransactionEntity -@python_2_unicode_compatible class CustomerType(QuickbooksReadOnlyObject, QuickbooksTransactionEntity): """ QBO definition: Customer types allow categorizing customers in ways that are meaningful to the business. diff --git a/quickbooks/objects/department.py b/quickbooks/objects/department.py index 60465f9b..f81ce49a 100644 --- a/quickbooks/objects/department.py +++ b/quickbooks/objects/department.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksManagedObject, QuickbooksTransactionEntity, Ref -@python_2_unicode_compatible class Department(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: The Department entity provides a way to track different segments of the business, divisions, or diff --git a/quickbooks/objects/deposit.py b/quickbooks/objects/deposit.py index 1b00a039..a8b0c54f 100644 --- a/quickbooks/objects/deposit.py +++ b/quickbooks/objects/deposit.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, LinkedTxn, QuickbooksManagedObject, LinkedTxnMixin, \ QuickbooksTransactionEntity, CustomField, AttachableRef from ..mixins import DeleteMixin @@ -35,7 +34,6 @@ def __init__(self): self.PaymentMethodRef = None -@python_2_unicode_compatible class DepositLine(QuickbooksBaseObject): class_dict = { "DepositToAccountRef": Ref, @@ -63,7 +61,6 @@ def __str__(self): return str(self.Amount) -@python_2_unicode_compatible class Deposit(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: A deposit object is a transaction that records one or more deposits of the following types: diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index c12b31e1..f9b89fdf 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, CustomField, LinkedTxn, MarkupInfo -@python_2_unicode_compatible class DetailLine(QuickbooksBaseObject): list_dict = { "LinkedTxn": LinkedTxn, @@ -100,7 +98,6 @@ def __init__(self): self.TaxCodeRef = None -@python_2_unicode_compatible class SalesItemLineDetail(QuickbooksBaseObject): class_dict = { "ItemRef": Ref, @@ -164,7 +161,6 @@ def __init__(self): self.DescriptionLineDetail = None -@python_2_unicode_compatible class AccountBasedExpenseLineDetail(QuickbooksBaseObject): class_dict = { "CustomerRef": Ref, @@ -201,7 +197,6 @@ def __init__(self): self.AccountBasedExpenseLineDetail = None -@python_2_unicode_compatible class TDSLineDetail(QuickbooksBaseObject): def __init__(self): super(TDSLineDetail, self).__init__() diff --git a/quickbooks/objects/employee.py b/quickbooks/objects/employee.py index d9f49adf..8e1636f5 100644 --- a/quickbooks/objects/employee.py +++ b/quickbooks/objects/employee.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import Address, PhoneNumber, QuickbooksManagedObject, QuickbooksTransactionEntity, Ref -@python_2_unicode_compatible class Employee(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: Employee represents the people who are working for the company. diff --git a/quickbooks/objects/estimate.py b/quickbooks/objects/estimate.py index 32bafa9e..6a9d5966 100644 --- a/quickbooks/objects/estimate.py +++ b/quickbooks/objects/estimate.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import CustomField, Ref, CustomerMemo, Address, EmailAddress, QuickbooksManagedObject, \ LinkedTxnMixin, QuickbooksTransactionEntity, LinkedTxn from .tax import TxnTaxDetail @@ -6,7 +5,6 @@ from ..mixins import QuickbooksPdfDownloadable, DeleteMixin, SendMixin -@python_2_unicode_compatible class Estimate(DeleteMixin, QuickbooksPdfDownloadable, QuickbooksManagedObject, diff --git a/quickbooks/objects/exchangerate.py b/quickbooks/objects/exchangerate.py index 15d61728..4168c9b9 100644 --- a/quickbooks/objects/exchangerate.py +++ b/quickbooks/objects/exchangerate.py @@ -1,16 +1,12 @@ -from six import python_2_unicode_compatible - from quickbooks.mixins import ListMixin, UpdateNoIdMixin, FromJsonMixin from .base import CustomField, QuickbooksBaseObject -@python_2_unicode_compatible class ExchangeRateMetaData(FromJsonMixin): def __init__(self): self.LastUpdatedTime = "" -@python_2_unicode_compatible class ExchangeRate(QuickbooksBaseObject, ListMixin, UpdateNoIdMixin): """ QBO definition: Applicable only for those companies that enable multicurrency, diff --git a/quickbooks/objects/invoice.py b/quickbooks/objects/invoice.py index 166ba499..c3b923f3 100644 --- a/quickbooks/objects/invoice.py +++ b/quickbooks/objects/invoice.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, CustomField, Address, EmailAddress, CustomerMemo, QuickbooksManagedObject, \ QuickbooksTransactionEntity, LinkedTxn, LinkedTxnMixin, MetaData from .tax import TxnTaxDetail @@ -13,7 +12,6 @@ def __init__(self): self.DeliveryTime = "" -@python_2_unicode_compatible class Invoice(DeleteMixin, QuickbooksPdfDownloadable, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, SendMixin, VoidMixin): """ diff --git a/quickbooks/objects/item.py b/quickbooks/objects/item.py index 123b8484..c8e6ad19 100644 --- a/quickbooks/objects/item.py +++ b/quickbooks/objects/item.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity -@python_2_unicode_compatible class Item(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: An item is a thing that your company buys, sells, or re-sells, diff --git a/quickbooks/objects/journalentry.py b/quickbooks/objects/journalentry.py index 0380bfe0..d1c5e9fa 100644 --- a/quickbooks/objects/journalentry.py +++ b/quickbooks/objects/journalentry.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, \ LinkedTxnMixin from .tax import TxnTaxDetail @@ -51,7 +50,6 @@ def __init__(self): self.JournalEntryLineDetail = None -@python_2_unicode_compatible class JournalEntry(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: Journal Entry is a transaction in which: @@ -83,7 +81,7 @@ def __init__(self): super(JournalEntry, self).__init__() self.Adjustment = False self.TxnDate = "" - #self.TxnSource = "" + # self.TxnSource = "" self.DocNumber = "" self.PrivateNote = "" self.TotalAmt = 0 diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index f82ce744..07e15222 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, LinkedTxn, \ QuickbooksManagedObject, QuickbooksTransactionEntity, \ LinkedTxnMixin, MetaData @@ -8,7 +7,6 @@ import json -@python_2_unicode_compatible class PaymentLine(QuickbooksBaseObject): list_dict = { "LinkedTxn": LinkedTxn, @@ -23,7 +21,6 @@ def __str__(self): return str(self.Amount) -@python_2_unicode_compatible class Payment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: A Payment entity records a payment in QuickBooks. The payment can be diff --git a/quickbooks/objects/paymentmethod.py b/quickbooks/objects/paymentmethod.py index dd4da4c5..e33089c6 100644 --- a/quickbooks/objects/paymentmethod.py +++ b/quickbooks/objects/paymentmethod.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksManagedObject, QuickbooksTransactionEntity, Ref -@python_2_unicode_compatible class PaymentMethod(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: The PaymentMethod entity provides the method of payment for received goods. Delete is achieved by setting the @@ -31,4 +29,3 @@ def to_ref(self): ref.value = self.Id return ref - diff --git a/quickbooks/objects/preferences.py b/quickbooks/objects/preferences.py index d7e7e5bc..49aa23c9 100644 --- a/quickbooks/objects/preferences.py +++ b/quickbooks/objects/preferences.py @@ -1,10 +1,7 @@ -from six import python_2_unicode_compatible - from quickbooks.mixins import PrefMixin, UpdateNoIdMixin from .base import QuickbooksBaseObject, QuickbooksTransactionEntity, Ref, EmailAddress -@python_2_unicode_compatible class PreferencesCustomField(QuickbooksBaseObject): def __init__(self): self.Type = "" @@ -202,7 +199,6 @@ def __init__(self): self.MultiCurrencyEnabled = False -@python_2_unicode_compatible class Preferences(PrefMixin, UpdateNoIdMixin, QuickbooksTransactionEntity): """ QBO definition: The Preferences resource represents a set of company preferences that diff --git a/quickbooks/objects/purchase.py b/quickbooks/objects/purchase.py index 49264e22..62b2c722 100644 --- a/quickbooks/objects/purchase.py +++ b/quickbooks/objects/purchase.py @@ -1,5 +1,3 @@ -from six import python_2_unicode_compatible - from quickbooks.objects.detailline import DetailLine, AccountBasedExpenseLine, ItemBasedExpenseLine, \ TDSLine from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, \ @@ -8,7 +6,6 @@ from ..mixins import DeleteMixin -@python_2_unicode_compatible class Purchase(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: This entity represents expenses, such as a purchase made from a vendor. diff --git a/quickbooks/objects/purchaseorder.py b/quickbooks/objects/purchaseorder.py index 6c6ac244..563391ea 100644 --- a/quickbooks/objects/purchaseorder.py +++ b/quickbooks/objects/purchaseorder.py @@ -1,5 +1,3 @@ -from six import python_2_unicode_compatible - from quickbooks.objects.detailline import DetailLine, ItemBasedExpenseLine, AccountBasedExpenseLine, \ TDSLine from .base import Ref, Address, QuickbooksManagedObject, LinkedTxnMixin, \ @@ -8,7 +6,6 @@ from ..mixins import DeleteMixin, SendMixin -@python_2_unicode_compatible class PurchaseOrder(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, SendMixin): """ QBO definition: The PurchaseOrder entity is a non-posting transaction representing a request to purchase diff --git a/quickbooks/objects/recurringtransaction.py b/quickbooks/objects/recurringtransaction.py index 0845d18e..2bfb3fe2 100644 --- a/quickbooks/objects/recurringtransaction.py +++ b/quickbooks/objects/recurringtransaction.py @@ -1,5 +1,3 @@ -from six import python_2_unicode_compatible - from .bill import Bill from .creditmemo import CreditMemo from .deposit import Deposit @@ -15,6 +13,7 @@ from .base import Ref, QuickbooksBaseObject from ..mixins import UpdateNoIdMixin, ListMixin, ReadMixin, DeleteNoIdMixin + class ScheduleInfo(QuickbooksBaseObject): def __init__(self): super(ScheduleInfo, self).__init__() @@ -23,20 +22,20 @@ def __init__(self): self.EndDate = None self.DaysBefore = None self.MaxOccurrences = None - + self.RemindDays = None self.IntervalType = None self.NumInterval = None - + self.DayOfMonth = None self.DayOfWeek = None self.MonthOfYear = None self.WeekOfMonth = None - + self.NextDate = None self.PreviousDate = None - + class RecurringInfo(QuickbooksBaseObject): class_dict = { "ScheduleInfo": ScheduleInfo @@ -52,7 +51,7 @@ def __init__(self): self.Active = False -class Recurring(): +class Recurring(): class_dict = { "RecurringInfo": RecurringInfo, "RecurDataRef": Ref @@ -107,7 +106,6 @@ class RecurringPurchaseOrder(PurchaseOrder): class_dict = {**PurchaseOrder.class_dict, **Recurring.class_dict} -@python_2_unicode_compatible class RecurringTransaction(QuickbooksBaseObject, ReadMixin, UpdateNoIdMixin, ListMixin, DeleteNoIdMixin): """ QBO definition: A RecurringTransaction object refers to scheduling creation of transactions, @@ -129,4 +127,4 @@ class RecurringTransaction(QuickbooksBaseObject, ReadMixin, UpdateNoIdMixin, Lis "PurchaseOrder": RecurringPurchaseOrder } - qbo_object_name = "RecurringTransaction" \ No newline at end of file + qbo_object_name = "RecurringTransaction" diff --git a/quickbooks/objects/refundreceipt.py b/quickbooks/objects/refundreceipt.py index ca45c654..fc56506e 100644 --- a/quickbooks/objects/refundreceipt.py +++ b/quickbooks/objects/refundreceipt.py @@ -1,5 +1,3 @@ -from six import python_2_unicode_compatible - from quickbooks.objects import CreditCardPayment from .base import Ref, CustomField, QuickbooksManagedObject, \ LinkedTxnMixin, QuickbooksTransactionEntity, LinkedTxn, Address, EmailAddress, QuickbooksBaseObject, CustomerMemo @@ -8,7 +6,6 @@ from ..mixins import DeleteMixin -@python_2_unicode_compatible class RefundReceiptCheckPayment(QuickbooksBaseObject): qbo_object_name = "CheckPayment" @@ -24,7 +21,6 @@ def __str__(self): return self.CheckNum -@python_2_unicode_compatible class RefundReceipt(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: RefundReceipt represents a refund to the customer for a product or service that was given. @@ -35,8 +31,8 @@ class RefundReceipt(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionE "TxnTaxDetail": TxnTaxDetail, "DepositToAccountRef": Ref, "CustomerRef": Ref, - "BillAddr": Address, - "ShipAddr": Address, + "BillAddr": Address, + "ShipAddr": Address, "ClassRef": Ref, "BillEmail": EmailAddress, "PaymentMethodRef": Ref, diff --git a/quickbooks/objects/salesreceipt.py b/quickbooks/objects/salesreceipt.py index 91ff18e8..83b55a20 100644 --- a/quickbooks/objects/salesreceipt.py +++ b/quickbooks/objects/salesreceipt.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import Ref, CustomField, QuickbooksManagedObject, LinkedTxnMixin, Address, \ EmailAddress, QuickbooksTransactionEntity, LinkedTxn from .tax import TxnTaxDetail @@ -6,7 +5,6 @@ from ..mixins import QuickbooksPdfDownloadable, DeleteMixin -@python_2_unicode_compatible class SalesReceipt(DeleteMixin, QuickbooksPdfDownloadable, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ diff --git a/quickbooks/objects/tax.py b/quickbooks/objects/tax.py index 295a789f..aa515071 100644 --- a/quickbooks/objects/tax.py +++ b/quickbooks/objects/tax.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, QuickbooksManagedObject -@python_2_unicode_compatible class TaxLineDetail(QuickbooksBaseObject): class_dict = { "TaxRateRef": Ref @@ -18,7 +16,6 @@ def __str__(self): return str(self.TaxPercent) -@python_2_unicode_compatible class TaxLine(QuickbooksBaseObject): class_dict = { "TaxLineDetail": TaxLineDetail @@ -33,7 +30,6 @@ def __str__(self): return str(self.Amount) -@python_2_unicode_compatible class TxnTaxDetail(QuickbooksBaseObject): class_dict = { "TxnTaxCodeRef": Ref, diff --git a/quickbooks/objects/taxagency.py b/quickbooks/objects/taxagency.py index 85de9ad9..171e1d43 100644 --- a/quickbooks/objects/taxagency.py +++ b/quickbooks/objects/taxagency.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksTransactionEntity, QuickbooksManagedObject -@python_2_unicode_compatible class TaxAgency(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: Tax Agency is an entity that is associated with a tax rate and identifies the agency to which that tax rate diff --git a/quickbooks/objects/taxcode.py b/quickbooks/objects/taxcode.py index 8943dff3..aa720dcb 100644 --- a/quickbooks/objects/taxcode.py +++ b/quickbooks/objects/taxcode.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from quickbooks.mixins import ListMixin, ReadMixin from .base import QuickbooksTransactionEntity, Ref, QuickbooksBaseObject @@ -29,7 +28,6 @@ def __init__(self): self.TaxRateDetail = [] -@python_2_unicode_compatible class TaxCode(QuickbooksTransactionEntity, QuickbooksBaseObject, ReadMixin, ListMixin): """ QBO definition: A TaxCode object is used to track the taxable or non-taxable status of products, diff --git a/quickbooks/objects/taxrate.py b/quickbooks/objects/taxrate.py index d172919a..af872f81 100644 --- a/quickbooks/objects/taxrate.py +++ b/quickbooks/objects/taxrate.py @@ -1,10 +1,7 @@ -from six import python_2_unicode_compatible - from quickbooks.mixins import ListMixin, ReadMixin from .base import QuickbooksTransactionEntity, Ref, QuickbooksBaseObject -@python_2_unicode_compatible class TaxRate(QuickbooksTransactionEntity, QuickbooksBaseObject, ReadMixin, ListMixin): """ QBO definition: A TaxRate object represents rate applied to calculate tax liability. Use the TaxService @@ -34,5 +31,3 @@ def __init__(self): def __str__(self): return self.Name - - diff --git a/quickbooks/objects/taxservice.py b/quickbooks/objects/taxservice.py index 84819b85..870d9065 100644 --- a/quickbooks/objects/taxservice.py +++ b/quickbooks/objects/taxservice.py @@ -1,10 +1,8 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject from ..mixins import UpdateMixin from ..client import QuickBooks -@python_2_unicode_compatible class TaxRateDetails(QuickbooksBaseObject): qbo_object_name = "TaxRateDetails" @@ -20,7 +18,6 @@ def __str__(self): return self.TaxRateName -@python_2_unicode_compatible class TaxService(QuickbooksBaseObject, UpdateMixin): """ QBO definition: The TaxService endpoint allows you to perform the following actions: diff --git a/quickbooks/objects/term.py b/quickbooks/objects/term.py index 26466eb5..674ac98e 100644 --- a/quickbooks/objects/term.py +++ b/quickbooks/objects/term.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksManagedObject, QuickbooksTransactionEntity, Ref -@python_2_unicode_compatible class Term(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: The Term entity represents the terms under which a sale is made, typically expressed in the @@ -38,4 +36,3 @@ def to_ref(self): ref.value = self.Id return ref - diff --git a/quickbooks/objects/timeactivity.py b/quickbooks/objects/timeactivity.py index 132471e6..feea8887 100644 --- a/quickbooks/objects/timeactivity.py +++ b/quickbooks/objects/timeactivity.py @@ -1,9 +1,7 @@ -from six import python_2_unicode_compatible from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, AttachableRef from ..mixins import DeleteMixin -@python_2_unicode_compatible class TimeActivity(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: The TimeActivity entity represents a record of time worked by a vendor or employee. diff --git a/quickbooks/objects/trackingclass.py b/quickbooks/objects/trackingclass.py index cd47cd70..da084bd7 100644 --- a/quickbooks/objects/trackingclass.py +++ b/quickbooks/objects/trackingclass.py @@ -1,8 +1,6 @@ -from six import python_2_unicode_compatible from .base import QuickbooksManagedObject, QuickbooksTransactionEntity, Ref -@python_2_unicode_compatible class Class(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: Classes provide a way to track different segments of the business so they're diff --git a/quickbooks/objects/transfer.py b/quickbooks/objects/transfer.py index 42a593e6..d4954353 100644 --- a/quickbooks/objects/transfer.py +++ b/quickbooks/objects/transfer.py @@ -1,9 +1,7 @@ -from six import python_2_unicode_compatible from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin from ..mixins import DeleteMixin -@python_2_unicode_compatible class Transfer(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: A Transfer represents a transaction where funds are moved between two accounts from the diff --git a/quickbooks/objects/vendor.py b/quickbooks/objects/vendor.py index a0e2f9e1..fa860c98 100644 --- a/quickbooks/objects/vendor.py +++ b/quickbooks/objects/vendor.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import Address, PhoneNumber, EmailAddress, WebAddress, Ref, QuickbooksBaseObject, \ QuickbooksManagedObject, QuickbooksTransactionEntity @@ -15,7 +14,6 @@ def __init__(self): self.Telephone = None -@python_2_unicode_compatible class Vendor(QuickbooksManagedObject, QuickbooksTransactionEntity): """ QBO definition: The Vendor represents the seller from whom your company purchases any service or product. diff --git a/quickbooks/objects/vendorcredit.py b/quickbooks/objects/vendorcredit.py index 53d8abd9..3f57d508 100644 --- a/quickbooks/objects/vendorcredit.py +++ b/quickbooks/objects/vendorcredit.py @@ -1,12 +1,9 @@ -from six import python_2_unicode_compatible - from .base import Ref, QuickbooksManagedObject, QuickbooksTransactionEntity, \ LinkedTxnMixin from .detailline import DetailLine, AccountBasedExpenseLine, ItemBasedExpenseLine, TDSLine from ..mixins import DeleteMixin -@python_2_unicode_compatible class VendorCredit(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): """ QBO definition: The Vendor Credit entity is an accounts payable transaction that represents a refund or credit @@ -47,4 +44,4 @@ def __init__(self): self.Line = [] def __str__(self): - return str(self.TotalAmt) \ No newline at end of file + return str(self.TotalAmt) diff --git a/quickbooks/utils.py b/quickbooks/utils.py index 91f39d84..19c4c44c 100644 --- a/quickbooks/utils.py +++ b/quickbooks/utils.py @@ -1,7 +1,3 @@ -import six -import sys - - def build_where_clause(**kwargs): where_clause = "" @@ -9,14 +5,7 @@ def build_where_clause(**kwargs): where = [] for key, value in kwargs.items(): - if isinstance(value, six.text_type) and sys.version_info[0] == 2: - # If using python 2, encode unicode as string. - encoded_value = value.encode('utf-8') - where.append("{0} = '{1}'".format(key, encoded_value.replace(r"'", r"\'"))) - elif isinstance(value, six.string_types): - where.append("{0} = '{1}'".format(key, value.replace(r"'", r"\'"))) - else: - where.append("{0} = {1}".format(key, value)) + where.append("{0} = {1}".format(key, value)) where_clause = " AND ".join(where) @@ -30,14 +19,7 @@ def build_choose_clause(choices, field): where = [] for choice in choices: - if isinstance(choice, six.text_type) and sys.version_info[0] == 2: - # If using python 2, encode unicode as string. - encoded_choice = choice.encode('utf-8') - where.append("'{0}'".format(encoded_choice.replace(r"'", r"\'"))) - elif isinstance(choice, six.string_types): - where.append("'{0}'".format(choice.replace(r"'", r"\'"))) - else: - where.append("{0}".format(choice)) + where.append("{0}".format(choice)) where_clause = ", ".join(where) where_clause = "{0} in ({1})".format(field, where_clause) diff --git a/requirements.txt b/requirements.txt index 9c49b1c3..e22107a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ intuit-oauth==1.2.4 rauth>=0.7.3 -requests>=2.26.0 -simplejson>=3.17.0 -six>=1.14.0 +requests>=2.31.0 +simplejson>=3.19.1 \ No newline at end of file diff --git a/setup.py b/setup.py index a52279b6..bef5cd5a 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 3) +VERSION = (0, 9, 4) version = '.'.join(map(str, VERSION)) setup( @@ -33,9 +33,8 @@ def read(*parts): 'setuptools', 'intuit-oauth==1.2.4', 'rauth>=0.7.3', - 'requests>=2.26.0', - 'simplejson>=3.17.0', - 'six>=1.14.0', + 'requests>=2.31.0', + 'simplejson>=3.19.1', 'python-dateutil', ], From 2709f026945b77232db4f1923d1d14f0b2bd327f Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 28 Aug 2023 12:13:14 -0500 Subject: [PATCH 064/154] Fix utils. --- quickbooks/utils.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/quickbooks/utils.py b/quickbooks/utils.py index 19c4c44c..5387e950 100644 --- a/quickbooks/utils.py +++ b/quickbooks/utils.py @@ -5,7 +5,10 @@ def build_where_clause(**kwargs): where = [] for key, value in kwargs.items(): - where.append("{0} = {1}".format(key, value)) + if isinstance(value, str): + where.append("{0} = '{1}'".format(key, value.replace(r"'", r"\'"))) + else: + where.append("{0} = {1}".format(key, value)) where_clause = " AND ".join(where) @@ -19,7 +22,10 @@ def build_choose_clause(choices, field): where = [] for choice in choices: - where.append("{0}".format(choice)) + if isinstance(choice, str): + where.append("'{0}'".format(choice.replace(r"'", r"\'"))) + else: + where.append("{0}".format(choice)) where_clause = ", ".join(where) where_clause = "{0} in ({1})".format(field, where_clause) From 672081c813e8359334a0260f769d80ef85b7bfd7 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 28 Aug 2023 12:19:41 -0500 Subject: [PATCH 065/154] Remove future --- quickbooks/mixins.py | 2 +- tests/unit/test_mixins.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 22c66728..9b51a426 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -1,4 +1,4 @@ -from future.moves.urllib.parse import quote +from urllib.parse import quote try: import simplejson as json except ImportError: import json diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index 613543a5..c3ff3ed8 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -2,7 +2,7 @@ import os import unittest -from future.moves.urllib.parse import quote +from urllib.parse import quote from quickbooks.objects import Bill, Invoice From 5ed1ff25452ca72fea5baa6769bbd60532c379a0 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 28 Aug 2023 15:51:50 -0500 Subject: [PATCH 066/154] Remove test files from package --- MANIFEST.in | 2 +- Makefile | 1 - Pipfile | 4 +- Pipfile.lock | 569 ++++++++++++++++++++++--------------------- dev_requirements.txt | 6 +- setup.py | 2 +- 6 files changed, 296 insertions(+), 288 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index d49e8c4c..9a8b7c4b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,3 @@ include README.md include LICENSE -recursive-include tests * \ No newline at end of file +recursive-exclude tests * \ No newline at end of file diff --git a/Makefile b/Makefile index 420f0b80..c59408cb 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ - publish: clean python setup.py sdist twine upload dist/* diff --git a/Pipfile b/Pipfile index e1c60e62..a3ddd036 100644 --- a/Pipfile +++ b/Pipfile @@ -10,8 +10,8 @@ urllib3 = ">=1.26.5" bleach = ">=3.3.0" intuit-oauth = "==1.2.4" rauth = ">=0.7.3" -requests = ">=2.26.0" -simplejson = ">=3.17.0" +requests = ">=2.31.0" +simplejson = ">=3.19.1" nose = "*" coverage = "*" twine = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 31478d1f..41ccc28b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0dcea13aefe56fd4407fd1616f124a4527372bbc6a4324e6d75ec31027624edd" + "sha256": "f8797f56e2b6c880a4ad872b0cdc9bf0b6388112b1e3b35ee6dc644e406507b0" }, "pipfile-spec": 6, "requires": { @@ -22,168 +22,171 @@ "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==6.0.0" }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2023.7.22" }, "charset-normalizer": { "hashes": [ - "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", - "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", - "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", - "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", - "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", - "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", - "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", - "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", - "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", - "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", - "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", - "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", - "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", - "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", - "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", - "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", - "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", - "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", - "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", - "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", - "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", - "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", - "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", - "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", - "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", - "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", - "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", - "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", - "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", - "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", - "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", - "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", - "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", - "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", - "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", - "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", - "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", - "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", - "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", - "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", - "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", - "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", - "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", - "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", - "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", - "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", - "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", - "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", - "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", - "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", - "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", - "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", - "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", - "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", - "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", - "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", - "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", - "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", - "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", - "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", - "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", - "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", - "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", - "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", - "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", - "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", - "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", - "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", - "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", - "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", - "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", - "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", - "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", - "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", - "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.0" + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.2.0" }, "coverage": { "hashes": [ - "sha256:0339dc3237c0d31c3b574f19c57985fcbe494280153bbcad33f2cdf469f4ac3e", - "sha256:09643fb0df8e29f7417adc3f40aaf379d071ee8f0350ab290517c7004f05360b", - "sha256:0bd7e628f6c3ec4e7d2d24ec0e50aae4e5ae95ea644e849d92ae4805650b4c4e", - "sha256:0cf557827be7eca1c38a2480484d706693e7bb1929e129785fe59ec155a59de6", - "sha256:0f8318ed0f3c376cfad8d3520f496946977abde080439d6689d7799791457454", - "sha256:1b7fb13850ecb29b62a447ac3516c777b0e7a09ecb0f4bb6718a8654c87dfc80", - "sha256:22c308bc508372576ffa3d2dbc4824bb70d28eeb4fcd79d4d1aed663a06630d0", - "sha256:3004765bca3acd9e015794e5c2f0c9a05587f5e698127ff95e9cfba0d3f29339", - "sha256:3a209d512d157379cc9ab697cbdbb4cfd18daa3e7eebaa84c3d20b6af0037384", - "sha256:436313d129db7cf5b4ac355dd2bd3f7c7e5294af077b090b85de75f8458b8616", - "sha256:49567ec91fc5e0b15356da07a2feabb421d62f52a9fff4b1ec40e9e19772f5f8", - "sha256:4dd34a935de268a133e4741827ae951283a28c0125ddcdbcbba41c4b98f2dfef", - "sha256:570c21a29493b350f591a4b04c158ce1601e8d18bdcd21db136fbb135d75efa6", - "sha256:5928b85416a388dd557ddc006425b0c37e8468bd1c3dc118c1a3de42f59e2a54", - "sha256:5d2b9b5e70a21474c105a133ba227c61bc95f2ac3b66861143ce39a5ea4b3f84", - "sha256:617a94ada56bbfe547aa8d1b1a2b8299e2ec1ba14aac1d4b26a9f7d6158e1273", - "sha256:6a034480e9ebd4e83d1aa0453fd78986414b5d237aea89a8fdc35d330aa13bae", - "sha256:6fce673f79a0e017a4dc35e18dc7bb90bf6d307c67a11ad5e61ca8d42b87cbff", - "sha256:78d2c3dde4c0b9be4b02067185136b7ee4681978228ad5ec1278fa74f5ca3e99", - "sha256:7f099da6958ddfa2ed84bddea7515cb248583292e16bb9231d151cd528eab657", - "sha256:80559eaf6c15ce3da10edb7977a1548b393db36cbc6cf417633eca05d84dd1ed", - "sha256:834c2172edff5a08d78e2f53cf5e7164aacabeb66b369f76e7bb367ca4e2d993", - "sha256:861cc85dfbf55a7a768443d90a07e0ac5207704a9f97a8eb753292a7fcbdfcfc", - "sha256:8649371570551d2fd7dee22cfbf0b61f1747cdfb2b7587bb551e4beaaa44cb97", - "sha256:87dc37f16fb5e3a28429e094145bf7c1753e32bb50f662722e378c5851f7fdc6", - "sha256:8a6450da4c7afc4534305b2b7d8650131e130610cea448ff240b6ab73d7eab63", - "sha256:8d3843ca645f62c426c3d272902b9de90558e9886f15ddf5efe757b12dd376f5", - "sha256:8dca3c1706670297851bca1acff9618455122246bdae623be31eca744ade05ec", - "sha256:97a3189e019d27e914ecf5c5247ea9f13261d22c3bb0cfcfd2a9b179bb36f8b1", - "sha256:99f4dd81b2bb8fc67c3da68b1f5ee1650aca06faa585cbc6818dbf67893c6d58", - "sha256:9e872b082b32065ac2834149dc0adc2a2e6d8203080501e1e3c3c77851b466f9", - "sha256:a81dbcf6c6c877986083d00b834ac1e84b375220207a059ad45d12f6e518a4e3", - "sha256:abacd0a738e71b20e224861bc87e819ef46fedba2fb01bc1af83dfd122e9c319", - "sha256:ae82c988954722fa07ec5045c57b6d55bc1a0890defb57cf4a712ced65b26ddd", - "sha256:b0c0d46de5dd97f6c2d1b560bf0fcf0215658097b604f1840365296302a9d1fb", - "sha256:b1991a6d64231a3e5bbe3099fb0dd7c9aeaa4275ad0e0aeff4cb9ef885c62ba2", - "sha256:b2167d116309f564af56f9aa5e75ef710ef871c5f9b313a83050035097b56820", - "sha256:bd5a12239c0006252244f94863f1c518ac256160cd316ea5c47fb1a11b25889a", - "sha256:bdd3f2f285ddcf2e75174248b2406189261a79e7fedee2ceeadc76219b6faa0e", - "sha256:c77f2a9093ccf329dd523a9b2b3c854c20d2a3d968b6def3b820272ca6732242", - "sha256:cb5f152fb14857cbe7f3e8c9a5d98979c4c66319a33cad6e617f0067c9accdc4", - "sha256:cca7c0b7f5881dfe0291ef09ba7bb1582cb92ab0aeffd8afb00c700bf692415a", - "sha256:d2ef6cae70168815ed91388948b5f4fcc69681480a0061114db737f957719f03", - "sha256:d9256d4c60c4bbfec92721b51579c50f9e5062c21c12bec56b55292464873508", - "sha256:e191a63a05851f8bce77bc875e75457f9b01d42843f8bd7feed2fc26bbe60833", - "sha256:e2b50ebc2b6121edf352336d503357321b9d8738bb7a72d06fc56153fd3f4cd8", - "sha256:e3ea04b23b114572b98a88c85379e9e9ae031272ba1fb9b532aa934c621626d4", - "sha256:e4d70c853f0546855f027890b77854508bdb4d6a81242a9d804482e667fff6e6", - "sha256:f29351393eb05e6326f044a7b45ed8e38cb4dcc38570d12791f271399dc41431", - "sha256:f3d07edb912a978915576a776756069dede66d012baa503022d3a0adba1b6afa", - "sha256:fac6343bae03b176e9b58104a9810df3cdccd5cfed19f99adfa807ffbf43cf9b" + "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34", + "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e", + "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7", + "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b", + "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3", + "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985", + "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95", + "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2", + "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a", + "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74", + "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd", + "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af", + "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54", + "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865", + "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214", + "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54", + "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe", + "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0", + "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321", + "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446", + "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e", + "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527", + "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12", + "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f", + "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f", + "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84", + "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479", + "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e", + "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873", + "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70", + "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0", + "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977", + "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51", + "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28", + "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1", + "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254", + "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1", + "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd", + "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689", + "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d", + "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543", + "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9", + "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637", + "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071", + "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482", + "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1", + "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b", + "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5", + "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a", + "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393", + "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a", + "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba" ], "index": "pypi", - "version": "==7.2.1" + "markers": "python_version >= '3.8'", + "version": "==7.3.0" }, "docutils": { "hashes": [ - "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", - "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc" + "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6", + "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b" ], "markers": "python_version >= '3.7'", - "version": "==0.19" + "version": "==0.20.1" }, "ecdsa": { "hashes": [ "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.18.0" }, "enum-compat": { @@ -197,7 +200,7 @@ "hashes": [ "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.18.3" }, "idna": { @@ -210,19 +213,19 @@ }, "importlib-metadata": { "hashes": [ - "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", - "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" + "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", + "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" ], - "markers": "python_version >= '3.7'", - "version": "==6.0.0" + "markers": "python_version >= '3.8'", + "version": "==6.8.0" }, "importlib-resources": { "hashes": [ - "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6", - "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a" + "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", + "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" ], "markers": "python_version < '3.9'", - "version": "==5.12.0" + "version": "==6.0.1" }, "intuit-oauth": { "hashes": [ @@ -234,27 +237,27 @@ }, "jaraco.classes": { "hashes": [ - "sha256:2353de3288bc6b82120752201c6b1c1a14b058267fa424ed5ce5984e3b922158", - "sha256:89559fa5c1d3c34eff6f631ad80bb21f378dbcbb35dd161fd2c6b93f5be2f98a" + "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb", + "sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621" ], - "markers": "python_version >= '3.7'", - "version": "==3.2.3" + "markers": "python_version >= '3.8'", + "version": "==3.3.0" }, "keyring": { "hashes": [ - "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd", - "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678" + "sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6", + "sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509" ], - "markers": "python_version >= '3.7'", - "version": "==23.13.1" + "markers": "python_version >= '3.8'", + "version": "==24.2.0" }, "markdown-it-py": { "hashes": [ - "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30", - "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1" + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" ], - "markers": "python_version >= '3.7'", - "version": "==2.2.0" + "markers": "python_version >= '3.8'", + "version": "==3.0.0" }, "mdurl": { "hashes": [ @@ -266,11 +269,11 @@ }, "more-itertools": { "hashes": [ - "sha256:cabaa341ad0389ea83c17a94566a53ae4c9d07349861ecb14dc6d0345cf9ac5d", - "sha256:d2bc7f02446e86a68911e58ded76d6561eea00cddfb2a91e7019bbb586c799f3" + "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a", + "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6" ], - "markers": "python_version >= '3.7'", - "version": "==9.1.0" + "markers": "python_version >= '3.8'", + "version": "==10.1.0" }, "nose": { "hashes": [ @@ -299,29 +302,19 @@ }, "pyasn1": { "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" + "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57", + "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==0.5.0" }, "pygments": { "hashes": [ - "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", - "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" + "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692", + "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" ], - "markers": "python_version >= '3.6'", - "version": "==2.14.0" + "markers": "python_version >= '3.7'", + "version": "==2.16.1" }, "python-jose": { "hashes": [ @@ -340,19 +333,20 @@ }, "readme-renderer": { "hashes": [ - "sha256:cd653186dfc73055656f090f227f5cb22a046d7f71a841dfa305f55c9a513273", - "sha256:f67a16caedfa71eef48a31b39708637a6f4664c4394801a7b0d6432d13907343" + "sha256:4f4b11e5893f5a5d725f592c5a343e0dc74f5f273cb3dcf8c42d9703a27073f7", + "sha256:a38243d5b6741b700a850026e62da4bd739edc7422071e95fd5c4bb60171df86" ], - "markers": "python_version >= '3.7'", - "version": "==37.3" + "markers": "python_version >= '3.8'", + "version": "==41.0" }, "requests": { "hashes": [ - "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", - "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", - "version": "==2.28.2" + "markers": "python_version >= '3.7'", + "version": "==2.31.0" }, "requests-oauthlib": { "hashes": [ @@ -364,11 +358,11 @@ }, "requests-toolbelt": { "hashes": [ - "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7", - "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d" + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.1" + "version": "==1.0.0" }, "rfc3986": { "hashes": [ @@ -380,11 +374,11 @@ }, "rich": { "hashes": [ - "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001", - "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f" + "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808", + "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39" ], - "markers": "python_version >= '3.7'", - "version": "==13.3.2" + "markers": "python_full_version >= '3.7.0'", + "version": "==13.5.2" }, "rsa": { "hashes": [ @@ -396,89 +390,102 @@ }, "simplejson": { "hashes": [ - "sha256:04a4b9a297cccbc9e1d66fe652fbffd55b36d6579c43132e821d315957302194", - "sha256:063db62a9251e61ea0c17e49c3e7bed465bfcc5359655abcb8c0bc6130a4e0d4", - "sha256:070ab073ce72f1624107dfd6d095c87ac32aafe7ba54a5c5055a3dd83cb06e51", - "sha256:099bbd3b5b4ea83159a980348cd481a34984dee5fe1b9fac31a9137158f46960", - "sha256:0baf8c60efef74944ed4adb034d14bcf737731576f0e4c3c56fb875ea256af69", - "sha256:0e7c3fae6c9540064e06a653780b4f263675cd69ca6841345029fee3e27e9bb5", - "sha256:141782a0a25c1792627575b37b4951583358ccc7137623aa45947f8425ee8d96", - "sha256:14b35fb90083218e59df5dba733c7086655f2938f3fcabe36ad849623941d660", - "sha256:169c2c7446ef33439c304a6aa5b7b5a2dbc938c9c2dd882dd3f2553f9518ebf6", - "sha256:16cc750d19852fa5ebafd55da86fa357f87991e07b4e2afb37a5975dfdde0153", - "sha256:1907d49d70c75530976119c13785db91168d2599288debaca7d25da9cd2f3747", - "sha256:1b79e2607ac5ba98381c2e068727acc1e4dd385a6d216914c0613f8f568a06a5", - "sha256:1e49c84df6e71e3c23169d3df481565dd607cbee4aa1e0af15c493cccad7c745", - "sha256:23fce984045804194f513a2739dcd82be350198470d5ade5058da019a48cf3f8", - "sha256:24823364fee93bab141621b3a2e10612e31be7ca58788bf9b2cd2b1ce37ab07d", - "sha256:290bbcdcbb37af3f7e43378f592ab7a9168fca640da6af63d42cdb535f96bbf2", - "sha256:2a1b3222bc8f6ac91b5ebe3263111c7dc4dc4b01c52f0153f5bb1f3ef3bf0023", - "sha256:2b0f6de11f5ce4b80f51bc49d08b898602e190547f8efe4e44af8ae3cda7779d", - "sha256:2be75f4cb9951efeb2616e16f944ee4f9a09768475a3f5c40a6ac4dc5ee68dfd", - "sha256:2c7ee643ee93684bf76196e2d84a2090c6df8f01737a016e869b579593827b6e", - "sha256:37bdef13412c0bc338db2993a38f3911d5bd2a0ba8d00b3bc66d1063edd7c33e", - "sha256:3bab9ea49ff477c926c5787f79ec47cf51c7ffb15c9d8dd0f09e728807d44f4b", - "sha256:44d6c52d4f5c0c087a6e88a92bf9f94234321d21be32c6471ba39856e304bbe3", - "sha256:4b8d4d958c5ab3489d1174917a7fad82da642560c39ce559a624e63deaaa36b1", - "sha256:4de9fed1166aeedee44150fa83bc059aca6b612940281f8b5a39374781f16196", - "sha256:502d86fbfe914263642479b87ed61af3b27b9e039df77acd2416cfccfc892e68", - "sha256:508342d7227ed66beecfbba7a38b46e1a713faeb034216f43f03ec5c175e0622", - "sha256:50f4b6d52f3a2d1cffd11834a1fe7f9516f0e3f20cbe78027aa88ff990fad7d6", - "sha256:52465a5578cfc2c5e374a574df14dfb75e04c6cb6a100b7abc8bf6c89bea8f5e", - "sha256:55aa983575b0aef143845f5bfbb35075475eccaebf7d4b30f4037a2fe8414666", - "sha256:55df3dfd8777bf134e1078d2f195352432a77f23ccb90b92b08218123d56adc9", - "sha256:56f186d44a9f625b5e5d9ba4b9551e263604000a7df60cb373b3e789ca603b2a", - "sha256:5780e3929435a8d39671537174f8ce0ccafb4f6e0c748ffe139916ffbdca39d3", - "sha256:59a629240cfbc5b4f390a8578dca74ae77ab617de971862acb946822d2eb1b11", - "sha256:5b009342e712026ffabe8a471d5b4a4ff2a038687387e74eae601574c04dae33", - "sha256:62628ea5df8c830d00a7417d5ecd949a1b24a8d0a5063a2a77f7ec7522110a0f", - "sha256:694332fd6fd10fe8868c2508583220d1a1a7be9ff049dab5bd6b9aedfb9edc50", - "sha256:6a49665169c18f27a0fc10935466332ee7406ee14ced8dc0a1b4d465547299aa", - "sha256:6b997739fdbc9b7030ff490fc8e5f8c144b8ec80f3605eff643983672bb8cfde", - "sha256:6bd81d10cb3384f64242316da8a2b2f88618776bc1ef38bcc79f1afe8ad36616", - "sha256:6c4c56c5abb82e22877b913186e5c0fd7d9eef0c930719e28fa451d3f11defb4", - "sha256:6fe1173b4146641c872bafa6f9a21f3a2012f502d54fbb523a76e6320024fae9", - "sha256:75eb555dc349d0cbe2c95ea2be665b306c6ac6d5b64e3a3920af9b805ecdb5f7", - "sha256:7c26fe63755ecc59c502ddde8e58ce8b765bf4fdd3f5858d2b7c8ab28bc2a9c8", - "sha256:7e73d9d6af3c29b60a92e28b3144d951110f59a3d05fc402c3f6c5248b883400", - "sha256:7ff65b475091084e5bdb7f26e9c555956be7355b573ce494fa96f9f8e34541ac", - "sha256:8209c40279ed9b2cd5fbe2d617a29a074e90ea97fce7c07a0128a01cb3e8afc5", - "sha256:88f59a07873dc1f06fd9e6712dd71286f1b297a066ad2fd9110ad080d3cb011c", - "sha256:96ade36640734b54176c4765d00a60767bd7fae5b7a5b3574accc055ac18e34c", - "sha256:9cf299fbb7d476676dfea372a3262654af98694bd1df35b060ce0fe1b68087f1", - "sha256:a2960b95f3ba822d077d1afa7e1fea9799cfb2990028cf010e666f64195ecb5a", - "sha256:a80bd9a3db88a76a401155c64e3499376c702307c2206cb381cc2a8dd9cc4f1f", - "sha256:aad323e92cb1bd3b1db6f57c007dca964d13c52247ad844203ce381e94066601", - "sha256:ab5bdf0b8d07f7fd603b2d0c1982412cd9f8ade997088ddced251f7e656c7fd4", - "sha256:b0352428b35da859a98770949e7353866ae65463026f1c8e4c89a6395d4b5fd7", - "sha256:b2c4e8b65987f3c6529149495d28e23efe213e94dc3659176c4ab22d18a9ee4a", - "sha256:bcd9eac304a133ee4af58e68c5ded4c5ba663d3ee4602e8613359b776a1f8c8f", - "sha256:c3b696770b504f881f271f97b94a687487ec1ef20bfbd5f20d92bbab7a85952d", - "sha256:c4514675f6571da8190fea52a110bca686fa844972e8b2b3bc07ace9e632ee4f", - "sha256:c98fddc374468158778a8afb3fd7296412a2b2fc34cebba64212ac3e018e7382", - "sha256:cde5a3ff5e0bd5d6da676314dfae86c9e99bff77bca03d30223c9718a58f9e83", - "sha256:cf7168b2046db0eceb83d8ed2ee31c0847ce18b2d8baf3e93de9560f3921a8c3", - "sha256:d774782159347d66563cd7ac18b9dd37010438a825160cde4818caa18110a746", - "sha256:d990ea42ba908cb57a3df97d283aa26c1822f10a0a60e250b54ee21cd08c48d0", - "sha256:e762e9d8556fa9f3a99f8a278eeba50a35b5f554b82deeb282ddbdd85816e638", - "sha256:e8a4750e8db92109e6f1f7783a7faae4254d6d5dc28a41ff7eff7d2265f0586b", - "sha256:eb81cfef0c0039010f0212f4e5eb6909641b8a54c761584054ac97fd7bd0c21a", - "sha256:ebb53837c5ffcb6100646018565d3f1afed6f4b185b14b2c9cbccf874fe40157", - "sha256:efa70fd9b6c7b57b048ecadb909683acd535cddebc5b22f3c05ba3b369739caf", - "sha256:f73bae5e315adf7bc8cb7f0a13a1e9e33bead42e8ce174be83ac9ecc2513c86a", - "sha256:f89f078114cacedb9a3392615cc099cf02a51efa7507f90e2006bf7ec38c880d", - "sha256:f9f72d2b539512f382a48cc9ad6cea2d3a572e71e92c40e03d2140041eeaa233", - "sha256:fc8df5831b645e96a318ea51a66ce6e2bb869eebc3fa9a860bbf67aecd270055" + "sha256:081ea6305b3b5e84ae7417e7f45956db5ea3872ec497a584ec86c3260cda049e", + "sha256:08be5a241fdf67a8e05ac7edbd49b07b638ebe4846b560673e196b2a25c94b92", + "sha256:0c16ec6a67a5f66ab004190829eeede01c633936375edcad7cbf06d3241e5865", + "sha256:0ccb2c1877bc9b25bc4f4687169caa925ffda605d7569c40e8e95186e9a5e58b", + "sha256:17a963e8dd4d81061cc05b627677c1f6a12e81345111fbdc5708c9f088d752c9", + "sha256:199a0bcd792811c252d71e3eabb3d4a132b3e85e43ebd93bfd053d5b59a7e78b", + "sha256:1cb19eacb77adc5a9720244d8d0b5507421d117c7ed4f2f9461424a1829e0ceb", + "sha256:203412745fed916fc04566ecef3f2b6c872b52f1e7fb3a6a84451b800fb508c1", + "sha256:2098811cd241429c08b7fc5c9e41fcc3f59f27c2e8d1da2ccdcf6c8e340ab507", + "sha256:22b867205cd258050c2625325fdd9a65f917a5aff22a23387e245ecae4098e78", + "sha256:23fbb7b46d44ed7cbcda689295862851105c7594ae5875dce2a70eeaa498ff86", + "sha256:2541fdb7467ef9bfad1f55b6c52e8ea52b3ce4a0027d37aff094190a955daa9d", + "sha256:3231100edee292da78948fa0a77dee4e5a94a0a60bcba9ed7a9dc77f4d4bb11e", + "sha256:344a5093b71c1b370968d0fbd14d55c9413cb6f0355fdefeb4a322d602d21776", + "sha256:37724c634f93e5caaca04458f267836eb9505d897ab3947b52f33b191bf344f3", + "sha256:3844305bc33d52c4975da07f75b480e17af3558c0d13085eaa6cc2f32882ccf7", + "sha256:390f4a8ca61d90bcf806c3ad644e05fa5890f5b9a72abdd4ca8430cdc1e386fa", + "sha256:3a4480e348000d89cf501b5606415f4d328484bbb431146c2971123d49fd8430", + "sha256:3b652579c21af73879d99c8072c31476788c8c26b5565687fd9db154070d852a", + "sha256:3e0902c278243d6f7223ba3e6c5738614c971fd9a887fff8feaa8dcf7249c8d4", + "sha256:412e58997a30c5deb8cab5858b8e2e5b40ca007079f7010ee74565cc13d19665", + "sha256:44cdb4e544134f305b033ad79ae5c6b9a32e7c58b46d9f55a64e2a883fbbba01", + "sha256:46133bc7dd45c9953e6ee4852e3de3d5a9a4a03b068bd238935a5c72f0a1ce34", + "sha256:46e89f58e4bed107626edce1cf098da3664a336d01fc78fddcfb1f397f553d44", + "sha256:4710806eb75e87919b858af0cba4ffedc01b463edc3982ded7b55143f39e41e1", + "sha256:476c8033abed7b1fd8db62a7600bf18501ce701c1a71179e4ce04ac92c1c5c3c", + "sha256:48600a6e0032bed17c20319d91775f1797d39953ccfd68c27f83c8d7fc3b32cb", + "sha256:4d3025e7e9ddb48813aec2974e1a7e68e63eac911dd5e0a9568775de107ac79a", + "sha256:547ea86ca408a6735335c881a2e6208851027f5bfd678d8f2c92a0f02c7e7330", + "sha256:54fca2b26bcd1c403146fd9461d1da76199442297160721b1d63def2a1b17799", + "sha256:5673d27806085d2a413b3be5f85fad6fca4b7ffd31cfe510bbe65eea52fff571", + "sha256:58ee5e24d6863b22194020eb62673cf8cc69945fcad6b283919490f6e359f7c5", + "sha256:5ca922c61d87b4c38f37aa706520328ffe22d7ac1553ef1cadc73f053a673553", + "sha256:5db86bb82034e055257c8e45228ca3dbce85e38d7bfa84fa7b2838e032a3219c", + "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c", + "sha256:6424d8229ba62e5dbbc377908cfee9b2edf25abd63b855c21f12ac596cd18e41", + "sha256:65dafe413b15e8895ad42e49210b74a955c9ae65564952b0243a18fb35b986cc", + "sha256:66389b6b6ee46a94a493a933a26008a1bae0cfadeca176933e7ff6556c0ce998", + "sha256:66d780047c31ff316ee305c3f7550f352d87257c756413632303fc59fef19eac", + "sha256:69a8b10a4f81548bc1e06ded0c4a6c9042c0be0d947c53c1ed89703f7e613950", + "sha256:6a561320485017ddfc21bd2ed5de2d70184f754f1c9b1947c55f8e2b0163a268", + "sha256:6aa7ca03f25b23b01629b1c7f78e1cd826a66bfb8809f8977a3635be2ec48f1a", + "sha256:6b79642a599740603ca86cf9df54f57a2013c47e1dd4dd2ae4769af0a6816900", + "sha256:6e7c70f19405e5f99168077b785fe15fcb5f9b3c0b70b0b5c2757ce294922c8c", + "sha256:70128fb92932524c89f373e17221cf9535d7d0c63794955cc3cd5868e19f5d38", + "sha256:73d0904c2471f317386d4ae5c665b16b5c50ab4f3ee7fd3d3b7651e564ad74b1", + "sha256:74bf802debe68627227ddb665c067eb8c73aa68b2476369237adf55c1161b728", + "sha256:79c748aa61fd8098d0472e776743de20fae2686edb80a24f0f6593a77f74fe86", + "sha256:79d46e7e33c3a4ef853a1307b2032cfb7220e1a079d0c65488fbd7118f44935a", + "sha256:7e78d79b10aa92f40f54178ada2b635c960d24fc6141856b926d82f67e56d169", + "sha256:8090e75653ea7db75bc21fa5f7bcf5f7bdf64ea258cbbac45c7065f6324f1b50", + "sha256:87b190e6ceec286219bd6b6f13547ca433f977d4600b4e81739e9ac23b5b9ba9", + "sha256:889328873c35cb0b2b4c83cbb83ec52efee5a05e75002e2c0c46c4e42790e83c", + "sha256:8f8d179393e6f0cf6c7c950576892ea6acbcea0a320838c61968ac7046f59228", + "sha256:919bc5aa4d8094cf8f1371ea9119e5d952f741dc4162810ab714aec948a23fe5", + "sha256:926957b278de22797bfc2f004b15297013843b595b3cd7ecd9e37ccb5fad0b72", + "sha256:93f5ac30607157a0b2579af59a065bcfaa7fadeb4875bf927a8f8b6739c8d910", + "sha256:96ade243fb6f3b57e7bd3b71e90c190cd0f93ec5dce6bf38734a73a2e5fa274f", + "sha256:9f14ecca970d825df0d29d5c6736ff27999ee7bdf5510e807f7ad8845f7760ce", + "sha256:a755f7bfc8adcb94887710dc70cc12a69a454120c6adcc6f251c3f7b46ee6aac", + "sha256:a79b439a6a77649bb8e2f2644e6c9cc0adb720fc55bed63546edea86e1d5c6c8", + "sha256:aa9d614a612ad02492f704fbac636f666fa89295a5d22b4facf2d665fc3b5ea9", + "sha256:ad071cd84a636195f35fa71de2186d717db775f94f985232775794d09f8d9061", + "sha256:b0e9a5e66969f7a47dc500e3dba8edc3b45d4eb31efb855c8647700a3493dd8a", + "sha256:b438e5eaa474365f4faaeeef1ec3e8d5b4e7030706e3e3d6b5bee6049732e0e6", + "sha256:b46aaf0332a8a9c965310058cf3487d705bf672641d2c43a835625b326689cf4", + "sha256:c39fa911e4302eb79c804b221ddec775c3da08833c0a9120041dd322789824de", + "sha256:ca56a6c8c8236d6fe19abb67ef08d76f3c3f46712c49a3b6a5352b6e43e8855f", + "sha256:cb502cde018e93e75dc8fc7bb2d93477ce4f3ac10369f48866c61b5e031db1fd", + "sha256:cd4d50a27b065447c9c399f0bf0a993bd0e6308db8bbbfbc3ea03b41c145775a", + "sha256:d125e754d26c0298715bdc3f8a03a0658ecbe72330be247f4b328d229d8cf67f", + "sha256:d300773b93eed82f6da138fd1d081dc96fbe53d96000a85e41460fe07c8d8b33", + "sha256:d396b610e77b0c438846607cd56418bfc194973b9886550a98fd6724e8c6cfec", + "sha256:d61482b5d18181e6bb4810b4a6a24c63a490c3a20e9fbd7876639653e2b30a1a", + "sha256:d9f2c27f18a0b94107d57294aab3d06d6046ea843ed4a45cae8bd45756749f3a", + "sha256:dc2b3f06430cbd4fac0dae5b2974d2bf14f71b415fb6de017f498950da8159b1", + "sha256:dc935d8322ba9bc7b84f99f40f111809b0473df167bf5b93b89fb719d2c4892b", + "sha256:e333c5b62e93949f5ac27e6758ba53ef6ee4f93e36cc977fe2e3df85c02f6dc4", + "sha256:e765b1f47293dedf77946f0427e03ee45def2862edacd8868c6cf9ab97c8afbd", + "sha256:ed18728b90758d171f0c66c475c24a443ede815cf3f1a91e907b0db0ebc6e508", + "sha256:eff87c68058374e45225089e4538c26329a13499bc0104b52b77f8428eed36b2", + "sha256:f05d05d99fce5537d8f7a0af6417a9afa9af3a6c4bb1ba7359c53b6257625fcb", + "sha256:f253edf694ce836631b350d758d00a8c4011243d58318fbfbe0dd54a6a839ab4", + "sha256:f41915a4e1f059dfad614b187bc06021fefb5fc5255bfe63abf8247d2f7a646a", + "sha256:f96def94576f857abf58e031ce881b5a3fc25cbec64b2bc4824824a8a4367af9" ], "index": "pypi", - "version": "==3.18.3" + "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2'", + "version": "==3.19.1" }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "twine": { @@ -487,23 +494,25 @@ "sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==4.0.2" }, "typing-extensions": { "hashes": [ - "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", - "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" + "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", + "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" ], "markers": "python_version < '3.9'", - "version": "==4.5.0" + "version": "==4.7.1" }, "urllib3": { "hashes": [ - "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", - "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" + "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", + "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" ], "index": "pypi", - "version": "==1.26.14" + "markers": "python_version >= '3.7'", + "version": "==2.0.4" }, "webencodings": { "hashes": [ @@ -514,11 +523,11 @@ }, "zipp": { "hashes": [ - "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", - "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556" + "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", + "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" ], - "markers": "python_version >= '3.7'", - "version": "==3.15.0" + "markers": "python_version >= '3.8'", + "version": "==3.16.2" } }, "develop": {} diff --git a/dev_requirements.txt b/dev_requirements.txt index 2becb719..74c3c14b 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,4 +1,4 @@ -coverage==6.4.2 -ipdb==0.13.9 -mock==2.0.0 +coverage==7.3.0 +ipdb==0.13.13 +mock==5.1.0 nose==1.3.7 \ No newline at end of file diff --git a/setup.py b/setup.py index bef5cd5a..665978c1 100644 --- a/setup.py +++ b/setup.py @@ -51,5 +51,5 @@ def read(*parts): 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', ], - packages=find_packages(), + packages=find_packages(exclude=("tests",)), ) From b3bccc1c493c52444cf40213838377002339a92b Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 29 Aug 2023 08:44:29 -0500 Subject: [PATCH 067/154] Fixed issue with AccountBasedExpenseLineDetail --- quickbooks/objects/detailline.py | 1 + 1 file changed, 1 insertion(+) diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index f9b89fdf..eb6465c2 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -180,6 +180,7 @@ def __init__(self): self.AccountRef = None self.TaxCodeRef = None self.ClassRef = None + self.MarkupInfo = None def __str__(self): return self.BillableStatus From e9d8606e7123564c5d592400260469848dba3b17 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 29 Aug 2023 10:14:37 -0500 Subject: [PATCH 068/154] Update changelog --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 60e8d37a..808e2697 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,11 @@ Changelog ========= +* 0.9.4 (August 29, 2023) + * Removed python 2 compatible decorators + * Removed python 2 dependencies + * Fixed issue with MarkupInfo field on AccountBasedExpenseLineDetail + * Removed test files from package + * 0.9.3 (March 7, 2023) * Added support for Recurring Transaction * Added support for optional query params From c0e1dc25f4752ed19c1d6c464f04ac8cb4441869 Mon Sep 17 00:00:00 2001 From: jaredthecoder Date: Fri, 15 Sep 2023 13:20:58 -0400 Subject: [PATCH 069/154] Fix taxinclusiveamt and vendor setting 1099 creation --- quickbooks/objects/detailline.py | 4 ++++ quickbooks/objects/vendor.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index 094287ee..de34cd0e 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -1,4 +1,5 @@ from six import python_2_unicode_compatible + from .base import QuickbooksBaseObject, Ref, CustomField, LinkedTxn, MarkupInfo @@ -115,6 +116,7 @@ def __init__(self): self.UnitPrice = 0 self.Qty = 0 self.ServiceDate = "" + self.TaxInclusiveAmt = 0 self.MarkupInfo = None self.ItemRef = None @@ -176,6 +178,7 @@ class AccountBasedExpenseLineDetail(QuickbooksBaseObject): def __init__(self): super(AccountBasedExpenseLineDetail, self).__init__() self.BillableStatus = None + self.TaxInclusiveAmt = 0 self.CustomerRef = None self.AccountRef = None @@ -235,6 +238,7 @@ def __init__(self): self.BillableStatus = None self.UnitPrice = 0 self.Qty = 0 + self.TaxInclusiveAmt = 0 self.ItemRef = None self.ClassRef = None self.PriceLevelRef = None diff --git a/quickbooks/objects/vendor.py b/quickbooks/objects/vendor.py index a0e2f9e1..d5d6e64e 100644 --- a/quickbooks/objects/vendor.py +++ b/quickbooks/objects/vendor.py @@ -1,4 +1,5 @@ from six import python_2_unicode_compatible + from .base import Address, PhoneNumber, EmailAddress, WebAddress, Ref, QuickbooksBaseObject, \ QuickbooksManagedObject, QuickbooksTransactionEntity @@ -51,7 +52,7 @@ def __init__(self): self.Balance = 0 self.BillRate = 0 self.AcctNum = "" - self.Vendor1099 = True + self.Vendor1099 = False self.TaxReportingBasis = "" self.BillAddr = None From 35172d53301aafee4ad63876decbf3619ff4be07 Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 19:24:13 +0800 Subject: [PATCH 070/154] qb-304 fix failing integration attachable tests --- quickbooks/objects/attachable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickbooks/objects/attachable.py b/quickbooks/objects/attachable.py index e7d23d05..23e71321 100644 --- a/quickbooks/objects/attachable.py +++ b/quickbooks/objects/attachable.py @@ -58,7 +58,7 @@ def save(self, qb=None): else: json_data = qb.create_object(self.qbo_object_name, self.to_json(), _file_path=self._FilePath) - if self.FileName: + if self.Id is None and self.FileName: obj = type(self).from_json(json_data['AttachableResponse'][0]['Attachable']) else: obj = type(self).from_json(json_data['Attachable']) From 45cb3e2a092c0882b076bceb67f57c23e5806506 Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 19:28:10 +0800 Subject: [PATCH 071/154] qb-304 update void mixin and it's unit tests for voiding other voidable types --- quickbooks/mixins.py | 57 ++++++++++++++++++++++++++++++++++----- tests/unit/test_mixins.py | 25 +++++++++++++++-- 2 files changed, 74 insertions(+), 8 deletions(-) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 9b51a426..2083139e 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -119,6 +119,53 @@ def send(self, qb=None, send_to=None): class VoidMixin(object): + + def get_void_params(self): + qb_object_params_map = { + "Payment": { + "operation": "update", + "include": "void" + }, + "SalesReceipt": { + "operation": "update", + "include": "void" + }, + "BillPayment": { + "operation": "update", + "include": "void" + }, + "Invoice": { + "operation": "void", + }, + } + # setting the default operation to void (the original behavior) + return qb_object_params_map.get(self.qbo_object_name, {"operation": "void"}) + + def get_void_data(self): + qb_object_params_map = { + "Payment": { + "Id": self.Id, + "SyncToken": self.SyncToken, + "sparse": True + }, + "SalesReceipt": { + "Id": self.Id, + "SyncToken": self.SyncToken, + "sparse": True + }, + "BillPayment": { + "Id": self.Id, + "SyncToken": self.SyncToken, + "sparse": True + }, + "Invoice": { + "Id": self.Id, + "SyncToken": self.SyncToken, + }, + } + # setting the default operation to void (the original behavior) + return qb_object_params_map.get(self.qbo_object_name, {"operation": "void"}) + def void(self, qb=None): if not qb: qb = QuickBooks() @@ -126,14 +173,12 @@ def void(self, qb=None): if not self.Id: raise QuickbooksException('Cannot void unsaved object') - data = { - 'Id': self.Id, - 'SyncToken': self.SyncToken, - } - endpoint = self.qbo_object_name.lower() url = "{0}/company/{1}/{2}".format(qb.api_url, qb.company_id, endpoint) - results = qb.post(url, json.dumps(data), params={'operation': 'void'}) + + data = self.get_void_data() + params = self.get_void_params() + results = qb.post(url, json.dumps(data), params=params) return results diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index c3ff3ed8..017df5d9 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -4,7 +4,7 @@ import unittest from urllib.parse import quote -from quickbooks.objects import Bill, Invoice +from quickbooks.objects import Bill, Invoice, Payment, BillPayment from tests.integration.test_base import QuickbooksUnitTestCase @@ -381,12 +381,33 @@ def test_send_with_send_to_email(self, mock_misc_op): class VoidMixinTest(QuickbooksUnitTestCase): @patch('quickbooks.mixins.QuickBooks.post') - def test_void(self, post): + def test_void_invoice(self, post): invoice = Invoice() invoice.Id = 2 invoice.void(qb=self.qb_client) self.assertTrue(post.called) + @patch('quickbooks.mixins.QuickBooks.post') + def test_void_payment(self, post): + payment = Payment() + payment.Id = 2 + payment.void(qb=self.qb_client) + self.assertTrue(post.called) + + @patch('quickbooks.mixins.QuickBooks.post') + def test_void_sales_receipt(self, post): + sales_receipt = SalesReceipt() + sales_receipt.Id = 2 + sales_receipt.void(qb=self.qb_client) + self.assertTrue(post.called) + + @patch('quickbooks.mixins.QuickBooks.post') + def test_void_bill_payment(self, post): + bill_payment = BillPayment() + bill_payment.Id = 2 + bill_payment.void(qb=self.qb_client) + self.assertTrue(post.called) + def test_delete_unsaved_exception(self): from quickbooks.exceptions import QuickbooksException From 252abd158cde185a11b902befb4b02fdecf8a5bd Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 19:29:50 +0800 Subject: [PATCH 072/154] qb-304 update billpayment, payment and salesreceipt to inherent from void mixin --- quickbooks/objects/billpayment.py | 4 ++-- quickbooks/objects/payment.py | 23 ++--------------------- quickbooks/objects/salesreceipt.py | 4 ++-- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/quickbooks/objects/billpayment.py b/quickbooks/objects/billpayment.py index 3f175d95..64569d90 100644 --- a/quickbooks/objects/billpayment.py +++ b/quickbooks/objects/billpayment.py @@ -1,6 +1,6 @@ from .base import QuickbooksBaseObject, Ref, LinkedTxn, QuickbooksManagedObject, LinkedTxnMixin, \ QuickbooksTransactionEntity -from ..mixins import DeleteMixin +from ..mixins import DeleteMixin, VoidMixin class CheckPayment(QuickbooksBaseObject): @@ -47,7 +47,7 @@ def __str__(self): return str(self.Amount) -class BillPayment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): +class BillPayment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, VoidMixin): """ QBO definition: A BillPayment entity represents the financial transaction of payment of bills that the business owner receives from a vendor for goods or services purchased diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index 07e15222..75cbf570 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -3,7 +3,7 @@ LinkedTxnMixin, MetaData from ..client import QuickBooks from .creditcardpayment import CreditCardPayment -from ..mixins import DeleteMixin +from ..mixins import DeleteMixin, VoidMixin import json @@ -21,7 +21,7 @@ def __str__(self): return str(self.Amount) -class Payment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin): +class Payment(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, LinkedTxnMixin, VoidMixin): """ QBO definition: A Payment entity records a payment in QuickBooks. The payment can be applied for a particular customer against multiple Invoices and Credit Memos. It can also @@ -81,24 +81,5 @@ def __init__(self): # These fields are for minor version 4 self.TransactionLocationType = None - def void(self, qb=None): - if not qb: - qb = QuickBooks() - - if not self.Id: - raise qb.QuickbooksException('Cannot void unsaved object') - - data = { - 'Id': self.Id, - 'SyncToken': self.SyncToken, - 'sparse': True - } - - endpoint = self.qbo_object_name.lower() - url = "{0}/company/{1}/{2}".format(qb.api_url, qb.company_id, endpoint) - results = qb.post(url, json.dumps(data), params={'operation': 'update', 'include': 'void'}) - - return results - def __str__(self): return str(self.TotalAmt) diff --git a/quickbooks/objects/salesreceipt.py b/quickbooks/objects/salesreceipt.py index 83b55a20..0a42925b 100644 --- a/quickbooks/objects/salesreceipt.py +++ b/quickbooks/objects/salesreceipt.py @@ -2,11 +2,11 @@ EmailAddress, QuickbooksTransactionEntity, LinkedTxn from .tax import TxnTaxDetail from .detailline import DetailLine -from ..mixins import QuickbooksPdfDownloadable, DeleteMixin +from ..mixins import QuickbooksPdfDownloadable, DeleteMixin, VoidMixin class SalesReceipt(DeleteMixin, QuickbooksPdfDownloadable, QuickbooksManagedObject, - QuickbooksTransactionEntity, LinkedTxnMixin): + QuickbooksTransactionEntity, LinkedTxnMixin, VoidMixin): """ QBO definition: SalesReceipt represents the sales receipt that is given to a customer. A sales receipt is similar to an invoice. However, for a sales receipt, payment is received From 2768fc1e7f778307b99ac9dae8b28afe1c573868 Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 20:05:20 +0800 Subject: [PATCH 073/154] qb-304 fix reusing the same bill for testing billpayment & add test for voiding bill payment --- tests/integration/test_billpayment.py | 72 ++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/tests/integration/test_billpayment.py b/tests/integration/test_billpayment.py index fab990c0..e1549f5e 100644 --- a/tests/integration/test_billpayment.py +++ b/tests/integration/test_billpayment.py @@ -1,5 +1,6 @@ from datetime import datetime +from quickbooks.objects import AccountBasedExpenseLine, Ref, AccountBasedExpenseLineDetail from quickbooks.objects.account import Account from quickbooks.objects.bill import Bill from quickbooks.objects.billpayment import BillPayment, BillPaymentLine, CheckPayment @@ -31,7 +32,24 @@ def test_create(self): ap_account = Account.where("AccountSubType = 'AccountsPayable'", qb=self.qb_client)[0] bill_payment.APAccountRef = ap_account.to_ref() - bill = Bill.all(max_results=1, qb=self.qb_client)[0] + # create new bill for testing, reusing the same bill will cause Line to be empty + # and the new bill payment will be voided automatically + bill = Bill() + line = AccountBasedExpenseLine() + line.Amount = 200 + line.DetailType = "AccountBasedExpenseLineDetail" + + account_ref = Ref() + account_ref.type = "Account" + account_ref.value = 1 + line.AccountBasedExpenseLineDetail = AccountBasedExpenseLineDetail() + line.AccountBasedExpenseLineDetail.AccountRef = account_ref + bill.Line.append(line) + + vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] + bill.VendorRef = vendor.to_ref() + + bill.save(qb=self.qb_client) line = BillPaymentLine() line.LinkedTxn.append(bill.to_linked_txn()) @@ -48,3 +66,55 @@ def test_create(self): self.assertEqual(len(query_bill_payment.Line), 1) self.assertEqual(query_bill_payment.Line[0].Amount, 200.0) + + def test_void(self): + bill_payment = BillPayment() + + bill_payment.PayType = "Check" + bill_payment.TotalAmt = 200 + bill_payment.PrivateNote = "Private Note" + + vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] + bill_payment.VendorRef = vendor.to_ref() + + bill_payment.CheckPayment = CheckPayment() + account = Account.where("AccountSubType = 'Checking'", qb=self.qb_client)[0] + bill_payment.CheckPayment.BankAccountRef = account.to_ref() + + ap_account = Account.where("AccountSubType = 'AccountsPayable'", qb=self.qb_client)[0] + bill_payment.APAccountRef = ap_account.to_ref() + + # create new bill for testing, reusing the same bill will cause Line to be empty + # and the new bill payment will be voided automatically + bill = Bill() + line = AccountBasedExpenseLine() + line.Amount = 200 + line.DetailType = "AccountBasedExpenseLineDetail" + + account_ref = Ref() + account_ref.type = "Account" + account_ref.value = 1 + line.AccountBasedExpenseLineDetail = AccountBasedExpenseLineDetail() + line.AccountBasedExpenseLineDetail.AccountRef = account_ref + bill.Line.append(line) + + vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] + bill.VendorRef = vendor.to_ref() + + bill.save(qb=self.qb_client) + + line = BillPaymentLine() + line.LinkedTxn.append(bill.to_linked_txn()) + line.Amount = 200 + + bill_payment.Line.append(line) + bill_payment.save(qb=self.qb_client) + query_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) + self.assertEqual(query_payment.TotalAmt, 200.0) + self.assertNotIn('Voided', query_payment.PrivateNote) + + bill_payment.void(qb=self.qb_client) + query_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) + + self.assertEqual(query_payment.TotalAmt, 0.0) + self.assertIn('Voided', query_payment.PrivateNote) \ No newline at end of file From fa183e9b3d4add9ffd11acb2b66c44a9057c6af0 Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 20:12:02 +0800 Subject: [PATCH 074/154] qb-304 refactor billpayment integration tests --- tests/integration/test_billpayment.py | 78 ++++++++------------------- 1 file changed, 22 insertions(+), 56 deletions(-) diff --git a/tests/integration/test_billpayment.py b/tests/integration/test_billpayment.py index e1549f5e..67e4f556 100644 --- a/tests/integration/test_billpayment.py +++ b/tests/integration/test_billpayment.py @@ -15,25 +15,7 @@ def setUp(self): self.account_number = datetime.now().strftime('%d%H%M') self.name = "Test Account {0}".format(self.account_number) - def test_create(self): - bill_payment = BillPayment() - - bill_payment.PayType = "Check" - bill_payment.TotalAmt = 200 - bill_payment.PrivateNote = "Private Note" - - vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] - bill_payment.VendorRef = vendor.to_ref() - - bill_payment.CheckPayment = CheckPayment() - account = Account.where("AccountSubType = 'Checking'", qb=self.qb_client)[0] - bill_payment.CheckPayment.BankAccountRef = account.to_ref() - - ap_account = Account.where("AccountSubType = 'AccountsPayable'", qb=self.qb_client)[0] - bill_payment.APAccountRef = ap_account.to_ref() - - # create new bill for testing, reusing the same bill will cause Line to be empty - # and the new bill payment will be voided automatically + def create_bill(self): bill = Bill() line = AccountBasedExpenseLine() line.Amount = 200 @@ -49,25 +31,9 @@ def test_create(self): vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] bill.VendorRef = vendor.to_ref() - bill.save(qb=self.qb_client) - - line = BillPaymentLine() - line.LinkedTxn.append(bill.to_linked_txn()) - line.Amount = 200 - - bill_payment.Line.append(line) - bill_payment.save(qb=self.qb_client) - - query_bill_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) - - self.assertEqual(query_bill_payment.PayType, "Check") - self.assertEqual(query_bill_payment.TotalAmt, 200.0) - self.assertEqual(query_bill_payment.PrivateNote, "Private Note") - - self.assertEqual(len(query_bill_payment.Line), 1) - self.assertEqual(query_bill_payment.Line[0].Amount, 200.0) + return bill.save(qb=self.qb_client) - def test_void(self): + def create_bill_payment(self, bill): bill_payment = BillPayment() bill_payment.PayType = "Check" @@ -84,31 +50,31 @@ def test_void(self): ap_account = Account.where("AccountSubType = 'AccountsPayable'", qb=self.qb_client)[0] bill_payment.APAccountRef = ap_account.to_ref() - # create new bill for testing, reusing the same bill will cause Line to be empty - # and the new bill payment will be voided automatically - bill = Bill() - line = AccountBasedExpenseLine() + line = BillPaymentLine() + line.LinkedTxn.append(bill.to_linked_txn()) line.Amount = 200 - line.DetailType = "AccountBasedExpenseLineDetail" - account_ref = Ref() - account_ref.type = "Account" - account_ref.value = 1 - line.AccountBasedExpenseLineDetail = AccountBasedExpenseLineDetail() - line.AccountBasedExpenseLineDetail.AccountRef = account_ref - bill.Line.append(line) + bill_payment.Line.append(line) + return bill_payment.save(qb=self.qb_client) - vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] - bill.VendorRef = vendor.to_ref() + def test_create(self): + # create new bill for testing, reusing the same bill will cause Line to be empty + # and the new bill payment will be voided automatically + bill = self.create_bill() + bill_payment = self.create_bill_payment(bill) - bill.save(qb=self.qb_client) + query_bill_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) - line = BillPaymentLine() - line.LinkedTxn.append(bill.to_linked_txn()) - line.Amount = 200 + self.assertEqual(query_bill_payment.PayType, "Check") + self.assertEqual(query_bill_payment.TotalAmt, 200.0) + self.assertEqual(query_bill_payment.PrivateNote, "Private Note") - bill_payment.Line.append(line) - bill_payment.save(qb=self.qb_client) + self.assertEqual(len(query_bill_payment.Line), 1) + self.assertEqual(query_bill_payment.Line[0].Amount, 200.0) + + def test_void(self): + bill = self.create_bill() + bill_payment = self.create_bill_payment(bill) query_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) self.assertEqual(query_payment.TotalAmt, 200.0) self.assertNotIn('Voided', query_payment.PrivateNote) From f20d920b00caafc71b0fc8739cdaee01bbf98a9c Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 20:16:21 +0800 Subject: [PATCH 075/154] qb-304 add test for voiding invoice --- tests/integration/test_invoice.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/integration/test_invoice.py b/tests/integration/test_invoice.py index 4a686a53..c02e40eb 100644 --- a/tests/integration/test_invoice.py +++ b/tests/integration/test_invoice.py @@ -75,3 +75,14 @@ def test_delete(self): query_invoice = Invoice.filter(Id=invoice_id, qb=self.qb_client) self.assertEqual([], query_invoice) + + def test_void(self): + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + invoice = self.create_invoice(customer) + invoice_id = invoice.Id + invoice.void(qb=self.qb_client) + + query_invoice = Invoice.get(invoice_id, qb=self.qb_client) + self.assertEqual(query_invoice.Balance, 0.0) + self.assertEqual(query_invoice.TotalAmt, 0.0) + self.assertIn('Voided', query_invoice.PrivateNote) From c770bcc85789849ece0efd42ac5cc4a05fc6083a Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 20:26:10 +0800 Subject: [PATCH 076/154] qb-304 refactor billpayment integration tests, add params to helper create billpayment method --- tests/integration/test_billpayment.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/integration/test_billpayment.py b/tests/integration/test_billpayment.py index 67e4f556..24ea6fa1 100644 --- a/tests/integration/test_billpayment.py +++ b/tests/integration/test_billpayment.py @@ -33,12 +33,12 @@ def create_bill(self): return bill.save(qb=self.qb_client) - def create_bill_payment(self, bill): + def create_bill_payment(self, bill, amount, private_note, pay_type): bill_payment = BillPayment() - bill_payment.PayType = "Check" - bill_payment.TotalAmt = 200 - bill_payment.PrivateNote = "Private Note" + bill_payment.PayType = pay_type + bill_payment.TotalAmt = amount + bill_payment.PrivateNote = private_note vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] bill_payment.VendorRef = vendor.to_ref() @@ -61,7 +61,7 @@ def test_create(self): # create new bill for testing, reusing the same bill will cause Line to be empty # and the new bill payment will be voided automatically bill = self.create_bill() - bill_payment = self.create_bill_payment(bill) + bill_payment = self.create_bill_payment(bill, 200, "Private Note", "Check") query_bill_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) @@ -74,7 +74,7 @@ def test_create(self): def test_void(self): bill = self.create_bill() - bill_payment = self.create_bill_payment(bill) + bill_payment = self.create_bill_payment(bill, 200, "Private Note", "Check") query_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) self.assertEqual(query_payment.TotalAmt, 200.0) self.assertNotIn('Voided', query_payment.PrivateNote) From a3bf716e51ffdbfa94cdabd46856d72ca4108c6b Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 20:27:59 +0800 Subject: [PATCH 077/154] qb-304 refactor billpayment integration tests, add params to helper create bill method --- tests/integration/test_billpayment.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integration/test_billpayment.py b/tests/integration/test_billpayment.py index 24ea6fa1..c7ce6501 100644 --- a/tests/integration/test_billpayment.py +++ b/tests/integration/test_billpayment.py @@ -15,10 +15,10 @@ def setUp(self): self.account_number = datetime.now().strftime('%d%H%M') self.name = "Test Account {0}".format(self.account_number) - def create_bill(self): + def create_bill(self, amount): bill = Bill() line = AccountBasedExpenseLine() - line.Amount = 200 + line.Amount = amount line.DetailType = "AccountBasedExpenseLineDetail" account_ref = Ref() @@ -60,7 +60,7 @@ def create_bill_payment(self, bill, amount, private_note, pay_type): def test_create(self): # create new bill for testing, reusing the same bill will cause Line to be empty # and the new bill payment will be voided automatically - bill = self.create_bill() + bill = self.create_bill(amount=200) bill_payment = self.create_bill_payment(bill, 200, "Private Note", "Check") query_bill_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) @@ -73,7 +73,7 @@ def test_create(self): self.assertEqual(query_bill_payment.Line[0].Amount, 200.0) def test_void(self): - bill = self.create_bill() + bill = self.create_bill(amount=200) bill_payment = self.create_bill_payment(bill, 200, "Private Note", "Check") query_payment = BillPayment.get(bill_payment.Id, qb=self.qb_client) self.assertEqual(query_payment.TotalAmt, 200.0) From 6abedeee3cf18ccf3ba3ddc4702ae152f20201cb Mon Sep 17 00:00:00 2001 From: Zeyad Obaia Date: Wed, 20 Sep 2023 20:40:31 +0800 Subject: [PATCH 078/154] qb-304 add integration tests for SalesReceipt create and void --- tests/integration/test_salesreceipt.py | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/integration/test_salesreceipt.py diff --git a/tests/integration/test_salesreceipt.py b/tests/integration/test_salesreceipt.py new file mode 100644 index 00000000..ce3bd2a9 --- /dev/null +++ b/tests/integration/test_salesreceipt.py @@ -0,0 +1,59 @@ +from datetime import datetime + +from quickbooks.objects import SalesReceipt, Customer, \ + SalesItemLine, SalesItemLineDetail, Item +from tests.integration.test_base import QuickbooksTestCase + + +class SalesReceiptTest(QuickbooksTestCase): + def setUp(self): + super(SalesReceiptTest, self).setUp() + + self.account_number = datetime.now().strftime('%d%H%M') + self.name = "Test Account {0}".format(self.account_number) + + def create_sales_receipt(self, qty=1, unit_price=100.0): + sales_receipt = SalesReceipt() + sales_receipt.TotalAmt = qty * unit_price + customer = Customer.all(max_results=1, qb=self.qb_client)[0] + sales_receipt.CustomerRef = customer.to_ref() + item = Item.all(max_results=1, qb=self.qb_client)[0] + line = SalesItemLine() + sales_item_line_detail = SalesItemLineDetail() + sales_item_line_detail.ItemRef = item.to_ref() + sales_item_line_detail.Qty = qty + sales_item_line_detail.UnitPrice = unit_price + today = datetime.now() + sales_item_line_detail.ServiceDate = today.strftime( + "%Y-%m-%d" + ) + line.SalesItemLineDetail = sales_item_line_detail + line.Amount = qty * unit_price + sales_receipt.Line = [line] + + return sales_receipt.save(qb=self.qb_client) + + def test_create(self): + sales_receipt = self.create_sales_receipt( + qty=1, + unit_price=100.0 + ) + query_sales_receipt = SalesReceipt.get(sales_receipt.Id, qb=self.qb_client) + + self.assertEqual(query_sales_receipt.TotalAmt, 100.0) + self.assertEqual(query_sales_receipt.Line[0].Amount, 100.0) + self.assertEqual(query_sales_receipt.Line[0].SalesItemLineDetail['Qty'], 1) + self.assertEqual(query_sales_receipt.Line[0].SalesItemLineDetail['UnitPrice'], 100.0) + + def test_void(self): + sales_receipt = self.create_sales_receipt( + qty=1, + unit_price=100.0 + ) + query_sales_receipt = SalesReceipt.get(sales_receipt.Id, qb=self.qb_client) + self.assertEqual(query_sales_receipt.TotalAmt, 100.0) + self.assertNotIn('Voided', query_sales_receipt.PrivateNote) + sales_receipt.void(qb=self.qb_client) + query_sales_receipt = SalesReceipt.get(sales_receipt.Id, qb=self.qb_client) + self.assertEqual(query_sales_receipt.TotalAmt, 0.0) + self.assertIn('Voided', query_sales_receipt.PrivateNote) From 429dbab65420950fe062c102c199979deb4a4913 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 13:58:32 -0500 Subject: [PATCH 079/154] Added to_ref to CreditMemo --- quickbooks/objects/creditmemo.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/quickbooks/objects/creditmemo.py b/quickbooks/objects/creditmemo.py index 9cfcc876..cbb5831b 100644 --- a/quickbooks/objects/creditmemo.py +++ b/quickbooks/objects/creditmemo.py @@ -70,3 +70,11 @@ def __init__(self): def __str__(self): return str(self.TotalAmt) + + def to_ref(self): + ref = Ref() + + ref.type = self.qbo_object_name + ref.value = self.Id + + return ref From 58a0e532fdbe31077aa35d7287fe8a3074d590c7 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 14:10:01 -0500 Subject: [PATCH 080/154] Added missing fields on estimate --- quickbooks/objects/estimate.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickbooks/objects/estimate.py b/quickbooks/objects/estimate.py index 6a9d5966..64b5df42 100644 --- a/quickbooks/objects/estimate.py +++ b/quickbooks/objects/estimate.py @@ -19,7 +19,9 @@ class Estimate(DeleteMixin, class_dict = { "BillAddr": Address, "ShipAddr": Address, + "ShipFromAddr": Address, "CustomerRef": Ref, + "ProjectRef": Ref, "TxnTaxDetail": TxnTaxDetail, "CustomerMemo": CustomerMemo, "BillEmail": EmailAddress, @@ -65,8 +67,10 @@ def __init__(self): self.GlobalTaxCalculation = "TaxExcluded" self.BillAddr = None self.ShipAddr = None + self.ShipFromAddr = None self.BillEmail = None self.CustomerRef = None + self.ProjectRef = None self.TxnTaxDetail = None self.CustomerMemo = None self.ClassRef = None From 6c548ed624a687dbecfc479251c9574a37a7f41c Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 14:45:17 -0500 Subject: [PATCH 081/154] Update objects and change log --- CHANGELOG.rst | 5 +++++ quickbooks/objects/detailline.py | 1 + quickbooks/objects/employee.py | 1 + quickbooks/objects/estimate.py | 1 + quickbooks/objects/invoice.py | 2 ++ setup.py | 2 +- 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 808e2697..31d4992e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,10 @@ Changelog ========= +* 0.9.5 (November 1, 2023) + * Added to_ref to CreditMemo object + * Added ProjectRef and ShipFromAddr to Estimate + * Added missing initialization for objects on DiscountLineDetail, Estimate, Employee, and Invoice + * 0.9.4 (August 29, 2023) * Removed python 2 compatible decorators * Removed python 2 dependencies diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index eb6465c2..2ada36d6 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -51,6 +51,7 @@ def __init__(self): self.Discount = None self.ClassRef = None self.TaxCodeRef = None + self.DiscountAccountRef = None self.PercentBased = False self.DiscountPercent = 0 diff --git a/quickbooks/objects/employee.py b/quickbooks/objects/employee.py index 8e1636f5..4e766f18 100644 --- a/quickbooks/objects/employee.py +++ b/quickbooks/objects/employee.py @@ -35,6 +35,7 @@ def __init__(self): self.BillableTime = False self.PrimaryAddr = None + self.PrimaryPhone = None def __str__(self): return self.DisplayName diff --git a/quickbooks/objects/estimate.py b/quickbooks/objects/estimate.py index 64b5df42..8ece9fb9 100644 --- a/quickbooks/objects/estimate.py +++ b/quickbooks/objects/estimate.py @@ -66,6 +66,7 @@ def __init__(self): self.AcceptedDate = None self.GlobalTaxCalculation = "TaxExcluded" self.BillAddr = None + self.DepartmentRef = None self.ShipAddr = None self.ShipFromAddr = None self.BillEmail = None diff --git a/quickbooks/objects/invoice.py b/quickbooks/objects/invoice.py index c3b923f3..8e1d1a98 100644 --- a/quickbooks/objects/invoice.py +++ b/quickbooks/objects/invoice.py @@ -95,6 +95,8 @@ def __init__(self): self.TxnTaxDetail = None self.DeliveryInfo = None self.RecurDataRef = None + self.SalesTermRef = None + self.ShipMethodRef = None self.TaxExemptionRef = None self.MetaData = None diff --git a/setup.py b/setup.py index 665978c1..c88111f3 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 4) +VERSION = (0, 9, 5) version = '.'.join(map(str, VERSION)) setup( From a02ca1ba6bac7ced8e1af07e6a04d7a46818df22 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 16:00:03 -0500 Subject: [PATCH 082/154] update pipfile.lock --- Pipfile | 3 - Pipfile.lock | 533 +++++++++++++++++++++++++++------------------------ 2 files changed, 282 insertions(+), 254 deletions(-) diff --git a/Pipfile b/Pipfile index a3ddd036..26e81a3e 100644 --- a/Pipfile +++ b/Pipfile @@ -15,6 +15,3 @@ simplejson = ">=3.19.1" nose = "*" coverage = "*" twine = "*" - -[requires] -python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 41ccc28b..311a7eb5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,12 +1,10 @@ { "_meta": { "hash": { - "sha256": "f8797f56e2b6c880a4ad872b0cdc9bf0b6388112b1e3b35ee6dc644e406507b0" + "sha256": "34f14be2688a7429ee79c084b29d6da49f332312e66876132edb44ae8a151246" }, "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, + "requires": {}, "sources": [ { "name": "pypi", @@ -18,12 +16,12 @@ "default": { "bleach": { "hashes": [ - "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414", - "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4" + "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe", + "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==6.0.0" + "markers": "python_version >= '3.8'", + "version": "==6.1.0" }, "certifi": { "hashes": [ @@ -35,143 +33,158 @@ }, "charset-normalizer": { "hashes": [ - "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", - "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", - "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", - "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", - "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", - "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", - "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", - "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", - "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", - "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", - "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", - "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", - "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", - "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", - "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", - "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", - "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", - "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", - "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", - "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", - "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", - "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", - "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", - "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", - "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", - "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", - "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", - "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", - "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", - "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", - "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", - "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", - "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", - "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", - "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", - "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", - "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", - "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", - "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", - "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", - "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", - "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", - "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", - "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", - "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", - "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", - "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", - "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", - "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", - "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", - "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", - "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", - "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", - "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", - "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", - "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", - "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", - "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", - "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", - "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", - "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", - "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", - "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", - "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", - "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", - "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", - "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", - "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", - "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", - "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", - "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", - "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", - "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", - "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", - "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.2.0" + "version": "==3.3.2" }, "coverage": { "hashes": [ - "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34", - "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e", - "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7", - "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b", - "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3", - "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985", - "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95", - "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2", - "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a", - "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74", - "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd", - "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af", - "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54", - "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865", - "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214", - "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54", - "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe", - "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0", - "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321", - "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446", - "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e", - "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527", - "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12", - "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f", - "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f", - "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84", - "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479", - "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e", - "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873", - "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70", - "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0", - "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977", - "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51", - "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28", - "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1", - "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254", - "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1", - "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd", - "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689", - "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d", - "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543", - "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9", - "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637", - "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071", - "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482", - "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1", - "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b", - "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5", - "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a", - "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393", - "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a", - "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba" + "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", + "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", + "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", + "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", + "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", + "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", + "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", + "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", + "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", + "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", + "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", + "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", + "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", + "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", + "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", + "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", + "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", + "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", + "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", + "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", + "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", + "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", + "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", + "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", + "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", + "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", + "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", + "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", + "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", + "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", + "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", + "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", + "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", + "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", + "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", + "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", + "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", + "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", + "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", + "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", + "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", + "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", + "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", + "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", + "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", + "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", + "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", + "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", + "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", + "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", + "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", + "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==7.3.0" + "version": "==7.3.2" }, "docutils": { "hashes": [ @@ -219,14 +232,6 @@ "markers": "python_version >= '3.8'", "version": "==6.8.0" }, - "importlib-resources": { - "hashes": [ - "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", - "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" - ], - "markers": "python_version < '3.9'", - "version": "==6.0.1" - }, "intuit-oauth": { "hashes": [ "sha256:14a1a8ed73f24369ba209f0e581eb30698571fd7bcbe05ca5bed65d2ff9df8b1", @@ -275,6 +280,27 @@ "markers": "python_version >= '3.8'", "version": "==10.1.0" }, + "nh3": { + "hashes": [ + "sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873", + "sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad", + "sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5", + "sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525", + "sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2", + "sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e", + "sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d", + "sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450", + "sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e", + "sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6", + "sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a", + "sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4", + "sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4", + "sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6", + "sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e", + "sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75" + ], + "version": "==0.2.14" + }, "nose": { "hashes": [ "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", @@ -333,11 +359,11 @@ }, "readme-renderer": { "hashes": [ - "sha256:4f4b11e5893f5a5d725f592c5a343e0dc74f5f273cb3dcf8c42d9703a27073f7", - "sha256:a38243d5b6741b700a850026e62da4bd739edc7422071e95fd5c4bb60171df86" + "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d", + "sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1" ], "markers": "python_version >= '3.8'", - "version": "==41.0" + "version": "==42.0" }, "requests": { "hashes": [ @@ -374,11 +400,11 @@ }, "rich": { "hashes": [ - "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808", - "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39" + "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245", + "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef" ], "markers": "python_full_version >= '3.7.0'", - "version": "==13.5.2" + "version": "==13.6.0" }, "rsa": { "hashes": [ @@ -390,95 +416,108 @@ }, "simplejson": { "hashes": [ - "sha256:081ea6305b3b5e84ae7417e7f45956db5ea3872ec497a584ec86c3260cda049e", - "sha256:08be5a241fdf67a8e05ac7edbd49b07b638ebe4846b560673e196b2a25c94b92", - "sha256:0c16ec6a67a5f66ab004190829eeede01c633936375edcad7cbf06d3241e5865", - "sha256:0ccb2c1877bc9b25bc4f4687169caa925ffda605d7569c40e8e95186e9a5e58b", - "sha256:17a963e8dd4d81061cc05b627677c1f6a12e81345111fbdc5708c9f088d752c9", - "sha256:199a0bcd792811c252d71e3eabb3d4a132b3e85e43ebd93bfd053d5b59a7e78b", - "sha256:1cb19eacb77adc5a9720244d8d0b5507421d117c7ed4f2f9461424a1829e0ceb", - "sha256:203412745fed916fc04566ecef3f2b6c872b52f1e7fb3a6a84451b800fb508c1", - "sha256:2098811cd241429c08b7fc5c9e41fcc3f59f27c2e8d1da2ccdcf6c8e340ab507", - "sha256:22b867205cd258050c2625325fdd9a65f917a5aff22a23387e245ecae4098e78", - "sha256:23fbb7b46d44ed7cbcda689295862851105c7594ae5875dce2a70eeaa498ff86", - "sha256:2541fdb7467ef9bfad1f55b6c52e8ea52b3ce4a0027d37aff094190a955daa9d", - "sha256:3231100edee292da78948fa0a77dee4e5a94a0a60bcba9ed7a9dc77f4d4bb11e", - "sha256:344a5093b71c1b370968d0fbd14d55c9413cb6f0355fdefeb4a322d602d21776", - "sha256:37724c634f93e5caaca04458f267836eb9505d897ab3947b52f33b191bf344f3", - "sha256:3844305bc33d52c4975da07f75b480e17af3558c0d13085eaa6cc2f32882ccf7", - "sha256:390f4a8ca61d90bcf806c3ad644e05fa5890f5b9a72abdd4ca8430cdc1e386fa", - "sha256:3a4480e348000d89cf501b5606415f4d328484bbb431146c2971123d49fd8430", - "sha256:3b652579c21af73879d99c8072c31476788c8c26b5565687fd9db154070d852a", - "sha256:3e0902c278243d6f7223ba3e6c5738614c971fd9a887fff8feaa8dcf7249c8d4", - "sha256:412e58997a30c5deb8cab5858b8e2e5b40ca007079f7010ee74565cc13d19665", - "sha256:44cdb4e544134f305b033ad79ae5c6b9a32e7c58b46d9f55a64e2a883fbbba01", - "sha256:46133bc7dd45c9953e6ee4852e3de3d5a9a4a03b068bd238935a5c72f0a1ce34", - "sha256:46e89f58e4bed107626edce1cf098da3664a336d01fc78fddcfb1f397f553d44", - "sha256:4710806eb75e87919b858af0cba4ffedc01b463edc3982ded7b55143f39e41e1", - "sha256:476c8033abed7b1fd8db62a7600bf18501ce701c1a71179e4ce04ac92c1c5c3c", - "sha256:48600a6e0032bed17c20319d91775f1797d39953ccfd68c27f83c8d7fc3b32cb", - "sha256:4d3025e7e9ddb48813aec2974e1a7e68e63eac911dd5e0a9568775de107ac79a", - "sha256:547ea86ca408a6735335c881a2e6208851027f5bfd678d8f2c92a0f02c7e7330", - "sha256:54fca2b26bcd1c403146fd9461d1da76199442297160721b1d63def2a1b17799", - "sha256:5673d27806085d2a413b3be5f85fad6fca4b7ffd31cfe510bbe65eea52fff571", - "sha256:58ee5e24d6863b22194020eb62673cf8cc69945fcad6b283919490f6e359f7c5", - "sha256:5ca922c61d87b4c38f37aa706520328ffe22d7ac1553ef1cadc73f053a673553", - "sha256:5db86bb82034e055257c8e45228ca3dbce85e38d7bfa84fa7b2838e032a3219c", - "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c", - "sha256:6424d8229ba62e5dbbc377908cfee9b2edf25abd63b855c21f12ac596cd18e41", - "sha256:65dafe413b15e8895ad42e49210b74a955c9ae65564952b0243a18fb35b986cc", - "sha256:66389b6b6ee46a94a493a933a26008a1bae0cfadeca176933e7ff6556c0ce998", - "sha256:66d780047c31ff316ee305c3f7550f352d87257c756413632303fc59fef19eac", - "sha256:69a8b10a4f81548bc1e06ded0c4a6c9042c0be0d947c53c1ed89703f7e613950", - "sha256:6a561320485017ddfc21bd2ed5de2d70184f754f1c9b1947c55f8e2b0163a268", - "sha256:6aa7ca03f25b23b01629b1c7f78e1cd826a66bfb8809f8977a3635be2ec48f1a", - "sha256:6b79642a599740603ca86cf9df54f57a2013c47e1dd4dd2ae4769af0a6816900", - "sha256:6e7c70f19405e5f99168077b785fe15fcb5f9b3c0b70b0b5c2757ce294922c8c", - "sha256:70128fb92932524c89f373e17221cf9535d7d0c63794955cc3cd5868e19f5d38", - "sha256:73d0904c2471f317386d4ae5c665b16b5c50ab4f3ee7fd3d3b7651e564ad74b1", - "sha256:74bf802debe68627227ddb665c067eb8c73aa68b2476369237adf55c1161b728", - "sha256:79c748aa61fd8098d0472e776743de20fae2686edb80a24f0f6593a77f74fe86", - "sha256:79d46e7e33c3a4ef853a1307b2032cfb7220e1a079d0c65488fbd7118f44935a", - "sha256:7e78d79b10aa92f40f54178ada2b635c960d24fc6141856b926d82f67e56d169", - "sha256:8090e75653ea7db75bc21fa5f7bcf5f7bdf64ea258cbbac45c7065f6324f1b50", - "sha256:87b190e6ceec286219bd6b6f13547ca433f977d4600b4e81739e9ac23b5b9ba9", - "sha256:889328873c35cb0b2b4c83cbb83ec52efee5a05e75002e2c0c46c4e42790e83c", - "sha256:8f8d179393e6f0cf6c7c950576892ea6acbcea0a320838c61968ac7046f59228", - "sha256:919bc5aa4d8094cf8f1371ea9119e5d952f741dc4162810ab714aec948a23fe5", - "sha256:926957b278de22797bfc2f004b15297013843b595b3cd7ecd9e37ccb5fad0b72", - "sha256:93f5ac30607157a0b2579af59a065bcfaa7fadeb4875bf927a8f8b6739c8d910", - "sha256:96ade243fb6f3b57e7bd3b71e90c190cd0f93ec5dce6bf38734a73a2e5fa274f", - "sha256:9f14ecca970d825df0d29d5c6736ff27999ee7bdf5510e807f7ad8845f7760ce", - "sha256:a755f7bfc8adcb94887710dc70cc12a69a454120c6adcc6f251c3f7b46ee6aac", - "sha256:a79b439a6a77649bb8e2f2644e6c9cc0adb720fc55bed63546edea86e1d5c6c8", - "sha256:aa9d614a612ad02492f704fbac636f666fa89295a5d22b4facf2d665fc3b5ea9", - "sha256:ad071cd84a636195f35fa71de2186d717db775f94f985232775794d09f8d9061", - "sha256:b0e9a5e66969f7a47dc500e3dba8edc3b45d4eb31efb855c8647700a3493dd8a", - "sha256:b438e5eaa474365f4faaeeef1ec3e8d5b4e7030706e3e3d6b5bee6049732e0e6", - "sha256:b46aaf0332a8a9c965310058cf3487d705bf672641d2c43a835625b326689cf4", - "sha256:c39fa911e4302eb79c804b221ddec775c3da08833c0a9120041dd322789824de", - "sha256:ca56a6c8c8236d6fe19abb67ef08d76f3c3f46712c49a3b6a5352b6e43e8855f", - "sha256:cb502cde018e93e75dc8fc7bb2d93477ce4f3ac10369f48866c61b5e031db1fd", - "sha256:cd4d50a27b065447c9c399f0bf0a993bd0e6308db8bbbfbc3ea03b41c145775a", - "sha256:d125e754d26c0298715bdc3f8a03a0658ecbe72330be247f4b328d229d8cf67f", - "sha256:d300773b93eed82f6da138fd1d081dc96fbe53d96000a85e41460fe07c8d8b33", - "sha256:d396b610e77b0c438846607cd56418bfc194973b9886550a98fd6724e8c6cfec", - "sha256:d61482b5d18181e6bb4810b4a6a24c63a490c3a20e9fbd7876639653e2b30a1a", - "sha256:d9f2c27f18a0b94107d57294aab3d06d6046ea843ed4a45cae8bd45756749f3a", - "sha256:dc2b3f06430cbd4fac0dae5b2974d2bf14f71b415fb6de017f498950da8159b1", - "sha256:dc935d8322ba9bc7b84f99f40f111809b0473df167bf5b93b89fb719d2c4892b", - "sha256:e333c5b62e93949f5ac27e6758ba53ef6ee4f93e36cc977fe2e3df85c02f6dc4", - "sha256:e765b1f47293dedf77946f0427e03ee45def2862edacd8868c6cf9ab97c8afbd", - "sha256:ed18728b90758d171f0c66c475c24a443ede815cf3f1a91e907b0db0ebc6e508", - "sha256:eff87c68058374e45225089e4538c26329a13499bc0104b52b77f8428eed36b2", - "sha256:f05d05d99fce5537d8f7a0af6417a9afa9af3a6c4bb1ba7359c53b6257625fcb", - "sha256:f253edf694ce836631b350d758d00a8c4011243d58318fbfbe0dd54a6a839ab4", - "sha256:f41915a4e1f059dfad614b187bc06021fefb5fc5255bfe63abf8247d2f7a646a", - "sha256:f96def94576f857abf58e031ce881b5a3fc25cbec64b2bc4824824a8a4367af9" + "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137", + "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a", + "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae", + "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a", + "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba", + "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087", + "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b", + "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41", + "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d", + "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd", + "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d", + "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e", + "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a", + "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9", + "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6", + "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb", + "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664", + "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2", + "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b", + "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5", + "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835", + "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17", + "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69", + "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd", + "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6", + "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2", + "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2", + "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428", + "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f", + "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2", + "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f", + "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7", + "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f", + "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637", + "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3", + "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816", + "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565", + "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378", + "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0", + "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b", + "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693", + "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358", + "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9", + "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23", + "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf", + "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a", + "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832", + "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414", + "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f", + "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48", + "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad", + "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290", + "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3", + "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917", + "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402", + "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0", + "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc", + "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867", + "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f", + "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589", + "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb", + "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b", + "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3", + "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb", + "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c", + "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46", + "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672", + "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c", + "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e", + "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0", + "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b", + "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4", + "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4", + "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c", + "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c", + "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8", + "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b", + "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb", + "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80", + "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2", + "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374", + "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc", + "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50", + "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c", + "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f", + "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28", + "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5", + "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734", + "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a", + "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d", + "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4", + "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c", + "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13", + "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973", + "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a", + "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e", + "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff", + "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded" ], "index": "pypi", "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2'", - "version": "==3.19.1" + "version": "==3.19.2" }, "six": { "hashes": [ @@ -497,22 +536,14 @@ "markers": "python_version >= '3.7'", "version": "==4.0.2" }, - "typing-extensions": { - "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" - ], - "markers": "python_version < '3.9'", - "version": "==4.7.1" - }, "urllib3": { "hashes": [ - "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", - "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" + "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", + "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.0.4" + "version": "==2.0.7" }, "webencodings": { "hashes": [ @@ -523,11 +554,11 @@ }, "zipp": { "hashes": [ - "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", - "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" ], "markers": "python_version >= '3.8'", - "version": "==3.16.2" + "version": "==3.17.0" } }, "develop": {} From ac9fea0e48b8e23ca26652deb00f49bb0b90ef2f Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 13:58:32 -0500 Subject: [PATCH 083/154] Added to_ref to CreditMemo --- quickbooks/objects/creditmemo.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/quickbooks/objects/creditmemo.py b/quickbooks/objects/creditmemo.py index 9cfcc876..cbb5831b 100644 --- a/quickbooks/objects/creditmemo.py +++ b/quickbooks/objects/creditmemo.py @@ -70,3 +70,11 @@ def __init__(self): def __str__(self): return str(self.TotalAmt) + + def to_ref(self): + ref = Ref() + + ref.type = self.qbo_object_name + ref.value = self.Id + + return ref From 2df66b3e68c7f5eabc045a76d3a6d89453a9caa8 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 14:10:01 -0500 Subject: [PATCH 084/154] Added missing fields on estimate --- quickbooks/objects/estimate.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickbooks/objects/estimate.py b/quickbooks/objects/estimate.py index 6a9d5966..64b5df42 100644 --- a/quickbooks/objects/estimate.py +++ b/quickbooks/objects/estimate.py @@ -19,7 +19,9 @@ class Estimate(DeleteMixin, class_dict = { "BillAddr": Address, "ShipAddr": Address, + "ShipFromAddr": Address, "CustomerRef": Ref, + "ProjectRef": Ref, "TxnTaxDetail": TxnTaxDetail, "CustomerMemo": CustomerMemo, "BillEmail": EmailAddress, @@ -65,8 +67,10 @@ def __init__(self): self.GlobalTaxCalculation = "TaxExcluded" self.BillAddr = None self.ShipAddr = None + self.ShipFromAddr = None self.BillEmail = None self.CustomerRef = None + self.ProjectRef = None self.TxnTaxDetail = None self.CustomerMemo = None self.ClassRef = None From 5d3029038b2623a3c61130ad98fa48553e4a97e8 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 14:45:17 -0500 Subject: [PATCH 085/154] Update objects and change log --- CHANGELOG.rst | 5 +++++ quickbooks/objects/detailline.py | 1 + quickbooks/objects/employee.py | 1 + quickbooks/objects/estimate.py | 1 + quickbooks/objects/invoice.py | 2 ++ setup.py | 2 +- 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 808e2697..31d4992e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,10 @@ Changelog ========= +* 0.9.5 (November 1, 2023) + * Added to_ref to CreditMemo object + * Added ProjectRef and ShipFromAddr to Estimate + * Added missing initialization for objects on DiscountLineDetail, Estimate, Employee, and Invoice + * 0.9.4 (August 29, 2023) * Removed python 2 compatible decorators * Removed python 2 dependencies diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index eb6465c2..2ada36d6 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -51,6 +51,7 @@ def __init__(self): self.Discount = None self.ClassRef = None self.TaxCodeRef = None + self.DiscountAccountRef = None self.PercentBased = False self.DiscountPercent = 0 diff --git a/quickbooks/objects/employee.py b/quickbooks/objects/employee.py index 8e1636f5..4e766f18 100644 --- a/quickbooks/objects/employee.py +++ b/quickbooks/objects/employee.py @@ -35,6 +35,7 @@ def __init__(self): self.BillableTime = False self.PrimaryAddr = None + self.PrimaryPhone = None def __str__(self): return self.DisplayName diff --git a/quickbooks/objects/estimate.py b/quickbooks/objects/estimate.py index 64b5df42..8ece9fb9 100644 --- a/quickbooks/objects/estimate.py +++ b/quickbooks/objects/estimate.py @@ -66,6 +66,7 @@ def __init__(self): self.AcceptedDate = None self.GlobalTaxCalculation = "TaxExcluded" self.BillAddr = None + self.DepartmentRef = None self.ShipAddr = None self.ShipFromAddr = None self.BillEmail = None diff --git a/quickbooks/objects/invoice.py b/quickbooks/objects/invoice.py index c3b923f3..8e1d1a98 100644 --- a/quickbooks/objects/invoice.py +++ b/quickbooks/objects/invoice.py @@ -95,6 +95,8 @@ def __init__(self): self.TxnTaxDetail = None self.DeliveryInfo = None self.RecurDataRef = None + self.SalesTermRef = None + self.ShipMethodRef = None self.TaxExemptionRef = None self.MetaData = None diff --git a/setup.py b/setup.py index 665978c1..c88111f3 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 4) +VERSION = (0, 9, 5) version = '.'.join(map(str, VERSION)) setup( From 7e564964df65dc7ac3e44acf307739383aff3754 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 16:00:03 -0500 Subject: [PATCH 086/154] update pipfile.lock --- Pipfile | 3 - Pipfile.lock | 533 +++++++++++++++++++++++++++------------------------ 2 files changed, 282 insertions(+), 254 deletions(-) diff --git a/Pipfile b/Pipfile index a3ddd036..26e81a3e 100644 --- a/Pipfile +++ b/Pipfile @@ -15,6 +15,3 @@ simplejson = ">=3.19.1" nose = "*" coverage = "*" twine = "*" - -[requires] -python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 41ccc28b..311a7eb5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,12 +1,10 @@ { "_meta": { "hash": { - "sha256": "f8797f56e2b6c880a4ad872b0cdc9bf0b6388112b1e3b35ee6dc644e406507b0" + "sha256": "34f14be2688a7429ee79c084b29d6da49f332312e66876132edb44ae8a151246" }, "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, + "requires": {}, "sources": [ { "name": "pypi", @@ -18,12 +16,12 @@ "default": { "bleach": { "hashes": [ - "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414", - "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4" + "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe", + "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==6.0.0" + "markers": "python_version >= '3.8'", + "version": "==6.1.0" }, "certifi": { "hashes": [ @@ -35,143 +33,158 @@ }, "charset-normalizer": { "hashes": [ - "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", - "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", - "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", - "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", - "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", - "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", - "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", - "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", - "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", - "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", - "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", - "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", - "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", - "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", - "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", - "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", - "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", - "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", - "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", - "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", - "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", - "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", - "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", - "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", - "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", - "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", - "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", - "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", - "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", - "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", - "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", - "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", - "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", - "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", - "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", - "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", - "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", - "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", - "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", - "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", - "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", - "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", - "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", - "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", - "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", - "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", - "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", - "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", - "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", - "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", - "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", - "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", - "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", - "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", - "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", - "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", - "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", - "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", - "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", - "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", - "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", - "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", - "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", - "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", - "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", - "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", - "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", - "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", - "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", - "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", - "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", - "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", - "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", - "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", - "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.2.0" + "version": "==3.3.2" }, "coverage": { "hashes": [ - "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34", - "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e", - "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7", - "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b", - "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3", - "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985", - "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95", - "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2", - "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a", - "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74", - "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd", - "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af", - "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54", - "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865", - "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214", - "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54", - "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe", - "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0", - "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321", - "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446", - "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e", - "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527", - "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12", - "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f", - "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f", - "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84", - "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479", - "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e", - "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873", - "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70", - "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0", - "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977", - "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51", - "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28", - "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1", - "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254", - "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1", - "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd", - "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689", - "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d", - "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543", - "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9", - "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637", - "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071", - "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482", - "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1", - "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b", - "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5", - "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a", - "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393", - "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a", - "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba" + "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", + "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", + "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", + "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", + "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", + "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", + "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", + "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", + "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", + "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", + "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", + "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", + "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", + "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", + "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", + "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", + "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", + "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", + "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", + "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", + "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", + "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", + "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", + "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", + "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", + "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", + "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", + "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", + "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", + "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", + "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", + "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", + "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", + "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", + "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", + "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", + "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", + "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", + "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", + "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", + "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", + "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", + "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", + "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", + "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", + "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", + "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", + "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", + "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", + "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", + "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", + "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==7.3.0" + "version": "==7.3.2" }, "docutils": { "hashes": [ @@ -219,14 +232,6 @@ "markers": "python_version >= '3.8'", "version": "==6.8.0" }, - "importlib-resources": { - "hashes": [ - "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", - "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" - ], - "markers": "python_version < '3.9'", - "version": "==6.0.1" - }, "intuit-oauth": { "hashes": [ "sha256:14a1a8ed73f24369ba209f0e581eb30698571fd7bcbe05ca5bed65d2ff9df8b1", @@ -275,6 +280,27 @@ "markers": "python_version >= '3.8'", "version": "==10.1.0" }, + "nh3": { + "hashes": [ + "sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873", + "sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad", + "sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5", + "sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525", + "sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2", + "sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e", + "sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d", + "sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450", + "sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e", + "sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6", + "sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a", + "sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4", + "sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4", + "sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6", + "sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e", + "sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75" + ], + "version": "==0.2.14" + }, "nose": { "hashes": [ "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", @@ -333,11 +359,11 @@ }, "readme-renderer": { "hashes": [ - "sha256:4f4b11e5893f5a5d725f592c5a343e0dc74f5f273cb3dcf8c42d9703a27073f7", - "sha256:a38243d5b6741b700a850026e62da4bd739edc7422071e95fd5c4bb60171df86" + "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d", + "sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1" ], "markers": "python_version >= '3.8'", - "version": "==41.0" + "version": "==42.0" }, "requests": { "hashes": [ @@ -374,11 +400,11 @@ }, "rich": { "hashes": [ - "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808", - "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39" + "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245", + "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef" ], "markers": "python_full_version >= '3.7.0'", - "version": "==13.5.2" + "version": "==13.6.0" }, "rsa": { "hashes": [ @@ -390,95 +416,108 @@ }, "simplejson": { "hashes": [ - "sha256:081ea6305b3b5e84ae7417e7f45956db5ea3872ec497a584ec86c3260cda049e", - "sha256:08be5a241fdf67a8e05ac7edbd49b07b638ebe4846b560673e196b2a25c94b92", - "sha256:0c16ec6a67a5f66ab004190829eeede01c633936375edcad7cbf06d3241e5865", - "sha256:0ccb2c1877bc9b25bc4f4687169caa925ffda605d7569c40e8e95186e9a5e58b", - "sha256:17a963e8dd4d81061cc05b627677c1f6a12e81345111fbdc5708c9f088d752c9", - "sha256:199a0bcd792811c252d71e3eabb3d4a132b3e85e43ebd93bfd053d5b59a7e78b", - "sha256:1cb19eacb77adc5a9720244d8d0b5507421d117c7ed4f2f9461424a1829e0ceb", - "sha256:203412745fed916fc04566ecef3f2b6c872b52f1e7fb3a6a84451b800fb508c1", - "sha256:2098811cd241429c08b7fc5c9e41fcc3f59f27c2e8d1da2ccdcf6c8e340ab507", - "sha256:22b867205cd258050c2625325fdd9a65f917a5aff22a23387e245ecae4098e78", - "sha256:23fbb7b46d44ed7cbcda689295862851105c7594ae5875dce2a70eeaa498ff86", - "sha256:2541fdb7467ef9bfad1f55b6c52e8ea52b3ce4a0027d37aff094190a955daa9d", - "sha256:3231100edee292da78948fa0a77dee4e5a94a0a60bcba9ed7a9dc77f4d4bb11e", - "sha256:344a5093b71c1b370968d0fbd14d55c9413cb6f0355fdefeb4a322d602d21776", - "sha256:37724c634f93e5caaca04458f267836eb9505d897ab3947b52f33b191bf344f3", - "sha256:3844305bc33d52c4975da07f75b480e17af3558c0d13085eaa6cc2f32882ccf7", - "sha256:390f4a8ca61d90bcf806c3ad644e05fa5890f5b9a72abdd4ca8430cdc1e386fa", - "sha256:3a4480e348000d89cf501b5606415f4d328484bbb431146c2971123d49fd8430", - "sha256:3b652579c21af73879d99c8072c31476788c8c26b5565687fd9db154070d852a", - "sha256:3e0902c278243d6f7223ba3e6c5738614c971fd9a887fff8feaa8dcf7249c8d4", - "sha256:412e58997a30c5deb8cab5858b8e2e5b40ca007079f7010ee74565cc13d19665", - "sha256:44cdb4e544134f305b033ad79ae5c6b9a32e7c58b46d9f55a64e2a883fbbba01", - "sha256:46133bc7dd45c9953e6ee4852e3de3d5a9a4a03b068bd238935a5c72f0a1ce34", - "sha256:46e89f58e4bed107626edce1cf098da3664a336d01fc78fddcfb1f397f553d44", - "sha256:4710806eb75e87919b858af0cba4ffedc01b463edc3982ded7b55143f39e41e1", - "sha256:476c8033abed7b1fd8db62a7600bf18501ce701c1a71179e4ce04ac92c1c5c3c", - "sha256:48600a6e0032bed17c20319d91775f1797d39953ccfd68c27f83c8d7fc3b32cb", - "sha256:4d3025e7e9ddb48813aec2974e1a7e68e63eac911dd5e0a9568775de107ac79a", - "sha256:547ea86ca408a6735335c881a2e6208851027f5bfd678d8f2c92a0f02c7e7330", - "sha256:54fca2b26bcd1c403146fd9461d1da76199442297160721b1d63def2a1b17799", - "sha256:5673d27806085d2a413b3be5f85fad6fca4b7ffd31cfe510bbe65eea52fff571", - "sha256:58ee5e24d6863b22194020eb62673cf8cc69945fcad6b283919490f6e359f7c5", - "sha256:5ca922c61d87b4c38f37aa706520328ffe22d7ac1553ef1cadc73f053a673553", - "sha256:5db86bb82034e055257c8e45228ca3dbce85e38d7bfa84fa7b2838e032a3219c", - "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c", - "sha256:6424d8229ba62e5dbbc377908cfee9b2edf25abd63b855c21f12ac596cd18e41", - "sha256:65dafe413b15e8895ad42e49210b74a955c9ae65564952b0243a18fb35b986cc", - "sha256:66389b6b6ee46a94a493a933a26008a1bae0cfadeca176933e7ff6556c0ce998", - "sha256:66d780047c31ff316ee305c3f7550f352d87257c756413632303fc59fef19eac", - "sha256:69a8b10a4f81548bc1e06ded0c4a6c9042c0be0d947c53c1ed89703f7e613950", - "sha256:6a561320485017ddfc21bd2ed5de2d70184f754f1c9b1947c55f8e2b0163a268", - "sha256:6aa7ca03f25b23b01629b1c7f78e1cd826a66bfb8809f8977a3635be2ec48f1a", - "sha256:6b79642a599740603ca86cf9df54f57a2013c47e1dd4dd2ae4769af0a6816900", - "sha256:6e7c70f19405e5f99168077b785fe15fcb5f9b3c0b70b0b5c2757ce294922c8c", - "sha256:70128fb92932524c89f373e17221cf9535d7d0c63794955cc3cd5868e19f5d38", - "sha256:73d0904c2471f317386d4ae5c665b16b5c50ab4f3ee7fd3d3b7651e564ad74b1", - "sha256:74bf802debe68627227ddb665c067eb8c73aa68b2476369237adf55c1161b728", - "sha256:79c748aa61fd8098d0472e776743de20fae2686edb80a24f0f6593a77f74fe86", - "sha256:79d46e7e33c3a4ef853a1307b2032cfb7220e1a079d0c65488fbd7118f44935a", - "sha256:7e78d79b10aa92f40f54178ada2b635c960d24fc6141856b926d82f67e56d169", - "sha256:8090e75653ea7db75bc21fa5f7bcf5f7bdf64ea258cbbac45c7065f6324f1b50", - "sha256:87b190e6ceec286219bd6b6f13547ca433f977d4600b4e81739e9ac23b5b9ba9", - "sha256:889328873c35cb0b2b4c83cbb83ec52efee5a05e75002e2c0c46c4e42790e83c", - "sha256:8f8d179393e6f0cf6c7c950576892ea6acbcea0a320838c61968ac7046f59228", - "sha256:919bc5aa4d8094cf8f1371ea9119e5d952f741dc4162810ab714aec948a23fe5", - "sha256:926957b278de22797bfc2f004b15297013843b595b3cd7ecd9e37ccb5fad0b72", - "sha256:93f5ac30607157a0b2579af59a065bcfaa7fadeb4875bf927a8f8b6739c8d910", - "sha256:96ade243fb6f3b57e7bd3b71e90c190cd0f93ec5dce6bf38734a73a2e5fa274f", - "sha256:9f14ecca970d825df0d29d5c6736ff27999ee7bdf5510e807f7ad8845f7760ce", - "sha256:a755f7bfc8adcb94887710dc70cc12a69a454120c6adcc6f251c3f7b46ee6aac", - "sha256:a79b439a6a77649bb8e2f2644e6c9cc0adb720fc55bed63546edea86e1d5c6c8", - "sha256:aa9d614a612ad02492f704fbac636f666fa89295a5d22b4facf2d665fc3b5ea9", - "sha256:ad071cd84a636195f35fa71de2186d717db775f94f985232775794d09f8d9061", - "sha256:b0e9a5e66969f7a47dc500e3dba8edc3b45d4eb31efb855c8647700a3493dd8a", - "sha256:b438e5eaa474365f4faaeeef1ec3e8d5b4e7030706e3e3d6b5bee6049732e0e6", - "sha256:b46aaf0332a8a9c965310058cf3487d705bf672641d2c43a835625b326689cf4", - "sha256:c39fa911e4302eb79c804b221ddec775c3da08833c0a9120041dd322789824de", - "sha256:ca56a6c8c8236d6fe19abb67ef08d76f3c3f46712c49a3b6a5352b6e43e8855f", - "sha256:cb502cde018e93e75dc8fc7bb2d93477ce4f3ac10369f48866c61b5e031db1fd", - "sha256:cd4d50a27b065447c9c399f0bf0a993bd0e6308db8bbbfbc3ea03b41c145775a", - "sha256:d125e754d26c0298715bdc3f8a03a0658ecbe72330be247f4b328d229d8cf67f", - "sha256:d300773b93eed82f6da138fd1d081dc96fbe53d96000a85e41460fe07c8d8b33", - "sha256:d396b610e77b0c438846607cd56418bfc194973b9886550a98fd6724e8c6cfec", - "sha256:d61482b5d18181e6bb4810b4a6a24c63a490c3a20e9fbd7876639653e2b30a1a", - "sha256:d9f2c27f18a0b94107d57294aab3d06d6046ea843ed4a45cae8bd45756749f3a", - "sha256:dc2b3f06430cbd4fac0dae5b2974d2bf14f71b415fb6de017f498950da8159b1", - "sha256:dc935d8322ba9bc7b84f99f40f111809b0473df167bf5b93b89fb719d2c4892b", - "sha256:e333c5b62e93949f5ac27e6758ba53ef6ee4f93e36cc977fe2e3df85c02f6dc4", - "sha256:e765b1f47293dedf77946f0427e03ee45def2862edacd8868c6cf9ab97c8afbd", - "sha256:ed18728b90758d171f0c66c475c24a443ede815cf3f1a91e907b0db0ebc6e508", - "sha256:eff87c68058374e45225089e4538c26329a13499bc0104b52b77f8428eed36b2", - "sha256:f05d05d99fce5537d8f7a0af6417a9afa9af3a6c4bb1ba7359c53b6257625fcb", - "sha256:f253edf694ce836631b350d758d00a8c4011243d58318fbfbe0dd54a6a839ab4", - "sha256:f41915a4e1f059dfad614b187bc06021fefb5fc5255bfe63abf8247d2f7a646a", - "sha256:f96def94576f857abf58e031ce881b5a3fc25cbec64b2bc4824824a8a4367af9" + "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137", + "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a", + "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae", + "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a", + "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba", + "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087", + "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b", + "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41", + "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d", + "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd", + "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d", + "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e", + "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a", + "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9", + "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6", + "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb", + "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664", + "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2", + "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b", + "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5", + "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835", + "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17", + "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69", + "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd", + "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6", + "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2", + "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2", + "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428", + "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f", + "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2", + "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f", + "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7", + "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f", + "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637", + "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3", + "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816", + "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565", + "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378", + "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0", + "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b", + "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693", + "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358", + "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9", + "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23", + "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf", + "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a", + "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832", + "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414", + "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f", + "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48", + "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad", + "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290", + "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3", + "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917", + "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402", + "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0", + "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc", + "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867", + "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f", + "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589", + "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb", + "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b", + "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3", + "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb", + "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c", + "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46", + "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672", + "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c", + "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e", + "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0", + "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b", + "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4", + "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4", + "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c", + "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c", + "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8", + "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b", + "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb", + "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80", + "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2", + "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374", + "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc", + "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50", + "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c", + "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f", + "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28", + "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5", + "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734", + "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a", + "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d", + "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4", + "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c", + "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13", + "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973", + "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a", + "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e", + "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff", + "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded" ], "index": "pypi", "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2'", - "version": "==3.19.1" + "version": "==3.19.2" }, "six": { "hashes": [ @@ -497,22 +536,14 @@ "markers": "python_version >= '3.7'", "version": "==4.0.2" }, - "typing-extensions": { - "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" - ], - "markers": "python_version < '3.9'", - "version": "==4.7.1" - }, "urllib3": { "hashes": [ - "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", - "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" + "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", + "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.0.4" + "version": "==2.0.7" }, "webencodings": { "hashes": [ @@ -523,11 +554,11 @@ }, "zipp": { "hashes": [ - "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", - "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" ], "markers": "python_version >= '3.8'", - "version": "==3.16.2" + "version": "==3.17.0" } }, "develop": {} From b12f7cf0290903622893cbfff11ff7481d953884 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 1 Nov 2023 16:15:05 -0500 Subject: [PATCH 087/154] Update changelog --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 31d4992e..169f8570 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,7 @@ Changelog ========= * 0.9.5 (November 1, 2023) + * Added the ability to void all voidable QB types * Added to_ref to CreditMemo object * Added ProjectRef and ShipFromAddr to Estimate * Added missing initialization for objects on DiscountLineDetail, Estimate, Employee, and Invoice From 209ab024e7806f5cfa3831aeafeafa5b9ec66d74 Mon Sep 17 00:00:00 2001 From: jaredthecoder Date: Sun, 24 Dec 2023 14:11:43 -0500 Subject: [PATCH 088/154] Remove six imports added mistakenly --- quickbooks/objects/detailline.py | 1 - quickbooks/objects/vendor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index 216d0f8e..f27449fd 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import QuickbooksBaseObject, Ref, CustomField, LinkedTxn, MarkupInfo diff --git a/quickbooks/objects/vendor.py b/quickbooks/objects/vendor.py index 1d4480a3..dec0cfde 100644 --- a/quickbooks/objects/vendor.py +++ b/quickbooks/objects/vendor.py @@ -1,4 +1,3 @@ -from six import python_2_unicode_compatible from .base import Address, PhoneNumber, EmailAddress, WebAddress, Ref, QuickbooksBaseObject, \ QuickbooksManagedObject, QuickbooksTransactionEntity From f3e3ac14c1ecadbdc06018e55efcf9040d32825c Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 2 Jan 2024 16:20:46 -0600 Subject: [PATCH 089/154] Add missing fields to employee and estimate --- CHANGELOG.rst | 4 ++++ Pipfile.lock | 8 ++++---- quickbooks/objects/bill.py | 4 +++- quickbooks/objects/employee.py | 9 +++++++-- quickbooks/objects/estimate.py | 1 + tests/integration/test_base.py | 2 +- tests/integration/test_bill.py | 21 ++++++++++++++++++++- tests/integration/test_estimate.py | 2 ++ 8 files changed, 42 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 169f8570..93e5793a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,9 @@ Changelog ========= +* 0.9.6 (January 2, 2024) + * Added new fields to Employee object + + * 0.9.5 (November 1, 2023) * Added the ability to void all voidable QB types * Added to_ref to CreditMemo object diff --git a/Pipfile.lock b/Pipfile.lock index 311a7eb5..9626e0bb 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -199,7 +199,7 @@ "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.18.0" }, "enum-compat": { @@ -213,7 +213,7 @@ "hashes": [ "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.18.3" }, "idna": { @@ -516,7 +516,7 @@ "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded" ], "index": "pypi", - "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.19.2" }, "six": { @@ -524,7 +524,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "twine": { diff --git a/quickbooks/objects/bill.py b/quickbooks/objects/bill.py index 834da6a4..09683bd9 100644 --- a/quickbooks/objects/bill.py +++ b/quickbooks/objects/bill.py @@ -1,7 +1,7 @@ from quickbooks.objects.detailline import DetailLine, ItemBasedExpenseLine, AccountBasedExpenseLine, \ TDSLine from .base import Ref, LinkedTxn, QuickbooksManagedObject, QuickbooksTransactionEntity, \ - LinkedTxnMixin + LinkedTxnMixin, Address from .tax import TxnTaxDetail from ..mixins import DeleteMixin @@ -20,6 +20,7 @@ class Bill(DeleteMixin, QuickbooksManagedObject, QuickbooksTransactionEntity, Li "AttachableRef": Ref, "DepartmentRef": Ref, "TxnTaxDetail": TxnTaxDetail, + "VendorAddr": Address, } list_dict = { @@ -53,6 +54,7 @@ def __init__(self): self.VendorRef = None self.DepartmentRef = None self.APAccountRef = None + self.VendorAddr = None self.LinkedTxn = [] self.Line = [] diff --git a/quickbooks/objects/employee.py b/quickbooks/objects/employee.py index 4e766f18..831ef86f 100644 --- a/quickbooks/objects/employee.py +++ b/quickbooks/objects/employee.py @@ -1,4 +1,4 @@ -from .base import Address, PhoneNumber, QuickbooksManagedObject, QuickbooksTransactionEntity, Ref +from .base import Address, PhoneNumber, QuickbooksManagedObject, QuickbooksTransactionEntity, Ref, EmailAddress class Employee(QuickbooksManagedObject, QuickbooksTransactionEntity): @@ -8,7 +8,9 @@ class Employee(QuickbooksManagedObject, QuickbooksTransactionEntity): class_dict = { "PrimaryAddr": Address, - "PrimaryPhone": PhoneNumber + "PrimaryPhone": PhoneNumber, + "Mobile": PhoneNumber, + "PrimaryEmailAddr": EmailAddress, } qbo_object_name = "Employee" @@ -26,6 +28,7 @@ def __init__(self): self.EmployeeNumber = "" self.Title = "" self.BillRate = 0 + self.CostRate = 0 self.BirthDate = "" self.Gender = None self.HiredDate = "" @@ -36,6 +39,8 @@ def __init__(self): self.PrimaryAddr = None self.PrimaryPhone = None + self.Mobile = None + self.EmailAddress = None def __str__(self): return self.DisplayName diff --git a/quickbooks/objects/estimate.py b/quickbooks/objects/estimate.py index 8ece9fb9..362937fc 100644 --- a/quickbooks/objects/estimate.py +++ b/quickbooks/objects/estimate.py @@ -77,6 +77,7 @@ def __init__(self): self.ClassRef = None self.SalesTermRef = None self.ShipMethodRef = None + self.TrackingNum = "" self.CustomField = [] self.LinkedTxn = [] diff --git a/tests/integration/test_base.py b/tests/integration/test_base.py index a4df0828..8b386af4 100644 --- a/tests/integration/test_base.py +++ b/tests/integration/test_base.py @@ -17,7 +17,7 @@ def setUp(self): ) self.qb_client = QuickBooks( - minorversion=65, + minorversion=69, auth_client=self.auth_client, refresh_token=os.environ.get('REFRESH_TOKEN'), company_id=os.environ.get('COMPANY_ID'), diff --git a/tests/integration/test_bill.py b/tests/integration/test_bill.py index 45b351b7..324ac6ce 100644 --- a/tests/integration/test_bill.py +++ b/tests/integration/test_bill.py @@ -1,6 +1,6 @@ from datetime import datetime -from quickbooks.objects.base import Ref +from quickbooks.objects.base import Ref, Address from quickbooks.objects.bill import Bill from quickbooks.objects.detailline import AccountBasedExpenseLine, AccountBasedExpenseLineDetail from quickbooks.objects.vendor import Vendor @@ -30,6 +30,15 @@ def test_create(self): vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] bill.VendorRef = vendor.to_ref() + # Test undocumented VendorAddr field + bill.VendorAddr = Address() + bill.VendorAddr.Line1 = "123 Main" + bill.VendorAddr.Line2 = "Apartment 1" + bill.VendorAddr.City = "City" + bill.VendorAddr.Country = "U.S.A" + bill.VendorAddr.CountrySubDivisionCode = "CA" + bill.VendorAddr.PostalCode = "94030" + bill.save(qb=self.qb_client) query_bill = Bill.get(bill.Id, qb=self.qb_client) @@ -37,3 +46,13 @@ def test_create(self): self.assertEqual(query_bill.Id, bill.Id) self.assertEqual(len(query_bill.Line), 1) self.assertEqual(query_bill.Line[0].Amount, 200.0) + + self.assertEqual(query_bill.VendorAddr.Line1, bill.VendorAddr.Line1) + self.assertEqual(query_bill.VendorAddr.Line2, bill.VendorAddr.Line2) + self.assertEqual(query_bill.VendorAddr.City, bill.VendorAddr.City) + self.assertEqual(query_bill.VendorAddr.Country, bill.VendorAddr.Country) + self.assertEqual(query_bill.VendorAddr.CountrySubDivisionCode, bill.VendorAddr.CountrySubDivisionCode) + self.assertEqual(query_bill.VendorAddr.PostalCode, bill.VendorAddr.PostalCode) + + + diff --git a/tests/integration/test_estimate.py b/tests/integration/test_estimate.py index df9ffbe5..c9210149 100644 --- a/tests/integration/test_estimate.py +++ b/tests/integration/test_estimate.py @@ -93,6 +93,7 @@ def test_create(self): line2.DetailType = "DiscountLineDetail" estimate.Line.append(line2) + estimate.TrackingNum = "42" estimate.save(qb=self.qb_client) @@ -134,3 +135,4 @@ def test_create(self): estimate.Line[1].DiscountLineDetail.DiscountAccountRef.value) self.assertEqual(query_estimate.Line[2].DiscountLineDetail.DiscountAccountRef.name, estimate.Line[1].DiscountLineDetail.DiscountAccountRef.name) + self.assertEqual(query_estimate.TrackingNum, estimate.TrackingNum) \ No newline at end of file From d93099b38625f3ebf91aa8406590a7bf693104f2 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 10:39:22 -0600 Subject: [PATCH 090/154] Replace Rauth and clean up client --- Pipfile | 4 +- Pipfile.lock | 203 +++++++++++++++++++++---------------------- quickbooks/client.py | 35 +++----- 3 files changed, 112 insertions(+), 130 deletions(-) diff --git a/Pipfile b/Pipfile index 26e81a3e..98c40273 100644 --- a/Pipfile +++ b/Pipfile @@ -9,9 +9,11 @@ verify_ssl = true urllib3 = ">=1.26.5" bleach = ">=3.3.0" intuit-oauth = "==1.2.4" -rauth = ">=0.7.3" + requests = ">=2.31.0" simplejson = ">=3.19.1" nose = "*" coverage = "*" twine = "*" +oauthlib = ">=3.2.2" +requests_oauthlib = ">=1.3.1" \ No newline at end of file diff --git a/Pipfile.lock b/Pipfile.lock index 9626e0bb..da52ceff 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "34f14be2688a7429ee79c084b29d6da49f332312e66876132edb44ae8a151246" + "sha256": "19fff79f66859fa72811df53a511bc9e1eff774700dd0f516eb6d68ede524fa0" }, "pipfile-spec": 6, "requires": {}, @@ -25,11 +25,11 @@ }, "certifi": { "hashes": [ - "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", - "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" + "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", + "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" ], "markers": "python_version >= '3.6'", - "version": "==2023.7.22" + "version": "==2023.11.17" }, "charset-normalizer": { "hashes": [ @@ -129,62 +129,62 @@ }, "coverage": { "hashes": [ - "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", - "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", - "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", - "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", - "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", - "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", - "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", - "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", - "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", - "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", - "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", - "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", - "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", - "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", - "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", - "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", - "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", - "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", - "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", - "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", - "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", - "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", - "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", - "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", - "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", - "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", - "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", - "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", - "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", - "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", - "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", - "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", - "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", - "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", - "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", - "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", - "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", - "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", - "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", - "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", - "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", - "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", - "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", - "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", - "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", - "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", - "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", - "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", - "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", - "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", - "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", - "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" + "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", + "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", + "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a", + "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058", + "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85", + "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143", + "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446", + "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590", + "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a", + "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105", + "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9", + "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a", + "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac", + "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25", + "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2", + "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450", + "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932", + "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba", + "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137", + "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae", + "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614", + "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70", + "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e", + "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505", + "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870", + "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc", + "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451", + "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7", + "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e", + "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566", + "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5", + "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26", + "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2", + "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42", + "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555", + "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43", + "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed", + "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa", + "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516", + "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952", + "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd", + "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09", + "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c", + "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f", + "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6", + "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1", + "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0", + "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e", + "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9", + "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9", + "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e", + "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==7.3.2" + "version": "==7.4.0" }, "docutils": { "hashes": [ @@ -218,19 +218,19 @@ }, "idna": { "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", + "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" ], "markers": "python_version >= '3.5'", - "version": "==3.4" + "version": "==3.6" }, "importlib-metadata": { "hashes": [ - "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", - "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" + "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", + "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" ], "markers": "python_version >= '3.8'", - "version": "==6.8.0" + "version": "==7.0.1" }, "intuit-oauth": { "hashes": [ @@ -250,11 +250,11 @@ }, "keyring": { "hashes": [ - "sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6", - "sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509" + "sha256:4446d35d636e6a10b8bce7caa66913dd9eca5fd222ca03a3d42c38608ac30836", + "sha256:e730ecffd309658a08ee82535a3b5ec4b4c8669a9be11efb66249d8e0aeb9a25" ], "markers": "python_version >= '3.8'", - "version": "==24.2.0" + "version": "==24.3.0" }, "markdown-it-py": { "hashes": [ @@ -282,24 +282,24 @@ }, "nh3": { "hashes": [ - "sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873", - "sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad", - "sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5", - "sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525", - "sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2", - "sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e", - "sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d", - "sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450", - "sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e", - "sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6", - "sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a", - "sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4", - "sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4", - "sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6", - "sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e", - "sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75" - ], - "version": "==0.2.14" + "sha256:0d02d0ff79dfd8208ed25a39c12cbda092388fff7f1662466e27d97ad011b770", + "sha256:3277481293b868b2715907310c7be0f1b9d10491d5adf9fce11756a97e97eddf", + "sha256:3b803a5875e7234907f7d64777dfde2b93db992376f3d6d7af7f3bc347deb305", + "sha256:427fecbb1031db085eaac9931362adf4a796428ef0163070c484b5a768e71601", + "sha256:5f0d77272ce6d34db6c87b4f894f037d55183d9518f948bba236fe81e2bb4e28", + "sha256:60684857cfa8fdbb74daa867e5cad3f0c9789415aba660614fe16cd66cbb9ec7", + "sha256:6f42f99f0cf6312e470b6c09e04da31f9abaadcd3eb591d7d1a88ea931dca7f3", + "sha256:86e447a63ca0b16318deb62498db4f76fc60699ce0a1231262880b38b6cff911", + "sha256:8d595df02413aa38586c24811237e95937ef18304e108b7e92c890a06793e3bf", + "sha256:9c0d415f6b7f2338f93035bba5c0d8c1b464e538bfbb1d598acd47d7969284f0", + "sha256:a5167a6403d19c515217b6bcaaa9be420974a6ac30e0da9e84d4fc67a5d474c5", + "sha256:ac19c0d68cd42ecd7ead91a3a032fdfff23d29302dbb1311e641a130dfefba97", + "sha256:b1e97221cedaf15a54f5243f2c5894bb12ca951ae4ddfd02a9d4ea9df9e1a29d", + "sha256:bc2d086fb540d0fa52ce35afaded4ea526b8fc4d3339f783db55c95de40ef02e", + "sha256:d1e30ff2d8d58fb2a14961f7aac1bbb1c51f9bdd7da727be35c63826060b0bf3", + "sha256:f3b53ba93bb7725acab1e030bc2ecd012a817040fd7851b332f86e2f9bb98dc6" + ], + "version": "==0.2.15" }, "nose": { "hashes": [ @@ -315,6 +315,7 @@ "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" ], + "index": "pypi", "markers": "python_version >= '3.6'", "version": "==3.2.2" }, @@ -328,19 +329,19 @@ }, "pyasn1": { "hashes": [ - "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57", - "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde" + "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58", + "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.5.0" + "version": "==0.5.1" }, "pygments": { "hashes": [ - "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692", - "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" + "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", + "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" ], "markers": "python_version >= '3.7'", - "version": "==2.16.1" + "version": "==2.17.2" }, "python-jose": { "hashes": [ @@ -349,14 +350,6 @@ ], "version": "==3.3.0" }, - "rauth": { - "hashes": [ - "sha256:524cdbc1c28560eacfc9a9d40c59525eb8d00fdf07fbad86107ea24411477b0a", - "sha256:b18590fbd77bc3d871936bbdb851377d1b0c08e337b219c303f8fc2b5a42ef2d" - ], - "index": "pypi", - "version": "==0.7.3" - }, "readme-renderer": { "hashes": [ "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d", @@ -400,11 +393,11 @@ }, "rich": { "hashes": [ - "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245", - "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef" + "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", + "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" ], "markers": "python_full_version >= '3.7.0'", - "version": "==13.6.0" + "version": "==13.7.0" }, "rsa": { "hashes": [ @@ -538,12 +531,12 @@ }, "urllib3": { "hashes": [ - "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", - "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e" + "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", + "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.0.7" + "markers": "python_version >= '3.8'", + "version": "==2.1.0" }, "webencodings": { "hashes": [ diff --git a/quickbooks/client.py b/quickbooks/client.py index 156530ac..5aa5a358 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -1,30 +1,14 @@ -import warnings - -try: # Python 3 - import http.client as httplib - from urllib.parse import parse_qsl - from functools import partial - to_bytes = lambda value, *args, **kwargs: bytes(value, "utf-8", *args, **kwargs) -except ImportError: # Python 2 - import httplib - from urlparse import parse_qsl - to_bytes = str - +import http.client as httplib import textwrap -import codecs import json - -from . import exceptions import base64 import hashlib import hmac -try: - from rauth import OAuth1Session, OAuth1Service, OAuth2Session -except ImportError: - print("Please import Rauth:\n\n") - print("http://rauth.readthedocs.org/en/latest//n") - raise +from . import exceptions +from requests_oauthlib import OAuth2Session + +to_bytes = lambda value, *args, **kwargs: bytes(value, "utf-8", *args, **kwargs) class Environments(object): @@ -102,10 +86,13 @@ def _start_session(self): self.auth_client.refresh(refresh_token=self.refresh_token) self.session = OAuth2Session( - client_id=self.auth_client.client_id, - client_secret=self.auth_client.client_secret, - access_token=self.auth_client.access_token, + self.auth_client.client_id, + token={ + 'access_token': self.auth_client.access_token, + 'refresh_token': self.auth_client.refresh_token, + } ) + return self.auth_client.refresh_token def _drop(self): From 512d57bcefad2390942fe4c1b9424b1e7d807ccd Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 11:05:31 -0600 Subject: [PATCH 091/154] Update python versions --- .github/workflows/pylint.yml | 2 +- .github/workflows/python-package.yml | 2 +- CHANGELOG.rst | 5 ++++- Pipfile | 2 -- README.md | 2 +- requirements.txt | 2 +- setup.py | 6 ++++-- 7 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 383e65cd..d76c6a23 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 41f71120..8cfe3484 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v3 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 93e5793a..ba8ce38b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,11 @@ Changelog ========= * 0.9.6 (January 2, 2024) + * Replace RAuth with requests_oauthlib + * Removed python 2 code from client.py * Added new fields to Employee object - + * Added VendorAddr to Bill object + * Added new fields to Estimate object * 0.9.5 (November 1, 2023) * Added the ability to void all voidable QB types diff --git a/Pipfile b/Pipfile index 98c40273..2565fe8f 100644 --- a/Pipfile +++ b/Pipfile @@ -9,11 +9,9 @@ verify_ssl = true urllib3 = ">=1.26.5" bleach = ">=3.3.0" intuit-oauth = "==1.2.4" - requests = ">=2.31.0" simplejson = ">=3.19.1" nose = "*" coverage = "*" twine = "*" -oauthlib = ">=3.2.2" requests_oauthlib = ">=1.3.1" \ No newline at end of file diff --git a/README.md b/README.md index ea09ef75..ded62e66 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ details) pass in minorversion when setting up the client: auth_client=auth_client, refresh_token='REFRESH_TOKEN', company_id='COMPANY_ID', - minorversion=59 + minorversion=69 ) Object Operations diff --git a/requirements.txt b/requirements.txt index e22107a0..2f1d93f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ intuit-oauth==1.2.4 -rauth>=0.7.3 +requests_oauthlib>=1.3.1 requests>=2.31.0 simplejson>=3.19.1 \ No newline at end of file diff --git a/setup.py b/setup.py index c88111f3..9e36a9d0 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 5) +VERSION = (0, 9, 6) version = '.'.join(map(str, VERSION)) setup( @@ -32,7 +32,7 @@ def read(*parts): install_requires=[ 'setuptools', 'intuit-oauth==1.2.4', - 'rauth>=0.7.3', + 'requests_oauthlib>=1.3.1', 'requests>=2.31.0', 'simplejson>=3.19.1', 'python-dateutil', @@ -50,6 +50,8 @@ def read(*parts): 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], packages=find_packages(exclude=("tests",)), ) From be3bb11864eb72943ceca2f4ecdb395ebe097bea Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 12:08:17 -0600 Subject: [PATCH 092/154] Remove unused packages --- Pipfile | 9 +- Pipfile.lock | 514 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 319 insertions(+), 204 deletions(-) diff --git a/Pipfile b/Pipfile index 2565fe8f..9ab2a78e 100644 --- a/Pipfile +++ b/Pipfile @@ -4,14 +4,13 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] +nose = "*" +coverage = "*" +twine = "*" [packages] -urllib3 = ">=1.26.5" -bleach = ">=3.3.0" +urllib3 = ">=2.1.0" intuit-oauth = "==1.2.4" requests = ">=2.31.0" simplejson = ">=3.19.1" -nose = "*" -coverage = "*" -twine = "*" requests_oauthlib = ">=1.3.1" \ No newline at end of file diff --git a/Pipfile.lock b/Pipfile.lock index da52ceff..2edb1e91 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,10 +1,12 @@ { "_meta": { "hash": { - "sha256": "19fff79f66859fa72811df53a511bc9e1eff774700dd0f516eb6d68ede524fa0" + "sha256": "3bb85d01d88e5dd481cd663a21728508e5b3fb0c57e372e0024b61eeaa6cc4ba" }, "pipfile-spec": 6, - "requires": {}, + "requires": { + "python_version": "3.12" + }, "sources": [ { "name": "pypi", @@ -14,15 +16,320 @@ ] }, "default": { - "bleach": { + "certifi": { + "hashes": [ + "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", + "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + ], + "markers": "python_version >= '3.6'", + "version": "==2023.11.17" + }, + "charset-normalizer": { + "hashes": [ + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" + }, + "ecdsa": { + "hashes": [ + "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", + "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.18.0" + }, + "enum-compat": { + "hashes": [ + "sha256:3677daabed56a6f724451d585662253d8fb4e5569845aafa8bb0da36b1a8751e", + "sha256:88091b617c7fc3bbbceae50db5958023c48dc40b50520005aa3bf27f8f7ea157" + ], + "version": "==0.0.3" + }, + "future": { + "hashes": [ + "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.18.3" + }, + "idna": { + "hashes": [ + "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", + "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + ], + "markers": "python_version >= '3.5'", + "version": "==3.6" + }, + "intuit-oauth": { "hashes": [ - "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe", - "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6" + "sha256:14a1a8ed73f24369ba209f0e581eb30698571fd7bcbe05ca5bed65d2ff9df8b1", + "sha256:dd09ef833a26e12e0fbe96d0e7694cdae2c9179776f763ea00e328f8cbd4464e" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==6.1.0" + "version": "==1.2.4" + }, + "oauthlib": { + "hashes": [ + "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", + "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.2" + }, + "pyasn1": { + "hashes": [ + "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58", + "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==0.5.1" + }, + "python-jose": { + "hashes": [ + "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", + "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a" + ], + "version": "==3.3.0" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "requests-oauthlib": { + "hashes": [ + "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", + "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.3.1" + }, + "rsa": { + "hashes": [ + "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", + "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==4.9" }, + "simplejson": { + "hashes": [ + "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137", + "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a", + "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae", + "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a", + "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba", + "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087", + "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b", + "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41", + "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d", + "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd", + "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d", + "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e", + "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a", + "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9", + "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6", + "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb", + "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664", + "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2", + "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b", + "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5", + "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835", + "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17", + "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69", + "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd", + "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6", + "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2", + "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2", + "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428", + "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f", + "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2", + "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f", + "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7", + "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f", + "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637", + "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3", + "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816", + "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565", + "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378", + "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0", + "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b", + "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693", + "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358", + "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9", + "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23", + "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf", + "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a", + "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832", + "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414", + "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f", + "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48", + "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad", + "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290", + "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3", + "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917", + "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402", + "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0", + "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc", + "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867", + "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f", + "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589", + "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb", + "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b", + "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3", + "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb", + "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c", + "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46", + "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672", + "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c", + "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e", + "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0", + "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b", + "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4", + "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4", + "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c", + "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c", + "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8", + "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b", + "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb", + "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80", + "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2", + "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374", + "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc", + "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50", + "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c", + "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f", + "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28", + "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5", + "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734", + "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a", + "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d", + "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4", + "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c", + "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13", + "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973", + "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a", + "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e", + "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff", + "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded" + ], + "index": "pypi", + "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==3.19.2" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "urllib3": { + "hashes": [ + "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", + "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.1.0" + } + }, + "develop": { "certifi": { "hashes": [ "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", @@ -194,28 +501,6 @@ "markers": "python_version >= '3.7'", "version": "==0.20.1" }, - "ecdsa": { - "hashes": [ - "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", - "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.0" - }, - "enum-compat": { - "hashes": [ - "sha256:3677daabed56a6f724451d585662253d8fb4e5569845aafa8bb0da36b1a8751e", - "sha256:88091b617c7fc3bbbceae50db5958023c48dc40b50520005aa3bf27f8f7ea157" - ], - "version": "==0.0.3" - }, - "future": { - "hashes": [ - "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.3" - }, "idna": { "hashes": [ "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", @@ -232,14 +517,6 @@ "markers": "python_version >= '3.8'", "version": "==7.0.1" }, - "intuit-oauth": { - "hashes": [ - "sha256:14a1a8ed73f24369ba209f0e581eb30698571fd7bcbe05ca5bed65d2ff9df8b1", - "sha256:dd09ef833a26e12e0fbe96d0e7694cdae2c9179776f763ea00e328f8cbd4464e" - ], - "index": "pypi", - "version": "==1.2.4" - }, "jaraco.classes": { "hashes": [ "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb", @@ -310,15 +587,6 @@ "index": "pypi", "version": "==1.3.7" }, - "oauthlib": { - "hashes": [ - "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", - "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" - ], - "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==3.2.2" - }, "pkginfo": { "hashes": [ "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546", @@ -327,14 +595,6 @@ "markers": "python_version >= '3.6'", "version": "==1.9.6" }, - "pyasn1": { - "hashes": [ - "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58", - "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.5.1" - }, "pygments": { "hashes": [ "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", @@ -343,13 +603,6 @@ "markers": "python_version >= '3.7'", "version": "==2.17.2" }, - "python-jose": { - "hashes": [ - "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", - "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a" - ], - "version": "==3.3.0" - }, "readme-renderer": { "hashes": [ "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d", @@ -367,14 +620,6 @@ "markers": "python_version >= '3.7'", "version": "==2.31.0" }, - "requests-oauthlib": { - "hashes": [ - "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", - "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.3.1" - }, "requests-toolbelt": { "hashes": [ "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", @@ -399,127 +644,6 @@ "markers": "python_full_version >= '3.7.0'", "version": "==13.7.0" }, - "rsa": { - "hashes": [ - "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", - "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" - ], - "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==4.9" - }, - "simplejson": { - "hashes": [ - "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137", - "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a", - "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae", - "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a", - "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba", - "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087", - "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b", - "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41", - "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d", - "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd", - "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d", - "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e", - "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a", - "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9", - "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6", - "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb", - "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664", - "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2", - "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b", - "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5", - "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835", - "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17", - "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69", - "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd", - "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6", - "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2", - "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2", - "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428", - "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f", - "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2", - "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f", - "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7", - "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f", - "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637", - "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3", - "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816", - "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565", - "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378", - "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0", - "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b", - "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693", - "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358", - "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9", - "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23", - "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf", - "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a", - "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832", - "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414", - "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f", - "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48", - "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad", - "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290", - "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3", - "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917", - "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402", - "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0", - "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc", - "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867", - "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f", - "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589", - "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb", - "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b", - "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3", - "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb", - "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c", - "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46", - "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672", - "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c", - "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e", - "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0", - "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b", - "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4", - "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4", - "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c", - "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c", - "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8", - "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b", - "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb", - "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80", - "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2", - "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374", - "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc", - "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50", - "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c", - "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f", - "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28", - "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5", - "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734", - "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a", - "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d", - "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4", - "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c", - "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13", - "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973", - "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a", - "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e", - "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff", - "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded" - ], - "index": "pypi", - "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==3.19.2" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, "twine": { "hashes": [ "sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8", @@ -538,13 +662,6 @@ "markers": "python_version >= '3.8'", "version": "==2.1.0" }, - "webencodings": { - "hashes": [ - "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", - "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" - ], - "version": "==0.5.1" - }, "zipp": { "hashes": [ "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", @@ -553,6 +670,5 @@ "markers": "python_version >= '3.8'", "version": "==3.17.0" } - }, - "develop": {} + } } From fa75eed88dc8253cf4ad3bf8ddd13cca7da2972a Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 13:15:04 -0600 Subject: [PATCH 093/154] update tests --- tests/unit/objects/test_companycurrency.py | 9 ++++----- tests/unit/test_client.py | 12 +++++++++--- tests/unit/test_mixins.py | 5 ----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/unit/objects/test_companycurrency.py b/tests/unit/objects/test_companycurrency.py index adb217d6..7582be3d 100644 --- a/tests/unit/objects/test_companycurrency.py +++ b/tests/unit/objects/test_companycurrency.py @@ -1,10 +1,8 @@ -from datetime import datetime - +import unittest from quickbooks.objects.companycurrency import CompanyCurrency -from tests.integration.test_base import QuickbooksUnitTestCase -class CompanyCurrencyTest(QuickbooksUnitTestCase): +class CompanyCurrencyTest(unittest.TestCase): def test_unicode(self): company_currency = CompanyCurrency() company_currency.Name = "test" @@ -21,4 +19,5 @@ def test_to_ref(self): self.assertEqual(ref.name, "test") self.assertEqual(ref.type, "CompanyCurrency") - self.assertEqual(ref.value, 23) \ No newline at end of file + self.assertEqual(ref.value, 23) + diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 6b4fe93a..35b9da3f 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,4 +1,4 @@ -from tests.integration.test_base import QuickbooksUnitTestCase +import unittest try: from mock import patch @@ -17,7 +17,7 @@ TEST_REFRESH_TOKEN = 'refresh' -class ClientTest(QuickbooksUnitTestCase): +class ClientTest(unittest.TestCase): def setUp(self): super(ClientTest, self).setUp() @@ -30,6 +30,13 @@ def setUp(self): self.auth_client.access_token = 'ACCESS_TOKEN' + self.qb_client = client.QuickBooks( + # auth_client=self.auth_client, + refresh_token='REFRESH_TOKEN', + company_id='COMPANY_ID', + ) + + self.qb_client.sandbox = True def tearDown(self): self.qb_client = client.QuickBooks() @@ -161,7 +168,6 @@ def test_make_request(self, process_request): "GET", url, data={}, headers={'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': 'python-quickbooks V3 library'}, params={}) - def test_handle_exceptions(self): qb_client = client.QuickBooks() error_data = { diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index 017df5d9..4250f6b9 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -1,6 +1,3 @@ - -import os - import unittest from urllib.parse import quote @@ -13,8 +10,6 @@ except ImportError: from unittest.mock import patch -from quickbooks import client - from quickbooks.objects.base import PhoneNumber, QuickbooksBaseObject from quickbooks.objects.department import Department from quickbooks.objects.customer import Customer From 7d34f251d143e59b9549ac918478e242c5430c02 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 13:38:21 -0600 Subject: [PATCH 094/154] Remove python 3.12 --- .github/workflows/pylint.yml | 2 +- .github/workflows/python-package.yml | 2 +- setup.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index d76c6a23..c9c962e5 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 8cfe3484..41f71120 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 diff --git a/setup.py b/setup.py index 9e36a9d0..f4620a52 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,6 @@ def read(*parts): 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', ], packages=find_packages(exclude=("tests",)), ) From 31f0a1fb67b77900a62b2e7c66bec6845042bb7d Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 13:46:08 -0600 Subject: [PATCH 095/154] Update changelog --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ba8ce38b..7c028ba0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,7 @@ Changelog * Added new fields to Employee object * Added VendorAddr to Bill object * Added new fields to Estimate object + * Fix taxinclusiveamt and vendor setting 1099 creation * 0.9.5 (November 1, 2023) * Added the ability to void all voidable QB types From cae8ed1bfbca469f4bd84acb144d4eb838eac4cb Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 15:57:22 -0600 Subject: [PATCH 096/154] Update readme --- Pipfile | 2 +- Pipfile.lock | 6 ++---- README.md | 10 +++++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Pipfile b/Pipfile index 9ab2a78e..630f4eca 100644 --- a/Pipfile +++ b/Pipfile @@ -13,4 +13,4 @@ urllib3 = ">=2.1.0" intuit-oauth = "==1.2.4" requests = ">=2.31.0" simplejson = ">=3.19.1" -requests_oauthlib = ">=1.3.1" \ No newline at end of file +requests_oauthlib = ">=1.3.1" diff --git a/Pipfile.lock b/Pipfile.lock index 2edb1e91..ac5ba738 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,12 +1,10 @@ { "_meta": { "hash": { - "sha256": "3bb85d01d88e5dd481cd663a21728508e5b3fb0c57e372e0024b61eeaa6cc4ba" + "sha256": "2ab50499e986c80ada85e1893167602499fae6cd6d46d2c25ac232c34cb22092" }, "pipfile-spec": 6, - "requires": { - "python_version": "3.12" - }, + "requires": {}, "sources": [ { "name": "pypi", diff --git a/README.md b/README.md index ded62e66..dbc998e3 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Then create a QuickBooks client object passing in the AuthClient, refresh token, company_id='COMPANY_ID', ) -If you need to access a minor version (See [Minor versions](https://developer.intuit.com/docs/0100_quickbooks_online/0200_dev_guides/accounting/minor_versions) for +If you need to access a minor version (See [Minor versions](https://developer.intuit.com/app/developer/qbo/docs/learn/explore-the-quickbooks-online-api/minor-versions#working-with-minor-versions) for details) pass in minorversion when setting up the client: client = QuickBooks( @@ -74,7 +74,9 @@ List of objects: **Note:** The maximum number of entities that can be returned in a response is 1000. If the result size is not specified, the default -number is 100. (See [Intuit developer guide](https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/querying_data) for details) +number is 100. (See [Query operations and syntax](https://developer.intuit.com/app/developer/qbo/docs/learn/explore-the-quickbooks-online-api/data-queries) for details) + +**Warning:** You should never allow user input to pass into a query without sanitizing it first! This library DOES NOT sanitize user input! Filtered list of objects: @@ -104,6 +106,8 @@ List with custom Where Clause (do not include the `"WHERE"`): customers = Customer.where("Active = True AND CompanyName LIKE 'S%'", qb=client) + + List with custom Where and ordering customers = Customer.where("Active = True AND CompanyName LIKE 'S%'", order_by='DisplayName', qb=client) @@ -112,7 +116,7 @@ List with custom Where Clause and paging: customers = Customer.where("CompanyName LIKE 'S%'", start_position=1, max_results=25, qb=client) -Filtering a list with a custom query (See [Intuit developer guide](https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/querying_data) for +Filtering a list with a custom query (See [Query operations and syntax](https://developer.intuit.com/app/developer/qbo/docs/learn/explore-the-quickbooks-online-api/data-queries) for supported SQL statements): customers = Customer.query("SELECT * FROM Customer WHERE Active = True", qb=client) From 6267c77399f222c858bbbc232a7309a997d460e9 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 16:39:28 -0600 Subject: [PATCH 097/154] Update contributing doc --- Pipfile | 3 ++- Pipfile.lock | 50 ++++++++++++++++++++++++++++++++++++++++++------- contributing.md | 21 ++++++++++++--------- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/Pipfile b/Pipfile index 630f4eca..85ad666e 100644 --- a/Pipfile +++ b/Pipfile @@ -4,9 +4,10 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -nose = "*" coverage = "*" twine = "*" +pytest = "*" +pytest-cov = "*" [packages] urllib3 = ">=2.1.0" diff --git a/Pipfile.lock b/Pipfile.lock index ac5ba738..d1ab4bdf 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2ab50499e986c80ada85e1893167602499fae6cd6d46d2c25ac232c34cb22092" + "sha256": "09dfd0a28da4402be6db03781432fb082e5fe5d6010dae3f98443aa5d336f526" }, "pipfile-spec": 6, "requires": {}, @@ -433,6 +433,9 @@ "version": "==3.3.2" }, "coverage": { + "extras": [ + "toml" + ], "hashes": [ "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", @@ -515,6 +518,14 @@ "markers": "python_version >= '3.8'", "version": "==7.0.1" }, + "iniconfig": { + "hashes": [ + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, "jaraco.classes": { "hashes": [ "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb", @@ -576,14 +587,13 @@ ], "version": "==0.2.15" }, - "nose": { + "packaging": { "hashes": [ - "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", - "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a", - "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" ], - "index": "pypi", - "version": "==1.3.7" + "markers": "python_version >= '3.7'", + "version": "==23.2" }, "pkginfo": { "hashes": [ @@ -593,6 +603,14 @@ "markers": "python_version >= '3.6'", "version": "==1.9.6" }, + "pluggy": { + "hashes": [ + "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", + "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + ], + "markers": "python_version >= '3.8'", + "version": "==1.3.0" + }, "pygments": { "hashes": [ "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", @@ -601,6 +619,24 @@ "markers": "python_version >= '3.7'", "version": "==2.17.2" }, + "pytest": { + "hashes": [ + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==7.4.4" + }, + "pytest-cov": { + "hashes": [ + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==4.1.0" + }, "readme-renderer": { "hashes": [ "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d", diff --git a/contributing.md b/contributing.md index ae676b08..d2b26410 100644 --- a/contributing.md +++ b/contributing.md @@ -1,10 +1,10 @@ # Contributing -I am accepting pull requests. Sometimes life gets busy and it takes me a little while to get everything merged in. To help speed up the process, please write tests to cover your changes. I will review/merge them as soon as possible. +I am accepting pull requests. Sometimes life gets busy and it takes me a little while to get everything reviewed and merged in. To help speed up the process, please write tests to cover your changes. I will review/merge them as soon as possible. # Testing -I use [nose](https://nose.readthedocs.io/en/latest/index.html) and [Coverage](https://coverage.readthedocs.io/en/latest/) to run the test suite. +I use [pytest](https://docs.pytest.org/en/7.4.x/contents.html), [Coverage](https://coverage.readthedocs.io/en/latest/), and [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/) to run the test suite. *WARNING*: The Tests connect to the QBO API and create/modify/delete data. DO NOT USE A PRODUCTION ACCOUNT! @@ -12,21 +12,24 @@ I use [nose](https://nose.readthedocs.io/en/latest/index.html) and [Coverage](ht 1. Create/login into your [Intuit Developer account](https://developer.intuit.com). 2. On your Intuit Developer account, create a Sandbox company and an App. -3. Go to the Intuit Developer OAuth 2.0 Playground and fill out the form to get an **access token** and **refresh token**. You will need to copy the following values into your enviroment variables: +3. Go to the Intuit Developer OAuth 2.0 Playground and fill out the form to get a **refresh token**. You will need to copy the following values into your enviroment variables: ``` export CLIENT_ID="" export CLIENT_SECRET="" - export COMPANY_ID="" - export ACCESS_TOKEN="" + export COMPANY_ID="" export REFRESH_TOKEN="" ``` - *Note*: You will need to update the access token when it expires. + *Note*: You will need to update the refresh token when it expires. -5. Install *nose* and *coverage*. Using Pip: - `pip install nose coverage` +5. Install *pytest*, *coverage*, and *pytest-cov*. Using Pip (or whatever): + `pip install pytest coverage pytest-cov` -6. Run `nosetests . --with-coverage --cover-package=quickbooks` +6. Run all tests: ```pytest --cov``` + Run only unit tests: ```pytest tests/unit --cov``` + Run only integration tests: ```pytest tests/intergration --cov``` + + ## Creating new tests Normal Unit tests that do not connect to the QBO API should be located under `test/unit` Test that connect to QBO API should go under `tests/integration`. Inheriting from `QuickbooksTestCase` will automatically setup `self.qb_client` to use when connecting to QBO. From e7ae6dd6b7c870d65858b87bf7b440f75180b55b Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 3 Jan 2024 16:50:27 -0600 Subject: [PATCH 098/154] Clean up test_client --- CHANGELOG.rst | 4 +++- tests/unit/test_client.py | 20 ++------------------ 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7c028ba0..159fd97b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,10 +3,12 @@ Changelog * 0.9.6 (January 2, 2024) * Replace RAuth with requests_oauthlib * Removed python 2 code from client.py + * Removed unused dependencies from Pipfile * Added new fields to Employee object * Added VendorAddr to Bill object * Added new fields to Estimate object - * Fix taxinclusiveamt and vendor setting 1099 creation + * Fix TaxInclusiveAmt and vendor setting 1099 creation + * Updated readme and contributing * 0.9.5 (November 1, 2023) * Added the ability to void all voidable QB types diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 35b9da3f..2a30a358 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,4 +1,4 @@ -import unittest +from tests.integration.test_base import QuickbooksUnitTestCase try: from mock import patch @@ -8,7 +8,6 @@ from quickbooks.exceptions import QuickbooksException, SevereException, AuthorizationException from quickbooks import client from quickbooks.objects.salesreceipt import SalesReceipt -from intuitlib.client import AuthClient TEST_SIGNATURE = 'nfPLN16u3vMvv08ghDs+dOkLuirEVDy5wAeG/lmM2OA=' @@ -17,27 +16,12 @@ TEST_REFRESH_TOKEN = 'refresh' -class ClientTest(unittest.TestCase): +class ClientTest(QuickbooksUnitTestCase): def setUp(self): super(ClientTest, self).setUp() - self.auth_client = AuthClient( - client_id='CLIENTID', - client_secret='CLIENT_SECRET', - environment='sandbox', - redirect_uri='http://localhost:8000/callback', - ) - self.auth_client.access_token = 'ACCESS_TOKEN' - self.qb_client = client.QuickBooks( - # auth_client=self.auth_client, - refresh_token='REFRESH_TOKEN', - company_id='COMPANY_ID', - ) - - self.qb_client.sandbox = True - def tearDown(self): self.qb_client = client.QuickBooks() self.qb_client._drop() From 269b84e54b474b93d3e89b230df88ab2e21b6d11 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 09:33:15 -0600 Subject: [PATCH 099/154] Add codecov yaml --- .github/workflows/codecov.yaml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/workflows/codecov.yaml diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml new file mode 100644 index 00000000..e420c7d4 --- /dev/null +++ b/.github/workflows/codecov.yaml @@ -0,0 +1,4 @@ +- name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 485626e89ab5aa245b40a3aa374d4a93c3076913 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 09:55:04 -0600 Subject: [PATCH 100/154] Update codecov.yaml --- .github/workflows/codecov.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index e420c7d4..ec2befe8 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -1,4 +1,4 @@ -- name: Upload coverage reports to Codecov +name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From cc8bb0a0f5b3f9a44dc2cd49aedf9445c335ab2d Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 10:08:15 -0600 Subject: [PATCH 101/154] Added test --- tests/unit/objects/test_creditmemo.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/unit/objects/test_creditmemo.py b/tests/unit/objects/test_creditmemo.py index 87de54e5..0935fecc 100644 --- a/tests/unit/objects/test_creditmemo.py +++ b/tests/unit/objects/test_creditmemo.py @@ -28,6 +28,14 @@ def test_valid_object_name(self): self.assertTrue(result) + def test_to_ref(self): + obj = CreditMemo() + obj.Id = 123 + + ref = obj.to_ref() + self.assertEqual(ref.value, obj.Id) + self.assertEqual(ref.type, "CreditMemo") + class DiscountLineDetailTests(unittest.TestCase): def test_init(self): From f50309a87245e5f049bc47186567f5833ce0a2f5 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 10:12:34 -0600 Subject: [PATCH 102/154] Fix workflow --- .github/workflows/codecov.yaml | 4 ---- .github/workflows/python-package.yml | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 .github/workflows/codecov.yaml diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml deleted file mode 100644 index ec2befe8..00000000 --- a/.github/workflows/codecov.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 41f71120..e2210b05 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -38,3 +38,7 @@ jobs: - name: Test with pytest run: | pytest tests/unit + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 9c40439a77be3b42966fe69dd85c947e0ad23371 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 10:19:27 -0600 Subject: [PATCH 103/154] Updated test --- tests/unit/objects/test_exchangerate.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unit/objects/test_exchangerate.py b/tests/unit/objects/test_exchangerate.py index 6e00bd2a..15488dbc 100644 --- a/tests/unit/objects/test_exchangerate.py +++ b/tests/unit/objects/test_exchangerate.py @@ -1,7 +1,7 @@ import unittest from quickbooks import QuickBooks -from quickbooks.objects.exchangerate import ExchangeRate +from quickbooks.objects.exchangerate import ExchangeRate, ExchangeRateMetaData class ExchangeRateTests(unittest.TestCase): @@ -9,7 +9,11 @@ def test_unicode(self): exchange_rate = ExchangeRate() exchange_rate.SourceCurrencyCode = "EUR" + exchange_rate.MetaData = ExchangeRateMetaData() + exchange_rate.MetaData.LastUpdatedTime = "1" + self.assertEqual(str(exchange_rate), "EUR") + self.assertEqual(exchange_rate.MetaData.LastUpdatedTime, "1") def test_valid_object_name(self): obj = ExchangeRate() From c7b9c5284c4bf01cced5b403e738b9da12853860 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 11:27:24 -0600 Subject: [PATCH 104/154] Update yml --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index e2210b05..f5da930c 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -37,7 +37,7 @@ jobs: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | - pytest tests/unit + pytest tests/unit --cov - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 env: From b487322e130657d018dc69b7bd613b9a635d519a Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 11:29:37 -0600 Subject: [PATCH 105/154] Update yml --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index f5da930c..d48c54b9 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install flake8 pytest + python -m pip install flake8 pytest coverage pytest-cov if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | From 453d38652a12b5f8bd3d6ac575d33298e07eb6ee Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 12:52:15 -0600 Subject: [PATCH 106/154] Added tests --- .../integration/test_recurringtransaction.py | 1 + .../unit/objects/test_recurringtransaction.py | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_recurringtransaction.py b/tests/integration/test_recurringtransaction.py index b4c93eaa..e3588c8e 100644 --- a/tests/integration/test_recurringtransaction.py +++ b/tests/integration/test_recurringtransaction.py @@ -7,6 +7,7 @@ from quickbooks.objects.vendor import Vendor from tests.integration.test_base import QuickbooksTestCase + class RecurringTransactionTest(QuickbooksTestCase): def setUp(self): super(RecurringTransactionTest, self).setUp() diff --git a/tests/unit/objects/test_recurringtransaction.py b/tests/unit/objects/test_recurringtransaction.py index a9b766b3..4320818d 100644 --- a/tests/unit/objects/test_recurringtransaction.py +++ b/tests/unit/objects/test_recurringtransaction.py @@ -1,7 +1,8 @@ import unittest from quickbooks import QuickBooks -from quickbooks.objects.recurringtransaction import RecurringTransaction +from quickbooks.objects.recurringtransaction import RecurringTransaction, ScheduleInfo, RecurringInfo + class RecurringTransactionTests(unittest.TestCase): def test_valid_object_name(self): @@ -9,4 +10,20 @@ def test_valid_object_name(self): client = QuickBooks() result = client.isvalid_object_name(obj.qbo_object_name) - self.assertTrue(result) \ No newline at end of file + self.assertTrue(result) + + +class ScheduleInfoTest(unittest.TestCase): + def test_create(self): + obj = ScheduleInfo() + obj.DayOfMonth = "1" + + self.assertEqual(obj.DayOfMonth, "1") + + +class RecurringInfoTest(unittest.TestCase): + def test_create(self): + obj = RecurringInfo() + + self.assertEqual(obj.RecurType, "Automated") + From 83be8cdf8c7ee65b2d2e3d7113f29ca28b426d18 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Thu, 4 Jan 2024 12:59:05 -0600 Subject: [PATCH 107/154] Add codecov badge to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dbc998e3..b0ae95be 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ python-quickbooks ================= [![Python package](https://github.com/ej2/python-quickbooks/actions/workflows/python-package.yml/badge.svg)](https://github.com/ej2/python-quickbooks/actions/workflows/python-package.yml) -[![Coverage Status](https://coveralls.io/repos/github/ej2/python-quickbooks/badge.svg?branch=master)](https://coveralls.io/github/ej2/python-quickbooks?branch=master) +[![codecov](https://codecov.io/gh/ej2/python-quickbooks/graph/badge.svg?token=AKXS2F7wvP)](https://codecov.io/gh/ej2/python-quickbooks) [![](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/ej2/python-quickbooks/blob/master/LICENSE) [![PyPI](https://img.shields.io/pypi/v/python-quickbooks)](https://pypi.org/project/python-quickbooks/) From 710fa4f5026c86ec537028d939a3f79cad1c943b Mon Sep 17 00:00:00 2001 From: redblacktree Date: Thu, 22 Feb 2024 06:38:47 -0500 Subject: [PATCH 108/154] Use `with` statement to make sure the file is closed after reading. --- quickbooks/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index 5aa5a358..967bba38 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -162,7 +162,6 @@ def make_request(self, request_type, url, request_body=None, content_type='appli } if file_path: - attachment = open(file_path, 'rb') url = url.replace('attachable', 'upload') boundary = '-------------PythonMultipartPost' headers.update({ @@ -173,7 +172,8 @@ def make_request(self, request_type, url, request_body=None, content_type='appli 'Connection': 'close' }) - binary_data = str(base64.b64encode(attachment.read()).decode('ascii')) + with open(file_path, 'rb') as attachment: + binary_data = str(base64.b64encode(attachment.read()).decode('ascii')) content_type = json.loads(request_body)['ContentType'] From 4d3b2cc6c91ada3ed3f201cce5c1acb6490afbfa Mon Sep 17 00:00:00 2001 From: redblacktree Date: Thu, 22 Feb 2024 07:33:00 -0500 Subject: [PATCH 109/154] added test --- tests/unit/test_client.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 2a30a358..aafbf336 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,9 +1,9 @@ from tests.integration.test_base import QuickbooksUnitTestCase try: - from mock import patch + from mock import patch, mock_open except ImportError: - from unittest.mock import patch + from unittest.mock import patch, mock_open from quickbooks.exceptions import QuickbooksException, SevereException, AuthorizationException from quickbooks import client @@ -217,6 +217,22 @@ def test_download_pdf_not_authorized(self, process_request): self.assertRaises(AuthorizationException, receipt.download_pdf, self.qb_client) + @patch('quickbooks.client.QuickBooks.process_request') + def test_make_request_file_closed(self, process_request): + file_path = '/path/to/file.txt' + process_request.return_value = MockResponse() + with patch('builtins.open', mock_open(read_data=b'file content')) as mock_file: + qb_client = client.QuickBooks(auth_client=self.auth_client) + qb_client.make_request('POST', + 'https://sandbox-quickbooks.api.intuit.com/v3/company/COMPANY_ID/attachable', + request_body='{"ContentType": "text/plain"}', + file_path=file_path) + + mock_file.assert_called_once_with(file_path, 'rb') + mock_file.return_value.__enter__.return_value.read.assert_called_once() + mock_file.return_value.__exit__.assert_called_once() + process_request.assert_called_once() + class MockResponse(object): @property From 54dfba3e96aec279a5d04daec2572d825349d147 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 12 Mar 2024 15:21:13 -0500 Subject: [PATCH 110/154] 0.9.7 changes --- Pipfile | 2 +- quickbooks/objects/companycurrency.py | 2 +- quickbooks/objects/customer.py | 1 + tests/unit/objects/test_companycurrency.py | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Pipfile b/Pipfile index 85ad666e..4d3612c1 100644 --- a/Pipfile +++ b/Pipfile @@ -11,7 +11,7 @@ pytest-cov = "*" [packages] urllib3 = ">=2.1.0" -intuit-oauth = "==1.2.4" +intuit-oauth = "==1.2.5" requests = ">=2.31.0" simplejson = ">=3.19.1" requests_oauthlib = ">=1.3.1" diff --git a/quickbooks/objects/companycurrency.py b/quickbooks/objects/companycurrency.py index b4f788ea..20f6b778 100644 --- a/quickbooks/objects/companycurrency.py +++ b/quickbooks/objects/companycurrency.py @@ -35,6 +35,6 @@ def to_ref(self): ref.name = self.Name ref.type = self.qbo_object_name - ref.value = self.Id + ref.value = self.Code return ref diff --git a/quickbooks/objects/customer.py b/quickbooks/objects/customer.py index 2bf0f19b..87bf95aa 100644 --- a/quickbooks/objects/customer.py +++ b/quickbooks/objects/customer.py @@ -71,6 +71,7 @@ def __init__(self): self.PaymentMethodRef = None self.ParentRef = None self.ARAccountRef = None + self.CurrencyRef = None def __str__(self): return self.DisplayName diff --git a/tests/unit/objects/test_companycurrency.py b/tests/unit/objects/test_companycurrency.py index 7582be3d..34a1a10f 100644 --- a/tests/unit/objects/test_companycurrency.py +++ b/tests/unit/objects/test_companycurrency.py @@ -13,11 +13,12 @@ def test_unicode(self): def test_to_ref(self): company_currency = CompanyCurrency() company_currency.Name = "test" + company_currency.Code = "USD" company_currency.Id = 23 ref = company_currency.to_ref() self.assertEqual(ref.name, "test") self.assertEqual(ref.type, "CompanyCurrency") - self.assertEqual(ref.value, 23) + self.assertEqual(ref.value, "USD") From d7c6d1918bde3f8c1763f50161453904269db3b3 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 12 Mar 2024 15:28:04 -0500 Subject: [PATCH 111/154] Update changelog and version --- CHANGELOG.rst | 6 ++++++ setup.py | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 159fd97b..86540755 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,11 @@ Changelog ========= +* 0.9.7 (March 12, 2024) + * Update intuit-oauth dependency + * Updated CompanyCurrency to ref to use Code instead of Id + * Added missing CurrentRef property from customer object + * Made improvements to file attachment handling + * 0.9.6 (January 2, 2024) * Replace RAuth with requests_oauthlib * Removed python 2 code from client.py diff --git a/setup.py b/setup.py index f4620a52..55f0654b 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 6) +VERSION = (0, 9, 7) version = '.'.join(map(str, VERSION)) setup( @@ -31,7 +31,7 @@ def read(*parts): install_requires=[ 'setuptools', - 'intuit-oauth==1.2.4', + 'intuit-oauth==1.2.5', 'requests_oauthlib>=1.3.1', 'requests>=2.31.0', 'simplejson>=3.19.1', From 7a55f1b3cdd85836489f77ffb3eccee990f479ee Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 12 Mar 2024 15:37:38 -0500 Subject: [PATCH 112/154] Add Python 3.12 to workflows --- .github/workflows/pylint.yml | 2 +- .github/workflows/python-package.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index c9c962e5..d76c6a23 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index d48c54b9..fcb126ce 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v3 From d77b308ab6c66ab42561b18289c679e2eb8c7877 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 20 May 2024 13:40:25 -0500 Subject: [PATCH 113/154] Update readme for from_json --- README.md | 4 ++-- tests/integration/test_account.py | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b0ae95be..45a2293c 100644 --- a/README.md +++ b/README.md @@ -277,10 +277,10 @@ Converting an object to JSON data: Loading JSON data into a quickbooks object: - account = Account() - account.from_json( + account = Account.from_json( { "AccountType": "Accounts Receivable", + "AcctNum": "123123", "Name": "MyJobs" } ) diff --git a/tests/integration/test_account.py b/tests/integration/test_account.py index 4efde66a..78d5b46f 100644 --- a/tests/integration/test_account.py +++ b/tests/integration/test_account.py @@ -32,3 +32,12 @@ def test_update(self): query_account = Account.get(account.Id, qb=self.qb_client) self.assertEqual(query_account.Name, "Updated Name {0}".format(self.account_number)) + + def test_create_using_from_json(self): + account = Account.from_json({ + "AcctNum": self.account_number, + "Name": self.name, + "AccountSubType": "CashOnHand" + }) + + account.save(qb=self.qb_client) From 33233633065f41f1c41041fb4963cb4a8d907650 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 20 May 2024 13:50:33 -0500 Subject: [PATCH 114/154] Add new field ItemAccountRef to SalesItemLineDetail --- quickbooks/objects/detailline.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickbooks/objects/detailline.py b/quickbooks/objects/detailline.py index f27449fd..cf4ef575 100644 --- a/quickbooks/objects/detailline.py +++ b/quickbooks/objects/detailline.py @@ -102,6 +102,7 @@ def __init__(self): class SalesItemLineDetail(QuickbooksBaseObject): class_dict = { "ItemRef": Ref, + "ItemAccountRef": Ref, "ClassRef": Ref, "TaxCodeRef": Ref, "PriceLevelRef": Ref, @@ -117,6 +118,7 @@ def __init__(self): self.MarkupInfo = None self.ItemRef = None + self.ItemAccountRef = None self.ClassRef = None self.TaxCodeRef = None self.PriceLevelRef = None From 60247530901ae10b43e16b251862c2495ede3ed6 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 20 May 2024 15:34:55 -0500 Subject: [PATCH 115/154] Update changelog --- CHANGELOG.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 86540755..4818f498 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,9 @@ Changelog ========= +* 0.9.7 (May 20, 2024) + * Added ItemAccountRef to SalesItemLineDetail + * Updated from_json example in readme + * 0.9.7 (March 12, 2024) * Update intuit-oauth dependency * Updated CompanyCurrency to ref to use Code instead of Id From 89a38ac337c74f6632250c3ae6fcada5a300706f Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 20 May 2024 15:36:41 -0500 Subject: [PATCH 116/154] Increment version number --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 55f0654b..e0b4c70c 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 7) +VERSION = (0, 9, 8) version = '.'.join(map(str, VERSION)) setup( From ab826d5e49e35d1169e77478f7d863fa21ff9833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=AD=20Gamboa?= Date: Tue, 21 May 2024 15:57:27 +0200 Subject: [PATCH 117/154] Add 3.12 to setup.py classifiers --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index e0b4c70c..6cc8a4bd 100644 --- a/setup.py +++ b/setup.py @@ -51,6 +51,7 @@ def read(*parts): 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], packages=find_packages(exclude=("tests",)), ) From c0f3e38f019c0eee64c29cd9fe250c3fc14e53b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=AD=20Gamboa?= Date: Tue, 21 May 2024 16:00:03 +0200 Subject: [PATCH 118/154] Update contributing.md some grammar nits --- contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index d2b26410..a15ae385 100644 --- a/contributing.md +++ b/contributing.md @@ -32,7 +32,7 @@ I use [pytest](https://docs.pytest.org/en/7.4.x/contents.html), [Coverage](https ## Creating new tests -Normal Unit tests that do not connect to the QBO API should be located under `test/unit` Test that connect to QBO API should go under `tests/integration`. Inheriting from `QuickbooksTestCase` will automatically setup `self.qb_client` to use when connecting to QBO. +Normal Unit tests that do not connect to the QBO API should be located under `test/unit`. Tests that connect to QBO API should go under `tests/integration`. Inheriting from `QuickbooksTestCase` will automatically setup `self.qb_client` to use when connecting to QBO. Example: ``` From da86e27806609a24579032bed154024c4ec0d012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=AD=20Gamboa?= Date: Tue, 21 May 2024 16:02:05 +0200 Subject: [PATCH 119/154] Fix path in pytest example --- contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index d2b26410..0367e5fb 100644 --- a/contributing.md +++ b/contributing.md @@ -27,7 +27,7 @@ I use [pytest](https://docs.pytest.org/en/7.4.x/contents.html), [Coverage](https 6. Run all tests: ```pytest --cov``` Run only unit tests: ```pytest tests/unit --cov``` - Run only integration tests: ```pytest tests/intergration --cov``` + Run only integration tests: ```pytest tests/integration --cov``` From 5afd3f5179aa52162bfcdfb08a71310eb38bbc90 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Wed, 22 May 2024 18:10:33 -0700 Subject: [PATCH 120/154] Use simplejson Decimal support Modified imports and removed unused json imports Modified calls to set use_decimal for serialization/deserialization --- quickbooks/client.py | 4 ++-- quickbooks/mixins.py | 10 ++++------ quickbooks/objects/payment.py | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index 967bba38..7a075786 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -1,6 +1,6 @@ import http.client as httplib import textwrap -import json +import simplejson as json import base64 import hashlib import hmac @@ -206,7 +206,7 @@ def make_request(self, request_type, url, request_body=None, content_type='appli "Application authentication failed", error_code=req.status_code, detail=req.text) try: - result = req.json() + result = json.loads(req.text, use_decimal=True) except: raise exceptions.QuickbooksException("Error reading json response: {0}".format(req.text), 10000) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 2083139e..6b0a1beb 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -1,16 +1,14 @@ from urllib.parse import quote -try: import simplejson as json -except ImportError: import json +import simplejson as json from .utils import build_where_clause, build_choose_clause from .client import QuickBooks from .exceptions import QuickbooksException - class ToJsonMixin(object): def to_json(self): - return json.dumps(self, default=self.json_filter(), sort_keys=True, indent=4) + return json.dumps(self, default=self.json_filter(), sort_keys=True, indent=4, use_decimal=True) def json_filter(self): """ @@ -178,7 +176,7 @@ def void(self, qb=None): data = self.get_void_data() params = self.get_void_params() - results = qb.post(url, json.dumps(data), params=params) + results = qb.post(url, json.dumps(data, use_decimal=True), params=params) return results @@ -232,7 +230,7 @@ def delete(self, qb=None, request_id=None): 'Id': self.Id, 'SyncToken': self.SyncToken, } - return qb.delete_object(self.qbo_object_name, json.dumps(data), request_id=request_id) + return qb.delete_object(self.qbo_object_name, json.dumps(data, use_decimal=True), request_id=request_id) class DeleteNoIdMixin(object): diff --git a/quickbooks/objects/payment.py b/quickbooks/objects/payment.py index 75cbf570..5783d169 100644 --- a/quickbooks/objects/payment.py +++ b/quickbooks/objects/payment.py @@ -4,7 +4,6 @@ from ..client import QuickBooks from .creditcardpayment import CreditCardPayment from ..mixins import DeleteMixin, VoidMixin -import json class PaymentLine(QuickbooksBaseObject): From 9de4c9ebab2f2b4aee52bb49470eeecaacd2d6ff Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Wed, 22 May 2024 20:40:06 -0700 Subject: [PATCH 121/154] Fixed mock object for simplejson case --- tests/unit/test_client.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index aafbf336..c0b0ab07 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,3 +1,4 @@ +import simplejson as json from tests.integration.test_base import QuickbooksUnitTestCase try: @@ -141,7 +142,7 @@ def test_get_single_object(self, make_req): @patch('quickbooks.client.QuickBooks.process_request') def test_make_request(self, process_request): - process_request.return_value = MockResponse() + process_request.return_value = MockResponseSimpleJson() qb_client = client.QuickBooks() qb_client.company_id = "1234" @@ -220,7 +221,7 @@ def test_download_pdf_not_authorized(self, process_request): @patch('quickbooks.client.QuickBooks.process_request') def test_make_request_file_closed(self, process_request): file_path = '/path/to/file.txt' - process_request.return_value = MockResponse() + process_request.return_value = MockResponseSimpleJson() with patch('builtins.open', mock_open(read_data=b'file content')) as mock_file: qb_client = client.QuickBooks(auth_client=self.auth_client) qb_client.make_request('POST', @@ -253,6 +254,18 @@ def json(self): def content(self): return '' +class MockResponseSimpleJson: + def __init__(self, json_data=None, status_code=200): + self.json_data = json_data or {} + self.status_code = status_code + + @property + def text(self): + return json.dumps(self.json_data) # Ensure this uses simplejson if necessary + + def json(self): + return self.json_data + class MockUnauthorizedResponse(object): @property From ddbbd3d9f63c207eb28c4509ad78f650fb0adcf0 Mon Sep 17 00:00:00 2001 From: Pablo Marti Gamboa Date: Thu, 30 May 2024 07:03:02 +0200 Subject: [PATCH 122/154] remove simplejson --- Pipfile | 1 - Pipfile.lock | 455 +++++++++++++++++-------------------------- quickbooks/mixins.py | 3 +- requirements.txt | 1 - setup.py | 1 - 5 files changed, 181 insertions(+), 280 deletions(-) diff --git a/Pipfile b/Pipfile index 4d3612c1..ab07e83a 100644 --- a/Pipfile +++ b/Pipfile @@ -13,5 +13,4 @@ pytest-cov = "*" urllib3 = ">=2.1.0" intuit-oauth = "==1.2.5" requests = ">=2.31.0" -simplejson = ">=3.19.1" requests_oauthlib = ">=1.3.1" diff --git a/Pipfile.lock b/Pipfile.lock index d1ab4bdf..156b7153 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "09dfd0a28da4402be6db03781432fb082e5fe5d6010dae3f98443aa5d336f526" + "sha256": "e25e6a93ea424fe54edd3dbdbd0eed5c76b49764b8e64cdb4c70d271932331f0" }, "pipfile-spec": 6, "requires": {}, @@ -16,11 +16,11 @@ "default": { "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -120,11 +120,11 @@ }, "ecdsa": { "hashes": [ - "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", - "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" + "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a", + "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.0" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.19.0" }, "enum-compat": { "hashes": [ @@ -133,28 +133,21 @@ ], "version": "==0.0.3" }, - "future": { - "hashes": [ - "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.3" - }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "intuit-oauth": { "hashes": [ - "sha256:14a1a8ed73f24369ba209f0e581eb30698571fd7bcbe05ca5bed65d2ff9df8b1", - "sha256:dd09ef833a26e12e0fbe96d0e7694cdae2c9179776f763ea00e328f8cbd4464e" + "sha256:1c3d53468c00590485dc3b040d5d18389060573c616a26e33a03c1b164c92823", + "sha256:74af897366c0fb984a6179ef3200bb10c0ed194760e7daf92c8b0927e856a022" ], "index": "pypi", - "version": "==1.2.4" + "version": "==1.2.5" }, "oauthlib": { "hashes": [ @@ -166,11 +159,11 @@ }, "pyasn1": { "hashes": [ - "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58", - "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c" + "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c", + "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.5.1" + "markers": "python_version >= '3.8'", + "version": "==0.6.0" }, "python-jose": { "hashes": [ @@ -181,20 +174,21 @@ }, "requests": { "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.31.0" + "markers": "python_version >= '3.8'", + "version": "==2.32.3" }, "requests-oauthlib": { "hashes": [ - "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", - "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", + "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.3.1" + "index": "pypi", + "markers": "python_version >= '3.4'", + "version": "==2.0.0" }, "rsa": { "hashes": [ @@ -204,111 +198,6 @@ "markers": "python_version >= '3.6' and python_version < '4'", "version": "==4.9" }, - "simplejson": { - "hashes": [ - "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137", - "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a", - "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae", - "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a", - "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba", - "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087", - "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b", - "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41", - "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d", - "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd", - "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d", - "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e", - "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a", - "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9", - "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6", - "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb", - "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664", - "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2", - "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b", - "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5", - "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835", - "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17", - "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69", - "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd", - "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6", - "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2", - "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2", - "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428", - "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f", - "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2", - "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f", - "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7", - "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f", - "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637", - "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3", - "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816", - "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565", - "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378", - "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0", - "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b", - "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693", - "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358", - "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9", - "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23", - "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf", - "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a", - "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832", - "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414", - "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f", - "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48", - "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad", - "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290", - "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3", - "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917", - "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402", - "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0", - "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc", - "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867", - "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f", - "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589", - "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb", - "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b", - "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3", - "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb", - "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c", - "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46", - "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672", - "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c", - "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e", - "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0", - "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b", - "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4", - "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4", - "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c", - "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c", - "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8", - "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b", - "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb", - "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80", - "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2", - "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374", - "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc", - "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50", - "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c", - "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f", - "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28", - "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5", - "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734", - "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a", - "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d", - "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4", - "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c", - "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13", - "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973", - "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a", - "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e", - "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff", - "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded" - ], - "index": "pypi", - "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==3.19.2" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -319,22 +208,22 @@ }, "urllib3": { "hashes": [ - "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", - "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.1.0" + "version": "==2.2.1" } }, "develop": { "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -437,86 +326,86 @@ "toml" ], "hashes": [ - "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", - "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", - "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a", - "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058", - "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85", - "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143", - "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446", - "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590", - "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a", - "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105", - "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9", - "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a", - "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac", - "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25", - "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2", - "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450", - "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932", - "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba", - "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137", - "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae", - "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614", - "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70", - "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e", - "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505", - "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870", - "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc", - "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451", - "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7", - "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e", - "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566", - "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5", - "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26", - "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2", - "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42", - "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555", - "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43", - "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed", - "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa", - "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516", - "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952", - "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd", - "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09", - "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c", - "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f", - "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6", - "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1", - "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0", - "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e", - "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9", - "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9", - "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e", - "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06" + "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523", + "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f", + "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d", + "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb", + "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0", + "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c", + "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98", + "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83", + "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8", + "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7", + "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac", + "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84", + "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb", + "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3", + "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884", + "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614", + "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd", + "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807", + "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd", + "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8", + "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc", + "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db", + "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0", + "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08", + "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232", + "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d", + "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a", + "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1", + "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286", + "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303", + "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341", + "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84", + "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45", + "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc", + "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec", + "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd", + "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155", + "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52", + "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d", + "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485", + "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31", + "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d", + "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d", + "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d", + "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85", + "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce", + "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb", + "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974", + "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24", + "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56", + "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9", + "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==7.4.0" + "version": "==7.5.3" }, "docutils": { "hashes": [ - "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6", - "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b" + "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", + "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2" ], - "markers": "python_version >= '3.7'", - "version": "==0.20.1" + "markers": "python_version >= '3.9'", + "version": "==0.21.2" }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "importlib-metadata": { "hashes": [ - "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", - "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" + "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2" ], "markers": "python_version >= '3.8'", - "version": "==7.0.1" + "version": "==7.1.0" }, "iniconfig": { "hashes": [ @@ -528,19 +417,35 @@ }, "jaraco.classes": { "hashes": [ - "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb", - "sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621" + "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" ], "markers": "python_version >= '3.8'", - "version": "==3.3.0" + "version": "==3.4.0" + }, + "jaraco.context": { + "hashes": [ + "sha256:3e16388f7da43d384a1a7cd3452e72e14732ac9fe459678773a3608a812bf266", + "sha256:c2f67165ce1f9be20f32f650f25d8edfc1646a8aeee48ae06fb35f90763576d2" + ], + "markers": "python_version >= '3.8'", + "version": "==5.3.0" + }, + "jaraco.functools": { + "hashes": [ + "sha256:3b24ccb921d6b593bdceb56ce14799204f473976e2a9d4b15b04d0f2c2326664", + "sha256:d33fa765374c0611b52f8b3a795f8900869aa88c84769d4d1746cd68fb28c3e8" + ], + "markers": "python_version >= '3.8'", + "version": "==4.0.1" }, "keyring": { "hashes": [ - "sha256:4446d35d636e6a10b8bce7caa66913dd9eca5fd222ca03a3d42c38608ac30836", - "sha256:e730ecffd309658a08ee82535a3b5ec4b4c8669a9be11efb66249d8e0aeb9a25" + "sha256:2458681cdefc0dbc0b7eb6cf75d0b98e59f9ad9b2d4edd319d18f68bdca95e50", + "sha256:daaffd42dbda25ddafb1ad5fec4024e5bbcfe424597ca1ca452b299861e49f1b" ], "markers": "python_version >= '3.8'", - "version": "==24.3.0" + "version": "==25.2.1" }, "markdown-it-py": { "hashes": [ @@ -560,99 +465,99 @@ }, "more-itertools": { "hashes": [ - "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a", - "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6" + "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1" ], "markers": "python_version >= '3.8'", - "version": "==10.1.0" + "version": "==10.2.0" }, "nh3": { "hashes": [ - "sha256:0d02d0ff79dfd8208ed25a39c12cbda092388fff7f1662466e27d97ad011b770", - "sha256:3277481293b868b2715907310c7be0f1b9d10491d5adf9fce11756a97e97eddf", - "sha256:3b803a5875e7234907f7d64777dfde2b93db992376f3d6d7af7f3bc347deb305", - "sha256:427fecbb1031db085eaac9931362adf4a796428ef0163070c484b5a768e71601", - "sha256:5f0d77272ce6d34db6c87b4f894f037d55183d9518f948bba236fe81e2bb4e28", - "sha256:60684857cfa8fdbb74daa867e5cad3f0c9789415aba660614fe16cd66cbb9ec7", - "sha256:6f42f99f0cf6312e470b6c09e04da31f9abaadcd3eb591d7d1a88ea931dca7f3", - "sha256:86e447a63ca0b16318deb62498db4f76fc60699ce0a1231262880b38b6cff911", - "sha256:8d595df02413aa38586c24811237e95937ef18304e108b7e92c890a06793e3bf", - "sha256:9c0d415f6b7f2338f93035bba5c0d8c1b464e538bfbb1d598acd47d7969284f0", - "sha256:a5167a6403d19c515217b6bcaaa9be420974a6ac30e0da9e84d4fc67a5d474c5", - "sha256:ac19c0d68cd42ecd7ead91a3a032fdfff23d29302dbb1311e641a130dfefba97", - "sha256:b1e97221cedaf15a54f5243f2c5894bb12ca951ae4ddfd02a9d4ea9df9e1a29d", - "sha256:bc2d086fb540d0fa52ce35afaded4ea526b8fc4d3339f783db55c95de40ef02e", - "sha256:d1e30ff2d8d58fb2a14961f7aac1bbb1c51f9bdd7da727be35c63826060b0bf3", - "sha256:f3b53ba93bb7725acab1e030bc2ecd012a817040fd7851b332f86e2f9bb98dc6" - ], - "version": "==0.2.15" + "sha256:0316c25b76289cf23be6b66c77d3608a4fdf537b35426280032f432f14291b9a", + "sha256:1a814dd7bba1cb0aba5bcb9bebcc88fd801b63e21e2450ae6c52d3b3336bc911", + "sha256:1aa52a7def528297f256de0844e8dd680ee279e79583c76d6fa73a978186ddfb", + "sha256:22c26e20acbb253a5bdd33d432a326d18508a910e4dcf9a3316179860d53345a", + "sha256:40015514022af31975c0b3bca4014634fa13cb5dc4dbcbc00570acc781316dcc", + "sha256:40d0741a19c3d645e54efba71cb0d8c475b59135c1e3c580f879ad5514cbf028", + "sha256:551672fd71d06cd828e282abdb810d1be24e1abb7ae2543a8fa36a71c1006fe9", + "sha256:66f17d78826096291bd264f260213d2b3905e3c7fae6dfc5337d49429f1dc9f3", + "sha256:85cdbcca8ef10733bd31f931956f7fbb85145a4d11ab9e6742bbf44d88b7e351", + "sha256:a3f55fabe29164ba6026b5ad5c3151c314d136fd67415a17660b4aaddacf1b10", + "sha256:b4427ef0d2dfdec10b641ed0bdaf17957eb625b2ec0ea9329b3d28806c153d71", + "sha256:ba73a2f8d3a1b966e9cdba7b211779ad8a2561d2dba9674b8a19ed817923f65f", + "sha256:c21bac1a7245cbd88c0b0e4a420221b7bfa838a2814ee5bb924e9c2f10a1120b", + "sha256:c551eb2a3876e8ff2ac63dff1585236ed5dfec5ffd82216a7a174f7c5082a78a", + "sha256:c790769152308421283679a142dbdb3d1c46c79c823008ecea8e8141db1a2062", + "sha256:d7a25fd8c86657f5d9d576268e3b3767c5cd4f42867c9383618be8517f0f022a" + ], + "version": "==0.2.17" }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "pkginfo": { "hashes": [ - "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546", - "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046" + "sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297", + "sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097" ], "markers": "python_version >= '3.6'", - "version": "==1.9.6" + "version": "==1.10.0" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.5.0" }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.8'", + "version": "==2.18.0" }, "pytest": { "hashes": [ - "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", - "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" + "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd", + "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==7.4.4" + "markers": "python_version >= '3.8'", + "version": "==8.2.1" }, "pytest-cov": { "hashes": [ - "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", - "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" + "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", + "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==4.1.0" + "markers": "python_version >= '3.8'", + "version": "==5.0.0" }, "readme-renderer": { "hashes": [ - "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d", - "sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1" + "sha256:1818dd28140813509eeed8d62687f7cd4f7bad90d4db586001c5dc09d4fde311", + "sha256:19db308d86ecd60e5affa3b2a98f017af384678c63c88e5d4556a380e674f3f9" ], "markers": "python_version >= '3.8'", - "version": "==42.0" + "version": "==43.0" }, "requests": { "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.31.0" + "markers": "python_version >= '3.8'", + "version": "==2.32.3" }, "requests-toolbelt": { "hashes": [ @@ -672,37 +577,37 @@ }, "rich": { "hashes": [ - "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", - "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" + "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", + "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432" ], "markers": "python_full_version >= '3.7.0'", - "version": "==13.7.0" + "version": "==13.7.1" }, "twine": { "hashes": [ - "sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8", - "sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8" + "sha256:4d74770c88c4fcaf8134d2a6a9d863e40f08255ff7d8e2acb3cbbd57d25f6e9d", + "sha256:fe1d814395bfe50cfbe27783cb74efe93abeac3f66deaeb6c8390e4e92bacb43" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==4.0.2" + "markers": "python_version >= '3.8'", + "version": "==5.1.0" }, "urllib3": { "hashes": [ - "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", - "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.1.0" + "version": "==2.2.1" }, "zipp": { "hashes": [ - "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", - "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + "sha256:952df858fb3164426c976d9338d3961e8e8b3758e2e059e0f754b8c4262625ee", + "sha256:96dc6ad62f1441bcaccef23b274ec471518daf4fbbc580341204936a5a3dddec" ], "markers": "python_version >= '3.8'", - "version": "==3.17.0" + "version": "==3.19.0" } } } diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 2083139e..4ed978d8 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -1,7 +1,6 @@ +import json from urllib.parse import quote -try: import simplejson as json -except ImportError: import json from .utils import build_where_clause, build_choose_clause from .client import QuickBooks diff --git a/requirements.txt b/requirements.txt index 2f1d93f7..16c4e401 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ intuit-oauth==1.2.4 requests_oauthlib>=1.3.1 requests>=2.31.0 -simplejson>=3.19.1 \ No newline at end of file diff --git a/setup.py b/setup.py index e0b4c70c..046aa758 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,6 @@ def read(*parts): 'intuit-oauth==1.2.5', 'requests_oauthlib>=1.3.1', 'requests>=2.31.0', - 'simplejson>=3.19.1', 'python-dateutil', ], From 3dcc61446bee45533410148e1b96ba28aa4b6a3c Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sat, 1 Jun 2024 12:09:38 -0700 Subject: [PATCH 123/154] Removed simplejson dependency See https://github.com/ej2/python-quickbooks/pull/358 --- Pipfile | 1 - Pipfile.lock | 457 +++++++++++++++++-------------------------- quickbooks/client.py | 8 +- quickbooks/mixins.py | 18 +- requirements.txt | 3 +- setup.py | 1 - 6 files changed, 199 insertions(+), 289 deletions(-) diff --git a/Pipfile b/Pipfile index 4d3612c1..ab07e83a 100644 --- a/Pipfile +++ b/Pipfile @@ -13,5 +13,4 @@ pytest-cov = "*" urllib3 = ">=2.1.0" intuit-oauth = "==1.2.5" requests = ">=2.31.0" -simplejson = ">=3.19.1" requests_oauthlib = ">=1.3.1" diff --git a/Pipfile.lock b/Pipfile.lock index d1ab4bdf..b95a5125 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "09dfd0a28da4402be6db03781432fb082e5fe5d6010dae3f98443aa5d336f526" + "sha256": "e25e6a93ea424fe54edd3dbdbd0eed5c76b49764b8e64cdb4c70d271932331f0" }, "pipfile-spec": 6, "requires": {}, @@ -16,11 +16,11 @@ "default": { "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -120,11 +120,11 @@ }, "ecdsa": { "hashes": [ - "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", - "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" + "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a", + "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.0" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.19.0" }, "enum-compat": { "hashes": [ @@ -133,28 +133,21 @@ ], "version": "==0.0.3" }, - "future": { - "hashes": [ - "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.3" - }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "intuit-oauth": { "hashes": [ - "sha256:14a1a8ed73f24369ba209f0e581eb30698571fd7bcbe05ca5bed65d2ff9df8b1", - "sha256:dd09ef833a26e12e0fbe96d0e7694cdae2c9179776f763ea00e328f8cbd4464e" + "sha256:1c3d53468c00590485dc3b040d5d18389060573c616a26e33a03c1b164c92823", + "sha256:74af897366c0fb984a6179ef3200bb10c0ed194760e7daf92c8b0927e856a022" ], "index": "pypi", - "version": "==1.2.4" + "version": "==1.2.5" }, "oauthlib": { "hashes": [ @@ -166,11 +159,11 @@ }, "pyasn1": { "hashes": [ - "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58", - "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c" + "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c", + "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.5.1" + "markers": "python_version >= '3.8'", + "version": "==0.6.0" }, "python-jose": { "hashes": [ @@ -181,20 +174,21 @@ }, "requests": { "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.31.0" + "markers": "python_version >= '3.8'", + "version": "==2.32.3" }, "requests-oauthlib": { "hashes": [ - "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", - "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", + "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.3.1" + "index": "pypi", + "markers": "python_version >= '3.4'", + "version": "==2.0.0" }, "rsa": { "hashes": [ @@ -204,111 +198,6 @@ "markers": "python_version >= '3.6' and python_version < '4'", "version": "==4.9" }, - "simplejson": { - "hashes": [ - "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137", - "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a", - "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae", - "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a", - "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba", - "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087", - "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b", - "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41", - "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d", - "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd", - "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d", - "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e", - "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a", - "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9", - "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6", - "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb", - "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664", - "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2", - "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b", - "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5", - "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835", - "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17", - "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69", - "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd", - "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6", - "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2", - "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2", - "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428", - "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f", - "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2", - "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f", - "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7", - "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f", - "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637", - "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3", - "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816", - "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565", - "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378", - "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0", - "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b", - "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693", - "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358", - "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9", - "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23", - "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf", - "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a", - "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832", - "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414", - "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f", - "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48", - "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad", - "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290", - "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3", - "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917", - "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402", - "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0", - "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc", - "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867", - "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f", - "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589", - "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb", - "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b", - "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3", - "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb", - "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c", - "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46", - "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672", - "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c", - "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e", - "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0", - "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b", - "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4", - "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4", - "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c", - "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c", - "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8", - "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b", - "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb", - "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80", - "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2", - "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374", - "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc", - "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50", - "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c", - "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f", - "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28", - "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5", - "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734", - "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a", - "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d", - "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4", - "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c", - "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13", - "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973", - "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a", - "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e", - "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff", - "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded" - ], - "index": "pypi", - "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==3.19.2" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -319,22 +208,22 @@ }, "urllib3": { "hashes": [ - "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", - "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.1.0" + "version": "==2.2.1" } }, "develop": { "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -437,86 +326,86 @@ "toml" ], "hashes": [ - "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", - "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", - "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a", - "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058", - "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85", - "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143", - "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446", - "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590", - "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a", - "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105", - "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9", - "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a", - "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac", - "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25", - "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2", - "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450", - "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932", - "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba", - "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137", - "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae", - "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614", - "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70", - "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e", - "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505", - "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870", - "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc", - "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451", - "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7", - "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e", - "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566", - "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5", - "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26", - "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2", - "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42", - "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555", - "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43", - "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed", - "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa", - "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516", - "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952", - "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd", - "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09", - "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c", - "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f", - "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6", - "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1", - "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0", - "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e", - "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9", - "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9", - "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e", - "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06" + "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523", + "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f", + "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d", + "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb", + "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0", + "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c", + "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98", + "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83", + "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8", + "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7", + "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac", + "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84", + "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb", + "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3", + "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884", + "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614", + "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd", + "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807", + "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd", + "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8", + "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc", + "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db", + "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0", + "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08", + "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232", + "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d", + "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a", + "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1", + "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286", + "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303", + "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341", + "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84", + "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45", + "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc", + "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec", + "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd", + "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155", + "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52", + "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d", + "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485", + "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31", + "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d", + "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d", + "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d", + "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85", + "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce", + "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb", + "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974", + "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24", + "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56", + "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9", + "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==7.4.0" + "version": "==7.5.3" }, "docutils": { "hashes": [ - "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6", - "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b" + "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", + "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2" ], - "markers": "python_version >= '3.7'", - "version": "==0.20.1" + "markers": "python_version >= '3.9'", + "version": "==0.21.2" }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "importlib-metadata": { "hashes": [ - "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", - "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" + "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2" ], "markers": "python_version >= '3.8'", - "version": "==7.0.1" + "version": "==7.1.0" }, "iniconfig": { "hashes": [ @@ -528,19 +417,35 @@ }, "jaraco.classes": { "hashes": [ - "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb", - "sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621" + "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" ], "markers": "python_version >= '3.8'", - "version": "==3.3.0" + "version": "==3.4.0" + }, + "jaraco.context": { + "hashes": [ + "sha256:3e16388f7da43d384a1a7cd3452e72e14732ac9fe459678773a3608a812bf266", + "sha256:c2f67165ce1f9be20f32f650f25d8edfc1646a8aeee48ae06fb35f90763576d2" + ], + "markers": "python_version >= '3.8'", + "version": "==5.3.0" + }, + "jaraco.functools": { + "hashes": [ + "sha256:3b24ccb921d6b593bdceb56ce14799204f473976e2a9d4b15b04d0f2c2326664", + "sha256:d33fa765374c0611b52f8b3a795f8900869aa88c84769d4d1746cd68fb28c3e8" + ], + "markers": "python_version >= '3.8'", + "version": "==4.0.1" }, "keyring": { "hashes": [ - "sha256:4446d35d636e6a10b8bce7caa66913dd9eca5fd222ca03a3d42c38608ac30836", - "sha256:e730ecffd309658a08ee82535a3b5ec4b4c8669a9be11efb66249d8e0aeb9a25" + "sha256:2458681cdefc0dbc0b7eb6cf75d0b98e59f9ad9b2d4edd319d18f68bdca95e50", + "sha256:daaffd42dbda25ddafb1ad5fec4024e5bbcfe424597ca1ca452b299861e49f1b" ], "markers": "python_version >= '3.8'", - "version": "==24.3.0" + "version": "==25.2.1" }, "markdown-it-py": { "hashes": [ @@ -560,99 +465,99 @@ }, "more-itertools": { "hashes": [ - "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a", - "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6" + "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1" ], "markers": "python_version >= '3.8'", - "version": "==10.1.0" + "version": "==10.2.0" }, "nh3": { "hashes": [ - "sha256:0d02d0ff79dfd8208ed25a39c12cbda092388fff7f1662466e27d97ad011b770", - "sha256:3277481293b868b2715907310c7be0f1b9d10491d5adf9fce11756a97e97eddf", - "sha256:3b803a5875e7234907f7d64777dfde2b93db992376f3d6d7af7f3bc347deb305", - "sha256:427fecbb1031db085eaac9931362adf4a796428ef0163070c484b5a768e71601", - "sha256:5f0d77272ce6d34db6c87b4f894f037d55183d9518f948bba236fe81e2bb4e28", - "sha256:60684857cfa8fdbb74daa867e5cad3f0c9789415aba660614fe16cd66cbb9ec7", - "sha256:6f42f99f0cf6312e470b6c09e04da31f9abaadcd3eb591d7d1a88ea931dca7f3", - "sha256:86e447a63ca0b16318deb62498db4f76fc60699ce0a1231262880b38b6cff911", - "sha256:8d595df02413aa38586c24811237e95937ef18304e108b7e92c890a06793e3bf", - "sha256:9c0d415f6b7f2338f93035bba5c0d8c1b464e538bfbb1d598acd47d7969284f0", - "sha256:a5167a6403d19c515217b6bcaaa9be420974a6ac30e0da9e84d4fc67a5d474c5", - "sha256:ac19c0d68cd42ecd7ead91a3a032fdfff23d29302dbb1311e641a130dfefba97", - "sha256:b1e97221cedaf15a54f5243f2c5894bb12ca951ae4ddfd02a9d4ea9df9e1a29d", - "sha256:bc2d086fb540d0fa52ce35afaded4ea526b8fc4d3339f783db55c95de40ef02e", - "sha256:d1e30ff2d8d58fb2a14961f7aac1bbb1c51f9bdd7da727be35c63826060b0bf3", - "sha256:f3b53ba93bb7725acab1e030bc2ecd012a817040fd7851b332f86e2f9bb98dc6" - ], - "version": "==0.2.15" + "sha256:0316c25b76289cf23be6b66c77d3608a4fdf537b35426280032f432f14291b9a", + "sha256:1a814dd7bba1cb0aba5bcb9bebcc88fd801b63e21e2450ae6c52d3b3336bc911", + "sha256:1aa52a7def528297f256de0844e8dd680ee279e79583c76d6fa73a978186ddfb", + "sha256:22c26e20acbb253a5bdd33d432a326d18508a910e4dcf9a3316179860d53345a", + "sha256:40015514022af31975c0b3bca4014634fa13cb5dc4dbcbc00570acc781316dcc", + "sha256:40d0741a19c3d645e54efba71cb0d8c475b59135c1e3c580f879ad5514cbf028", + "sha256:551672fd71d06cd828e282abdb810d1be24e1abb7ae2543a8fa36a71c1006fe9", + "sha256:66f17d78826096291bd264f260213d2b3905e3c7fae6dfc5337d49429f1dc9f3", + "sha256:85cdbcca8ef10733bd31f931956f7fbb85145a4d11ab9e6742bbf44d88b7e351", + "sha256:a3f55fabe29164ba6026b5ad5c3151c314d136fd67415a17660b4aaddacf1b10", + "sha256:b4427ef0d2dfdec10b641ed0bdaf17957eb625b2ec0ea9329b3d28806c153d71", + "sha256:ba73a2f8d3a1b966e9cdba7b211779ad8a2561d2dba9674b8a19ed817923f65f", + "sha256:c21bac1a7245cbd88c0b0e4a420221b7bfa838a2814ee5bb924e9c2f10a1120b", + "sha256:c551eb2a3876e8ff2ac63dff1585236ed5dfec5ffd82216a7a174f7c5082a78a", + "sha256:c790769152308421283679a142dbdb3d1c46c79c823008ecea8e8141db1a2062", + "sha256:d7a25fd8c86657f5d9d576268e3b3767c5cd4f42867c9383618be8517f0f022a" + ], + "version": "==0.2.17" }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "pkginfo": { "hashes": [ - "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546", - "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046" + "sha256:6d4998d1cd42c297af72cc0eab5f5bab1d356fb8a55b828fa914173f8bc1ba05", + "sha256:dba885aa82e31e80d615119874384923f4e011c2a39b0c4b7104359e36cb7087" ], - "markers": "python_version >= '3.6'", - "version": "==1.9.6" + "markers": "python_version >= '3.8'", + "version": "==1.11.0" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.5.0" }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.8'", + "version": "==2.18.0" }, "pytest": { "hashes": [ - "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", - "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" + "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd", + "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==7.4.4" + "markers": "python_version >= '3.8'", + "version": "==8.2.1" }, "pytest-cov": { "hashes": [ - "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", - "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" + "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", + "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==4.1.0" + "markers": "python_version >= '3.8'", + "version": "==5.0.0" }, "readme-renderer": { "hashes": [ - "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d", - "sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1" + "sha256:1818dd28140813509eeed8d62687f7cd4f7bad90d4db586001c5dc09d4fde311", + "sha256:19db308d86ecd60e5affa3b2a98f017af384678c63c88e5d4556a380e674f3f9" ], "markers": "python_version >= '3.8'", - "version": "==42.0" + "version": "==43.0" }, "requests": { "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.31.0" + "markers": "python_version >= '3.8'", + "version": "==2.32.3" }, "requests-toolbelt": { "hashes": [ @@ -672,37 +577,37 @@ }, "rich": { "hashes": [ - "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", - "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" + "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", + "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432" ], "markers": "python_full_version >= '3.7.0'", - "version": "==13.7.0" + "version": "==13.7.1" }, "twine": { "hashes": [ - "sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8", - "sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8" + "sha256:4d74770c88c4fcaf8134d2a6a9d863e40f08255ff7d8e2acb3cbbd57d25f6e9d", + "sha256:fe1d814395bfe50cfbe27783cb74efe93abeac3f66deaeb6c8390e4e92bacb43" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==4.0.2" + "markers": "python_version >= '3.8'", + "version": "==5.1.0" }, "urllib3": { "hashes": [ - "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", - "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.1.0" + "version": "==2.2.1" }, "zipp": { "hashes": [ - "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", - "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091", + "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f" ], "markers": "python_version >= '3.8'", - "version": "==3.17.0" + "version": "==3.19.1" } } } diff --git a/quickbooks/client.py b/quickbooks/client.py index 7a075786..23b057a3 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -1,14 +1,16 @@ import http.client as httplib import textwrap -import simplejson as json +import json import base64 import hashlib import hmac +import decimal from . import exceptions from requests_oauthlib import OAuth2Session -to_bytes = lambda value, *args, **kwargs: bytes(value, "utf-8", *args, **kwargs) +def to_bytes(value, *args, **kwargs): + return bytes(value, "utf-8", *args, **kwargs) class Environments(object): @@ -206,7 +208,7 @@ def make_request(self, request_type, url, request_body=None, content_type='appli "Application authentication failed", error_code=req.status_code, detail=req.text) try: - result = json.loads(req.text, use_decimal=True) + result = json.loads(req.text, parse_float=decimal.Decimal) except: raise exceptions.QuickbooksException("Error reading json response: {0}".format(req.text), 10000) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 6b0a1beb..e5a860ff 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -1,14 +1,20 @@ +import decimal +import json from urllib.parse import quote -import simplejson as json - -from .utils import build_where_clause, build_choose_clause from .client import QuickBooks from .exceptions import QuickbooksException +from .utils import build_choose_clause, build_where_clause + +class DecimalEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, decimal.Decimal): + return str(obj) + return super(DecimalEncoder, self).default(obj) class ToJsonMixin(object): def to_json(self): - return json.dumps(self, default=self.json_filter(), sort_keys=True, indent=4, use_decimal=True) + return json.dumps(self, cls=DecimalEncoder, default=self.json_filter(), sort_keys=True, indent=4) def json_filter(self): """ @@ -176,7 +182,7 @@ def void(self, qb=None): data = self.get_void_data() params = self.get_void_params() - results = qb.post(url, json.dumps(data, use_decimal=True), params=params) + results = qb.post(url, json.dumps(data, cls=DecimalEncoder), params=params) return results @@ -230,7 +236,7 @@ def delete(self, qb=None, request_id=None): 'Id': self.Id, 'SyncToken': self.SyncToken, } - return qb.delete_object(self.qbo_object_name, json.dumps(data, use_decimal=True), request_id=request_id) + return qb.delete_object(self.qbo_object_name, json.dumps(data, cls=DecimalEncoder), request_id=request_id) class DeleteNoIdMixin(object): diff --git a/requirements.txt b/requirements.txt index 2f1d93f7..d67d7f66 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ intuit-oauth==1.2.4 requests_oauthlib>=1.3.1 -requests>=2.31.0 -simplejson>=3.19.1 \ No newline at end of file +requests>=2.31.0 \ No newline at end of file diff --git a/setup.py b/setup.py index e0b4c70c..046aa758 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,6 @@ def read(*parts): 'intuit-oauth==1.2.5', 'requests_oauthlib>=1.3.1', 'requests>=2.31.0', - 'simplejson>=3.19.1', 'python-dateutil', ], From 4158e8b08e63eda2cea025d83c8682d08b0a93aa Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sat, 1 Jun 2024 12:10:18 -0700 Subject: [PATCH 124/154] Updated test Put the decode on the test, removed the name for clarity --- tests/unit/test_client.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index c0b0ab07..a606d0ea 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,4 +1,4 @@ -import simplejson as json +import json from tests.integration.test_base import QuickbooksUnitTestCase try: @@ -7,7 +7,7 @@ from unittest.mock import patch, mock_open from quickbooks.exceptions import QuickbooksException, SevereException, AuthorizationException -from quickbooks import client +from quickbooks import client, mixins from quickbooks.objects.salesreceipt import SalesReceipt @@ -142,7 +142,7 @@ def test_get_single_object(self, make_req): @patch('quickbooks.client.QuickBooks.process_request') def test_make_request(self, process_request): - process_request.return_value = MockResponseSimpleJson() + process_request.return_value = MockResponseJson() qb_client = client.QuickBooks() qb_client.company_id = "1234" @@ -221,7 +221,7 @@ def test_download_pdf_not_authorized(self, process_request): @patch('quickbooks.client.QuickBooks.process_request') def test_make_request_file_closed(self, process_request): file_path = '/path/to/file.txt' - process_request.return_value = MockResponseSimpleJson() + process_request.return_value = MockResponseJson() with patch('builtins.open', mock_open(read_data=b'file content')) as mock_file: qb_client = client.QuickBooks(auth_client=self.auth_client) qb_client.make_request('POST', @@ -254,14 +254,14 @@ def json(self): def content(self): return '' -class MockResponseSimpleJson: +class MockResponseJson: def __init__(self, json_data=None, status_code=200): self.json_data = json_data or {} self.status_code = status_code @property def text(self): - return json.dumps(self.json_data) # Ensure this uses simplejson if necessary + return json.dumps(self.json_data, cls=mixins.DecimalEncoder) def json(self): return self.json_data From 031831ea5700f9c90ac359c138c03d0f4aca5b3e Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sat, 1 Jun 2024 12:25:11 -0700 Subject: [PATCH 125/154] Created use_decimal flag on client creation https://github.com/ej2/python-quickbooks/pull/358#issuecomment-2143554544 --- quickbooks/client.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index 23b057a3..0566ddb6 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -26,6 +26,7 @@ class QuickBooks(object): minorversion = None verifier_token = None invoice_link = False + use_decimal = False sandbox_api_url_v3 = "https://sandbox-quickbooks.api.intuit.com/v3" api_url_v3 = "https://quickbooks.api.intuit.com/v3" @@ -81,6 +82,9 @@ def __new__(cls, **kwargs): if 'verifier_token' in kwargs: instance.verifier_token = kwargs.get('verifier_token') + if 'use_decimal' in kwargs: + instance.use_decimal = kwargs.get('use_decimal') + return instance def _start_session(self): @@ -208,7 +212,10 @@ def make_request(self, request_type, url, request_body=None, content_type='appli "Application authentication failed", error_code=req.status_code, detail=req.text) try: - result = json.loads(req.text, parse_float=decimal.Decimal) + if (self.use_decimal): + result = json.loads(req.text, parse_float=decimal.Decimal) + else: + result = json.loads(req.text) except: raise exceptions.QuickbooksException("Error reading json response: {0}".format(req.text), 10000) From 39e56d2c48b05f0076abd50f07e7dfcabb9ab5a5 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 9 Jul 2024 10:35:40 -0500 Subject: [PATCH 126/154] Fix tests --- tests/integration/test_account.py | 5 +++-- tests/integration/test_attachable.py | 13 ++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/integration/test_account.py b/tests/integration/test_account.py index 78d5b46f..b90c953d 100644 --- a/tests/integration/test_account.py +++ b/tests/integration/test_account.py @@ -7,6 +7,7 @@ class AccountTest(QuickbooksTestCase): def setUp(self): super(AccountTest, self).setUp() + self.time = datetime.now() self.account_number = datetime.now().strftime('%d%H%M') self.name = "Test Account {0}".format(self.account_number) @@ -35,8 +36,8 @@ def test_update(self): def test_create_using_from_json(self): account = Account.from_json({ - "AcctNum": self.account_number, - "Name": self.name, + "AcctNum": datetime.now().strftime('%d%H%M%S'), + "Name": "{} {}".format(self.name, self.time.strftime("%Y-%m-%d %H:%M:%S")), "AccountSubType": "CashOnHand" }) diff --git a/tests/integration/test_attachable.py b/tests/integration/test_attachable.py index eec05931..2eeffabd 100644 --- a/tests/integration/test_attachable.py +++ b/tests/integration/test_attachable.py @@ -41,7 +41,11 @@ def test_update_note(self): def test_create_file(self): attachable = Attachable() - test_file = tempfile.NamedTemporaryFile(suffix=".txt") + test_file = tempfile.NamedTemporaryFile(mode='w+t', suffix=".txt", delete=False) + + with test_file as f: + f.write("File contents") + f.flush() vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] @@ -49,12 +53,19 @@ def test_create_file(self): attachable_ref.EntityRef = vendor.to_ref() attachable.AttachableRef.append(attachable_ref) + attachable.Note = "Sample note" attachable.FileName = os.path.basename(test_file.name) attachable._FilePath = test_file.name attachable.ContentType = 'text/plain' attachable.save(qb=self.qb_client) + test_file.close() + os.unlink(test_file.name) + query_attachable = Attachable.get(attachable.Id, qb=self.qb_client) self.assertEqual(query_attachable.AttachableRef[0].EntityRef.value, vendor.Id) + self.assertEqual(query_attachable.Note, "Sample note") + + From 223c5fcacddb0386d3405255fa970d3f172c24a2 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 9 Jul 2024 10:53:43 -0500 Subject: [PATCH 127/154] Update CHANGELOG --- CHANGELOG.rst | 5 +- Pipfile.lock | 221 +++++++++++++++++++++++++------------------------- 2 files changed, 114 insertions(+), 112 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4818f498..c3b59f79 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,11 @@ Changelog ========= -* 0.9.7 (May 20, 2024) + +* 0.9.8 (July 9, 2024) * Added ItemAccountRef to SalesItemLineDetail * Updated from_json example in readme + * Removed simplejson + * Added use_decimal option (See PR: https://github.com/ej2/python-quickbooks/pull/356 for details) * 0.9.7 (March 12, 2024) * Update intuit-oauth dependency diff --git a/Pipfile.lock b/Pipfile.lock index b95a5125..9e8ef697 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -16,11 +16,11 @@ "default": { "certifi": { "hashes": [ - "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", - "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" + "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", + "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" ], "markers": "python_version >= '3.6'", - "version": "==2024.2.2" + "version": "==2024.7.4" }, "charset-normalizer": { "hashes": [ @@ -186,7 +186,6 @@ "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9" ], - "index": "pypi", "markers": "python_version >= '3.4'", "version": "==2.0.0" }, @@ -208,22 +207,22 @@ }, "urllib3": { "hashes": [ - "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", - "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" + "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", + "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.2.1" + "version": "==2.2.2" } }, "develop": { "certifi": { "hashes": [ - "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", - "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" + "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", + "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" ], "markers": "python_version >= '3.6'", - "version": "==2024.2.2" + "version": "==2024.7.4" }, "charset-normalizer": { "hashes": [ @@ -326,62 +325,62 @@ "toml" ], "hashes": [ - "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523", - "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f", - "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d", - "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb", - "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0", - "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c", - "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98", - "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83", - "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8", - "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7", - "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac", - "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84", - "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb", - "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3", - "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884", - "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614", - "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd", - "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807", - "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd", - "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8", - "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc", - "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db", - "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0", - "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08", - "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232", - "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d", - "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a", - "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1", - "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286", - "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303", - "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341", - "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84", - "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45", - "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc", - "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec", - "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd", - "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155", - "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52", - "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d", - "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485", - "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31", - "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d", - "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d", - "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d", - "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85", - "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce", - "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb", - "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974", - "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24", - "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56", - "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9", - "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35" + "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f", + "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d", + "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747", + "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f", + "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d", + "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f", + "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47", + "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e", + "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba", + "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c", + "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b", + "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4", + "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7", + "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555", + "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233", + "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace", + "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805", + "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136", + "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4", + "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d", + "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806", + "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99", + "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8", + "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b", + "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5", + "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da", + "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0", + "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078", + "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f", + "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029", + "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353", + "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638", + "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9", + "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f", + "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7", + "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3", + "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e", + "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016", + "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088", + "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4", + "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882", + "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7", + "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53", + "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d", + "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080", + "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5", + "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d", + "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c", + "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8", + "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633", + "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9", + "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==7.5.3" + "version": "==7.5.4" }, "docutils": { "hashes": [ @@ -401,11 +400,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", - "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2" + "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f", + "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812" ], "markers": "python_version >= '3.8'", - "version": "==7.1.0" + "version": "==8.0.0" }, "iniconfig": { "hashes": [ @@ -465,48 +464,48 @@ }, "more-itertools": { "hashes": [ - "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", - "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1" + "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463", + "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320" ], "markers": "python_version >= '3.8'", - "version": "==10.2.0" + "version": "==10.3.0" }, "nh3": { "hashes": [ - "sha256:0316c25b76289cf23be6b66c77d3608a4fdf537b35426280032f432f14291b9a", - "sha256:1a814dd7bba1cb0aba5bcb9bebcc88fd801b63e21e2450ae6c52d3b3336bc911", - "sha256:1aa52a7def528297f256de0844e8dd680ee279e79583c76d6fa73a978186ddfb", - "sha256:22c26e20acbb253a5bdd33d432a326d18508a910e4dcf9a3316179860d53345a", - "sha256:40015514022af31975c0b3bca4014634fa13cb5dc4dbcbc00570acc781316dcc", - "sha256:40d0741a19c3d645e54efba71cb0d8c475b59135c1e3c580f879ad5514cbf028", - "sha256:551672fd71d06cd828e282abdb810d1be24e1abb7ae2543a8fa36a71c1006fe9", - "sha256:66f17d78826096291bd264f260213d2b3905e3c7fae6dfc5337d49429f1dc9f3", - "sha256:85cdbcca8ef10733bd31f931956f7fbb85145a4d11ab9e6742bbf44d88b7e351", - "sha256:a3f55fabe29164ba6026b5ad5c3151c314d136fd67415a17660b4aaddacf1b10", - "sha256:b4427ef0d2dfdec10b641ed0bdaf17957eb625b2ec0ea9329b3d28806c153d71", - "sha256:ba73a2f8d3a1b966e9cdba7b211779ad8a2561d2dba9674b8a19ed817923f65f", - "sha256:c21bac1a7245cbd88c0b0e4a420221b7bfa838a2814ee5bb924e9c2f10a1120b", - "sha256:c551eb2a3876e8ff2ac63dff1585236ed5dfec5ffd82216a7a174f7c5082a78a", - "sha256:c790769152308421283679a142dbdb3d1c46c79c823008ecea8e8141db1a2062", - "sha256:d7a25fd8c86657f5d9d576268e3b3767c5cd4f42867c9383618be8517f0f022a" - ], - "version": "==0.2.17" + "sha256:0411beb0589eacb6734f28d5497ca2ed379eafab8ad8c84b31bb5c34072b7164", + "sha256:14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86", + "sha256:19aaba96e0f795bd0a6c56291495ff59364f4300d4a39b29a0abc9cb3774a84b", + "sha256:34c03fa78e328c691f982b7c03d4423bdfd7da69cd707fe572f544cf74ac23ad", + "sha256:36c95d4b70530b320b365659bb5034341316e6a9b30f0b25fa9c9eff4c27a204", + "sha256:3a157ab149e591bb638a55c8c6bcb8cdb559c8b12c13a8affaba6cedfe51713a", + "sha256:42c64511469005058cd17cc1537578eac40ae9f7200bedcfd1fc1a05f4f8c200", + "sha256:5f36b271dae35c465ef5e9090e1fdaba4a60a56f0bb0ba03e0932a66f28b9189", + "sha256:6955369e4d9f48f41e3f238a9e60f9410645db7e07435e62c6a9ea6135a4907f", + "sha256:7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811", + "sha256:8ce0f819d2f1933953fca255db2471ad58184a60508f03e6285e5114b6254844", + "sha256:94a166927e53972a9698af9542ace4e38b9de50c34352b962f4d9a7d4c927af4", + "sha256:a7f1b5b2c15866f2db413a3649a8fe4fd7b428ae58be2c0f6bca5eefd53ca2be", + "sha256:c8b3a1cebcba9b3669ed1a84cc65bf005728d2f0bc1ed2a6594a992e817f3a50", + "sha256:de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307", + "sha256:f0eca9ca8628dbb4e916ae2491d72957fdd35f7a5d326b7032a345f111ac07fe" + ], + "version": "==0.2.18" }, "packaging": { "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", + "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" ], - "markers": "python_version >= '3.7'", - "version": "==24.0" + "markers": "python_version >= '3.8'", + "version": "==24.1" }, "pkginfo": { "hashes": [ - "sha256:6d4998d1cd42c297af72cc0eab5f5bab1d356fb8a55b828fa914173f8bc1ba05", - "sha256:dba885aa82e31e80d615119874384923f4e011c2a39b0c4b7104359e36cb7087" + "sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297", + "sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097" ], - "markers": "python_version >= '3.8'", - "version": "==1.11.0" + "markers": "python_version >= '3.6'", + "version": "==1.10.0" }, "pluggy": { "hashes": [ @@ -526,12 +525,12 @@ }, "pytest": { "hashes": [ - "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd", - "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1" + "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343", + "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.2.1" + "version": "==8.2.2" }, "pytest-cov": { "hashes": [ @@ -544,11 +543,11 @@ }, "readme-renderer": { "hashes": [ - "sha256:1818dd28140813509eeed8d62687f7cd4f7bad90d4db586001c5dc09d4fde311", - "sha256:19db308d86ecd60e5affa3b2a98f017af384678c63c88e5d4556a380e674f3f9" + "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", + "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1" ], - "markers": "python_version >= '3.8'", - "version": "==43.0" + "markers": "python_version >= '3.9'", + "version": "==44.0" }, "requests": { "hashes": [ @@ -585,29 +584,29 @@ }, "twine": { "hashes": [ - "sha256:4d74770c88c4fcaf8134d2a6a9d863e40f08255ff7d8e2acb3cbbd57d25f6e9d", - "sha256:fe1d814395bfe50cfbe27783cb74efe93abeac3f66deaeb6c8390e4e92bacb43" + "sha256:215dbe7b4b94c2c50a7315c0275d2258399280fbb7d04182c7e55e24b5f93997", + "sha256:9aa0825139c02b3434d913545c7b847a21c835e11597f5255842d457da2322db" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.1.0" + "version": "==5.1.1" }, "urllib3": { "hashes": [ - "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", - "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" + "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", + "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.2.1" + "version": "==2.2.2" }, "zipp": { "hashes": [ - "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091", - "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f" + "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19", + "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c" ], "markers": "python_version >= '3.8'", - "version": "==3.19.1" + "version": "==3.19.2" } } } From 6943dec863d9a581efd78c0d18a42d81d45ead6c Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 9 Jul 2024 11:05:07 -0500 Subject: [PATCH 128/154] 0.9.9 release update --- CHANGELOG.rst | 8 +++++--- Pipfile | 1 + Pipfile.lock | 11 ++++++++++- setup.py | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c3b59f79..8c40d982 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,12 +1,14 @@ Changelog ========= -* 0.9.8 (July 9, 2024) - * Added ItemAccountRef to SalesItemLineDetail - * Updated from_json example in readme +* 0.9.9 (July 9, 2024) * Removed simplejson * Added use_decimal option (See PR: https://github.com/ej2/python-quickbooks/pull/356 for details) +* 0.9.8 (May 20, 2024) + * Added ItemAccountRef to SalesItemLineDetail + * Updated from_json example in readme + * 0.9.7 (March 12, 2024) * Update intuit-oauth dependency * Updated CompanyCurrency to ref to use Code instead of Id diff --git a/Pipfile b/Pipfile index ab07e83a..3cd83217 100644 --- a/Pipfile +++ b/Pipfile @@ -14,3 +14,4 @@ urllib3 = ">=2.1.0" intuit-oauth = "==1.2.5" requests = ">=2.31.0" requests_oauthlib = ">=1.3.1" +setuptools = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 9e8ef697..02590442 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e25e6a93ea424fe54edd3dbdbd0eed5c76b49764b8e64cdb4c70d271932331f0" + "sha256": "6a78c31b140898b03234b1dc6ab067544c9588f797604f80a23e274afe08f875" }, "pipfile-spec": 6, "requires": {}, @@ -197,6 +197,15 @@ "markers": "python_version >= '3.6' and python_version < '4'", "version": "==4.9" }, + "setuptools": { + "hashes": [ + "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05", + "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==70.2.0" + }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", diff --git a/setup.py b/setup.py index b7800e0c..1b4c1c57 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 8) +VERSION = (0, 9, 9) version = '.'.join(map(str, VERSION)) setup( From f4e766145e425baa9aec00285d8bc815a9b7ec82 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 7 Aug 2024 11:21:05 -0500 Subject: [PATCH 129/154] Fix issue with invoice sharable link --- Pipfile | 2 +- Pipfile.lock | 303 ++++++++++++++++++++--------- README.md | 16 +- quickbooks/client.py | 7 +- quickbooks/mixins.py | 4 +- tests/integration/test_base.py | 2 +- tests/integration/test_invoice.py | 46 ++++- tests/unit/objects/test_invoice.py | 1 - 8 files changed, 268 insertions(+), 113 deletions(-) diff --git a/Pipfile b/Pipfile index 3cd83217..31d70a4f 100644 --- a/Pipfile +++ b/Pipfile @@ -11,7 +11,7 @@ pytest-cov = "*" [packages] urllib3 = ">=2.1.0" -intuit-oauth = "==1.2.5" +intuit-oauth = "==1.2.6" requests = ">=2.31.0" requests_oauthlib = ">=1.3.1" setuptools = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 02590442..1f088af2 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "6a78c31b140898b03234b1dc6ab067544c9588f797604f80a23e274afe08f875" + "sha256": "ac47337a60c459de39be3440865879adc5be2217a477fbec6374e69659297513" }, "pipfile-spec": 6, "requires": {}, @@ -22,6 +22,79 @@ "markers": "python_version >= '3.6'", "version": "==2024.7.4" }, + "cffi": { + "hashes": [ + "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f", + "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab", + "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499", + "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058", + "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693", + "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb", + "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377", + "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885", + "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2", + "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401", + "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4", + "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b", + "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59", + "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f", + "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c", + "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555", + "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa", + "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424", + "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb", + "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2", + "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8", + "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e", + "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9", + "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82", + "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828", + "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759", + "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc", + "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118", + "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf", + "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932", + "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a", + "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29", + "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206", + "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2", + "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c", + "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c", + "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0", + "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a", + "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195", + "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6", + "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9", + "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc", + "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb", + "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0", + "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7", + "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb", + "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a", + "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492", + "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720", + "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42", + "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7", + "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d", + "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d", + "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb", + "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4", + "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2", + "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b", + "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8", + "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e", + "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204", + "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3", + "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150", + "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4", + "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76", + "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e", + "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb", + "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91" + ], + "markers": "platform_python_implementation != 'PyPy'", + "version": "==1.17.0" + }, "charset-normalizer": { "hashes": [ "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", @@ -118,13 +191,37 @@ "markers": "python_full_version >= '3.7.0'", "version": "==3.3.2" }, - "ecdsa": { - "hashes": [ - "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a", - "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.19.0" + "cryptography": { + "hashes": [ + "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709", + "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069", + "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2", + "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b", + "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e", + "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70", + "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778", + "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22", + "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895", + "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf", + "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431", + "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f", + "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947", + "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74", + "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc", + "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66", + "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66", + "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf", + "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f", + "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5", + "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e", + "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f", + "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55", + "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1", + "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47", + "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5", + "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0" + ], + "version": "==43.0.0" }, "enum-compat": { "hashes": [ @@ -143,11 +240,11 @@ }, "intuit-oauth": { "hashes": [ - "sha256:1c3d53468c00590485dc3b040d5d18389060573c616a26e33a03c1b164c92823", - "sha256:74af897366c0fb984a6179ef3200bb10c0ed194760e7daf92c8b0927e856a022" + "sha256:4c25b3fcbdb5aaaa65dcc8f0f71e8f8400dcaa4dcdac58b8333d5f1b11a8f82d", + "sha256:b93439e8135d536acdbe53cf9842930ade2205410c6ab3530fb1dbea12eee5d0" ], "index": "pypi", - "version": "==1.2.5" + "version": "==1.2.6" }, "oauthlib": { "hashes": [ @@ -157,20 +254,24 @@ "markers": "python_version >= '3.6'", "version": "==3.2.2" }, - "pyasn1": { + "pycparser": { "hashes": [ - "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c", - "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473" + "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" ], "markers": "python_version >= '3.8'", - "version": "==0.6.0" + "version": "==2.22" }, - "python-jose": { + "pyjwt": { + "extras": [ + "crypto" + ], "hashes": [ - "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", - "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a" + "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850", + "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c" ], - "version": "==3.3.0" + "markers": "python_version >= '3.8'", + "version": "==2.9.0" }, "requests": { "hashes": [ @@ -189,22 +290,14 @@ "markers": "python_version >= '3.4'", "version": "==2.0.0" }, - "rsa": { - "hashes": [ - "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", - "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" - ], - "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==4.9" - }, "setuptools": { "hashes": [ - "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05", - "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1" + "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1", + "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==70.2.0" + "version": "==72.1.0" }, "six": { "hashes": [ @@ -334,62 +427,82 @@ "toml" ], "hashes": [ - "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f", - "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d", - "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747", - "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f", - "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d", - "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f", - "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47", - "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e", - "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba", - "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c", - "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b", - "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4", - "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7", - "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555", - "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233", - "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace", - "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805", - "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136", - "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4", - "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d", - "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806", - "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99", - "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8", - "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b", - "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5", - "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da", - "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0", - "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078", - "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f", - "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029", - "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353", - "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638", - "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9", - "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f", - "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7", - "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3", - "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e", - "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016", - "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088", - "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4", - "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882", - "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7", - "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53", - "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d", - "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080", - "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5", - "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d", - "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c", - "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8", - "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633", - "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9", - "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c" + "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca", + "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", + "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", + "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989", + "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", + "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", + "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", + "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", + "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", + "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", + "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", + "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb", + "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", + "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", + "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", + "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8", + "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", + "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", + "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", + "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8", + "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", + "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc", + "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2", + "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", + "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", + "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0", + "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c", + "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", + "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004", + "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", + "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", + "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", + "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", + "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", + "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de", + "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", + "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", + "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569", + "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", + "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", + "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", + "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36", + "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a", + "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6", + "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", + "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", + "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", + "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", + "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", + "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b", + "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255", + "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", + "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3", + "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", + "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", + "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", + "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", + "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", + "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", + "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", + "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", + "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", + "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7", + "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", + "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", + "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", + "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", + "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", + "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a", + "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", + "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", + "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==7.5.4" + "version": "==7.6.1" }, "docutils": { "hashes": [ @@ -409,11 +522,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f", - "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812" + "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369", + "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d" ], "markers": "python_version >= '3.8'", - "version": "==8.0.0" + "version": "==8.2.0" }, "iniconfig": { "hashes": [ @@ -441,19 +554,19 @@ }, "jaraco.functools": { "hashes": [ - "sha256:3b24ccb921d6b593bdceb56ce14799204f473976e2a9d4b15b04d0f2c2326664", - "sha256:d33fa765374c0611b52f8b3a795f8900869aa88c84769d4d1746cd68fb28c3e8" + "sha256:3460c74cd0d32bf82b9576bbb3527c4364d5b27a21f5158a62aed6c4b42e23f5", + "sha256:c9d16a3ed4ccb5a889ad8e0b7a343401ee5b2a71cee6ed192d3f68bc351e94e3" ], "markers": "python_version >= '3.8'", - "version": "==4.0.1" + "version": "==4.0.2" }, "keyring": { "hashes": [ - "sha256:2458681cdefc0dbc0b7eb6cf75d0b98e59f9ad9b2d4edd319d18f68bdca95e50", - "sha256:daaffd42dbda25ddafb1ad5fec4024e5bbcfe424597ca1ca452b299861e49f1b" + "sha256:8d85a1ea5d6db8515b59e1c5d1d1678b03cf7fc8b8dcfb1651e8c4a524eb42ef", + "sha256:8d963da00ccdf06e356acd9bf3b743208878751032d8599c6cc89eb51310ffae" ], "markers": "python_version >= '3.8'", - "version": "==25.2.1" + "version": "==25.3.0" }, "markdown-it-py": { "hashes": [ @@ -534,12 +647,12 @@ }, "pytest": { "hashes": [ - "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343", - "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977" + "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", + "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.2.2" + "version": "==8.3.2" }, "pytest-cov": { "hashes": [ diff --git a/README.md b/README.md index 45a2293c..fb517d98 100644 --- a/README.md +++ b/README.md @@ -252,15 +252,23 @@ One example is `include=allowduplicatedocnum` on the Purchase object. You can ad purchase.save(qb=self.qb_client, params={'include': 'allowduplicatedocnum'}) -Other operations +Sharable Invoice Link ---------------- -Add Sharable link for an invoice sent to external customers (minorversion must be set to 36 or greater): +To add a sharable link for an invoice, make sure the AllowOnlineCreditCardPayment is set to True and BillEmail is set to a invalid email address: - invoice.invoice_link = true + invoice.AllowOnlineCreditCardPayment = True + invoice.BillEmail = EmailAddress() + invoice.BillEmail.Address = 'test@email.com' +When you query the invoice include the following params (minorversion must be set to 36 or greater): -Void an invoice: + invoice = Invoice.get(id, qb=self.qb_client, params={'include': 'invoiceLink'}) + +Void an invoice +---------------- +Call `void` on any invoice with an Id: + invoice = Invoice() invoice.Id = 7 invoice.void(qb=client) diff --git a/quickbooks/client.py b/quickbooks/client.py index 0566ddb6..df88d375 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -155,9 +155,6 @@ def make_request(self, request_type, url, request_body=None, content_type='appli if request_id: params['requestid'] = request_id - if self.invoice_link: - params['include'] = 'invoiceLink' - if not request_body: request_body = {} @@ -242,9 +239,9 @@ def process_request(self, request_type, url, headers="", params="", data=""): return self.session.request( request_type, url, headers=headers, params=params, data=data) - def get_single_object(self, qbbo, pk): + def get_single_object(self, qbbo, pk, params=None): url = "{0}/company/{1}/{2}/{3}/".format(self.api_url, self.company_id, qbbo.lower(), pk) - result = self.get(url, {}) + result = self.get(url, {}, params=params) return result diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index e5a860ff..c3b60d96 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -94,11 +94,11 @@ class ReadMixin(object): qbo_json_object_name = "" @classmethod - def get(cls, id, qb=None): + def get(cls, id, qb=None, params=None): if not qb: qb = QuickBooks() - json_data = qb.get_single_object(cls.qbo_object_name, pk=id) + json_data = qb.get_single_object(cls.qbo_object_name, pk=id, params=params) if cls.qbo_json_object_name != '': return cls.from_json(json_data[cls.qbo_json_object_name]) diff --git a/tests/integration/test_base.py b/tests/integration/test_base.py index 8b386af4..404d6a4f 100644 --- a/tests/integration/test_base.py +++ b/tests/integration/test_base.py @@ -17,7 +17,7 @@ def setUp(self): ) self.qb_client = QuickBooks( - minorversion=69, + minorversion=73, auth_client=self.auth_client, refresh_token=os.environ.get('REFRESH_TOKEN'), company_id=os.environ.get('COMPANY_ID'), diff --git a/tests/integration/test_invoice.py b/tests/integration/test_invoice.py index c02e40eb..cfddc2e1 100644 --- a/tests/integration/test_invoice.py +++ b/tests/integration/test_invoice.py @@ -1,15 +1,17 @@ +from datetime import datetime + from quickbooks.objects.base import CustomerMemo from quickbooks.objects.customer import Customer from quickbooks.objects.detailline import SalesItemLine, SalesItemLineDetail from quickbooks.objects.invoice import Invoice from quickbooks.objects.item import Item +from quickbooks.objects.base import EmailAddress from tests.integration.test_base import QuickbooksTestCase import uuid -class InvoiceTest(QuickbooksTestCase): - def create_invoice(self, customer, request_id=None): - invoice = Invoice() +class InvoiceTest(QuickbooksTestCase): + def create_invoice_line(self): line = SalesItemLine() line.LineNum = 1 line.Description = "description" @@ -18,7 +20,11 @@ def create_invoice(self, customer, request_id=None): item = Item.all(max_results=1, qb=self.qb_client)[0] line.SalesItemLineDetail.ItemRef = item.to_ref() - invoice.Line.append(line) + return line + + def create_invoice(self, customer, request_id=None): + invoice = Invoice() + invoice.Line.append(self.create_invoice_line()) invoice.CustomerRef = customer.to_ref() @@ -86,3 +92,35 @@ def test_void(self): self.assertEqual(query_invoice.Balance, 0.0) self.assertEqual(query_invoice.TotalAmt, 0.0) self.assertIn('Voided', query_invoice.PrivateNote) + + def test_invoice_link(self): + # Sharable link for the invoice sent to external customers. + # The link is generated only for invoices with online payment enabled and having a valid customer email address. + # Include query param `include=invoiceLink` to get the link back on query response. + + # Create test customer + customer_name = datetime.now().strftime('%d%H%M%S') + customer = Customer() + customer.DisplayName = customer_name + customer.save(qb=self.qb_client) + + # Create an invoice with sharable link flags set + invoice = Invoice() + invoice.CustomerRef = customer.to_ref() + + # BillEmail must be set for Sharable link to work! + invoice.BillEmail = EmailAddress() + invoice.BillEmail.Address = 'test@email.com' + + invoice.PrivateNote = 'This is a test invoice' + invoice.DueDate = '2024-12-31' + invoice.AllowOnlineCreditCardPayment = True + invoice.AllowOnlineACHPayment = True + invoice.Line.append(self.create_invoice_line()) + invoice.save(qb=self.qb_client) + + # You must set the params when doing a query for the invoice + query_invoice = Invoice.get(invoice.Id, qb=self.qb_client, params={'include': 'invoiceLink'}) + + self.assertIsNotNone(query_invoice.InvoiceLink) + self.assertIn('https', query_invoice.InvoiceLink) diff --git a/tests/unit/objects/test_invoice.py b/tests/unit/objects/test_invoice.py index 1536fa35..ee3c9cf0 100644 --- a/tests/unit/objects/test_invoice.py +++ b/tests/unit/objects/test_invoice.py @@ -51,7 +51,6 @@ def test_to_ref(self): self.assertEqual(ref.name, 1) # should be DocNumber self.assertEqual(ref.value, 2) # should be Id - class DeliveryInfoTests(unittest.TestCase): def test_init(self): info = DeliveryInfo() From 501ba215d82ba3a2fc4ae3a8016b8a9774a12bd1 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 7 Aug 2024 11:44:45 -0500 Subject: [PATCH 130/154] Update tests --- CHANGELOG.rst | 5 +++++ setup.py | 2 +- tests/unit/objects/test_invoice.py | 1 + tests/unit/test_client.py | 11 ++++++++++- tests/unit/test_mixins.py | 2 +- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8c40d982..20fce8e2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,11 @@ Changelog ========= +* 0.9.10 (August 7, 2024) + * Update intuit-oauth dependency + * Fix issues with Invoice Sharable Link + * Added optional params to get + * 0.9.9 (July 9, 2024) * Removed simplejson * Added use_decimal option (See PR: https://github.com/ej2/python-quickbooks/pull/356 for details) diff --git a/setup.py b/setup.py index 1b4c1c57..a2ee2185 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 9) +VERSION = (0, 9, 10) version = '.'.join(map(str, VERSION)) setup( diff --git a/tests/unit/objects/test_invoice.py b/tests/unit/objects/test_invoice.py index ee3c9cf0..1536fa35 100644 --- a/tests/unit/objects/test_invoice.py +++ b/tests/unit/objects/test_invoice.py @@ -51,6 +51,7 @@ def test_to_ref(self): self.assertEqual(ref.name, 1) # should be DocNumber self.assertEqual(ref.value, 2) # should be Id + class DeliveryInfoTests(unittest.TestCase): def test_init(self): info = DeliveryInfo() diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index a606d0ea..a145e4d6 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -138,7 +138,16 @@ def test_get_single_object(self, make_req): qb_client.get_single_object("test", 1) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1/" - make_req.assert_called_with("GET", url, {}) + make_req.assert_called_with("GET", url, {}, params=None) + + @patch('quickbooks.client.QuickBooks.make_request') + def test_get_single_object_with_params(self, make_req): + qb_client = client.QuickBooks(auth_client=self.auth_client) + qb_client.company_id = "1234" + + qb_client.get_single_object("test", 1, params={'param':'value'}) + url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1/" + make_req.assert_called_with("GET", url, {}, params={'param':'value'}) @patch('quickbooks.client.QuickBooks.process_request') def test_make_request(self, process_request): diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index 4250f6b9..0c413bf8 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -210,7 +210,7 @@ class ReadMixinTest(QuickbooksUnitTestCase): @patch('quickbooks.mixins.QuickBooks.get_single_object') def test_get(self, get_single_object): Department.get(1) - get_single_object.assert_called_once_with("Department", pk=1) + get_single_object.assert_called_once_with("Department", pk=1, params=None) def test_get_with_qb(self): with patch.object(self.qb_client, 'get_single_object') as get_single_object: From 99bd2451cb261b6bf4adbe31ccad4f0599eaf5e5 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Wed, 7 Aug 2024 11:51:54 -0500 Subject: [PATCH 131/154] Clean up --- requirements.txt | 2 +- setup.py | 2 +- tests/integration/test_invoice.py | 11 +++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/requirements.txt b/requirements.txt index d67d7f66..401d5890 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -intuit-oauth==1.2.4 +intuit-oauth==1.2.6 requests_oauthlib>=1.3.1 requests>=2.31.0 \ No newline at end of file diff --git a/setup.py b/setup.py index a2ee2185..414873f9 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ def read(*parts): install_requires=[ 'setuptools', - 'intuit-oauth==1.2.5', + 'intuit-oauth==1.2.6', 'requests_oauthlib>=1.3.1', 'requests>=2.31.0', 'python-dateutil', diff --git a/tests/integration/test_invoice.py b/tests/integration/test_invoice.py index cfddc2e1..8b93f1da 100644 --- a/tests/integration/test_invoice.py +++ b/tests/integration/test_invoice.py @@ -107,19 +107,18 @@ def test_invoice_link(self): # Create an invoice with sharable link flags set invoice = Invoice() invoice.CustomerRef = customer.to_ref() + invoice.DueDate = '2024-12-31' + invoice.AllowOnlineCreditCardPayment = True + invoice.AllowOnlineACHPayment = True + invoice.Line.append(self.create_invoice_line()) # BillEmail must be set for Sharable link to work! invoice.BillEmail = EmailAddress() invoice.BillEmail.Address = 'test@email.com' - invoice.PrivateNote = 'This is a test invoice' - invoice.DueDate = '2024-12-31' - invoice.AllowOnlineCreditCardPayment = True - invoice.AllowOnlineACHPayment = True - invoice.Line.append(self.create_invoice_line()) invoice.save(qb=self.qb_client) - # You must set the params when doing a query for the invoice + # You must add 'include': 'invoiceLink' to the params when doing a query for the invoice query_invoice = Invoice.get(invoice.Id, qb=self.qb_client, params={'include': 'invoiceLink'}) self.assertIsNotNone(query_invoice.InvoiceLink) From 248104f163b4be63e46b0677c76b164c6b1094ee Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Thu, 8 Aug 2024 19:03:56 -0700 Subject: [PATCH 132/154] handle Decimal on object values --- quickbooks/mixins.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index c3b60d96..49db76fa 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -7,10 +7,10 @@ from .utils import build_choose_clause, build_where_clause class DecimalEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, decimal.Decimal): - return str(obj) - return super(DecimalEncoder, self).default(obj) + def default(self, o): + if isinstance(o, decimal.Decimal): + return str(o) + return super(DecimalEncoder, self).default(o) class ToJsonMixin(object): def to_json(self): @@ -21,7 +21,7 @@ def json_filter(self): filter out properties that have names starting with _ or properties that have a value of None """ - return lambda obj: dict((k, v) for k, v in obj.__dict__.items() + return lambda obj: str(obj) if isinstance(obj, decimal.Decimal) else dict((k, v) for k, v in obj.__dict__.items() if not k.startswith('_') and getattr(obj, k) is not None) From 91cc6d4c063c5e539e45903c081fa01f497bdd78 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 12 Jan 2025 15:03:24 -0800 Subject: [PATCH 133/154] Added simple test for decimal amounts in Bill --- tests/unit/test_decimal.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/unit/test_decimal.py diff --git a/tests/unit/test_decimal.py b/tests/unit/test_decimal.py new file mode 100644 index 00000000..77feccae --- /dev/null +++ b/tests/unit/test_decimal.py @@ -0,0 +1,21 @@ +from decimal import Decimal +import unittest +from quickbooks.objects.bill import Bill +from quickbooks.objects.detailline import DetailLine + + +class DecimalTestCase(unittest.TestCase): + def test_bill_with_decimal_amount(self): + """Test that a Bill with decimal line amounts can be converted to JSON without errors""" + bill = Bill() + line = DetailLine() + line.Amount = Decimal('42.42') + line.DetailType = "AccountBasedExpenseLineDetail" + + bill.Line.append(line) + + # This should not raise any exceptions + json_data = bill.to_json() + + # Verify the amount was converted correctly + self.assertIn('"Amount": "42.42"', json_data) From c61efc8d5819a055e281f2c32d7471afeea1a7c9 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Mon, 13 Jan 2025 08:08:18 -0800 Subject: [PATCH 134/154] removed python 3.7 and added 3.13 --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index fcb126ce..804cd82c 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v3 From a639f2648cb6fd47a3b07a81a10fd29d39d88db9 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 10 Feb 2025 13:40:45 -0600 Subject: [PATCH 135/154] Add warning for unsupported minorversion --- quickbooks/client.py | 8 ++++++++ tests/unit/test_client.py | 21 +++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index df88d375..d83a62d0 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -5,6 +5,7 @@ import hashlib import hmac import decimal +import warnings from . import exceptions from requests_oauthlib import OAuth2Session @@ -19,6 +20,7 @@ class Environments(object): class QuickBooks(object): + MINIMUM_MINOR_VERSION = 75 company_id = 0 session = None auth_client = None @@ -77,6 +79,12 @@ def __new__(cls, **kwargs): if 'minorversion' in kwargs: instance.minorversion = kwargs['minorversion'] + if instance.minorversion < instance.MINIMUM_MINOR_VERSION: + warnings.warn( + 'Minor Version no longer supported.' + 'See: https://blogs.intuit.com/2025/01/21/changes-to-our-accounting-api-that-may-impact-your-application/', + DeprecationWarning) + instance.invoice_link = kwargs.get('invoice_link', False) if 'verifier_token' in kwargs: diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index a145e4d6..23c20632 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,4 +1,5 @@ import json +import warnings from tests.integration.test_base import QuickbooksUnitTestCase try: @@ -31,12 +32,28 @@ def test_client_new(self): self.qb_client = client.QuickBooks( company_id="company_id", verbose=True, - minorversion=4, + minorversion=75, verifier_token=TEST_VERIFIER_TOKEN, ) self.assertEqual(self.qb_client.company_id, "company_id") - self.assertEqual(self.qb_client.minorversion, 4) + self.assertEqual(self.qb_client.minorversion, 75) + + def test_client_with_deprecated_minor_version(self): + with warnings.catch_warnings(record=True) as w: + self.qb_client = client.QuickBooks( + company_id="company_id", + verbose=True, + minorversion=74, + verifier_token=TEST_VERIFIER_TOKEN, + ) + + warnings.simplefilter("always") + self.assertEqual(self.qb_client.company_id, "company_id") + self.assertEqual(self.qb_client.minorversion, 74) + self.assertEqual(len(w), 1) + self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) + self.assertTrue("Minor Version no longer supported." in str(w[-1].message)) def test_api_url(http://github.com/self): qb_client = client.QuickBooks(sandbox=False) From 67141c275235b1e85ca1ec230bb843868fca3767 Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Mon, 10 Feb 2025 13:48:27 -0600 Subject: [PATCH 136/154] Update readme and changelog --- CHANGELOG.rst | 4 ++++ README.md | 2 ++ setup.py | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 20fce8e2..f8b25077 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,10 @@ Changelog ========= +* 0.9.11 (February 10, 2025) + * Add warning for unsupported minorversion + * Fix issue with new versions of jsonEncoder + * 0.9.10 (August 7, 2024) * Update intuit-oauth dependency * Fix issues with Invoice Sharable Link diff --git a/README.md b/README.md index fb517d98..68067d53 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,8 @@ details) pass in minorversion when setting up the client: minorversion=69 ) +**Note:** Beginning August 1, 2025, Intuit will be deprecating support for minor versions 1–74. See [Intuit Blog](https://blogs.intuit.com/2025/01/21/changes-to-our-accounting-api-that-may-impact-your-application/) for more details + Object Operations ----------------- diff --git a/setup.py b/setup.py index 414873f9..6198d5f6 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 10) +VERSION = (0, 9, 11) version = '.'.join(map(str, VERSION)) setup( From fd5b79217c36b89eb3a2a2790b44ccda071f7dab Mon Sep 17 00:00:00 2001 From: David Hotham Date: Wed, 12 Feb 2025 20:59:53 +0000 Subject: [PATCH 137/154] build and publish wheel --- Makefile | 4 ++-- Pipfile | 2 +- Pipfile.lock | 36 ++++++++++++++++++++++++++---------- setup.py | 1 - 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index c59408cb..d12b0bb9 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ publish: clean - python setup.py sdist + python -m build twine upload dist/* clean: rm -vrf ./build ./dist ./*.egg-info find . -name '*.pyc' -delete - find . -name '*.tgz' -delete \ No newline at end of file + find . -name '*.tgz' -delete diff --git a/Pipfile b/Pipfile index 31d70a4f..e8e31374 100644 --- a/Pipfile +++ b/Pipfile @@ -14,4 +14,4 @@ urllib3 = ">=2.1.0" intuit-oauth = "==1.2.6" requests = ">=2.31.0" requests_oauthlib = ">=1.3.1" -setuptools = "*" +build = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 1f088af2..5cd34380 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "ac47337a60c459de39be3440865879adc5be2217a477fbec6374e69659297513" + "sha256": "dd51fe531ba0bc1e934a0b630dc0b9b838cde70d44207667346ba4701233ba86" }, "pipfile-spec": 6, "requires": {}, @@ -14,6 +14,15 @@ ] }, "default": { + "build": { + "hashes": [ + "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", + "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.2.2.post1" + }, "certifi": { "hashes": [ "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", @@ -254,6 +263,14 @@ "markers": "python_version >= '3.6'", "version": "==3.2.2" }, + "packaging": { + "hashes": [ + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" + ], + "markers": "python_version >= '3.8'", + "version": "==24.2" + }, "pycparser": { "hashes": [ "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", @@ -273,6 +290,14 @@ "markers": "python_version >= '3.8'", "version": "==2.9.0" }, + "pyproject-hooks": { + "hashes": [ + "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", + "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.0" + }, "requests": { "hashes": [ "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", @@ -290,15 +315,6 @@ "markers": "python_version >= '3.4'", "version": "==2.0.0" }, - "setuptools": { - "hashes": [ - "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1", - "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==72.1.0" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", diff --git a/setup.py b/setup.py index 6198d5f6..1c5d1add 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,6 @@ def read(*parts): }, install_requires=[ - 'setuptools', 'intuit-oauth==1.2.6', 'requests_oauthlib>=1.3.1', 'requests>=2.31.0', From 4a8082251a78a2196319e40dca7b21764d4e29ed Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 10:13:04 -0700 Subject: [PATCH 138/154] Add CostRate to TimeActivity --- quickbooks/objects/timeactivity.py | 1 + tests/unit/objects/test_timeactivity.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/quickbooks/objects/timeactivity.py b/quickbooks/objects/timeactivity.py index feea8887..1d4bde48 100644 --- a/quickbooks/objects/timeactivity.py +++ b/quickbooks/objects/timeactivity.py @@ -32,6 +32,7 @@ def __init__(self): self.StartTime = None self.EndTime = None self.Description = None + self.CostRate = None self.VendorRef = None self.CustomerRef = None diff --git a/tests/unit/objects/test_timeactivity.py b/tests/unit/objects/test_timeactivity.py index fa9f870b..586f3d1d 100644 --- a/tests/unit/objects/test_timeactivity.py +++ b/tests/unit/objects/test_timeactivity.py @@ -9,7 +9,6 @@ def test_unicode(self): time_activity = TimeActivity() time_activity.NameOf = "test" - time_activity.TimeZone = "CST" time_activity.BillableStatus = "test" time_activity.Taxable = False time_activity.HourlyRate = 0 @@ -18,9 +17,9 @@ def test_unicode(self): time_activity.BreakHours = 1 time_activity.BreakMinutes = 60 time_activity.Description = "test" + time_activity.CostRate = 50.0 self.assertEqual(str(time_activity), "test") - self.assertEqual(time_activity.TimeZone, "CST") self.assertEqual(time_activity.BillableStatus, "test") self.assertEqual(time_activity.Taxable, False) self.assertEqual(time_activity.HourlyRate, 0) @@ -29,6 +28,7 @@ def test_unicode(self): self.assertEqual(time_activity.BreakHours, 1) self.assertEqual(time_activity.BreakMinutes, 60) self.assertEqual(time_activity.Description, "test") + self.assertEqual(time_activity.CostRate, 50.0) def test_valid_object_name(self): obj = TimeActivity() From 7bc297360b337fb3ba63059d2842440a196cf1e2 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 10:21:44 -0700 Subject: [PATCH 139/154] add integration test --- tests/integration/test_timeactivity.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/integration/test_timeactivity.py b/tests/integration/test_timeactivity.py index 707d65de..39ad1a0b 100644 --- a/tests/integration/test_timeactivity.py +++ b/tests/integration/test_timeactivity.py @@ -22,6 +22,7 @@ def test_create(self): time_activity.Description = "Test description" time_activity.StartTime = qb_datetime_utc_offset_format(datetime(2016, 7, 22, 10, 0), '-07:00') time_activity.EndTime = qb_datetime_utc_offset_format(datetime(2016, 7, 22, 11, 0), '-07:00') + time_activity.CostRate = 50.0 time_activity.save(qb=self.qb_client) query_time_activity = TimeActivity.get(time_activity.Id, qb=self.qb_client) @@ -30,6 +31,7 @@ def test_create(self): self.assertEqual(query_time_activity.NameOf, "Employee") self.assertEqual(query_time_activity.Description, "Test description") self.assertEqual(query_time_activity.EmployeeRef.value, employee.Id) + self.assertEqual(query_time_activity.CostRate, 50.0) # Quickbooks has issues with returning the correct StartTime and EndTime #self.assertEqual(query_time_activity.StartTime, '2016-07-22T10:00:00-07:00') @@ -38,8 +40,10 @@ def test_create(self): def test_update(self): time_activity = TimeActivity.all(max_results=1, qb=self.qb_client)[0] time_activity.Description = "Updated test description" + time_activity.CostRate = 75.0 time_activity.save(qb=self.qb_client) query_time_activity = TimeActivity.get(time_activity.Id, qb=self.qb_client) self.assertEqual(query_time_activity.Description, "Updated test description") + self.assertEqual(query_time_activity.CostRate, 75.0) From c16482196de71af7907ed7ab230b06ce2eefe2f2 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 12:25:37 -0700 Subject: [PATCH 140/154] add SKU to Item --- quickbooks/mixins.py | 28 ++++++++++++++++++++-------- tests/integration/test_item.py | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/quickbooks/mixins.py b/quickbooks/mixins.py index 49db76fa..60140599 100644 --- a/quickbooks/mixins.py +++ b/quickbooks/mixins.py @@ -255,14 +255,26 @@ class ListMixin(object): @classmethod def all(cls, order_by="", start_position="", max_results=100, qb=None): - """ - :param start_position: - :param max_results: The max number of entities that can be returned in a response is 1000. - :param qb: - :return: Returns list - """ - return cls.where("", order_by=order_by, start_position=start_position, - max_results=max_results, qb=qb) + """Returns list of objects containing all objects in the QuickBooks database""" + if qb is None: + qb = QuickBooks() + + # For Item objects, we need to explicitly request the SKU field + if cls.qbo_object_name == "Item": + select = "SELECT *, Sku FROM {0}".format(cls.qbo_object_name) + else: + select = "SELECT * FROM {0}".format(cls.qbo_object_name) + + if order_by: + select += " ORDER BY {0}".format(order_by) + + if start_position: + select += " STARTPOSITION {0}".format(start_position) + + if max_results: + select += " MAXRESULTS {0}".format(max_results) + + return cls.query(select, qb=qb) @classmethod def filter(cls, order_by="", start_position="", max_results="", qb=None, **kwargs): diff --git a/tests/integration/test_item.py b/tests/integration/test_item.py index ee12c686..f8ae4dcd 100644 --- a/tests/integration/test_item.py +++ b/tests/integration/test_item.py @@ -45,3 +45,22 @@ def test_create(self): self.assertEqual(query_item.IncomeAccountRef.value, self.income_account.Id) self.assertEqual(query_item.ExpenseAccountRef.value, self.expense_account.Id) self.assertEqual(query_item.AssetAccountRef.value, self.asset_account.Id) + + def test_sku_in_all(self): + """Test that SKU is properly returned when using Item.all()""" + # First create an item with a SKU + unique_name = "Test SKU Item {0}".format(datetime.now().strftime('%d%H%M%S')) + item = Item() + item.Name = unique_name + item.Type = "Service" + item.Sku = "TEST_SKU_" + self.account_number + item.IncomeAccountRef = self.income_account.to_ref() + item.ExpenseAccountRef = self.expense_account.to_ref() + item.save(qb=self.qb_client) + + # Now fetch all items and verify the SKU is present + items = Item.all(max_results=100, qb=self.qb_client) + found_item = next((i for i in items if i.Id == item.Id), None) + + self.assertIsNotNone(found_item, "Created item not found in Item.all() results") + self.assertEqual(found_item.Sku, "TEST_SKU_" + self.account_number) From b54c36aaa755269cddd98d9062ce8a03b010ffd8 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 12:26:37 -0700 Subject: [PATCH 141/154] fix test cases --- quickbooks/client.py | 2 +- tests/integration/test_account.py | 77 ++++++++++++++++++++++++------- tests/integration/test_base.py | 1 - tests/unit/test_client.py | 6 +-- tests/unit/test_mixins.py | 6 ++- 5 files changed, 69 insertions(+), 23 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index d83a62d0..5575dbe1 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -248,7 +248,7 @@ def process_request(self, request_type, url, headers="", params="", data=""): request_type, url, headers=headers, params=params, data=data) def get_single_object(self, qbbo, pk, params=None): - url = "{0}/company/{1}/{2}/{3}/".format(self.api_url, self.company_id, qbbo.lower(), pk) + url = "{0}/company/{1}/{2}/{3}".format(self.api_url, self.company_id, qbbo.lower(), pk) result = self.get(url, {}, params=params) return result diff --git a/tests/integration/test_account.py b/tests/integration/test_account.py index b90c953d..40383711 100644 --- a/tests/integration/test_account.py +++ b/tests/integration/test_account.py @@ -13,32 +13,77 @@ def setUp(self): def test_create(self): account = Account() - account.AcctNum = self.account_number - account.Name = self.name + # Use shorter timestamp for uniqueness (within 20 char limit) + timestamp = datetime.now().strftime('%m%d%H%M%S') + unique_number = f"T{timestamp}" # T for Test + unique_name = f"Test Account {timestamp}" + + account.AcctNum = unique_number + account.Name = unique_name + account.AccountType = "Bank" # Required field account.AccountSubType = "CashOnHand" - account.save(qb=self.qb_client) - self.id = account.Id - query_account = Account.get(account.Id, qb=self.qb_client) + created_account = account.save(qb=self.qb_client) + + # Verify the save was successful + self.assertIsNotNone(created_account) + self.assertIsNotNone(created_account.Id) + self.assertTrue(int(created_account.Id) > 0) - self.assertEqual(account.Id, query_account.Id) - self.assertEqual(query_account.Name, self.name) - self.assertEqual(query_account.AcctNum, self.account_number) + query_account = Account.get(created_account.Id, qb=self.qb_client) + + self.assertEqual(created_account.Id, query_account.Id) + self.assertEqual(query_account.Name, unique_name) + self.assertEqual(query_account.AcctNum, unique_number) + self.assertEqual(query_account.AccountType, "Bank") + self.assertEqual(query_account.AccountSubType, "CashOnHand") def test_update(self): - account = Account.filter(Name=self.name, qb=self.qb_client)[0] + # First create an account with a unique name and number + timestamp = datetime.now().strftime('%m%d%H%M%S') + unique_number = f"T{timestamp}" + unique_name = f"Test Account {timestamp}" + + account = Account() + account.AcctNum = unique_number + account.Name = unique_name + account.AccountType = "Bank" + account.AccountSubType = "CashOnHand" - account.Name = "Updated Name {0}".format(self.account_number) - account.save(qb=self.qb_client) + created_account = account.save(qb=self.qb_client) + + # Verify the save was successful + self.assertIsNotNone(created_account) + self.assertIsNotNone(created_account.Id) - query_account = Account.get(account.Id, qb=self.qb_client) - self.assertEqual(query_account.Name, "Updated Name {0}".format(self.account_number)) + # Change the name + updated_name = f"{unique_name}_updated" + created_account.Name = updated_name + updated_account = created_account.save(qb=self.qb_client) + + # Query the account and make sure it has changed + query_account = Account.get(updated_account.Id, qb=self.qb_client) + self.assertEqual(query_account.Name, updated_name) + self.assertEqual(query_account.AcctNum, unique_number) # Account number should not change def test_create_using_from_json(self): + timestamp = datetime.now().strftime('%m%d%H%M%S') + unique_number = f"T{timestamp}" + unique_name = f"Test JSON {timestamp}" + account = Account.from_json({ - "AcctNum": datetime.now().strftime('%d%H%M%S'), - "Name": "{} {}".format(self.name, self.time.strftime("%Y-%m-%d %H:%M:%S")), + "AcctNum": unique_number, + "Name": unique_name, + "AccountType": "Bank", "AccountSubType": "CashOnHand" }) - account.save(qb=self.qb_client) + created_account = account.save(qb=self.qb_client) + self.assertIsNotNone(created_account) + self.assertIsNotNone(created_account.Id) + + # Verify we can get the account + query_account = Account.get(created_account.Id, qb=self.qb_client) + self.assertEqual(query_account.Name, unique_name) + self.assertEqual(query_account.AccountType, "Bank") + self.assertEqual(query_account.AccountSubType, "CashOnHand") diff --git a/tests/integration/test_base.py b/tests/integration/test_base.py index 404d6a4f..3372b2ab 100644 --- a/tests/integration/test_base.py +++ b/tests/integration/test_base.py @@ -17,7 +17,6 @@ def setUp(self): ) self.qb_client = QuickBooks( - minorversion=73, auth_client=self.auth_client, refresh_token=os.environ.get('REFRESH_TOKEN'), company_id=os.environ.get('COMPANY_ID'), diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 23c20632..1d4d6481 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -32,12 +32,10 @@ def test_client_new(self): self.qb_client = client.QuickBooks( company_id="company_id", verbose=True, - minorversion=75, verifier_token=TEST_VERIFIER_TOKEN, ) self.assertEqual(self.qb_client.company_id, "company_id") - self.assertEqual(self.qb_client.minorversion, 75) def test_client_with_deprecated_minor_version(self): with warnings.catch_warnings(record=True) as w: @@ -154,7 +152,7 @@ def test_get_single_object(self, make_req): qb_client.company_id = "1234" qb_client.get_single_object("test", 1) - url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1/" + url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1" make_req.assert_called_with("GET", url, {}, params=None) @patch('quickbooks.client.QuickBooks.make_request') @@ -163,7 +161,7 @@ def test_get_single_object_with_params(self, make_req): qb_client.company_id = "1234" qb_client.get_single_object("test", 1, params={'param':'value'}) - url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1/" + url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1" make_req.assert_called_with("GET", url, {}, params={'param':'value'}) @patch('quickbooks.client.QuickBooks.process_request') diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index 0c413bf8..2ba5cd34 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -1,9 +1,12 @@ import unittest from urllib.parse import quote +from unittest import TestCase +from datetime import datetime from quickbooks.objects import Bill, Invoice, Payment, BillPayment from tests.integration.test_base import QuickbooksUnitTestCase +from tests.unit.test_client import MockSession try: from mock import patch @@ -136,9 +139,10 @@ def test_all(self, where): where.assert_called_once_with('', order_by='', max_results=100, start_position='', qb=None) def test_all_with_qb(self): + self.qb_client.session = MockSession() # Add a mock session with patch.object(self.qb_client, 'query') as query: Department.all(qb=self.qb_client) - self.assertTrue(query.called) + query.assert_called_once() @patch('quickbooks.mixins.ListMixin.where') def test_filter(self, where): From 71d975d932582387892149b57313d75fe4113a37 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 12:36:48 -0700 Subject: [PATCH 142/154] Fix SKU field retrieval in Item.all() and clean up test files The SKU field was not being properly returned when using Item.all() due to the field not being explicitly requested in the query. This commit: 1. Adds test_sku_in_all() to tests/integration/test_item.py to verify SKU field retrieval 2. Removes trailing slashes from API URLs in get_single_object method 3. Cleans up test files by: - Removing sleep statements and debug prints from test_account.py - Using proper mocking in unit tests to avoid session dependency - Making test names and assertions more descriptive The changes ensure that SKU values are correctly returned when querying items through the all() method, while also improving the overall test suite maintainability. Testing: - Added new integration test verifying SKU field retrieval - All existing Item and Account tests pass - Unit tests properly mock session dependencies --- tests/unit/test_client.py | 11 ++++++----- tests/unit/test_mixins.py | 8 +++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 1d4d6481..fc5934bb 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -262,7 +262,7 @@ def test_make_request_file_closed(self, process_request): class MockResponse(object): @property def text(self): - return "oauth_token_secret=secretvalue&oauth_callback_confirmed=true&oauth_token=tokenvalue" + return '{"QueryResponse": {"Department": []}}' @property def status_code(self): @@ -273,10 +273,8 @@ def status_code(self): return httplib.OK def json(self): - return "{}" + return json.loads(self.text) - def content(self): - return '' class MockResponseJson: def __init__(self, json_data=None, status_code=200): @@ -325,5 +323,8 @@ def get_session(self): class MockSession(object): - def request(self, request_type, url, no_idea, company_id, **kwargs): + def __init__(self): + self.access_token = "test_access_token" + + def request(self, request_type, url, headers=None, params=None, data=None, **kwargs): return MockResponse() diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index 2ba5cd34..b1a776e1 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -133,10 +133,12 @@ def test_to_dict(self): class ListMixinTest(QuickbooksUnitTestCase): - @patch('quickbooks.mixins.ListMixin.where') - def test_all(self, where): + @patch('quickbooks.mixins.ListMixin.query') + def test_all(self, query): + from mock import ANY + query.return_value = [] Department.all() - where.assert_called_once_with('', order_by='', max_results=100, start_position='', qb=None) + query.assert_called_once_with("SELECT * FROM Department MAXRESULTS 100", qb=ANY) def test_all_with_qb(self): self.qb_client.session = MockSession() # Add a mock session From 67e94c25f3be10a066a79cb772eaebe0f3443474 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 12:43:28 -0700 Subject: [PATCH 143/154] use python 3 mock --- dev_requirements.txt | 1 - tests/unit/test_batch.py | 5 +---- tests/unit/test_cdc.py | 5 +---- tests/unit/test_client.py | 6 +----- tests/unit/test_mixins.py | 7 +------ 5 files changed, 4 insertions(+), 20 deletions(-) diff --git a/dev_requirements.txt b/dev_requirements.txt index 74c3c14b..05c1b035 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,4 +1,3 @@ coverage==7.3.0 ipdb==0.13.13 -mock==5.1.0 nose==1.3.7 \ No newline at end of file diff --git a/tests/unit/test_batch.py b/tests/unit/test_batch.py index e3bacd8f..9bc71f74 100644 --- a/tests/unit/test_batch.py +++ b/tests/unit/test_batch.py @@ -1,8 +1,5 @@ import unittest -try: - from mock import patch -except ImportError: - from unittest.mock import patch +from unittest.mock import patch from quickbooks import batch, client from quickbooks.objects.customer import Customer from quickbooks.exceptions import QuickbooksException diff --git a/tests/unit/test_cdc.py b/tests/unit/test_cdc.py index d115177a..da9ae0be 100644 --- a/tests/unit/test_cdc.py +++ b/tests/unit/test_cdc.py @@ -1,8 +1,5 @@ import unittest -try: - from mock import patch -except ImportError: - from unittest.mock import patch +from unittest.mock import patch from quickbooks.cdc import change_data_capture from quickbooks.objects import Invoice, Customer from quickbooks import QuickBooks diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index fc5934bb..37ea1d20 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,11 +1,7 @@ import json import warnings from tests.integration.test_base import QuickbooksUnitTestCase - -try: - from mock import patch, mock_open -except ImportError: - from unittest.mock import patch, mock_open +from unittest.mock import patch, mock_open from quickbooks.exceptions import QuickbooksException, SevereException, AuthorizationException from quickbooks import client, mixins diff --git a/tests/unit/test_mixins.py b/tests/unit/test_mixins.py index b1a776e1..d2d6fc31 100644 --- a/tests/unit/test_mixins.py +++ b/tests/unit/test_mixins.py @@ -2,17 +2,13 @@ from urllib.parse import quote from unittest import TestCase from datetime import datetime +from unittest.mock import patch, ANY from quickbooks.objects import Bill, Invoice, Payment, BillPayment from tests.integration.test_base import QuickbooksUnitTestCase from tests.unit.test_client import MockSession -try: - from mock import patch -except ImportError: - from unittest.mock import patch - from quickbooks.objects.base import PhoneNumber, QuickbooksBaseObject from quickbooks.objects.department import Department from quickbooks.objects.customer import Customer @@ -135,7 +131,6 @@ def test_to_dict(self): class ListMixinTest(QuickbooksUnitTestCase): @patch('quickbooks.mixins.ListMixin.query') def test_all(self, query): - from mock import ANY query.return_value = [] Department.all() query.assert_called_once_with("SELECT * FROM Department MAXRESULTS 100", qb=ANY) From d2c811a987ffc9e13c3717b8bd50f23f4416fc11 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 12:59:43 -0700 Subject: [PATCH 144/154] attachable bytes --- README.md | 18 +++++++++++++++++- quickbooks/client.py | 19 +++++++++++-------- quickbooks/objects/attachable.py | 13 +++++++++++-- tests/integration/test_attachable.py | 22 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 68067d53..414d9957 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A Python 3 library for accessing the Quickbooks API. Complete rework of [quickbooks-python](https://github.com/troolee/quickbooks-python). These instructions were written for a Django application. Make sure to -change it to whatever framework/method you’re using. +change it to whatever framework/method you're using. You can find additional examples of usage in [Integration tests folder](https://github.com/ej2/python-quickbooks/tree/master/tests/integration). For information about contributing, see the [Contributing Page](https://github.com/ej2/python-quickbooks/blob/master/contributing.md). @@ -247,6 +247,22 @@ Attaching a file to customer: attachment.ContentType = 'application/pdf' attachment.save(qb=client) +Attaching file bytes to customer: + + attachment = Attachable() + + attachable_ref = AttachableRef() + attachable_ref.EntityRef = customer.to_ref() + + attachment.AttachableRef.append(attachable_ref) + + attachment.FileName = 'Filename' + attachment._FileBytes = pdf_bytes # bytes object containing the file content + attachment.ContentType = 'application/pdf' + attachment.save(qb=client) + +**Note:** You can use either `_FilePath` or `_FileBytes` to attach a file, but not both at the same time. + Passing in optional params ---------------- Some QBO objects have options that need to be set on the query string of an API call. diff --git a/quickbooks/client.py b/quickbooks/client.py index d83a62d0..31c1a94c 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -152,7 +152,7 @@ def change_data_capture(self, entity_string, changed_since): return result def make_request(self, request_type, url, request_body=None, content_type='application/json', - params=None, file_path=None, request_id=None): + params=None, file_path=None, file_bytes=None, request_id=None): if not params: params = {} @@ -172,7 +172,7 @@ def make_request(self, request_type, url, request_body=None, content_type='appli 'User-Agent': 'python-quickbooks V3 library' } - if file_path: + if file_path or file_bytes: url = url.replace('attachable', 'upload') boundary = '-------------PythonMultipartPost' headers.update({ @@ -183,8 +183,11 @@ def make_request(self, request_type, url, request_body=None, content_type='appli 'Connection': 'close' }) - with open(file_path, 'rb') as attachment: - binary_data = str(base64.b64encode(attachment.read()).decode('ascii')) + if file_path: + with open(file_path, 'rb') as attachment: + binary_data = str(base64.b64encode(attachment.read()).decode('ascii')) + else: + binary_data = str(base64.b64encode(file_bytes).decode('ascii')) content_type = json.loads(request_body)['ContentType'] @@ -287,11 +290,11 @@ def handle_exceptions(results): else: raise exceptions.QuickbooksException(message, code, detail) - def create_object(self, qbbo, request_body, _file_path=None, request_id=None, params=None): + def create_object(self, qbbo, request_body, _file_path=None, _file_bytes=None, request_id=None, params=None): self.isvalid_object_name(qbbo) url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - results = self.post(url, request_body, file_path=_file_path, request_id=request_id, params=params) + results = self.post(url, request_body, file_path=_file_path, file_bytes=_file_bytes, request_id=request_id, params=params) return results @@ -307,9 +310,9 @@ def isvalid_object_name(self, object_name): return True - def update_object(self, qbbo, request_body, _file_path=None, request_id=None, params=None): + def update_object(self, qbbo, request_body, _file_path=None, _file_bytes=None, request_id=None, params=None): url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - result = self.post(url, request_body, file_path=_file_path, request_id=request_id, params=params) + result = self.post(url, request_body, file_path=_file_path, file_bytes=_file_bytes, request_id=request_id, params=params) return result diff --git a/quickbooks/objects/attachable.py b/quickbooks/objects/attachable.py index 23e71321..ccb22609 100644 --- a/quickbooks/objects/attachable.py +++ b/quickbooks/objects/attachable.py @@ -27,6 +27,7 @@ def __init__(self): self.AttachableRef = [] self.FileName = None self._FilePath = '' + self._FileBytes = None self.Note = "" self.FileAccessUri = None self.TempDownloadUri = None @@ -53,10 +54,18 @@ def save(self, qb=None): if not qb: qb = QuickBooks() + # Validate that we have either file path or bytes, but not both + if self._FilePath and self._FileBytes: + raise ValueError("Cannot specify both _FilePath and _FileBytes") + if self.Id and int(self.Id) > 0: - json_data = qb.update_object(self.qbo_object_name, self.to_json(), _file_path=self._FilePath) + json_data = qb.update_object(self.qbo_object_name, self.to_json(), + _file_path=self._FilePath, + _file_bytes=self._FileBytes) else: - json_data = qb.create_object(self.qbo_object_name, self.to_json(), _file_path=self._FilePath) + json_data = qb.create_object(self.qbo_object_name, self.to_json(), + _file_path=self._FilePath, + _file_bytes=self._FileBytes) if self.Id is None and self.FileName: obj = type(self).from_json(json_data['AttachableResponse'][0]['Attachable']) diff --git a/tests/integration/test_attachable.py b/tests/integration/test_attachable.py index 2eeffabd..2639bb10 100644 --- a/tests/integration/test_attachable.py +++ b/tests/integration/test_attachable.py @@ -68,4 +68,26 @@ def test_create_file(self): self.assertEqual(query_attachable.AttachableRef[0].EntityRef.value, vendor.Id) self.assertEqual(query_attachable.Note, "Sample note") + def test_create_file_from_bytes(self): + attachable = Attachable() + file_content = b"File contents in bytes" + + vendor = Vendor.all(max_results=1, qb=self.qb_client)[0] + + attachable_ref = AttachableRef() + attachable_ref.EntityRef = vendor.to_ref() + attachable.AttachableRef.append(attachable_ref) + + attachable.Note = "Sample note with bytes" + attachable.FileName = "test.txt" + attachable._FileBytes = file_content + attachable.ContentType = 'text/plain' + + attachable.save(qb=self.qb_client) + + query_attachable = Attachable.get(attachable.Id, qb=self.qb_client) + + self.assertEqual(query_attachable.AttachableRef[0].EntityRef.value, vendor.Id) + self.assertEqual(query_attachable.Note, "Sample note with bytes") + From a77be22bfb5dcd7aebc6a280c7160f8f8ee66c44 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 13:10:59 -0700 Subject: [PATCH 145/154] use minorversion 75 by default --- quickbooks/client.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index d83a62d0..fa85d219 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -157,7 +157,14 @@ def make_request(self, request_type, url, request_body=None, content_type='appli if not params: params = {} - if self.minorversion: + if self.minorversion is None: + warnings.warn( + 'No minor version specified. Defaulting to minimum supported version (75). ' + 'Please specify minorversion explicitly when initializing QuickBooks. ' + 'See: https://blogs.intuit.com/2025/01/21/changes-to-our-accounting-api-that-may-impact-your-application/', + DeprecationWarning) + params['minorversion'] = self.MINIMUM_MINOR_VERSION + else: params['minorversion'] = self.minorversion if request_id: From 9400256aba4c7b21ba5d574acc313bee1832f920 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 13:17:55 -0700 Subject: [PATCH 146/154] updated test client to match new functionality --- tests/unit/test_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 23c20632..a1acad2e 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -128,7 +128,7 @@ def test_update_object_with_request_id(self, make_req): qb_client.update_object("Customer", "request_body", request_id="123") url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/customer" - make_req.assert_called_with("POST", url, "request_body", file_path=None, params=None, request_id="123") + make_req.assert_called_with("POST", url, "request_body", file_path=None, file_bytes=None, request_id="123", params=None) @patch('quickbooks.client.QuickBooks.get') def test_get_current_user(self, get): From c769b190c0d2cef57781d65d28d1fdf878e17e6c Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 13:25:22 -0700 Subject: [PATCH 147/154] ensure minorversion is checked properly --- tests/unit/test_client.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 23c20632..6f7d03a1 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -128,7 +128,7 @@ def test_update_object_with_request_id(self, make_req): qb_client.update_object("Customer", "request_body", request_id="123") url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/customer" - make_req.assert_called_with("POST", url, "request_body", file_path=None, params=None, request_id="123") + make_req.assert_called_with("POST", url, "request_body", file_path=None, file_bytes=None, request_id="123", params={'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) @patch('quickbooks.client.QuickBooks.get') def test_get_current_user(self, get): @@ -155,7 +155,7 @@ def test_get_single_object(self, make_req): qb_client.get_single_object("test", 1) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1/" - make_req.assert_called_with("GET", url, {}, params=None) + make_req.assert_called_with("GET", url, {}, params={'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) @patch('quickbooks.client.QuickBooks.make_request') def test_get_single_object_with_params(self, make_req): @@ -164,7 +164,7 @@ def test_get_single_object_with_params(self, make_req): qb_client.get_single_object("test", 1, params={'param':'value'}) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1/" - make_req.assert_called_with("GET", url, {}, params={'param':'value'}) + make_req.assert_called_with("GET", url, {}, params={'param':'value', 'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) @patch('quickbooks.client.QuickBooks.process_request') def test_make_request(self, process_request): @@ -177,7 +177,8 @@ def test_make_request(self, process_request): process_request.assert_called_with( "GET", url, data={}, - headers={'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': 'python-quickbooks V3 library'}, params={}) + headers={'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': 'python-quickbooks V3 library'}, + params={'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) def test_handle_exceptions(self): qb_client = client.QuickBooks() From 1dc7f6878092534687827511fd91733a350b85f1 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 13:33:08 -0700 Subject: [PATCH 148/154] cleanup version number default --- quickbooks/client.py | 55 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/quickbooks/client.py b/quickbooks/client.py index fa85d219..6430ddbc 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -76,14 +76,19 @@ def __new__(cls, **kwargs): if 'company_id' in kwargs: instance.company_id = kwargs['company_id'] - if 'minorversion' in kwargs: - instance.minorversion = kwargs['minorversion'] - - if instance.minorversion < instance.MINIMUM_MINOR_VERSION: - warnings.warn( - 'Minor Version no longer supported.' - 'See: https://blogs.intuit.com/2025/01/21/changes-to-our-accounting-api-that-may-impact-your-application/', - DeprecationWarning) + # Handle minorversion with default + instance.minorversion = kwargs.get('minorversion', instance.MINIMUM_MINOR_VERSION) + if 'minorversion' not in kwargs: + warnings.warn( + 'No minor version specified. Defaulting to minimum supported version (75). ' + 'Please specify minorversion explicitly when initializing QuickBooks. ' + 'See: https://blogs.intuit.com/2025/01/21/changes-to-our-accounting-api-that-may-impact-your-application/', + DeprecationWarning) + elif instance.minorversion < instance.MINIMUM_MINOR_VERSION: + warnings.warn( + f'Minor Version {instance.minorversion} is no longer supported. Minimum supported version is {instance.MINIMUM_MINOR_VERSION}. ' + 'See: https://blogs.intuit.com/2025/01/21/changes-to-our-accounting-api-that-may-impact-your-application/', + DeprecationWarning) instance.invoice_link = kwargs.get('invoice_link', False) @@ -157,15 +162,7 @@ def make_request(self, request_type, url, request_body=None, content_type='appli if not params: params = {} - if self.minorversion is None: - warnings.warn( - 'No minor version specified. Defaulting to minimum supported version (75). ' - 'Please specify minorversion explicitly when initializing QuickBooks. ' - 'See: https://blogs.intuit.com/2025/01/21/changes-to-our-accounting-api-that-may-impact-your-application/', - DeprecationWarning) - params['minorversion'] = self.MINIMUM_MINOR_VERSION - else: - params['minorversion'] = self.minorversion + params['minorversion'] = self.minorversion if request_id: params['requestid'] = request_id @@ -240,10 +237,18 @@ def make_request(self, request_type, url, request_body=None, content_type='appli return result def get(self, *args, **kwargs): - return self.make_request("GET", *args, **kwargs) + if 'params' not in kwargs: + kwargs['params'] = {} + if 'minorversion' not in kwargs['params']: + kwargs['params']['minorversion'] = self.MINIMUM_MINOR_VERSION + return self.make_request('GET', *args, **kwargs) def post(self, *args, **kwargs): - return self.make_request("POST", *args, **kwargs) + if 'params' not in kwargs: + kwargs['params'] = {} + if 'minorversion' not in kwargs['params']: + kwargs['params']['minorversion'] = self.MINIMUM_MINOR_VERSION + return self.make_request('POST', *args, **kwargs) def process_request(self, request_type, url, headers="", params="", data=""): if self.session is None: @@ -256,9 +261,9 @@ def process_request(self, request_type, url, headers="", params="", data=""): def get_single_object(self, qbbo, pk, params=None): url = "{0}/company/{1}/{2}/{3}/".format(self.api_url, self.company_id, qbbo.lower(), pk) - result = self.get(url, {}, params=params) - - return result + if params is None: + params = {} + return self.get(url, {}, params=params) @staticmethod def handle_exceptions(results): @@ -316,9 +321,9 @@ def isvalid_object_name(self, object_name): def update_object(self, qbbo, request_body, _file_path=None, request_id=None, params=None): url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) - result = self.post(url, request_body, file_path=_file_path, request_id=request_id, params=params) - - return result + if params is None: + params = {} + return self.post(url, request_body, file_path=_file_path, request_id=request_id, params=params) def delete_object(self, qbbo, request_body, _file_path=None, request_id=None): url = "{0}/company/{1}/{2}".format(self.api_url, self.company_id, qbbo.lower()) From b4014b4f967c023af5bac6d6deba0014f7904154 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Sun, 16 Mar 2025 13:38:18 -0700 Subject: [PATCH 149/154] fixed for new message --- tests/unit/test_client.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 6f7d03a1..9704cf80 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -53,7 +53,8 @@ def test_client_with_deprecated_minor_version(self): self.assertEqual(self.qb_client.minorversion, 74) self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) - self.assertTrue("Minor Version no longer supported." in str(w[-1].message)) + self.assertTrue("Minor Version 74 is no longer supported" in str(w[-1].message)) + self.assertTrue("Minimum supported version is 75" in str(w[-1].message)) def test_api_url(http://github.com/self): qb_client = client.QuickBooks(sandbox=False) @@ -128,7 +129,7 @@ def test_update_object_with_request_id(self, make_req): qb_client.update_object("Customer", "request_body", request_id="123") url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/customer" - make_req.assert_called_with("POST", url, "request_body", file_path=None, file_bytes=None, request_id="123", params={'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) + make_req.assert_called_with("POST", url, "request_body", file_path=None, request_id="123", params={'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) @patch('quickbooks.client.QuickBooks.get') def test_get_current_user(self, get): @@ -146,7 +147,8 @@ def test_get_report(self, make_req): qb_client.get_report("profitandloss", {1: 2}) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/reports/profitandloss" - make_req.assert_called_with("GET", url, params={1: 2}) + expected_params = {1: 2, 'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION} + make_req.assert_called_with("GET", url, params=expected_params) @patch('quickbooks.client.QuickBooks.make_request') def test_get_single_object(self, make_req): From ff14b00005398eddd577ff4820a571a753c2da53 Mon Sep 17 00:00:00 2001 From: "William N. Green" Date: Mon, 24 Mar 2025 10:49:56 -0700 Subject: [PATCH 150/154] fix setup.cfg - -> _ --- setup.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 4f71077b..6b91b5f6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,9 +1,9 @@ [metadata] -description-file = README.md +description_file = README.md [flake8] -max-line-length = 100 -max-complexity = 10 +max_line_length = 100 +max_complexity = 10 filename = *.py format = default exclude =/quickbooks/objects/__init__.py From 58c1855977307a14dc9053cf200ac8207613e718 Mon Sep 17 00:00:00 2001 From: Yonatan Romero Date: Mon, 24 Mar 2025 16:15:46 -0300 Subject: [PATCH 151/154] Remove description-file. It is not supported by setuptools https://github.com/pypa/setuptools/issues/4913 --- setup.cfg | 3 --- 1 file changed, 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 4f71077b..658090f7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,3 @@ -[metadata] -description-file = README.md - [flake8] max-line-length = 100 max-complexity = 10 From beab2723592248a45a33af1096000fe5a5dea0ff Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 15 Apr 2025 20:31:07 -0500 Subject: [PATCH 152/154] Update tests and fix issues --- CHANGELOG.rst | 7 +++++++ quickbooks/client.py | 6 ++---- quickbooks/objects/employee.py | 6 +++--- tests/integration/test_account.py | 2 +- tests/integration/test_base.py | 2 ++ tests/integration/test_employee.py | 10 ++++++---- tests/unit/test_client.py | 8 ++++---- 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f8b25077..176f3c63 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,13 @@ Changelog ========= +* 0.9.11 (April 15, 2025) + * Add CostRate to TimeActivity + * Fix retrieval of Item SKU field + * Added support for attaching files using byte streams + * Default minor version to minimum supported version + * Fix incompatibility issues with setuptools + * 0.9.11 (February 10, 2025) * Add warning for unsupported minorversion * Fix issue with new versions of jsonEncoder diff --git a/quickbooks/client.py b/quickbooks/client.py index 45d6ca46..a4280444 100644 --- a/quickbooks/client.py +++ b/quickbooks/client.py @@ -242,15 +242,13 @@ def make_request(self, request_type, url, request_body=None, content_type='appli def get(self, *args, **kwargs): if 'params' not in kwargs: kwargs['params'] = {} - if 'minorversion' not in kwargs['params']: - kwargs['params']['minorversion'] = self.MINIMUM_MINOR_VERSION + return self.make_request('GET', *args, **kwargs) def post(self, *args, **kwargs): if 'params' not in kwargs: kwargs['params'] = {} - if 'minorversion' not in kwargs['params']: - kwargs['params']['minorversion'] = self.MINIMUM_MINOR_VERSION + return self.make_request('POST', *args, **kwargs) def process_request(self, request_type, url, headers="", params="", data=""): diff --git a/quickbooks/objects/employee.py b/quickbooks/objects/employee.py index 831ef86f..64d4e0ff 100644 --- a/quickbooks/objects/employee.py +++ b/quickbooks/objects/employee.py @@ -17,7 +17,7 @@ class Employee(QuickbooksManagedObject, QuickbooksTransactionEntity): def __init__(self): super(Employee, self).__init__() - self.SSN = "" + self.SSN = None self.GivenName = "" self.FamilyName = "" @@ -29,9 +29,9 @@ def __init__(self): self.Title = "" self.BillRate = 0 self.CostRate = 0 - self.BirthDate = "" + self.BirthDate = None self.Gender = None - self.HiredDate = "" + self.HiredDate = None self.ReleasedDate = "" self.Active = True self.Organization = False diff --git a/tests/integration/test_account.py b/tests/integration/test_account.py index 40383711..741a6b7a 100644 --- a/tests/integration/test_account.py +++ b/tests/integration/test_account.py @@ -24,7 +24,7 @@ def test_create(self): account.AccountSubType = "CashOnHand" created_account = account.save(qb=self.qb_client) - + # Verify the save was successful self.assertIsNotNone(created_account) self.assertIsNotNone(created_account.Id) diff --git a/tests/integration/test_base.py b/tests/integration/test_base.py index 3372b2ab..aca87d42 100644 --- a/tests/integration/test_base.py +++ b/tests/integration/test_base.py @@ -20,6 +20,7 @@ def setUp(self): auth_client=self.auth_client, refresh_token=os.environ.get('REFRESH_TOKEN'), company_id=os.environ.get('COMPANY_ID'), + minorversion=75 ) self.qb_client.sandbox = True @@ -40,6 +41,7 @@ def setUp(self): # auth_client=self.auth_client, refresh_token='REFRESH_TOKEN', company_id='COMPANY_ID', + minorversion=75 ) self.qb_client.sandbox = True diff --git a/tests/integration/test_employee.py b/tests/integration/test_employee.py index 3d8c2235..2f389130 100644 --- a/tests/integration/test_employee.py +++ b/tests/integration/test_employee.py @@ -1,15 +1,17 @@ -from datetime import datetime +from datetime import datetime, date from quickbooks.objects.base import Address, PhoneNumber from quickbooks.objects.employee import Employee from tests.integration.test_base import QuickbooksTestCase +from quickbooks.helpers import qb_date_format class EmployeeTest(QuickbooksTestCase): def test_create(self): employee = Employee() - employee.SSN = "444-55-6666" + employee.SSN = None employee.GivenName = "John" + employee.HiredDate = qb_date_format(date(2020, 7, 22)) employee.FamilyName = "Smith {0}".format(datetime.now().strftime('%d%H%M%S')) employee.PrimaryAddr = Address() @@ -19,13 +21,13 @@ def test_create(self): employee.PrimaryAddr.PostalCode = "93242" employee.PrimaryPhone = PhoneNumber() - employee.PrimaryPhone.FreeFormNumber = "408-525-1234" + employee.PrimaryPhone.FreeFormNumber = "4085251234" + employee.save(qb=self.qb_client) query_employee = Employee.get(employee.Id, qb=self.qb_client) self.assertEqual(query_employee.Id, employee.Id) - self.assertEqual(query_employee.SSN, "XXX-XX-XXXX") self.assertEqual(query_employee.GivenName, employee.GivenName) self.assertEqual(query_employee.FamilyName, employee.FamilyName) self.assertEqual(query_employee.PrimaryAddr.Line1, employee.PrimaryAddr.Line1) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 6740b7cc..94b1eff7 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -123,7 +123,7 @@ def test_update_object_with_request_id(self, make_req): qb_client.update_object("Customer", "request_body", request_id="123") url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/customer" - make_req.assert_called_with("POST", url, "request_body", file_path=None, file_bytes=None, request_id="123", params={'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) + make_req.assert_called_with("POST", url, "request_body", file_path=None, file_bytes=None, request_id="123", params={}) @patch('quickbooks.client.QuickBooks.get') def test_get_current_user(self, get): @@ -141,7 +141,7 @@ def test_get_report(self, make_req): qb_client.get_report("profitandloss", {1: 2}) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/reports/profitandloss" - expected_params = {1: 2, 'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION} + expected_params = {1: 2} make_req.assert_called_with("GET", url, params=expected_params) @patch('quickbooks.client.QuickBooks.make_request') @@ -151,7 +151,7 @@ def test_get_single_object(self, make_req): qb_client.get_single_object("test", 1) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1" - make_req.assert_called_with("GET", url, {}, params={'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) + make_req.assert_called_with("GET", url, {}, params={}) @patch('quickbooks.client.QuickBooks.make_request') def test_get_single_object_with_params(self, make_req): @@ -160,7 +160,7 @@ def test_get_single_object_with_params(self, make_req): qb_client.get_single_object("test", 1, params={'param':'value'}) url = "https://sandbox-quickbooks.api.intuit.com/v3/company/1234/test/1" - make_req.assert_called_with("GET", url, {}, params={'param':'value', 'minorversion': client.QuickBooks.MINIMUM_MINOR_VERSION}) + make_req.assert_called_with("GET", url, {}, params={'param':'value'}) @patch('quickbooks.client.QuickBooks.process_request') def test_make_request(self, process_request): From 71693d0a1c591a55f6523706747d49dc976413fd Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 15 Apr 2025 20:42:08 -0500 Subject: [PATCH 153/154] Update version number --- CHANGELOG.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 176f3c63..10f03ced 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,7 @@ Changelog ========= -* 0.9.11 (April 15, 2025) +* 0.9.12 (April 15, 2025) * Add CostRate to TimeActivity * Fix retrieval of Item SKU field * Added support for attaching files using byte streams diff --git a/setup.py b/setup.py index 1c5d1add..b9d6fb9c 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(*parts): return fp.read() -VERSION = (0, 9, 11) +VERSION = (0, 9, 12) version = '.'.join(map(str, VERSION)) setup( From 264a0f63d6336b006e77bfaadfe27131fa5607bd Mon Sep 17 00:00:00 2001 From: Edward Emanuel Date: Tue, 15 Apr 2025 21:10:40 -0500 Subject: [PATCH 154/154] Update setup --- Pipfile | 1 + Pipfile.lock | 1077 ++++++++++++++++++++++++++++---------------------- setup.cfg | 4 + 3 files changed, 617 insertions(+), 465 deletions(-) diff --git a/Pipfile b/Pipfile index e8e31374..b0ea8afa 100644 --- a/Pipfile +++ b/Pipfile @@ -15,3 +15,4 @@ intuit-oauth = "==1.2.6" requests = ">=2.31.0" requests_oauthlib = ">=1.3.1" build = "*" +twine = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 5cd34380..220836a7 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "dd51fe531ba0bc1e934a0b630dc0b9b838cde70d44207667346ba4701233ba86" + "sha256": "37e1068d8771427de42f27a0fe22a2e43995ba6c50304dfc3595fe3a6185b33e" }, "pipfile-spec": 6, "requires": {}, @@ -25,212 +25,230 @@ }, "certifi": { "hashes": [ - "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", - "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" + "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", + "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe" ], "markers": "python_version >= '3.6'", - "version": "==2024.7.4" + "version": "==2025.1.31" }, "cffi": { "hashes": [ - "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f", - "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab", - "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499", - "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058", - "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693", - "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb", - "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377", - "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885", - "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2", - "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401", - "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4", - "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b", - "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59", - "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f", - "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c", - "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555", - "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa", - "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424", - "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb", - "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2", - "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8", - "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e", - "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9", - "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82", - "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828", - "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759", - "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc", - "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118", - "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf", - "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932", - "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a", - "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29", - "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206", - "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2", - "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c", - "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c", - "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0", - "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a", - "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195", - "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6", - "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9", - "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc", - "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb", - "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0", - "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7", - "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb", - "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a", - "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492", - "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720", - "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42", - "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7", - "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d", - "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d", - "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb", - "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4", - "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2", - "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b", - "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8", - "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e", - "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204", - "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3", - "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150", - "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4", - "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76", - "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e", - "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb", - "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91" + "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", + "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", + "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1", + "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", + "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", + "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", + "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", + "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", + "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", + "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", + "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc", + "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", + "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", + "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", + "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", + "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", + "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", + "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b", + "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", + "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", + "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c", + "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", + "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", + "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", + "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8", + "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1", + "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", + "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", + "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", + "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", + "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", + "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", + "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", + "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", + "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", + "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", + "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", + "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", + "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964", + "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", + "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", + "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", + "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", + "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", + "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", + "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", + "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", + "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", + "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", + "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", + "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", + "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", + "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9", + "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", + "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", + "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", + "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", + "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", + "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", + "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", + "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", + "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], "markers": "platform_python_implementation != 'PyPy'", - "version": "==1.17.0" + "version": "==1.17.1" }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "cryptography": { "hashes": [ - "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709", - "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069", - "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2", - "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b", - "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e", - "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70", - "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778", - "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22", - "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895", - "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf", - "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431", - "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f", - "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947", - "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74", - "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc", - "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66", - "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66", - "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf", - "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f", - "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5", - "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e", - "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f", - "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55", - "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1", - "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47", - "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5", - "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0" - ], - "version": "==43.0.0" + "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390", + "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41", + "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", + "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5", + "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", + "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d", + "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", + "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", + "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", + "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", + "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", + "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", + "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", + "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", + "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", + "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", + "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562", + "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", + "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", + "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", + "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d", + "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471", + "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", + "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa", + "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb", + "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", + "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", + "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", + "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", + "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", + "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", + "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615", + "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", + "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", + "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308" + ], + "version": "==44.0.2" + }, + "docutils": { + "hashes": [ + "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", + "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2" + ], + "markers": "python_version >= '3.9'", + "version": "==0.21.2" }, "enum-compat": { "hashes": [ @@ -239,13 +257,21 @@ ], "version": "==0.0.3" }, + "id": { + "hashes": [ + "sha256:292cb8a49eacbbdbce97244f47a97b4c62540169c976552e497fd57df0734c1d", + "sha256:f1434e1cef91f2cbb8a4ec64663d5a23b9ed43ef44c4c957d02583d61714c658" + ], + "markers": "python_version >= '3.8'", + "version": "==1.5.0" + }, "idna": { "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], - "markers": "python_version >= '3.5'", - "version": "==3.7" + "markers": "python_version >= '3.6'", + "version": "==3.10" }, "intuit-oauth": { "hashes": [ @@ -255,6 +281,92 @@ "index": "pypi", "version": "==1.2.6" }, + "jaraco.classes": { + "hashes": [ + "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" + ], + "markers": "python_version >= '3.8'", + "version": "==3.4.0" + }, + "jaraco.context": { + "hashes": [ + "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", + "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.1" + }, + "jaraco.functools": { + "hashes": [ + "sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", + "sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649" + ], + "markers": "python_version >= '3.8'", + "version": "==4.1.0" + }, + "keyring": { + "hashes": [ + "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66", + "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd" + ], + "markers": "platform_machine != 'ppc64le' and platform_machine != 's390x'", + "version": "==25.6.0" + }, + "markdown-it-py": { + "hashes": [ + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "more-itertools": { + "hashes": [ + "sha256:2cd7fad1009c31cc9fb6a035108509e6547547a7a738374f10bd49a09eb3ee3b", + "sha256:6eb054cb4b6db1473f6e15fcc676a08e4732548acd47c708f0e179c2c7c01e89" + ], + "markers": "python_version >= '3.9'", + "version": "==10.6.0" + }, + "nh3": { + "hashes": [ + "sha256:087ffadfdcd497658c3adc797258ce0f06be8a537786a7217649fc1c0c60c293", + "sha256:20979783526641c81d2f5bfa6ca5ccca3d1e4472474b162c6256745fbfe31cd1", + "sha256:2a5174551f95f2836f2ad6a8074560f261cf9740a48437d6151fd2d4d7d617ab", + "sha256:31eedcd7d08b0eae28ba47f43fd33a653b4cdb271d64f1aeda47001618348fde", + "sha256:4990e7ee6a55490dbf00d61a6f476c9a3258e31e711e13713b2ea7d6616f670e", + "sha256:55823c5ea1f6b267a4fad5de39bc0524d49a47783e1fe094bcf9c537a37df251", + "sha256:6141caabe00bbddc869665b35fc56a478eb774a8c1dfd6fba9fe1dfdf29e6efa", + "sha256:637d4a10c834e1b7d9548592c7aad760611415fcd5bd346f77fd8a064309ae6d", + "sha256:63ca02ac6f27fc80f9894409eb61de2cb20ef0a23740c7e29f9ec827139fa578", + "sha256:6ae319f17cd8960d0612f0f0ddff5a90700fa71926ca800e9028e7851ce44a6f", + "sha256:6c9c30b8b0d291a7c5ab0967ab200598ba33208f754f2f4920e9343bdd88f79a", + "sha256:713d16686596e556b65e7f8c58328c2df63f1a7abe1277d87625dcbbc012ef82", + "sha256:818f2b6df3763e058efa9e69677b5a92f9bc0acff3295af5ed013da544250d5b", + "sha256:9d67709bc0d7d1f5797b21db26e7a8b3d15d21c9c5f58ccfe48b5328483b685b", + "sha256:a5f77e62aed5c4acad635239ac1290404c7e940c81abe561fd2af011ff59f585", + "sha256:a772dec5b7b7325780922dd904709f0f5f3a79fbf756de5291c01370f6df0967", + "sha256:a7ea28cd49293749d67e4fcf326c554c83ec912cd09cd94aa7ec3ab1921c8283", + "sha256:ac7006c3abd097790e611fe4646ecb19a8d7f2184b882f6093293b8d9b887431", + "sha256:b3b5c58161e08549904ac4abd450dacd94ff648916f7c376ae4b2c0652b98ff9", + "sha256:b8d55ea1fc7ae3633d758a92aafa3505cd3cc5a6e40470c9164d54dff6f96d42", + "sha256:bb0014948f04d7976aabae43fcd4cb7f551f9f8ce785a4c9ef66e6c2590f8629", + "sha256:d002b648592bf3033adfd875a48f09b8ecc000abd7f6a8769ed86b6ccc70c759", + "sha256:d426d7be1a2f3d896950fe263332ed1662f6c78525b4520c8e9861f8d7f0d243", + "sha256:fcff321bd60c6c5c9cb4ddf2554e22772bb41ebd93ad88171bbbb6f271255286" + ], + "markers": "python_version >= '3.8'", + "version": "==0.2.21" + }, "oauthlib": { "hashes": [ "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", @@ -279,16 +391,24 @@ "markers": "python_version >= '3.8'", "version": "==2.22" }, + "pygments": { + "hashes": [ + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" + ], + "markers": "python_version >= '3.8'", + "version": "==2.19.1" + }, "pyjwt": { "extras": [ "crypto" ], "hashes": [ - "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850", - "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c" + "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", + "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb" ], - "markers": "python_version >= '3.8'", - "version": "==2.9.0" + "markers": "python_version >= '3.9'", + "version": "==2.10.1" }, "pyproject-hooks": { "hashes": [ @@ -298,6 +418,14 @@ "markers": "python_version >= '3.7'", "version": "==1.2.0" }, + "readme-renderer": { + "hashes": [ + "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", + "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1" + ], + "markers": "python_version >= '3.9'", + "version": "==44.0" + }, "requests": { "hashes": [ "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", @@ -315,210 +443,236 @@ "markers": "python_version >= '3.4'", "version": "==2.0.0" }, + "requests-toolbelt": { + "hashes": [ + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.0.0" + }, + "rfc3986": { + "hashes": [ + "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "rich": { + "hashes": [ + "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", + "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==14.0.0" + }, "six": { "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", + "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "version": "==1.17.0" }, - "urllib3": { + "twine": { "hashes": [ - "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", - "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" + "sha256:a47f973caf122930bf0fbbf17f80b83bc1602c9ce393c7845f289a3001dc5384", + "sha256:be324f6272eff91d07ee93f251edf232fc647935dd585ac003539b42404a8dbd" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.2.2" + "version": "==6.1.0" + }, + "urllib3": { + "hashes": [ + "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", + "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==2.4.0" } }, "develop": { "certifi": { "hashes": [ - "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", - "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" + "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", + "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe" ], "markers": "python_version >= '3.6'", - "version": "==2024.7.4" + "version": "==2025.1.31" }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "coverage": { "extras": [ "toml" ], "hashes": [ - "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca", - "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", - "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", - "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989", - "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", - "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", - "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", - "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", - "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", - "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", - "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", - "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb", - "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", - "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", - "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", - "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8", - "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", - "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", - "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", - "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8", - "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", - "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc", - "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2", - "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", - "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", - "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0", - "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c", - "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", - "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004", - "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", - "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", - "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", - "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", - "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", - "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de", - "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", - "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", - "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569", - "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", - "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", - "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", - "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36", - "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a", - "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6", - "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", - "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", - "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", - "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", - "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", - "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b", - "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255", - "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", - "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3", - "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", - "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", - "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", - "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", - "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", - "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", - "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", - "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", - "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", - "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7", - "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", - "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", - "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", - "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", - "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", - "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a", - "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", - "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", - "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc" + "sha256:042e7841a26498fff7a37d6fda770d17519982f5b7d8bf5278d140b67b61095f", + "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3", + "sha256:0915742f4c82208ebf47a2b154a5334155ed9ef9fe6190674b8a46c2fb89cb05", + "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25", + "sha256:2931f66991175369859b5fd58529cd4b73582461877ecfd859b6549869287ffe", + "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257", + "sha256:3043ba1c88b2139126fc72cb48574b90e2e0546d4c78b5299317f61b7f718b78", + "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada", + "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64", + "sha256:4dfd9a93db9e78666d178d4f08a5408aa3f2474ad4d0e0378ed5f2ef71640cb6", + "sha256:52a523153c568d2c0ef8826f6cc23031dc86cffb8c6aeab92c4ff776e7951b28", + "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067", + "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733", + "sha256:5a26c0c795c3e0b63ec7da6efded5f0bc856d7c0b24b2ac84b4d1d7bc578d676", + "sha256:5a570cd9bd20b85d1a0d7b009aaf6c110b52b5755c17be6962f8ccd65d1dbd23", + "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008", + "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd", + "sha256:5c8a5c139aae4c35cbd7cadca1df02ea8cf28a911534fc1b0456acb0b14234f3", + "sha256:6b8af63b9afa1031c0ef05b217faa598f3069148eeee6bb24b79da9012423b82", + "sha256:769773614e676f9d8e8a0980dd7740f09a6ea386d0f383db6821df07d0f08545", + "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00", + "sha256:77af0f6447a582fdc7de5e06fa3757a3ef87769fbb0fdbdeba78c23049140a47", + "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501", + "sha256:821f7bcbaa84318287115d54becb1915eece6918136c6f91045bb84e2f88739d", + "sha256:89b1f4af0d4afe495cd4787a68e00f30f1d15939f550e869de90a86efa7e0814", + "sha256:8a1d96e780bdb2d0cbb297325711701f7c0b6f89199a57f2049e90064c29f6bd", + "sha256:8a40fcf208e021eb14b0fac6bdb045c0e0cab53105f93ba0d03fd934c956143a", + "sha256:8f99eb72bf27cbb167b636eb1726f590c00e1ad375002230607a844d9e9a2318", + "sha256:90e7fbc6216ecaffa5a880cdc9c77b7418c1dcb166166b78dbc630d07f278cc3", + "sha256:94ec0be97723ae72d63d3aa41961a0b9a6f5a53ff599813c324548d18e3b9e8c", + "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42", + "sha256:96121edfa4c2dfdda409877ea8608dd01de816a4dc4a0523356067b305e4e17a", + "sha256:a1f406a8e0995d654b2ad87c62caf6befa767885301f3b8f6f73e6f3c31ec3a6", + "sha256:a321c61477ff8ee705b8a5fed370b5710c56b3a52d17b983d9215861e37b642a", + "sha256:a5761c70c017c1b0d21b0815a920ffb94a670c8d5d409d9b38857874c21f70d7", + "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487", + "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4", + "sha256:b44674870709017e4b4036e3d0d6c17f06a0e6d4436422e0ad29b882c40697d2", + "sha256:b571bf5341ba8c6bc02e0baeaf3b061ab993bf372d982ae509807e7f112554e9", + "sha256:b8194fb8e50d556d5849753de991d390c5a1edeeba50f68e3a9253fbd8bf8ccd", + "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73", + "sha256:bbb5cc845a0292e0c520656d19d7ce40e18d0e19b22cb3e0409135a575bf79fc", + "sha256:be945402e03de47ba1872cd5236395e0f4ad635526185a930735f66710e1bd3f", + "sha256:bf13d564d310c156d1c8e53877baf2993fb3073b2fc9f69790ca6a732eb4bfea", + "sha256:cf60dd2696b457b710dd40bf17ad269d5f5457b96442f7f85722bdb16fa6c899", + "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a", + "sha256:d39fc4817fd67b3915256af5dda75fd4ee10621a3d484524487e33416c6f3543", + "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1", + "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7", + "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d", + "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502", + "sha256:e5d2b9be5b0693cf21eb4ce0ec8d211efb43966f6657807f6859aab3814f946b", + "sha256:e5ff52d790c7e1628241ffbcaeb33e07d14b007b6eb00a19320c7b8a7024c040", + "sha256:e75a2ad7b647fd8046d58c3132d7eaf31b12d8a53c0e4b21fa9c4d23d6ee6d3c", + "sha256:e7ac22a0bb2c7c49f441f7a6d46c9c80d96e56f5a8bc6972529ed43c8b694e27", + "sha256:ed2144b8a78f9d94d9515963ed273d620e07846acd5d4b0a642d4849e8d91a0c", + "sha256:f017a61399f13aa6d1039f75cd467be388d157cd81f1a119b9d9a68ba6f2830d", + "sha256:f1d8a2a57b47142b10374902777e798784abf400a004b14f1b0b9eaf1e528ba4", + "sha256:f2d32f95922927186c6dbc8bc60df0d186b6edb828d299ab10898ef3f40052fe", + "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323", + "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883", + "sha256:f9983d01d7705b2d1f7a95e10bbe4091fabc03a46881a256c2787637b087003f", + "sha256:fa260de59dfb143af06dcf30c2be0b200bed2a73737a8a59248fcb9fa601ef0f" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==7.6.1" + "markers": "python_version >= '3.9'", + "version": "==7.8.0" }, "docutils": { "hashes": [ @@ -528,29 +682,29 @@ "markers": "python_version >= '3.9'", "version": "==0.21.2" }, - "idna": { + "id": { "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" + "sha256:292cb8a49eacbbdbce97244f47a97b4c62540169c976552e497fd57df0734c1d", + "sha256:f1434e1cef91f2cbb8a4ec64663d5a23b9ed43ef44c4c957d02583d61714c658" ], - "markers": "python_version >= '3.5'", - "version": "==3.7" + "markers": "python_version >= '3.8'", + "version": "==1.5.0" }, - "importlib-metadata": { + "idna": { "hashes": [ - "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369", - "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], - "markers": "python_version >= '3.8'", - "version": "==8.2.0" + "markers": "python_version >= '3.6'", + "version": "==3.10" }, "iniconfig": { "hashes": [ - "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", - "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", + "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" + "markers": "python_version >= '3.8'", + "version": "==2.1.0" }, "jaraco.classes": { "hashes": [ @@ -562,27 +716,27 @@ }, "jaraco.context": { "hashes": [ - "sha256:3e16388f7da43d384a1a7cd3452e72e14732ac9fe459678773a3608a812bf266", - "sha256:c2f67165ce1f9be20f32f650f25d8edfc1646a8aeee48ae06fb35f90763576d2" + "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", + "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4" ], "markers": "python_version >= '3.8'", - "version": "==5.3.0" + "version": "==6.0.1" }, "jaraco.functools": { "hashes": [ - "sha256:3460c74cd0d32bf82b9576bbb3527c4364d5b27a21f5158a62aed6c4b42e23f5", - "sha256:c9d16a3ed4ccb5a889ad8e0b7a343401ee5b2a71cee6ed192d3f68bc351e94e3" + "sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", + "sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649" ], "markers": "python_version >= '3.8'", - "version": "==4.0.2" + "version": "==4.1.0" }, "keyring": { "hashes": [ - "sha256:8d85a1ea5d6db8515b59e1c5d1d1678b03cf7fc8b8dcfb1651e8c4a524eb42ef", - "sha256:8d963da00ccdf06e356acd9bf3b743208878751032d8599c6cc89eb51310ffae" + "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66", + "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd" ], - "markers": "python_version >= '3.8'", - "version": "==25.3.0" + "markers": "platform_machine != 'ppc64le' and platform_machine != 's390x'", + "version": "==25.6.0" }, "markdown-it-py": { "hashes": [ @@ -602,48 +756,49 @@ }, "more-itertools": { "hashes": [ - "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463", - "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320" + "sha256:2cd7fad1009c31cc9fb6a035108509e6547547a7a738374f10bd49a09eb3ee3b", + "sha256:6eb054cb4b6db1473f6e15fcc676a08e4732548acd47c708f0e179c2c7c01e89" ], - "markers": "python_version >= '3.8'", - "version": "==10.3.0" + "markers": "python_version >= '3.9'", + "version": "==10.6.0" }, "nh3": { "hashes": [ - "sha256:0411beb0589eacb6734f28d5497ca2ed379eafab8ad8c84b31bb5c34072b7164", - "sha256:14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86", - "sha256:19aaba96e0f795bd0a6c56291495ff59364f4300d4a39b29a0abc9cb3774a84b", - "sha256:34c03fa78e328c691f982b7c03d4423bdfd7da69cd707fe572f544cf74ac23ad", - "sha256:36c95d4b70530b320b365659bb5034341316e6a9b30f0b25fa9c9eff4c27a204", - "sha256:3a157ab149e591bb638a55c8c6bcb8cdb559c8b12c13a8affaba6cedfe51713a", - "sha256:42c64511469005058cd17cc1537578eac40ae9f7200bedcfd1fc1a05f4f8c200", - "sha256:5f36b271dae35c465ef5e9090e1fdaba4a60a56f0bb0ba03e0932a66f28b9189", - "sha256:6955369e4d9f48f41e3f238a9e60f9410645db7e07435e62c6a9ea6135a4907f", - "sha256:7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811", - "sha256:8ce0f819d2f1933953fca255db2471ad58184a60508f03e6285e5114b6254844", - "sha256:94a166927e53972a9698af9542ace4e38b9de50c34352b962f4d9a7d4c927af4", - "sha256:a7f1b5b2c15866f2db413a3649a8fe4fd7b428ae58be2c0f6bca5eefd53ca2be", - "sha256:c8b3a1cebcba9b3669ed1a84cc65bf005728d2f0bc1ed2a6594a992e817f3a50", - "sha256:de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307", - "sha256:f0eca9ca8628dbb4e916ae2491d72957fdd35f7a5d326b7032a345f111ac07fe" - ], - "version": "==0.2.18" - }, - "packaging": { - "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:087ffadfdcd497658c3adc797258ce0f06be8a537786a7217649fc1c0c60c293", + "sha256:20979783526641c81d2f5bfa6ca5ccca3d1e4472474b162c6256745fbfe31cd1", + "sha256:2a5174551f95f2836f2ad6a8074560f261cf9740a48437d6151fd2d4d7d617ab", + "sha256:31eedcd7d08b0eae28ba47f43fd33a653b4cdb271d64f1aeda47001618348fde", + "sha256:4990e7ee6a55490dbf00d61a6f476c9a3258e31e711e13713b2ea7d6616f670e", + "sha256:55823c5ea1f6b267a4fad5de39bc0524d49a47783e1fe094bcf9c537a37df251", + "sha256:6141caabe00bbddc869665b35fc56a478eb774a8c1dfd6fba9fe1dfdf29e6efa", + "sha256:637d4a10c834e1b7d9548592c7aad760611415fcd5bd346f77fd8a064309ae6d", + "sha256:63ca02ac6f27fc80f9894409eb61de2cb20ef0a23740c7e29f9ec827139fa578", + "sha256:6ae319f17cd8960d0612f0f0ddff5a90700fa71926ca800e9028e7851ce44a6f", + "sha256:6c9c30b8b0d291a7c5ab0967ab200598ba33208f754f2f4920e9343bdd88f79a", + "sha256:713d16686596e556b65e7f8c58328c2df63f1a7abe1277d87625dcbbc012ef82", + "sha256:818f2b6df3763e058efa9e69677b5a92f9bc0acff3295af5ed013da544250d5b", + "sha256:9d67709bc0d7d1f5797b21db26e7a8b3d15d21c9c5f58ccfe48b5328483b685b", + "sha256:a5f77e62aed5c4acad635239ac1290404c7e940c81abe561fd2af011ff59f585", + "sha256:a772dec5b7b7325780922dd904709f0f5f3a79fbf756de5291c01370f6df0967", + "sha256:a7ea28cd49293749d67e4fcf326c554c83ec912cd09cd94aa7ec3ab1921c8283", + "sha256:ac7006c3abd097790e611fe4646ecb19a8d7f2184b882f6093293b8d9b887431", + "sha256:b3b5c58161e08549904ac4abd450dacd94ff648916f7c376ae4b2c0652b98ff9", + "sha256:b8d55ea1fc7ae3633d758a92aafa3505cd3cc5a6e40470c9164d54dff6f96d42", + "sha256:bb0014948f04d7976aabae43fcd4cb7f551f9f8ce785a4c9ef66e6c2590f8629", + "sha256:d002b648592bf3033adfd875a48f09b8ecc000abd7f6a8769ed86b6ccc70c759", + "sha256:d426d7be1a2f3d896950fe263332ed1662f6c78525b4520c8e9861f8d7f0d243", + "sha256:fcff321bd60c6c5c9cb4ddf2554e22772bb41ebd93ad88171bbbb6f271255286" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==0.2.21" }, - "pkginfo": { + "packaging": { "hashes": [ - "sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297", - "sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], - "markers": "python_version >= '3.6'", - "version": "==1.10.0" + "markers": "python_version >= '3.8'", + "version": "==24.2" }, "pluggy": { "hashes": [ @@ -655,29 +810,29 @@ }, "pygments": { "hashes": [ - "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", - "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" ], "markers": "python_version >= '3.8'", - "version": "==2.18.0" + "version": "==2.19.1" }, "pytest": { "hashes": [ - "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", - "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce" + "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", + "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.3.2" + "version": "==8.3.5" }, "pytest-cov": { "hashes": [ - "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", - "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857" + "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", + "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==5.0.0" + "markers": "python_version >= '3.9'", + "version": "==6.1.1" }, "readme-renderer": { "hashes": [ @@ -714,37 +869,29 @@ }, "rich": { "hashes": [ - "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", - "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432" + "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", + "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.7.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==14.0.0" }, "twine": { "hashes": [ - "sha256:215dbe7b4b94c2c50a7315c0275d2258399280fbb7d04182c7e55e24b5f93997", - "sha256:9aa0825139c02b3434d913545c7b847a21c835e11597f5255842d457da2322db" + "sha256:a47f973caf122930bf0fbbf17f80b83bc1602c9ce393c7845f289a3001dc5384", + "sha256:be324f6272eff91d07ee93f251edf232fc647935dd585ac003539b42404a8dbd" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.1.1" + "version": "==6.1.0" }, "urllib3": { "hashes": [ - "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", - "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" + "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", + "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==2.2.2" - }, - "zipp": { - "hashes": [ - "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19", - "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c" - ], - "markers": "python_version >= '3.8'", - "version": "==3.19.2" + "markers": "python_version >= '3.9'", + "version": "==2.4.0" } } } diff --git a/setup.cfg b/setup.cfg index 29ffc5c1..5af119fa 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,7 @@ +[project] +name = "python-quickbooks" +version = "0.9.12" + [flake8] max_line_length = 100 max_complexity = 10