python-terminusgps 32.0.0__py3-none-any.whl → 32.0.1__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: 32.0.1
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
@@ -2,11 +2,11 @@ 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
4
  terminusgps/authorizenet/errors.py,sha256=HG5NwVxQCtOYidVl30y49PC0Ovw5VYdsy9wTgUFMw9M,949
5
- terminusgps/authorizenet/utils.py,sha256=T0ufuNiBgn54VS07qJRJHf7pmapA3sFLSiSGe_nfUog,2802
5
+ terminusgps/authorizenet/utils.py,sha256=JvU99PTfJrMlc0ufwR_iYYYlWg6GMgHhOoJ7eUEQNOc,3940
6
6
  terminusgps/authorizenet/profiles/__init__.py,sha256=IG4XCEEYtHKqXOatlZlob6J3ukAgF7cFR-RXxOSMS1c,161
7
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
8
+ terminusgps/authorizenet/profiles/base.py,sha256=qE2mZxtzNenVD7RDD8KF3ctfKdoK-1awcCi52Ajhb0c,2725
9
+ terminusgps/authorizenet/profiles/customers.py,sha256=9cLZoakpTVlospAe3v15vbXep6CsxVQG5-khggoA1qc,9480
10
10
  terminusgps/authorizenet/profiles/payments.py,sha256=ohhZrs9MB7GkCi7jQvPVvELNKnR9BwzMd607jJmT4n4,11316
11
11
  terminusgps/authorizenet/profiles/subscriptions.py,sha256=N4_0kbBBJ0FtKdIydN8FLnAG2kSI9DHQWAwemMt7Qu8,11020
12
12
  terminusgps/authorizenet/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -32,20 +32,20 @@ terminusgps/wialon/constants.py,sha256=Ju2XL2A4DPFD-w8NjYqEfnnqregl1luPT0XGhGSUn
32
32
  terminusgps/wialon/flags.py,sha256=M50EdhxQ8IMnJnU0mrHK7-h8Asc6tvNiTOOfd1dBW6A,12815
33
33
  terminusgps/wialon/session.py,sha256=09WYWvON_H844IFfdt7_x1we6tHhQSkt9K_BEedBjv0,10396
34
34
  terminusgps/wialon/utils.py,sha256=JWHZ7VEeo8VNBH67gjOAQk5ITKuPllWDlJ4dVSQ5blA,11002
35
- terminusgps/wialon/validators.py,sha256=CVEpFsxqplEcpv4U2ipA6v9y5cSrMKFUXLvze-3vs4U,4223
35
+ terminusgps/wialon/validators.py,sha256=j5vrtcfClAzRdRkWTvRRAmrne1t0R6cKkmYdE7fAkSs,4247
36
36
  terminusgps/wialon/items/__init__.py,sha256=3BVthghekMvhMQSzQgBMlD_phxmKSmp3Zvmo-z0O8Bs,211
37
37
  terminusgps/wialon/items/base.py,sha256=7J5B-EPj997GJV7TbZP7pAfjl2G4nTcKmP-RMxmuzoY,10959
38
38
  terminusgps/wialon/items/resource.py,sha256=DDnyL_Y5P3DxiirUkQb9y4cokMXZVq3xnfn16Vx8sxk,16992
39
39
  terminusgps/wialon/items/retranslator.py,sha256=sVEWrp8q1I-tO_rMTCH7TeQDDbZryIq8d9KVnhYyhH0,3795
40
40
  terminusgps/wialon/items/route.py,sha256=amNPKZqgl8pEzKA_XJudnvBPzEsfHTmrC7uF15sZVI4,1216
41
- terminusgps/wialon/items/unit.py,sha256=iwHM4AfUED2blKkP940RbUxFFPD_4pTDe4Dut853cfA,12302
41
+ terminusgps/wialon/items/unit.py,sha256=0XPLfpFh7djiVOcuZE-lUdB_-_LRSO8C2PvfzBFh3HQ,10744
42
42
  terminusgps/wialon/items/unit_group.py,sha256=QV2ZZgICaN3n6W1pFIyMLyNKB6KYBsLyKG64i-qXoOg,4113
