python-terminusgps 45.6.1__py3-none-any.whl → 45.7.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: 45.6.1
3
+ Version: 45.7.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://terminusgps.github.io/python-terminusgps
6
6
  Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
@@ -3,16 +3,14 @@ terminusgps/default_settings.py,sha256=7GLW3RlkuTbpj82KSWjcbgf-unEmrPvKCyLci14LG
3
3
  terminusgps/mixins.py,sha256=Q9ZJuzpk3d9lDnlVA8ZTVvnZWxB13p08EQ8yVJcztn4,1034
4
4
  terminusgps/validators.py,sha256=Mf0c7ku_wTQ7uv4hcLRyz0r2eRjvznIL77LLTE5uJ6E,9152
5
5
  terminusgps/authorizenet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- terminusgps/authorizenet/auth.py,sha256=T4lPm6eq2ZRoPffLg6GrLZn7wUZ-RTBNi0epyw6ph_w,1035
7
6
  terminusgps/authorizenet/constants.py,sha256=--3DNOw3_gjh2BIEqP3Jel5TvZsdoptYV17B4sg9bK0,2131
8
- terminusgps/authorizenet/controllers.py,sha256=gmsvCVzGglmhIu3_TJpzOlel19cNuLiN7CCnaNM-Lm0,2072
9
- terminusgps/authorizenet/services.py,sha256=oNnY9Sk4k7IbASnggavPUqlCj98OfBa-uuUE2xlKtXg,2496
7
+ terminusgps/authorizenet/service.py,sha256=MKtudM2vwmBytCneZsQ9PDAX-RO4Ma2sPL6ZwEcHDms,4198
10
8
  terminusgps/authorizenet/api/__init__.py,sha256=VXR4Yco1yz5R-R7vgaH2zTP9VFqzfvvGy_XJVjyb3i0,154
11
9
  terminusgps/authorizenet/api/address_profiles.py,sha256=VouUN6dIxlnuE3qEiacFqqDBi_VtwvSbsELqTqFZ0BE,4746
12
10
  terminusgps/authorizenet/api/customer_profiles.py,sha256=oya9KMRE10nKLjECTIdanfV_P8-gnNZLE0sYmRYVkgM,4505
13
11
  terminusgps/authorizenet/api/payment_profiles.py,sha256=s-telQZXdq6bu5TxWVYv5xBNHWq81ve_hQVrRlqoBb0,8089
14
12
  terminusgps/authorizenet/api/subscriptions.py,sha256=VAXKjOHLOfifrixObK6XbiJCmPobkYBzXJQrjtos9LE,4542
15
- terminusgps/authorizenet/api/transactions.py,sha256=drymc7uplWHOoaMmatz8nP1gDN_GDef0QVJBqB9oIfE,20
13
+ terminusgps/authorizenet/api/transactions.py,sha256=YS674zn_oumWlK5zZrF8Isu0On_MAL8xBU9zUVEGx8E,3686
16
14
  terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
15
  terminusgps/wialon/constants.py,sha256=p2BhopeE6lXzjzdzb4ZKOz0rhJQIMUbXLrBy1Yzf57s,13730
18
16
  terminusgps/wialon/flags.py,sha256=M50EdhxQ8IMnJnU0mrHK7-h8Asc6tvNiTOOfd1dBW6A,12815
@@ -29,7 +27,7 @@ terminusgps/wialon/items/route.py,sha256=9hmRBEFRJF3lKukv_y3blZxqxv75YgFCcRALrU6
29
27
  terminusgps/wialon/items/unit.py,sha256=B5iuGEghu89SL8KzYLUytYNRa8cogsVtf-bJ_RybPTA,5522
30
28
  terminusgps/wialon/items/unit_group.py,sha256=MIR0x5IlTjcnwx8Y9wXLNTql-wwVVj7NCe7dL2vOw4c,2131
31
29
  terminusgps/wialon/items/user.py,sha256=CRSICiJ-qzybEO_gXuKyzW5oa2RQeIp0SzX9ARcdME4,5151
