python-terminusgps 31.8.1__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: 31.8.1
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=253SeY0CSYlcxsXUmjNJ4X-FgtFTdO3N1XAytAtb_R0,3970
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=RlvSDuBNmtotu1WD24fQEktiBKyqKiTkGaBgoS2_V84,8851
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-31.8.1.dist-info/METADATA,sha256=SAIylvokXcWj7ZD4knARCl2FwzCI1-VVxKDzcj5SIRw,1581
49
- python_terminusgps-31.8.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
50
- python_terminusgps-31.8.1.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
51
- python_terminusgps-31.8.1.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,8 +1,7 @@
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):
@@ -10,8 +9,12 @@ class CustomerProfile(AuthorizenetProfileBase):
10
9
 
11
10
  def __init__(self, *args, **kwargs) -> None:
12
11
  super().__init__(*args, **kwargs)
13
- self._email = None
14
- self._desc = None
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
+ )
15
18
 
16
19
  def create(self, email: str, desc: str = "") -> int:
17
20
  """
@@ -34,7 +37,12 @@ class CustomerProfile(AuthorizenetProfileBase):
34
37
  self._desc = desc
35
38
  return int(response.customerProfileId)
36
39
 
37
- 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:
38
46
  """
39
47
  Updates the customer profile.
40
48
 
@@ -47,11 +55,11 @@ class CustomerProfile(AuthorizenetProfileBase):
47
55
  :rtype: :py:obj:`None`
48
56
 
49
57
  """
50
- self._authorizenet_update_customer_profile(email, desc)
51
- if email:
58
+ if any([merchant_id, email, desc]):
59
+ self._authorizenet_update_customer_profile(merchant_id, email, desc)
52
60
  self._email = email
53
- if desc:
54
61
  self._desc = desc
62
+ self._merchantCustomerId = merchant_id
55
63
 
56
64
  def delete(self) -> None:
57
65
  """
@@ -67,50 +75,51 @@ class CustomerProfile(AuthorizenetProfileBase):
67
75
  @property
68
76
  def payment_profile_ids(self) -> list[int]:
69
77
  """A list of the customer's payment profile ids, if any."""
70
- try:
71
- response = self._authorizenet_get_customer_profile(issuer_info=False)
72
- return [
73
- int(profile.customerPaymentProfileId)
74
- for profile in response.profile.paymentProfiles
75
- ]
76
- except (ControllerExecutionError, AttributeError):
77
- 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
+ ]
78
83
 
79
84
  @property
80
85
  def address_profile_ids(self) -> list[int]:
81
86
  """A list of the customer's address profile ids, if any."""
82
- try:
83
- response = self._authorizenet_get_customer_profile(issuer_info=False)
84
- return [
85
- int(profile.customerAddressId)
86
- for profile in response.profile.shipToList
87
- ]
88
- except (ControllerExecutionError, AttributeError):
89
- return []
87
+ response = self._authorizenet_get_customer_profile(issuer_info=False)
88
+ return [
89
+ int(profile.customerAddressId) for profile in response.profile.shipToList
90
+ ]
90
91
 
91
92
  @property
92
93
  def email(self) -> str | None:
93
- if not self._email:
94
+ """A customer email address."""
95
+ if self._email is None:
94
96
  response = self._authorizenet_get_customer_profile(issuer_info=False)
95
- self._email = response.profile.email if response else None
97
+ self._email = response.profile.email if response is not None else None
96
98
  return self._email
97
99
 
98
- def _authorizenet_get_customer_profile_ids(self) -> dict | None:
99
- """
100
- 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)
101
105
 
102
- `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
103
113
 
104
- :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
105
- :returns: An Authorizenet API response, if any.
106
- :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)
107
119
 
108
- """
109
- request = apicontractsv1.getCustomerProfileIdsRequest(
110
- merchantAuthentication=self.merchantAuthentication
111
- )
112
- controller = apicontrollers.getCustomerProfileIdsController(request)
113
- return self.execute_controller(controller)
120
+ @property
121
+ def exists(self) -> bool:
122
+ return bool(self._authorizenet_get_customer_profile())
114
123
 