43
43
  terminusgps/wialon/items/user.py,sha256=5LgwalGO8KS_7psmAVmAlnC0S6SPBDZMOuT5ZqPKRmo,7758
44
44
  terminusgps/wialon/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  terminusgps/wialon/tests/test_items.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  terminusgps/wialon/tests/test_session.py,sha256=9mBlYchMo9NeqRIZsmxYzrM1zBHorqu4ooxqSNppLpI,1336
47
47
  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,,
48
+ python_terminusgps-32.0.1.dist-info/METADATA,sha256=_vNbpBrKZT9QAhVQIJPAQBzN-ShJP0ygvzp3fNKjG6s,1581
49
+ python_terminusgps-32.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
50
+ python_terminusgps-32.0.1.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
51
+ python_terminusgps-32.0.1.dist-info/RECORD,,
@@ -9,10 +9,25 @@ from ..utils import ControllerExecutionMixin
9
9
 
10
10
  class AuthorizenetProfileBase(ControllerExecutionMixin):
11
11
  def __init__(
12
- self, merchant_id: int | str, id: int | str | None = None, *args, **kwargs
12
+ self,
13
+ id: int | str | None = None,
14
+ merchant_id: str | None = None,
15
+ *args,
16
+ **kwargs,
13
17
  ) -> None:
14
- self._merchantCustomerId = merchant_id
15
- self._id = int(id) if id else self.create(*args, **kwargs)
18
+ """
19
+ Sets :py:attr:`id` and :py:attr:`merchant_id`, if provided.
20
+
21
+ :raises ValueError: If ``id`` was provided as a string, and contained non-digit characters.
22
+ :returns: Nothing.
23
+ :rtype: :py:obj:`None`
24
+
25
+ """
26
+ if isinstance(id, str) and not id.isdigit():
27
+ raise ValueError(f"'id' can only contain digits, got '{id}'.")
28
+
29
+ self._merchantCustomerId: str | None = merchant_id
30
+ self._id: int | None = int(id) if id else None
16
31
 
17
32
  @override
18
33
  def __str__(self) -> str:
@@ -20,13 +35,13 @@ class AuthorizenetProfileBase(ControllerExecutionMixin):
20
35
 
21
36
  @property
22
37
  def merchantCustomerId(self) -> str:
23
- """An internally designated customer id."""
24
- return str(self._merchantCustomerId)
38
+ """An merchant designated customer id."""
39
+ return str(self._merchantCustomerId) if self._merchantCustomerId else ""
25
40
 
26
41
  @property
27
- def id(self) -> str:
42
+ def id(self) -> str | None:
28
43
  """An Authorizenet generated id."""
29
- return str(self._id)
44
+ return str(self._id) if self._id else None
30
45
 
31
46
  @property
32
47
  def merchantAuthentication(self) -> apicontractsv1.merchantAuthenticationType:
@@ -1,31 +1,20 @@
1
1
  from authorizenet import apicontractsv1, apicontrollers
2
2
  from authorizenet.apicontractsv1 import customerProfileType
3
3
 
4
- from ..utils import ControllerExecutionError
5
- from .base import AuthorizenetProfileBase
4
+ from terminusgps.authorizenet.profiles.base import AuthorizenetProfileBase
6
5
 
7
6
 
8
7
  class CustomerProfile(AuthorizenetProfileBase):
9
8
  """An Authorizenet customer profile."""
10
9
 