32
- python_terminusgps-45.6.1.dist-info/METADATA,sha256=BBwcaIviUs-BQVicJ4DQiWMo7OO32HOVdzUoim0ryhk,938
33
- python_terminusgps-45.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
- python_terminusgps-45.6.1.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
35
- python_terminusgps-45.6.1.dist-info/RECORD,,
30
+ python_terminusgps-45.7.0.dist-info/METADATA,sha256=Algwc2rwWNixwYnpupTI7AaSXiVT9S86s8GGOlqTb5o,938
31
+ python_terminusgps-45.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ python_terminusgps-45.7.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
33
+ python_terminusgps-45.7.0.dist-info/RECORD,,
@@ -1,2 +1,100 @@
1
- # TODO
1
+ from decimal import Decimal
2
+
3
+ from authorizenet import apicontractsv1, apicontrollers
4
+ from authorizenet.apicontrollersbase import APIOperationBase
5
+ from lxml.objectify import ObjectifiedElement
6
+
2
7
  __all__ = []
8
+
9
+
10
+ def build_transaction_request(
11
+ transaction_type: str,
12
+ amount: Decimal,
13
+ payment: apicontractsv1.paymentType | None = None,
14
+ order: apicontractsv1.orderType | None = None,
15
+ address: apicontractsv1.customerAddressType | None = None,
16
+ customer_data: apicontractsv1.customerDataType | None = None,
17
+ settings: apicontractsv1.settingType | None = None,
18
+ line_items: apicontractsv1.ArrayOfLineItem | None = None,
19
+ ) -> apicontractsv1.transactionRequestType:
20
+ request = apicontractsv1.transactionRequestType()
21
+ request.transactionType = transaction_type
22
+ request.amount = amount
23
+
24
+ if payment is not None:
25
+ request.payment = payment
26
+ if order is not None:
27
+ request.order = order
28
+ if address is not None:
29
+ request.billTo = address
30
+ if customer_data is not None:
31
+ request.customer = customer_data
32
+ if settings is not None:
33
+ request.transactionSettings = settings
34
+ if line_items is not None:
35
+ request.lineItems = line_items
36
+ return request
37
+
38
+
39
+ def charge_credit_card(
40
+ amount: Decimal,
41
+ credit_card: apicontractsv1.creditCardType,
42
+ address: apicontractsv1.customerAddressType,
43
+ order: apicontractsv1.orderType | None = None,
44
+ customer_data: apicontractsv1.customerDataType | None = None,
45
+ settings: apicontractsv1.settingType | None = None,
46
+ ) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
47
+ request = apicontractsv1.createTransactionRequest()
48
+ request.transactionRequest = build_transaction_request(
49
+ transaction_type="authCaptureTransaction",
50
+ amount=amount,
51
+ payment=apicontractsv1.paymentType(creditCard=credit_card),
52
+ address=address,
53
+ order=order,
54
+ customer_data=customer_data,
55
+ settings=settings,
56
+ )
57
+ return request, apicontrollers.createTransactionController
58
+
59
+
60
+ def authorize_credit_card(
61
+ amount: Decimal,
62
+ credit_card: apicontractsv1.creditCardType,
63
+ address: apicontractsv1.customerAddressType,
64
+ order: apicontractsv1.orderType | None = None,
65
+ customer_data: apicontractsv1.customerDataType | None = None,
66
+ settings: apicontractsv1.settingType | None = None,
67
+ ) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
68
+ request = apicontractsv1.createTransactionRequest()
69
+ request.transactionRequest = build_transaction_request(
70
+ transaction_type="authOnlyTransaction",
71
+ amount=amount,
72
+ payment=apicontractsv1.paymentType(creditCard=credit_card),
73
+ address=address,
74
+ order=order,
75
+ customer_data=customer_data,
76
+ settings=settings,
77
+ )
78
+ return request, apicontrollers.createTransactionController
79
+
80
+
81
+ def capture_authorized_amount(
82
+ amount: Decimal,
83
+ ) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
84
+ request = apicontractsv1.createTransactionRequest()
85
+ request.transactionRequest = build_transaction_request(
86
+ transaction_type="priorAuthCaptureTransaction", amount=amount
87
+ )
88
+ return request, apicontrollers.createTransactionController
89
+
90
+
91
+ def refund_credit_card(
92
+ amount: Decimal, credit_card: apicontractsv1.creditCardType
93
+ ) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
94
+ request = apicontractsv1.createTransactionRequest()
95
+ request.transactionRequest = build_transaction_request(
96
+ transaction_type="refundTransaction",
97
+ amount=amount,
98
+ payment=apicontractsv1.paymentType(creditCard=credit_card),
99
+ )
100
+ return request, apicontrollers.createTransactionController
@@ -0,0 +1,112 @@
1
+ from functools import cached_property
2
+
3
+ from authorizenet.apicontractsv1 import merchantAuthenticationType
4
+ from authorizenet.apicontrollersbase import APIOperationBase
5
+ from django.conf import settings
6
+ from django.core.exceptions import ImproperlyConfigured
7
+ from lxml.objectify import ObjectifiedElement
8
+
9
+ if not settings.configured:
10
+ from terminusgps import default_settings
11
+
12
+ settings.configure(default_settings)
13
+
14
+
15
+ class AuthorizenetControllerExecutionError(Exception):
16
+ """Raised when an Authorizenet API controller fails to execute."""
17
+
18
+ def __init__(self, message: str, code: str, *args, **kwargs) -> None:
19
+ super().__init__(message, *args, **kwargs)
20
+ self._message: str = message
21
+ self._code: str = code
22
+
23
+ def __str__(self) -> str:
24
+ return f"{self.code}: {self.message}"
25
+
26
+ @property
27
+ def message(self) -> str:
28
+ """An Authorizenet API error message."""
29
+ return self._message
30
+
31
+ @property
32
+ def code(self) -> str:
33
+ """An Authorizenet API error code."""
34
+ return self._code
35
+
36
+
37
+ class AuthorizenetService:
38
+ """A service for safely interacting with the Authorizenet API."""
39
+
40
+ REQUIRED_SETTINGS = (
41
+ "MERCHANT_AUTH_ENVIRONMENT",
42
+ "MERCHANT_AUTH_LOGIN_ID",
43
+ "MERCHANT_AUTH_TRANSACTION_KEY",
44
+ "MERCHANT_AUTH_VALIDATION_MODE",
45
+ )
46
+
47
+ def __init__(self) -> None:
48
+ """Raises :py:exc:`~django.core.exceptions.ImproperlyConfigured` if required settings weren't set."""
49
+ for setting in self.REQUIRED_SETTINGS:
50
+ if not hasattr(settings, setting):
51
+ raise ImproperlyConfigured(f"'{setting}' setting is required.")
52
+
53
+ def call_api(
54
+ self,
55
+ request: ObjectifiedElement,
56
+ controller_cls: type[APIOperationBase],
57
+ reference_id: str | None = None,
58
+ ) -> ObjectifiedElement:
59
+ """
60
+ Adds required authentication data to the request before executing it and returning its response.
61
+
62
+ If ``reference_id`` was provided, it is added to the request before execution.
63
+
64
+ :param request: An Authorizenet API request element.
65
+ :type request: ~lxml.objectify.ObjectifiedElement
66
+ :param controller_cls: An Authorizenet controller class.
67
+ :type controller_cls: type[~authorizenet.apicontrollersbase.APIOperationBase]
68
+ :param reference_id: An optional reference id string for the API call. Default is :py:obj:`None`.
69
+ :type reference_id: str | None
70
+ :raises AuthorizenetControllerExecutionError: If the API call failed.
71
+ :returns: An Authorizenet API response.
72
+ :rtype: ~lxml.objectify.ObjectifiedElement
73
+
74
+ """
75
+ request.merchantAuthentication = self.merchantAuthentication
76
+ if reference_id is not None:
77
+ request.refId = reference_id
78
+
79
+ controller = controller_cls(request)
80
+ controller.setenvironment(self.environment)
81
+ controller.execute()
82
+
83
+ response: ObjectifiedElement | None = controller.getresponse()
84
+ if response is None:
85
+ raise AuthorizenetControllerExecutionError(
86
+ message="No response from the Authorizenet API controller.",
87
+ code="1",
88
+ )
89
+ elif response is not None and response.messages.resultCode != "Ok":
90
+ raise AuthorizenetControllerExecutionError(
91
+ message=response.messages.message[0]["text"].text,
92
+ code=response.messages.message[0]["code"].text,
93
+ )
94
+ return response
95
+
96
+ @cached_property
97
+ def merchantAuthentication(self) -> merchantAuthenticationType:
98
+ """Merchant authentication element for Authorizenet API requests."""
99
+ return merchantAuthenticationType(
100
+ name=str(settings.MERCHANT_AUTH_LOGIN_ID),
101
+ transactionKey=str(settings.MERCHANT_AUTH_TRANSACTION_KEY),
102
+ )
103
+
104
+ @cached_property
105
+ def environment(self) -> str:
106
+ """Environment for Authorizenet API requests."""
107
+ return str(settings.MERCHANT_AUTH_ENVIRONMENT)
108
+
109
+ @cached_property
110
+ def validationMode(self) -> str:
111
+ """Validation mode for Authorizenet API requests."""
112
+ return str(settings.MERCHANT_AUTH_VALIDATION_MODE)
@@ -1,38 +0,0 @@
1
- from authorizenet.apicontractsv1 import merchantAuthenticationType
2
- from django.conf import settings
3
-
4
-
5
- def get_merchant_auth() -> merchantAuthenticationType:
6
- """
7
- Returns the merchant authentication information for Authorizenet API controller execution.
8
-
9
- :returns: A merchant authentication object.
10
- :rtype: ~authorizenet.apicontractsv1.merchantAuthenticationType
11
-
12
- """
13
- return merchantAuthenticationType(
14
- name=str(settings.MERCHANT_AUTH_LOGIN_ID),
15
- transactionKey=str(settings.MERCHANT_AUTH_TRANSACTION_KEY),
16
- )
17
-
18
-
19
- def get_environment() -> str:
20
- """
21
- Returns the environment for Authorizenet API controller execution.
22
-
23
- :returns: An Authorizenet API environment string.
24
- :rtype: str
25
-
26
- """
27
- return settings.MERCHANT_AUTH_ENVIRONMENT
28
-
29
-
30
- def get_validation_mode() -> str:
31
- """
32
- Returns the validation mode for Authorizenet API controller execution.
33
-
34
- :returns: An Authorizenet API validation string.
35
- :rtype: str
36
-
37
- """
38
- return settings.MERCHANT_AUTH_VALIDATION_MODE
@@ -1,57 +0,0 @@
1
- from authorizenet.apicontrollersbase import APIOperationBase
2
- from lxml.objectify import ObjectifiedElement
3
-
4
-
5
- def execute_controller(
6
- controller: APIOperationBase, environment: str
7
- ) -> ObjectifiedElement:
8
- """
9
- Executes an Authorizenet API controller and returns its response.
10
-
11
- :param controller: An Authorizenet API controller.
12
- :type controller: ~authorizenet.apicontrollersbase.APIOperationBase
13
- :param environment: Authorizenet environment to execute the controller in.
14
- :type environment: :py:obj:`str`
15
- :param merchant_auth: Authorizenet merchant authentication element.
16
- :type merchant_auth: ~authorizenet.apicontractsv1.merchantAuthenticationType
17
- :raises AuthorizenetControllerExecutionError: If the API call fails.
18
- :returns: An Authorizenet API response.
19
- :rtype: ~lxml.objectify.ObjectifiedElement
20
-
21
- """
22
- controller.setenvironment(environment)
23
- controller.execute()
24
- response: ObjectifiedElement | None = controller.getresponse()
25
-
26
- if response is None:
27
- raise AuthorizenetControllerExecutionError(
28
- message="Authorizenet controller response didn't exist.", code="1"
29
- )
30
- elif response is not None and response.messages.resultCode != "Ok":
31
- raise AuthorizenetControllerExecutionError(
32
- message=response.messages.message[0]["text"].text,
33
- code=response.messages.message[0]["code"].text,
34
- )
35
- return response
36
-
37
-
38
- class AuthorizenetControllerExecutionError(Exception):
39
- """Raised when an Authorizenet API controller fails to execute."""
40
-
41
- def __init__(self, message: str, code: str, *args, **kwargs) -> None:
42
- super().__init__(message, *args, **kwargs)
43
- self._message: str = message
44
- self._code: str = code
45
-
46
- def __str__(self) -> str:
47
- return f"{self.code}: {self.message}"
48
-
49
- @property
50
- def message(self) -> str:
51
- """An Authorizenet API error message."""
52
- return self._message
53
-
54
- @property
55
- def code(self) -> str:
56
- """An Authorizenet API error code."""
57
- return self._code
@@ -1,66 +0,0 @@
1
- from functools import cached_property
2
- from typing import Callable
3
-
4
- from authorizenet.apicontractsv1 import merchantAuthenticationType
5
- from django.conf import settings
6
- from django.core.exceptions import ImproperlyConfigured
7
- from lxml.objectify import ObjectifiedElement
8
-
9
- from .auth import get_environment, get_merchant_auth, get_validation_mode
10
- from .controllers import (
11
- AuthorizenetControllerExecutionError,
12
- execute_controller,
13
- )
14
-
15
-
16
- class AuthorizenetService:
17
- """A service for safely interacting with the Authorizenet API."""
18
-
19
- REQUIRED_SETTINGS = (
20
- "MERCHANT_AUTH_ENVIRONMENT",
21
- "MERCHANT_AUTH_LOGIN_ID",
22
- "MERCHANT_AUTH_TRANSACTION_KEY",
23
- "MERCHANT_AUTH_VALIDATION_MODE",
24
- )
25
-
26
- def __init__(self) -> None:
27
- """Raises :py:exc:`~django.core.exceptions.ImproperlyConfigured` if required settings weren't set."""
28
- for setting in self.REQUIRED_SETTINGS:
29
- if not hasattr(settings, setting):
30
- raise ImproperlyConfigured(f"'{setting}' setting is required.")
31
-
32
- def request(self, func: Callable, *args, **kwargs) -> ObjectifiedElement:
33
- """
34
- Calls the Authorizenet API function with arguments and returns the result.
35
-
36
- :param func: An Authorizenet API function.
37
- :type func: ~typing.Callable
38
- :param args: Positional arguments for the API call.
39
- :param kwargs: Keyword arguments for the API call.
40
- :raises ~terminusgps.authorizenet.controllers.AuthorizenetControllerExecutionError: If the API call failed.
41
- :returns: The Authorizenet API call response.
42
- :rtype: ~lxml.objectify.ObjectifiedElement
43
-
44
- """
45
- try:
46
- request, controller_cls = func(*args, **kwargs)
47
- request.merchantAuthentication = self.merchantAuthentication
48
- controller = controller_cls(request)
49
- return execute_controller(controller, self.environment)
50
- except AuthorizenetControllerExecutionError:
51
- raise
52
-
53
- @cached_property
54
- def merchantAuthentication(self) -> merchantAuthenticationType:
55
- """Merchant authentication element for Authorizenet API requests."""
56
- return get_merchant_auth()
57
-
58
- @cached_property
59
- def environment(self) -> str:
60
- """Environment for Authorizenet API requests."""
61
- return get_environment()
62
-
63
- @cached_property
64
- def validationMode(self) -> str:
65
- """Validation mode for Authorizenet API requests."""
66
- return get_validation_mode()