python-terminusgps 32.0.0__py3-none-any.whl → 33.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-terminusgps
3
- Version: 32.0.0
3
+ Version: 33.0.0
4
4
  Summary: Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more.
5
5
  Project-URL: Documentation, https://docs.terminusgps.com
6
6
  Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
@@ -1,17 +1,18 @@
1
1
  terminusgps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  terminusgps/authorizenet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  terminusgps/authorizenet/auth.py,sha256=umNpOXObDrIt2K40padWBedQl7tVAmEg2alBWhGk-qQ,1238
4
- terminusgps/authorizenet/errors.py,sha256=HG5NwVxQCtOYidVl30y49PC0Ovw5VYdsy9wTgUFMw9M,949
5
- terminusgps/authorizenet/utils.py,sha256=T0ufuNiBgn54VS07qJRJHf7pmapA3sFLSiSGe_nfUog,2802
4
+ terminusgps/authorizenet/constants.py,sha256=xmulPmiBLhFfZoc7Il3l-DZA9Nq5HSaJmJKU-v-5X-Y,420
5
+ terminusgps/authorizenet/controllers.py,sha256=9t62qdGpmAkP4tNyPefd7vBRutXvMWsxql6z_pg52Bg,2146
6
+ terminusgps/authorizenet/utils.py,sha256=zmBVqRamCmxEO6tZWRaGPn5uvL_Lr0yO36Lgc954m8k,2930
6
7
  terminusgps/authorizenet/profiles/__init__.py,sha256=IG4XCEEYtHKqXOatlZlob6J3ukAgF7cFR-RXxOSMS1c,161
7
- terminusgps/authorizenet/profiles/addresses.py,sha256=7yrOrb9kIsiiazgWbeH8v_YUBiWG3Y61g46R3S5DD-k,6592
8
- terminusgps/authorizenet/profiles/base.py,sha256=TOUHr22QRQBLErdysOkfcpJBusTjrUTqOmWEyNvMacA,2240
9
- terminusgps/authorizenet/profiles/customers.py,sha256=EkgYUmTt42nhDbIykvDdO5yDLbZra2hm1wimF9YMsKg,9832
10
- terminusgps/authorizenet/profiles/payments.py,sha256=ohhZrs9MB7GkCi7jQvPVvELNKnR9BwzMd607jJmT4n4,11316
11
- terminusgps/authorizenet/profiles/subscriptions.py,sha256=N4_0kbBBJ0FtKdIydN8FLnAG2kSI9DHQWAwemMt7Qu8,11020
8
+ terminusgps/authorizenet/profiles/addresses.py,sha256=xDlnFlIjuR7NVXwfj5aJT9E_GolnYFuYASkfenvWfm8,6292
9
+ terminusgps/authorizenet/profiles/base.py,sha256=lPc8Pugp5EcXtZmeBpeqicij7l0ROGvMYTV8J0fLLmQ,3768
10
+ terminusgps/authorizenet/profiles/customers.py,sha256=ArXOHPgyBu01tgBPHHYyezb4PIeXh70IWjYCy-lHpWg,11734
11
+ terminusgps/authorizenet/profiles/payments.py,sha256=MmjvE4ZSfgyGPRUzeREB_dX_n6QfpC3zGIlqFnIC8BQ,10956
12
+ terminusgps/authorizenet/profiles/subscriptions.py,sha256=m_jb9GqeD1tLmeqSnaGwJrzPcQOulEkF8K1wCaqKR24,7924
12
13
  terminusgps/authorizenet/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- terminusgps/authorizenet/tests/test_auth.py,sha256=zetg5xlg6A0dKuBJR7sPTHfza8TOIG8yIEP_CvI9XWQ,1612
14
- terminusgps/authorizenet/tests/test_profiles.py,sha256=PWSynAZmosnAJVe6vNOpSui1-UwqggrYtaweD9uDDrg,1351
14
+ terminusgps/authorizenet/tests/test_auth.py,sha256=sdByYrcv8RKjcJckOHbyHH1z_M4qrATFI3qj_XDQXbk,1624
15
+ terminusgps/authorizenet/tests/test_profiles.py,sha256=24lo71F5MWOUNdB2MwTAstPUkyfZ58aOiIxiRwyWcd0,7476
15
16
  terminusgps/authorizenet/tests/test_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