11
- def __init__(
12
- self, merchant_id: int | str, id: int | str | None = None, *args, **kwargs
13
- ) -> None:
14
- self._email = None
15
- self._desc = None
16
- try:
17
- response = self._authorizenet_get_customer_profile(
18
- merchant_id=int(merchant_id), issuer_info=False
19
- )
20
- id = (
21
- int(response.profile.customerProfileId)
22
- if response is not None
23
- else None
24
- )
25
- except ControllerExecutionError:
26
- id = None
27
- finally:
28
- super().__init__(merchant_id, id, *args, **kwargs)
10
+ def __init__(self, *args, **kwargs) -> None:
11
+ super().__init__(*args, **kwargs)
12
+ response = self._authorizenet_get_customer_profile()
13
+ self._id = (
14
+ int(response.profile.customerProfileId)
15
+ if response is not None
16
+ else self.create(*args, **kwargs)
17
+ )
29
18
 
30
19
  def create(self, email: str, desc: str = "") -> int:
31
20
  """
@@ -48,7 +37,12 @@ class CustomerProfile(AuthorizenetProfileBase):
48
37
  self._desc = desc
49
38
  return int(response.customerProfileId)
50
39
 
51
- def update(self, email: str, desc: str = "") -> None:
40
+ def update(
41
+ self,
42
+ merchant_id: int | str | None = None,
43
+ email: str | None = None,
44
+ desc: str | None = None,
45
+ ) -> None:
52
46
  """
53
47
  Updates the customer profile.
54
48
 
@@ -61,11 +55,11 @@ class CustomerProfile(AuthorizenetProfileBase):
61
55
  :rtype: :py:obj:`None`
62
56
 
63
57
  """
64
- self._authorizenet_update_customer_profile(email, desc)
65
- if email:
58
+ if any([merchant_id, email, desc]):
59
+ self._authorizenet_update_customer_profile(merchant_id, email, desc)
66
60
  self._email = email
67
- if desc:
68
61
  self._desc = desc
62
+ self._merchantCustomerId = merchant_id
69
63
 
70
64
  def delete(self) -> None:
71
65
  """
@@ -81,56 +75,51 @@ class CustomerProfile(AuthorizenetProfileBase):
81
75
  @property
82
76
  def payment_profile_ids(self) -> list[int]:
83
77
  """A list of the customer's payment profile ids, if any."""
84
- try:
85
- response = self._authorizenet_get_customer_profile(issuer_info=False)
86
- return [
87
- int(profile.customerPaymentProfileId)
88
- for profile in response.profile.paymentProfiles
89
- ]
90
- except ControllerExecutionError:
91
- return []
78
+ response = self._authorizenet_get_customer_profile(issuer_info=False)
79
+ return [
80
+ int(profile.customerPaymentProfileId)
81
+ for profile in response.profile.paymentProfiles
82
+ ]
92
83
 
93
84
  @property
94
85
  def address_profile_ids(self) -> list[int]:
95
86
  """A list of the customer's address profile ids, if any."""
96
- try:
97
- response = self._authorizenet_get_customer_profile(issuer_info=False)
98
- return [
99
- int(profile.customerAddressId)
100
- for profile in response.profile.shipToList
101
- ]
102
- except ControllerExecutionError:
103
- return []
87
+ response = self._authorizenet_get_customer_profile(issuer_info=False)
88
+ return [
89
+ int(profile.customerAddressId) for profile in response.profile.shipToList
90
+ ]
104
91
 
105
92
  @property
106
93
  def email(self) -> str | None:
107
- if not self._email:
94
+ """A customer email address."""
95
+ if self._email is None:
108
96
  response = self._authorizenet_get_customer_profile(issuer_info=False)
109
- self._email = response.profile.email if response else None
97
+ self._email = response.profile.email if response is not None else None
110
98
  return self._email
111
99
 