115
124
  def _authorizenet_create_customer_profile(
116
125
  self, email: str, desc: str = ""
@@ -148,36 +157,41 @@ class CustomerProfile(AuthorizenetProfileBase):
148
157
 
149
158
  `getCustomerProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-get-customer-profile>`_
150
159
 
160
+ :param merchant_id: An optional customer merchant id.
161
+ :type merchant_id: :py:obj:`int` | :py:obj:`None`
151
162
  :param issuer_info: Whether or not to include issuer info in the response.
152
163
  :type issuer_info: :py:obj:`bool`
153
- :raises AssertionError: If :py:attr:`id` was not set.
154
164
  :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
155
165
  :returns: An Authorizenet API response, if any.
156
166
  :rtype: :py:obj:`dict` | :py:obj:`None`
157
167
 
158
168
  """
159
- assert self.id, "'id' was not set."
160
-
161
169
  request = apicontractsv1.getCustomerProfileRequest(
162
170
  merchantAuthentication=self.merchantAuthentication,
163
- customerProfileId=self.id,
164
171
  includeIssuerInfo=str(issuer_info).lower(),
165
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)
177
+ else:
178
+ return
179
+
166
180
  controller = apicontrollers.getCustomerProfileController(request)
167
181
  return self.execute_controller(controller)
168
182
 
169
183
  def _authorizenet_update_customer_profile(
170
- self, email: str, desc: str = ""
184
+ self, email: str | None = None, desc: str | None = None
171
185
  ) -> dict | None:
172
186
  """
173
187
  Executes an :py:obj:`~authorizenet.apicontractsv1.updateCustomerProfileRequest` using the Authorizenet API.
174
188
 
175
189
  `updateCustomerProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-update-customer-profile>`_
176
190
 
177
- :param email: An email address.
178
- :type email: :py:obj:`str`
179
- :param desc: An optional description.
180
- :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`
181
195
  :raises ControllerExecutionError: If something goes wrong during an Authorizenet API call.
182
196
  :raises AssertionError: If :py:attr:`id` wasn't set.
183
197
  :returns: An Authorizenet API response, if any.
@@ -186,14 +200,16 @@ class CustomerProfile(AuthorizenetProfileBase):
186
200
  """
187
201
  assert self.id, "'id' was not set."
188
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
+
189
211
  request = apicontractsv1.updateCustomerProfileRequest(
190
- merchantAuthentication=self.merchantAuthentication,
191
- profile=customerProfileType(
192
- merchantCustomerId=self.merchantCustomerId,
193
- email=email,
194
- description=desc,
195
- customerProfileId=self.id,
196
- ),
212
+ merchantAuthentication=self.merchantAuthentication, profile=new_profile
197
213
  )
198
214
  controller = apicontrollers.updateCustomerProfileController(request)
199
215
  return self.execute_controller(controller)
@@ -44,59 +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
- def get_customer_profile_id(email: str) -> int | None:
53
+ def generate_customer_address(form: forms.Form) -> apicontractsv1.customerAddressType:
60
54
  """
61
- Retrieves an Authorizenet customer profile id by email address.
55
+ Takes a form and returns a :py:obj:`~authorizenet.apicontractsv1.customerAddressType`.
62
56
 
63
- :param email: A customer email address.
64
- :type email: :py:obj:`str`
65
- :raises ControllerExecutionError: If something goes wrong with the Authorizenet API.
66
- :returns: A customer profile id, if found.
67
- :rtype: :py:obj:`int` | :py:obj:`None`
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`
68
64
 
69
65
  """
70
- request = apicontractsv1.getCustomerProfileRequest(
71
- merchantAuthentication=get_merchant_auth(), email=email, includeIssuerInfo=False
72
- )
73
- controller = apicontrollers.getCustomerProfileController(request)
74
- controller.setenvironment(get_environment())
75
- controller.execute()
76
- response = controller.getresponse()
77
-
78
- if response is not None and response.messages.resultCode != "Ok":
79
- if response.messages.message[0]["code"].text == "E00040":
80
- return # Record not found
81
-
82
- raise ControllerExecutionError(
83
- message=response.messages.message[0]["text"].text,
84
- code=response.messages.message[0]["code"].text,
85
- )
86
- elif response is not None:
87
- return int(response.profile.customerProfileId)
88
-
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
+ )
89
72
 
90
- def generate_customer_address(form: forms.Form) -> apicontractsv1.customerAddressType:
91
- """Takes a form and returns a :py:obj:`~authorizenet.apicontractsv1.customerAddressType`."""
92
73
  address: apicontractsv1.customerAddressType = form.cleaned_data["address"]
93
74
  address.firstName = form.cleaned_data["first_name"]
94
75
  address.lastName = form.cleaned_data["last_name"]
95
- address.phone = form.cleaned_data["phone"]
76
+ if form.cleaned_data.get("phone"):
77
+ address.phone = form.cleaned_data["phone"]
96
78
  return address
97
79
 
98
80
 
99
81
  def generate_customer_payment(form: forms.Form) -> apicontractsv1.paymentType:
100
- """Takes a form and returns a :py:obj:`~authorizenet.apicontractsv1.paymentType`."""
101
- 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"]
102
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