17
  terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
18
  terminusgps/aws/connect.py,sha256=TWf2bVz6LqSNQfVD7FKRn3K71VuLOwBj05Gs-9BsROg,693
@@ -32,20 +33,20 @@ terminusgps/wialon/constants.py,sha256=Ju2XL2A4DPFD-w8NjYqEfnnqregl1luPT0XGhGSUn
32
33
  terminusgps/wialon/flags.py,sha256=M50EdhxQ8IMnJnU0mrHK7-h8Asc6tvNiTOOfd1dBW6A,12815
33
34
  terminusgps/wialon/session.py,sha256=09WYWvON_H844IFfdt7_x1we6tHhQSkt9K_BEedBjv0,10396
34
35
  terminusgps/wialon/utils.py,sha256=JWHZ7VEeo8VNBH67gjOAQk5ITKuPllWDlJ4dVSQ5blA,11002
35
- terminusgps/wialon/validators.py,sha256=CVEpFsxqplEcpv4U2ipA6v9y5cSrMKFUXLvze-3vs4U,4223
36
+ terminusgps/wialon/validators.py,sha256=j5vrtcfClAzRdRkWTvRRAmrne1t0R6cKkmYdE7fAkSs,4247
36
37
  terminusgps/wialon/items/__init__.py,sha256=3BVthghekMvhMQSzQgBMlD_phxmKSmp3Zvmo-z0O8Bs,211
37
38
  terminusgps/wialon/items/base.py,sha256=7J5B-EPj997GJV7TbZP7pAfjl2G4nTcKmP-RMxmuzoY,10959
38
39
  terminusgps/wialon/items/resource.py,sha256=DDnyL_Y5P3DxiirUkQb9y4cokMXZVq3xnfn16Vx8sxk,16992
39
40
  terminusgps/wialon/items/retranslator.py,sha256=sVEWrp8q1I-tO_rMTCH7TeQDDbZryIq8d9KVnhYyhH0,3795
40
41
  terminusgps/wialon/items/route.py,sha256=amNPKZqgl8pEzKA_XJudnvBPzEsfHTmrC7uF15sZVI4,1216
41
- terminusgps/wialon/items/unit.py,sha256=iwHM4AfUED2blKkP940RbUxFFPD_4pTDe4Dut853cfA,12302
42
+ terminusgps/wialon/items/unit.py,sha256=0XPLfpFh7djiVOcuZE-lUdB_-_LRSO8C2PvfzBFh3HQ,10744
42
43
  terminusgps/wialon/items/unit_group.py,sha256=QV2ZZgICaN3n6W1pFIyMLyNKB6KYBsLyKG64i-qXoOg,4113
43
44
  terminusgps/wialon/items/user.py,sha256=5LgwalGO8KS_7psmAVmAlnC0S6SPBDZMOuT5ZqPKRmo,7758
44
45
  terminusgps/wialon/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
46
  terminusgps/wialon/tests/test_items.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
47
  terminusgps/wialon/tests/test_session.py,sha256=9mBlYchMo9NeqRIZsmxYzrM1zBHorqu4ooxqSNppLpI,1336
47
48
  terminusgps/wialon/tests/test_utils.py,sha256=SK4PxJQGECFnzx_EQeRAQfsQ5_3FLaVcis2W9u_ibuI,1730