112
- @property
113
- def exists(self) -> bool:
114
- return bool(
115
- self._authorizenet_get_customer_profile(merchant_id=self.merchantCustomerId)
116
- )
117
-
118
- def _authorizenet_get_customer_profile_ids(self) -> dict | None:
119
- """
120
- Executes a :py:obj:`~authorizenet.apicontractsv1.getCustomerProfileIdsRequest` using the Authorizenet API.
100
+ @email.setter
101
+ def email(self, other: str) -> None:
102
+ """Sets :py:attr:`email` and updates the customer profile email in Authorizenet."""
103
+ self._email = other
104
+ self._authorizenet_update_customer_profile(email=other)
121
105
 
122
- `getCustomerProfileIdsRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-get-customer-profile-ids>`_
106
+ @property
107
+ def desc(self) -> str | None:
108
+ """A customer description."""
109
+ if self._desc is None:
110
+ response = self._authorizenet_get_customer_profile(issuer_info=False)
111
+ self._desc = response.profile.description if response is not None else None
112
+ return self._desc
123
113
 
124
- :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
125
- :returns: An Authorizenet API response, if any.
126
- :rtype: :py:obj:`dict` | :py:obj:`None`
114
+ @desc.setter
115
+ def desc(self, other: str) -> None:
116
+ """Sets :py:attr:`desc` and updates the customer profile description in Authorizenet."""
117
+ self._desc = other
118
+ self._authorizenet_update_customer_profile(desc=other)
127
119
 
128
- """
129
- request = apicontractsv1.getCustomerProfileIdsRequest(
130
- merchantAuthentication=self.merchantAuthentication
131
- )
132
- controller = apicontrollers.getCustomerProfileIdsController(request)
133
- return self.execute_controller(controller)
120
+ @property
121
+ def exists(self) -> bool:
122
+ return bool(self._authorizenet_get_customer_profile())
134
123
 
135
124
  def _authorizenet_create_customer_profile(
136
125
  self, email: str, desc: str = ""
@@ -161,7 +150,7 @@ class CustomerProfile(AuthorizenetProfileBase):
161
150
  return self.execute_controller(controller)
162
151
 
163
152
  def _authorizenet_get_customer_profile(
164
- self, merchant_id: int | None = None, issuer_info: bool = True
153
+ self, issuer_info: bool = True
165
154
  ) -> dict | None:
166
155
  """
167
156
  Executes a :py:obj:`~authorizenet.apicontractsv1.getCustomerProfileRequest` using the Authorizenet API.
@@ -177,33 +166,32 @@ class CustomerProfile(AuthorizenetProfileBase):
177
166
  :rtype: :py:obj:`dict` | :py:obj:`None`
178
167
 
179
168
  """
180
- if merchant_id is not None:
181
- request = apicontractsv1.getCustomerProfileRequest(
182
- merchantAuthentication=self.merchantAuthentication,
183
- merchantCustomerId=str(merchant_id),
184
- includeIssuerInfo=str(issuer_info).lower(),
185
- )
169
+ request = apicontractsv1.getCustomerProfileRequest(
170
+ merchantAuthentication=self.merchantAuthentication,
171
+ includeIssuerInfo=str(issuer_info).lower(),
172
+ )
173
+ if self.id is not None:
174
+ request.customerProfileId = str(self.id)
175
+ elif self.id is None and self.merchantCustomerId is not None:
176
+ request.merchantCustomerId = str(self.merchantCustomerId)
186
177
  else:
187
- request = apicontractsv1.getCustomerProfileRequest(
188
- merchantAuthentication=self.merchantAuthentication,
189
- customerProfileId=self.id,
190
- includeIssuerInfo=str(issuer_info).lower(),
191
- )
178
+ return
179
+
192
180
  controller = apicontrollers.getCustomerProfileController(request)
193
181
  return self.execute_controller(controller)
194
182
 
195
183
  def _authorizenet_update_customer_profile(
196
- self, email: str, desc: str = ""
184
+ self, email: str | None = None, desc: str | None = None
197
185
  ) -> dict | None:
198
186
  """
199
187
  Executes an :py:obj:`~authorizenet.apicontractsv1.updateCustomerProfileRequest` using the Authorizenet API.
200
188
 
201
189
  `updateCustomerProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-update-customer-profile>`_
202
190
 
203
- :param email: An email address.
204
- :type email: :py:obj:`str`
205
- :param desc: An optional description.
206
- :type desc: :py:obj:`str`
191
+ :param email: A customer email address.
192
+ :type email: :py:obj:`str` | :py:obj:`None`
193
+ :param desc: A customer description.
194
+ :type desc: :py:obj:`str` | :py:obj:`None`
207
195
  :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
208
196
  :raises AssertionError: If :py:attr:`id` wasn't set.
209
197
  :returns: An Authorizenet API response, if any.
@@ -212,14 +200,16 @@ class CustomerProfile(AuthorizenetProfileBase):
212
200
  """
213
201
  assert self.id, "'id' was not set."
214
202
 
203
+ new_profile: customerProfileType = customerProfileType(
204
+ merchantCustomerId=self.merchantCustomerId, customerProfileId=self.id
205
+ )
206
+ if email is not None:
207
+ new_profile.email = email
208
+ if desc is not None:
209
+ new_profile.desc = desc
210
+
215
211
  request = apicontractsv1.updateCustomerProfileRequest(
216
- merchantAuthentication=self.merchantAuthentication,
217
- profile=customerProfileType(
218
- merchantCustomerId=self.merchantCustomerId,
219
- email=email,
220
- description=desc,
221
- customerProfileId=self.id,
222
- ),
212
+ merchantAuthentication=self.merchantAuthentication, profile=new_profile
223
213
  )
224
214
  controller = apicontrollers.updateCustomerProfileController(request)
225
215
  return self.execute_controller(controller)
@@ -44,28 +44,57 @@ def get_customer_profile_ids() -> list[int]:
44
44
  merchantAuthentication=get_merchant_auth()
45
45
  )
46
46
  controller = apicontrollers.getCustomerProfileIdsController(request)
47
- controller.setenvironment(get_environment())
48
- controller.execute()
49
- response = controller.getresponse()
50
-
51
- if response is not None and response.messages.resultCode != "Ok":
52
- raise ControllerExecutionError(
53
- message=response.messages.message[0]["text"].text,
54
- code=response.messages.message[0]["code"].text,
55
- )
47
+ response = ControllerExecutionMixin.execute_controller(controller)
48
+ if response is None or "ids" not in response.getchildren():
49
+ return []
56
50
  return [int(id) for id in response.ids.getchildren()]
57
51
 
58
52
 
59
53
  def generate_customer_address(form: forms.Form) -> apicontractsv1.customerAddressType:
60
- """Takes a form and returns a :py:obj:`~authorizenet.apicontractsv1.customerAddressType`."""
54
+ """
55
+ Takes a form and returns a :py:obj:`~authorizenet.apicontractsv1.customerAddressType`.
56
+
57
+ :param form: A Django form.
58
+ :type form: :py:obj:`~django.forms.Form`
59
+ :raises ValueError: If ``address`` wasn't in the form.
60
+ :raises ValueError: If ``first_name`` wasn't in the form.
61
+ :raises ValueError: If ``last_name`` wasn't in the form.
62
+ :returns: A customer address object.
63
+ :rtype: :py:obj:`~authorizenet.apicontractsv1.customerAddressType`
64
+
65
+ """
66
+ required_fields: list[str] = ["address", "first_name", "last_name"]
67
+ for field in required_fields:
68
+ if field not in form.cleaned_data or form.cleaned_data.get(field) is None:
69
+ raise ValueError(
70
+ f"'{field}' was not provided by the form, got '{form.cleaned_data.get(field)}'."
71
+ )
72
+
61
73
  address: apicontractsv1.customerAddressType = form.cleaned_data["address"]
62
74
  address.firstName = form.cleaned_data["first_name"]
63
75
  address.lastName = form.cleaned_data["last_name"]
64
- address.phone = form.cleaned_data["phone"]
76
+ if form.cleaned_data.get("phone"):
77
+ address.phone = form.cleaned_data["phone"]
65
78
  return address
66
79
 
67
80
 
68
81
  def generate_customer_payment(form: forms.Form) -> apicontractsv1.paymentType:
69
- """Takes a form and returns a :py:obj:`~authorizenet.apicontractsv1.paymentType`."""
70
- credit_card = form.cleaned_data["credit_card"]
82
+ """
83
+ Takes a form and returns a :py:obj:`~authorizenet.apicontractsv1.paymentType`.
84
+
85
+ :param form: A Django form.
86
+ :type form: :py:obj:`~django.forms.Form`
87
+ :raises ValueError: If ``credit_card`` wasn't in the form.
88
+ :returns: A payment object.
89
+ :rtype: :py:obj:`~authorizenet.apicontractsv1.paymentType`
90
+
91
+ """
92
+ required_fields: list[str] = ["credit_card"]
93
+ for field in required_fields:
94
+ if field not in form.cleaned_data or form.cleaned_data.get(field) is None:
95
+ raise ValueError(
96
+ f"'{field}' was not provided by the form, got '{form.cleaned_data.get(field)}'."
97
+ )
98
+
99
+ credit_card: apicontractsv1.creditCardType = form.cleaned_data["credit_card"]
71
100
  return apicontractsv1.paymentType(creditCard=credit_card)
@@ -153,61 +153,10 @@ class WialonUnit(WialonBase):
153
153
  @property
154
154
  def image_url(self) -> str | None:
155
155
  """Returns an absolute url to the unit's icon in Wialon."""
156
- if hasattr(settings, "WIALON_HOST"):
156
+ if settings.configured and hasattr(settings, "WIALON_HOST"):
157
157
  return urljoin(settings.WIALON_HOST, self._image_uri)
158
158
  return urljoin("https://hst-api.wialon.com", self._image_uri)
159
159
 
160
- def assign_to_number(self, value: str) -> None:
161
- """
162
- Sets ``value`` to the unit's ``to_number`` custom field.
163
-
164
- :param value: A new value for the unit's ``to_number`` custom field.
165
- :type value: :py:obj:`str`
166
- :returns: Nothing.
167
- :rtype: :py:obj:`None`
168
-
169
- """
170
- cfield_key: str = "to_number"
171
- cfield_val: str = value
172
- cfield_id: int | None = self.get_cfield_id(cfield_key)
173
-
174
- if cfield_id:
175
- self.update_cfield(cfield_id, cfield_key, cfield_val)
176
-
177
- def assign_iccid(self, value: str) -> None:
178
- """
179
- Sets ``value`` to the unit's ``iccid`` admin field.
180
-
181
- :param value: A new value for the unit's ``iccid`` custom field.
182
- :type value: :py:obj:`str`
183
- :returns: Nothing.
184
- :rtype: :py:obj:`None`
185
-
186
- """
187
- afield_key: str = "iccid"
188
- afield_val: str = value
189
- afield_id: int | None = self.get_afield_id(afield_key)
190
-
191
- if afield_id:
192
- self.update_afield(afield_id, afield_key, afield_val)
193
-
194
- def assign_carrier(self, value: str) -> None:
195
- """
196
- Sets ``value`` to the unit's ``carrier`` admin field.
197
-
198
- :param value: A new value for the unit's ``carrier`` custom field.
199
- :type value: :py:obj:`str`
200
- :returns: Nothing.
201
- :rtype: :py:obj:`None`
202
-
203
- """
204
- afield_key: str = "carrier"
205
- afield_val: str = value
206
- afield_id: int | None = self.get_afield_id(afield_key)
207
-
208
- if afield_id:
209
- self.update_afield(afield_id, afield_key, afield_val)
210
-
211
160
  def execute_command(
212
161
  self,
213
162
  name: str,
@@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
6
6
 
7
7
  from .session import WialonSession
8
8
 
9
- if not hasattr(settings, "WIALON_TOKEN"):
9
+ if settings.configured and not hasattr(settings, "WIALON_TOKEN"):
10
10
  raise ImproperlyConfigured("'WIALON_TOKEN' setting is required.")
11
11
 
12
12