48
- python_terminusgps-32.0.0.dist-info/METADATA,sha256=v9Izrqd4pgBliL_jgwpnjN2iAg9Mj70Vxra2zeHXhtI,1581
49
- python_terminusgps-32.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
50
- python_terminusgps-32.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
51
- python_terminusgps-32.0.0.dist-info/RECORD,,
49
+ python_terminusgps-33.0.0.dist-info/METADATA,sha256=4YbYgxxufZKqEuoRveOGbtRDupqslS3dx_JwW-PzZ9A,1581
50
+ python_terminusgps-33.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
+ python_terminusgps-33.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
52
+ python_terminusgps-33.0.0.dist-info/RECORD,,
@@ -0,0 +1,16 @@
1
+ import enum
2
+
3
+
4
+ class AuthorizenetSubscriptionStatus(enum.StrEnum):
5
+ """Authorizenet subscription statuses."""
6
+
7
+ ACTIVE = "active"
8
+ """An active subscription."""
9
+ EXPIRED = "expired"
10
+ """An expired subscription."""
11
+ SUSPENDED = "suspended"
12
+ """A suspended subscription."""
13
+ CANCELED = "canceled"
14
+ """A canceled subscription."""
15
+ TERMINATED = "terminated"
16
+ """A terminated subscription."""
@@ -0,0 +1,63 @@
1
+ from authorizenet.apicontrollersbase import APIOperationBase
2
+
3
+ from .auth import get_environment
4
+
5
+
6
+ class AuthorizenetControllerExecutor:
7
+ """Allows objects to use :py:meth:`execute_controller` to execute Authorizenet API controllers."""
8
+
9
+ @staticmethod
10
+ def execute_controller(controller: APIOperationBase) -> dict | None:
11
+ """
12
+ Executes an Authorizenet API controller and returns its response.
13
+
14
+ :param controller: An Authorizenet API controller.
15
+ :type controller: :py:obj:`~authorizenet.apicontrollersbase.APIOperationBase`
16
+ :raises AuthorizenetControllerExecutionError: If the API call fails.
17
+ :returns: An Authorizenet API response, if any.
18
+ :rtype: :py:obj:`dict` | :py:obj:`None`
19
+
20
+ """
21
+ controller.setenvironment(get_environment())
22
+ controller.execute()
23
+ response = controller.getresponse()
24
+
25
+ if response is not None and response.messages.resultCode != "Ok":
26
+ raise AuthorizenetControllerExecutionError(
27
+ message=response.messages.message[0]["text"].text,
28
+ code=response.messages.message[0]["code"].text,
29
+ )
30
+ return response
31
+
32
+
33
+ class AuthorizenetControllerExecutionError(Exception):
34
+ """Raised when an Authorizenet API controller fails to execute."""
35
+
36
+ def __init__(self, message: str, code: str, *args, **kwargs) -> None:
37
+ """
38
+ Sets :py:attr:`message` and :py:attr`code` for the exception.
39
+
40
+ :param message: An Authorizenet API error message.
41
+ :type message: :py:obj:`str`
42
+ :param code: An Authorizenet API error code.
43
+ :type code: :py:obj:`str`
44
+ :returns: Nothing.
45
+ :rtype: :py:obj:`None`
46
+
47
+ """
48
+ super().__init__(message, *args, **kwargs)
49
+ self._message = message
50
+ self._code = code
51
+
52
+ def __str__(self) -> str:
53
+ return f"{self.code}: {self.message}"
54
+
55
+ @property
56
+ def message(self) -> str:
57
+ """An Authorizenet API error message."""
58
+ return self._message
59
+
60
+ @property
61
+ def code(self) -> str:
62
+ """An Authorizenet API error code."""
63
+ return self._code
@@ -1,6 +1,6 @@
1
1
  from authorizenet import apicontractsv1, apicontrollers
2
2
 
3
- from .base import AuthorizenetSubProfileBase
3
+ from terminusgps.authorizenet.profiles.base import AuthorizenetSubProfileBase
4
4
 
5
5
 
6
6
  class AddressProfile(AuthorizenetSubProfileBase):
@@ -8,54 +8,42 @@ class AddressProfile(AuthorizenetSubProfileBase):
8
8
 
9
9
  def create(self, address: apicontractsv1.customerAddressType) -> int:
10
10
  """
11
- Creates an Authorizenet address profile.
11
+ Creates the customer shipping address profile in Authorizenet.
12
12
 
13
13
  :param address: A customer address.
14
14
  :type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
15
- :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
16
- :raises ValueError: If the Authorizenet API response was not retrieved.
17
- :returns: A new address profile id.
18
- :rtype: :py:obj:`int`
15
+ :returns: Nothing.
16
+ :rtype: :py:obj:`None`
19
17
 
20
18
  """
21
- response = self._authorizenet_create_shipping_address(address)
22
- if response is None:
23
- raise ValueError("Failed to retrieve Authorizenet API response.")
24
- return int(response.customerAddressId)
19
+ return int(
20
+ self._authorizenet_create_shipping_address(address).customerAddressId
21
+ )
25
22
 
26
- def update(self, address: apicontractsv1.customerAddressType) -> dict | None:
23
+ def update(self, address: apicontractsv1.customerAddressType) -> None:
27
24
  """
28
- Updates the Authorizenet address profile.
25
+ Updates the customer shipping address to the new address in Authorizenet.
29
26
 
30
- :param address: A customer shipping address.
27
+ :param address: A customer address.
31
28
  :type address: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
32
- :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
33
- :returns: An Authorizenet API response, if any.
34
- :rtype: :py:obj:`dict` | :py:obj:`None`
29
+ :returns: Nothing.
30
+ :rtype: :py:obj:`None`
35
31
 
36
32
  """
37
- return self._authorizenet_update_shipping_address(address)
33
+ if self.id:
34
+ self._authorizenet_update_shipping_address(address)
38
35
 
39
- def delete(self) -> dict | None:
36
+ def delete(self) -> None:
40
37
  """
41
- Deletes the Authorizenet address profile.
38
+ Deletes the customer address profile in Authorizenet and sets :py:attr:`id` to :py:obj:`None` if :py:attr:`id` is set.
42
39
 
43
- :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
44
- :returns: An Authorizenet API response, if any.
45
- :rtype: :py:obj:`dict` | :py:obj:`None`
40
+ :returns: Nothing.
41
+ :rtype: :py:obj:`None`
46
42
 
47
43
  """
48
- return self._authorizenet_delete_shipping_address()
49
-
50
- def get_details(self) -> dict | None:
51
- """
52
- Gets details for the Authorizenet address profile.
53
-
54
- :returns: An Authorizenet API response, if any.
55
- :rtype: :py:obj:`dict` | :py:obj:`None`
56
-
57
- """
58
- return self._authorizenet_get_shipping_address()
44
+ if self.id:
45
+ self._authorizenet_delete_shipping_address()
46
+ self.id = None
59
47
 
60
48
  def _authorizenet_get_shipping_address(self) -> dict | None:
61
49
  """
@@ -64,12 +52,14 @@ class AddressProfile(AuthorizenetSubProfileBase):
64
52
  `getCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-get-customer-shipping-address>`_
65
53
 
66
54
  :raises AssertionError: If :py:attr:`id` wasn't set.
55
+ :raises AssertionError: If :py:attr:`customerProfileId` wasn't set.
67
56
  :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
68
57
  :returns: An Authorizenet API response, if any.
69
58
  :rtype: :py:obj:`dict` | :py:obj:`None`
70
59
 
71
60
  """
72
- assert self.id, "'id' was not set."
61
+ assert self.id, "'id' wasn't set."
62
+ assert self.customerProfileId, "'customerProfileId' wasn't set."
73
63
 
74
64
  request = apicontractsv1.getCustomerShippingAddressRequest(
75
65
  merchantAuthentication=self.merchantAuthentication,
@@ -87,7 +77,6 @@ class AddressProfile(AuthorizenetSubProfileBase):
87
77
 
88
78
  `createCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-create-customer-shipping-address>`_
89
79
 
90
- :raises AssertionError: If :py:attr:`id` wasn't set.
91
80
  :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
92
81
  :returns: An Authorizenet API response, if any.
93
82
  :rtype: :py:obj:`dict` | :py:obj:`None`
@@ -99,6 +88,7 @@ class AddressProfile(AuthorizenetSubProfileBase):
99
88
  address=address,
100
89
  defaultShippingAddress=self.default,
101
90
  )
91
+
102
92
  controller = apicontrollers.createCustomerShippingAddressController(request)
103
93
  return self.execute_controller(controller)
104
94
 
@@ -111,12 +101,14 @@ class AddressProfile(AuthorizenetSubProfileBase):
111
101
  `updateCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-update-customer-shipping-address>`_
112
102
 
113
103
  :raises AssertionError: If :py:attr:`id` wasn't set.
104
+ :raises AssertionError: If :py:attr:`customerProfileId` wasn't set.
114
105
  :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
115
106
  :returns: An Authorizenet API response, if any.
116
107
  :rtype: :py:obj:`dict` | :py:obj:`None`
117
108
 
118
109
  """
119
- assert self.id, "'id' was not set."
110
+ assert self.id, "'id' wasn't set."
111
+ assert self.customerProfileId, "'customerProfileId' wasn't set."
120
112
 
121
113
  address.customerAddressId = self.id
122
114
  request = apicontractsv1.updateCustomerShippingAddressRequest(
@@ -135,17 +127,20 @@ class AddressProfile(AuthorizenetSubProfileBase):
135
127
  `deleteCustomerShippingAddressRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-delete-customer-shipping-address>`_
136
128
 
137
129
  :raises AssertionError: If :py:attr:`id` wasn't set.
130
+ :raises AssertionError: If :py:attr:`customerProfileId` wasn't set.
138
131
  :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
139
132
  :returns: An Authorizenet API response, if any.
140
133
  :rtype: :py:obj:`dict` | :py:obj:`None`
141
134
 
142
135
  """
143
- assert self.id, "'id' was not set."
136
+ assert self.id, "'id' wasn't set."
137
+ assert self.customerProfileId, "'customerProfileId' wasn't set."
144
138
 
145
139
  request = apicontractsv1.deleteCustomerShippingAddressRequest(
146
140
  merchantAuthentication=self.merchantAuthentication,
147
141
  customerProfileId=self.customerProfileId,
148
142
  customerAddressId=self.id,
149
143
  )
144
+
150
145
  controller = apicontrollers.deleteCustomerShippingAddressController(request)
151
146
  return self.execute_controller(controller)
@@ -1,70 +1,129 @@
1
- from abc import abstractmethod
2
- from typing import override
3
-
4
1
  from authorizenet import apicontractsv1
5
2
 
6
- from ..auth import get_merchant_auth, get_validation_mode
7
- from ..utils import ControllerExecutionMixin
3
+ from terminusgps.authorizenet.auth import get_merchant_auth, get_validation_mode
4
+ from terminusgps.authorizenet.controllers import AuthorizenetControllerExecutor
8
5
 
9
6
 
10
- class AuthorizenetProfileBase(ControllerExecutionMixin):
11
- def __init__(
12
- self, merchant_id: int | str, id: int | str | None = None, *args, **kwargs
13
- ) -> None:
14
- self._merchantCustomerId = merchant_id
15
- self._id = int(id) if id else self.create(*args, **kwargs)
7
+ class AuthorizenetProfileBase(AuthorizenetControllerExecutor):
8
+ """Base class for Authorizenet profiles."""
9
+
10
+ def __init__(self, id: int | str | None = None, *args, **kwargs) -> None:
11
+ """
12
+ Sets :py:attr:`id` if provided.
13
+
14
+ :returns: Nothing.
15
+ :rtype: :py:obj:`None`
16
+
17
+ """
18
+ self.id = id
16
19
 
17
- @override
18
20
  def __str__(self) -> str:
19
- return f"#{self.id}"
21
+ """
22
+ Returns a string representation of the profile, if :py:attr:`id` was set.
20
23
 
21
- @property
22
- def merchantCustomerId(self) -> str:
23
- """An internally designated customer id."""
24
- return str(self._merchantCustomerId)
24
+ :returns: A string in the format '#id' where 'id' is the profile's Authorizenet generated id number, or a blank string if :py:attr:`id` wasn't set.
25
+ :rtype: :py:obj:`str`
26
+
27
+ """
28
+ return f"#{self.id}" if self.id else ""
25
29
 
26
30
  @property
27
- def id(self) -> str:
28
- """An Authorizenet generated id."""
29
- return str(self._id)
31
+ def id(self) -> str | None:
32
+ """
33
+ An Authorizenet generated id.
34
+
35
+ :type: :py:obj:`str` | :py:obj:`None`
36
+
37
+ """
38
+ return self._id
39
+
40
+ @id.setter
41
+ def id(self, other: int | str | None) -> None:
42
+ """
43
+ Sets :py:attr:`id` to ``other``.
44
+
45
+ :raises ValueError: If ``other`` was provided as a string containing non-digit characters.
46
+ :returns: Nothing.
47
+ :rtype: :py:obj:`None`
48
+
49
+ """
50
+ if isinstance(other, str) and not other.isdigit():
51
+ raise ValueError(f"'id' can only contain digit characters, got '{other}'.")
52
+ self._id = str(other) if other is not None else None
30
53
 
31
54
  @property
32
55
  def merchantAuthentication(self) -> apicontractsv1.merchantAuthenticationType:
33
- """Merchant authentication for Authorizenet API calls."""
34
- return get_merchant_auth()
35
-
36
- @abstractmethod
37
- def create(self, *args, **kwargs) -> int:
38
- raise NotImplementedError("Subclasses must implement this method.")
56
+ """
57
+ A merchant authentication object to authenticate Authorizenet API calls.
39
58
 
40
- @abstractmethod
41
- def update(self, *args, **kwargs) -> dict:
42
- raise NotImplementedError("Subclasses must implement this method.")
59
+ :returns: A merchant authentication object.
60
+ :rtype: :py:obj:`~authorizenet.apicontractsv1.merchantAuthenticationType`
43
61
 
44
- @abstractmethod
45
- def delete(self, *args, **kwargs) -> dict:
46
- raise NotImplementedError("Subclasses must implement this method.")
62
+ """
63
+ return get_merchant_auth()
47
64
 
48
65
 
49
66
  class AuthorizenetSubProfileBase(AuthorizenetProfileBase):
67
+ """Base class for Authorizenet 'sub-profiles', profiles that have an associated customer profile."""
68
+
50
69
  def __init__(
51
- self, customer_profile_id: int | str, default: bool, *args, **kwargs
70
+ self,
71
+ customer_profile_id: int | str,
72
+ id: int | str | None = None,
73
+ default: bool = False,
52
74
  ) -> None:
53
- self._customerProfileId = customer_profile_id
54
- self._default = default
55
- super().__init__(*args, **kwargs)
75
+ """
76
+ Sets :py:attr:`customerProfileId` for the sub-profile.
77
+
78
+ :returns: Nothing.
79
+ :rtype: :py:obj:`None`
80
+
81
+ """
82
+ super().__init__(id=id)
83
+ self.customerProfileId = customer_profile_id
84
+ self.default = default
56
85
 
57
86
  @property
58
87
  def validationMode(self) -> str:
59
- """The validation mode for Authorizenet API calls."""
60
88
  return get_validation_mode()
61
89
 
90
+ @property
91
+ def customerProfileId(self) -> str:
92
+ """
93
+ A customer profile id.
94
+
95
+ :type: :py:obj:`str`
96
+
97
+ """
98
+ return str(self._customerProfileId)
99
+
100
+ @customerProfileId.setter
101
+ def customerProfileId(self, other: int | str) -> None:
102
+ """
103
+ Sets :py:attr:`customerProfileId` to ``other``.
104
+
105
+ :raises ValueError: If the new customer profile id is a string that contains non-digits.
106
+ :param other: A new customer profile id.
107
+ :type other: :py:obj:`int` | :py:obj:`str`
108
+
109
+ """
110
+ if isinstance(other, str) and not other.isdigit():
111
+ raise ValueError(
112
+ f"'customerProfileId' can only contain digits, got '{other}'."
113
+ )
114
+ self._customerProfileId = str(other)
115
+
62
116
  @property
63
117
  def default(self) -> str:
64
- """Whether or not the sub profile is set as default in Authorizenet."""
118
+ """
119
+ Whether or not the sub-profile is set as default.
120
+
121
+ :type: :py:obj:`str`
122
+
123
+ """
65
124
  return str(self._default).lower()
66
125
 
67
- @property
68
- def customerProfileId(self) -> str:
69
- """An Authorizenet generated customer profile id."""
70
- return str(self._customerProfileId)
126
+ @default.setter
127
+ def default(self, other: bool) -> None:
128
+ """Sets :py:attr:`default` to ``other``."""
129
+ self._default = other