masstack-python-client 0.0.2__py3-none-any.whl → 0.0.3__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,4 +1,4 @@
1
- __version__ = "0.0.2"
1
+ __version__ = "0.0.3"
2
2
  __homepage__ = "https://somconnexio.coop/"
3
3
  __author__ = "Borja Gimeno <borja.gimeno@somconnexio.coop>"
4
4
  __license__ = "GPL-3.0-only"
@@ -0,0 +1,106 @@
1
+ from typing import Optional
2
+ from dataclasses import asdict
3
+
4
+ from masstack_python_client.client import MasstackClient
5
+ from masstack_python_client.resources.enums.document_type_search import (
6
+ DocumentTypeSearch,
7
+ )
8
+ from masstack_python_client.resources.models.signup import (
9
+ SignupRequestData,
10
+ SignupsResponseData,
11
+ )
12
+ from masstack_python_client.resources.models.user import UserData
13
+ from masstack_python_client.resources.utils.serialize import remove_none
14
+
15
+
16
+ class CustomersResource:
17
+ """Provide the necessary functionality to be able to give
18
+ E2E coverage to the entire life-cycle of a client
19
+ https://developers.masstack.com/en/docs/apis_customers_doc_swagger/2/apioverview
20
+ """
21
+
22
+ _api_domain = "customers"
23
+
24
+ @classmethod
25
+ def _request(
26
+ cls,
27
+ method: str,
28
+ endpoint: str,
29
+ params: Optional[dict] = None,
30
+ data: Optional[dict] = None,
31
+ ) -> dict:
32
+ client = MasstackClient()
33
+ func = getattr(client, method)
34
+
35
+ return func(
36
+ api=cls._api_domain,
37
+ version=cls._version,
38
+ endpoint=endpoint,
39
+ params=params,
40
+ data=data,
41
+ )
42
+
43
+
44
+ class SignupsResource(CustomersResource):
45
+ _api_path = "signups"
46
+ _version = "v2"
47
+
48
+ @classmethod
49
+ def add_customer(cls, customer_data: SignupRequestData) -> SignupsResponseData:
50
+ """Add new customers including products purchased.
51
+
52
+ Args:
53
+ customer_data (SignupRequestData): The data of the customer to be added.
54
+
55
+ Returns:
56
+ SignupsResponseData
57
+ """
58
+ payload = remove_none(asdict(customer_data))
59
+ result = cls._request(
60
+ method="post",
61
+ endpoint=cls._api_path,
62
+ data=payload,
63
+ )
64
+
65
+ return SignupsResponseData(
66
+ sell_id=result["sell_id"],
67
+ customer_id=result["customer_id"],
68
+ work_order_id=[result["work_order_id"]],
69
+ )
70
+
71
+
72
+ class Users(CustomersResource):
73
+ _api_path = "users"
74
+ _version = "v2"
75
+
76
+ @classmethod
77
+ def get_user_id_by_doc(cls, doc: str, doc_type: DocumentTypeSearch) -> str:
78
+ """
79
+ Get user ID associated to a given document identification
80
+
81
+ Args:
82
+ doc (str): The user's document number.
83
+ doc_type (DocumentTypeSearch): The type of document.
84
+
85
+ Returns:
86
+ user id.
87
+ """
88
+ data = {"document_type": doc_type.value, "document": doc}
89
+
90
+ return cls._request(method="post", endpoint=f"{cls._api_path}/tree", data=data)[
91
+ "id"
92
+ ]
93
+
94
+ @classmethod
95
+ def get_user_by_id(cls, user_id: str) -> dict:
96
+ """
97
+ Get user information by user ID
98
+
99
+ Args:
100
+ user_id (str): The user's ID.
101
+
102
+ Returns:
103
+ UserData
104
+ """
105
+ user = cls._request(method="get", endpoint=f"{cls._api_path}/{user_id}")
106
+ return UserData.from_dict(**user)
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ class DocumentTypeSearch(Enum):
5
+ NIF = "NIF"
6
+ DNI = "DNI"
7
+ TR = "TR"
8
+ PASS = "PASS"
9
+ CIF = "CIF"
@@ -0,0 +1,11 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(frozen=True)
5
+ class ClientAddress:
6
+ street_name: str
7
+ state_id: int
8
+ locality: str
9
+ postal_code: str
10
+ number: int
11
+ country: str = "España"
@@ -0,0 +1,27 @@
1
+ from dataclasses import dataclass
2
+ from typing import Dict, Any
3
+
4
+ from masstack_python_client.resources.models.client_address import ClientAddress
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class ClientAttribute:
9
+ type: str
10
+ document_type_id: int
11
+ document_value: str
12
+ email: str
13
+ birthdate: str
14
+ nationality_id: int
15
+ contact_phone: str
16
+ gender: str
17
+ language_id: int
18
+ address: ClientAddress
19
+ name: str = None
20
+ company_name: str = None
21
+ middlename: str = "."
22
+ lastname: str = "."
23
+
24
+ @classmethod
25
+ def from_dict(cls, data: Dict[str, Any]) -> "ClientAttribute":
26
+ data_address = data.pop("address")
27
+ return cls(address=ClientAddress(**data_address), **data)
@@ -0,0 +1,14 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(frozen=True)
5
+ class BankAccount:
6
+ bank_account: str
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class ScoringAccount:
11
+ id_value: float = 1.01
12
+ scoring_value: int = 71
13
+ up_front: float = 1.01
14
+ forced_value: float = 0.01
@@ -0,0 +1,90 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import List, Dict, Any
3
+
4
+
5
+ @dataclass(frozen=True)
6
+ class Contact:
7
+ name: str
8
+ phone: str
9
+ email: str
10
+ document_type_id: str
11
+ document_value: str
12
+ middlename: str = "."
13
+ lastname: str = "."
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class Address:
18
+ street_type_id: int
19
+ street_name: str
20
+ number: int
21
+ supplement: str
22
+ state_id: int
23
+ locality: str
24
+ postal_code: str
25
+ gescal: str
26
+ address_id: str
27
+ pair_vacancy: bool = True
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class Info:
32
+ contact: Contact
33
+ address: Address
34
+
35
+ @classmethod
36
+ def from_dict(
37
+ cls,
38
+ data: Dict[str, Any],
39
+ ) -> "Info":
40
+ return cls(
41
+ contact=Contact(**data["contact"]),
42
+ address=Address(**data["address"]),
43
+ )
44
+
45
+
46
+ @dataclass(frozen=True)
47
+ class Landline:
48
+ product_id: int
49
+ number: str
50
+ services: List = field(default_factory=list)
51
+ wants_communications: bool = False
52
+ # TODO portability_info
53
+
54
+
55
+ @dataclass(frozen=True)
56
+ class Ftth:
57
+ product_id: int
58
+ connection_type: str = ""
59
+ installer: str = "MM"
60
+ wants_communications: bool = False
61
+ # TODO access_reuse
62
+ # TODO access_reuse_choice
63
+ # TODO iua
64
+
65
+
66
+ @dataclass(frozen=True)
67
+ class Bundle:
68
+ bundle_id: int
69
+ territory_owner: str
70
+ installation_info: Info
71
+ delivery_info: Info
72
+ landline: Landline
73
+ ftth: Ftth
74
+
75
+ @classmethod
76
+ def from_dict(
77
+ cls,
78
+ bundle_id: int,
79
+ territory_owner: str,
80
+ **data,
81
+ ) -> "Bundle":
82
+ info = Info.from_dict(data["client_info"])
83
+ return cls(
84
+ bundle_id,
85
+ territory_owner,
86
+ installation_info=info,
87
+ delivery_info=info,
88
+ landline=Landline(**data["land_line"]),
89
+ ftth=Ftth(**data["ftth"]),
90
+ )
@@ -0,0 +1,78 @@
1
+ from dataclasses import dataclass
2
+ from typing import List, Dict, Any
3
+
4
+ from masstack_python_client.resources.models.client_attribute import ClientAttribute
5
+ from masstack_python_client.resources.models.client_payment import (
6
+ BankAccount,
7
+ ScoringAccount,
8
+ )
9
+ from masstack_python_client.resources.models.products import Bundle
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class SalesInfo:
14
+ dealer_id: str
15
+ shop_id: str
16
+ channel: str = "dealer"
17
+ logistic: bool = False
18
+
19
+
20
+ @dataclass(frozen=True)
21
+ class Clients:
22
+ attributes: List[ClientAttribute]
23
+ sector_id: int = 1
24
+
25
+ @classmethod
26
+ def from_dict(cls, data: Dict[str, Any]) -> "Clients":
27
+ client_types = ["client", "account"]
28
+ return cls(
29
+ attributes=[
30
+ ClientAttribute.from_dict({"type": client_type, **data})
31
+ for client_type in client_types
32
+ ]
33
+ )
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class ClientPayment:
38
+ info: BankAccount
39
+ scoring: ScoringAccount = ScoringAccount()
40
+ billing_type_id: int = 1
41
+
42
+ @classmethod
43
+ def from_dict(cls, data: Dict[str, Any]) -> "ClientPayment":
44
+ return cls(info=BankAccount(bank_account=data["bank_account"]))
45
+
46
+
47
+ @dataclass(frozen=True)
48
+ class Products:
49
+ bundle: Bundle
50
+
51
+ @classmethod
52
+ def from_dict(cls, data: Dict[str, Any]) -> "Products":
53
+ return cls(bundle=Bundle.from_dict(**data))
54
+
55
+
56
+ @dataclass(frozen=True)
57
+ class SignupRequestData:
58
+ sales_info: SalesInfo
59
+ clients: Clients
60
+ payment: ClientPayment
61
+ products: Products
62
+ sales_type: str = "telecomunications"
63
+
64
+ @classmethod
65
+ def from_dict(cls, data: Dict[str, Any]) -> "SignupRequestData":
66
+ return cls(
67
+ sales_info=SalesInfo(**data["sales"]),
68
+ clients=Clients.from_dict(data["client"]),
69
+ payment=ClientPayment.from_dict(data["payment"]),
70
+ products=Products.from_dict(data["products"]),
71
+ )
72
+
73
+
74
+ @dataclass(frozen=True)
75
+ class SignupsResponseData:
76
+ sell_id: int
77
+ customer_id: int
78
+ work_order_id: str
@@ -0,0 +1,42 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(frozen=True)
5
+ class UserData:
6
+ id: int
7
+ document_value: str
8
+ document_type_id: int
9
+ gender: str
10
+ first_name: str
11
+ middle_name: str
12
+ last_name: str
13
+ nationality: str
14
+ email: str
15
+ birthdate: str
16
+ phone: str
17
+
18
+ @classmethod
19
+ def from_dict(
20
+ cls,
21
+ id,
22
+ document_value: str,
23
+ document_type: dict,
24
+ nationality: dict,
25
+ personal: dict,
26
+ **kwargs,
27
+ ):
28
+ return cls(
29
+ **{
30
+ "id": id,
31
+ "document_value": document_value,
32
+ "document_type_id": document_type["id"],
33
+ "gender": personal["gender"],
34
+ "first_name": personal["first_name"],
35
+ "middle_name": personal["middle_name"],
36
+ "last_name": personal["last_name"],
37
+ "nationality": nationality["value"],
38
+ "email": personal["email"],
39
+ "birthdate": personal["birthdate"],
40
+ "phone": personal["other_phone"],
41
+ }
42
+ )
@@ -0,0 +1,7 @@
1
+ def remove_none(obj):
2
+ if isinstance(obj, dict):
3
+ return {k: remove_none(v) for k, v in obj.items() if v is not None}
4
+ elif isinstance(obj, list):
5
+ return [remove_none(v) for v in obj if v is not None]
6
+ else:
7
+ return obj
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: masstack-python-client
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: This Python API client provides access to masmovil core API domains
5
5
  Author-email: Borja Gimeno <borja.gimeno@somconnexio.coop>
6
6
  License: GPL-3.0-only
@@ -38,6 +38,13 @@ This Python API client provides access to masmovil core API domains.
38
38
  - get: returns a unit by id with a list of coverages
39
39
  - get_coverage: returns coverage info for a unit id and territory_owner
40
40
 
41
+ * Customers
42
+ - Signups - access to signups new clients
43
+ - post new client
44
+ - Users
45
+ - returns customer tree data associated to a given document identification, email or number of the client.
46
+ - returns user data by userId
47
+
41
48
  ## Installation
42
49
 
43
50
  ```commandline
@@ -1,4 +1,4 @@
1
- masstack_python_client/__init__.py,sha256=nONqqQfdBA4hcdLRiI-BLjO8OP62ZMf3nBkKc4iK0PI,154
1
+ masstack_python_client/__init__.py,sha256=ZGw_LqC_xbgEF9n0CyxrpBpNtc1-3gLH0fxTScbA7Bk,154
2
2
  masstack_python_client/client.py,sha256=5b52Q2ekABi7DlZPsNobcmaJXOKzZfhKE_kHvNEqE9Q,2496
3
3
  masstack_python_client/exceptions.py,sha256=HkX1cP4Ryeas59CzIVW8N5gmnRE1x0yQUQwS3tm9QZQ,2115
4
4
  masstack_python_client/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -10,10 +10,19 @@ masstack_python_client/data/province_translation.csv,sha256=Jpd6jbjYaqeNOk9lUA3W
10
10
  masstack_python_client/data/street_type_translation.csv,sha256=2MGeTs0v6wVz2yRMyZUuoNOYA4NSqKGJCGYIRi9X8Ic,1791
11
11
  masstack_python_client/data/unit_translation.csv,sha256=34FPfaCC1eSmBfV0BbHSHJ-tktQk7YLlfT8tMxnfnys,194
12
12
  masstack_python_client/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ masstack_python_client/resources/customers.py,sha256=9GTXQ5fiVosbAzK__uydZOBu9wXC9yO4pHufseHqD38,2924
13
14
  masstack_python_client/resources/feasibility.py,sha256=DbiPwWa9orSmITgcID7RVPKf7b50Pk8h1XQh0xxGYhw,7119
15
+ masstack_python_client/resources/enums/document_type_search.py,sha256=pniXpUA_odqeKyxS6yYiN2uje0-F1kKXXBLOk0F8UTQ,136
14
16
  masstack_python_client/resources/models/address.py,sha256=hKnEUVVz8AfGjhaDngzQ0HuR4_Z6zhK6Xe8Aj6xJR7I,5451
15
- masstack_python_client-0.0.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
16
- masstack_python_client-0.0.2.dist-info/METADATA,sha256=PYQ7cZDcfSEI-bLe2FKf4l3LLFCzd1vRtwpBmH7WEPE,3462
17
- masstack_python_client-0.0.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
18
- masstack_python_client-0.0.2.dist-info/top_level.txt,sha256=q_iYlqJq22lhg_2O2iktARr7Mzz3QfjaW4l6J4vwyE8,23
19
- masstack_python_client-0.0.2.dist-info/RECORD,,
17
+ masstack_python_client/resources/models/client_address.py,sha256=7WBiPTce2X6uZUVVZvZlTMgiohbVITUzmKgYYPvpM-w,204
18
+ masstack_python_client/resources/models/client_attribute.py,sha256=rZlLjJeBVD6IpXbSEucujTqcmHhqoJGRTOV1wqyStak,697
19
+ masstack_python_client/resources/models/client_payment.py,sha256=yMGMTuk_07-TzXWO89sCaaZv8soTO9cT0TzfV3xQa1o,262
20
+ masstack_python_client/resources/models/products.py,sha256=cIuUlEKs0OfvBXtYxxUwG4vibfAlZL4uVBK7-nAL9rw,1831
21
+ masstack_python_client/resources/models/signup.py,sha256=Hvo5nZce1ikpUUMEoLt_2g2HipHwh4XRIz344X8_IJk,2018
22
+ masstack_python_client/resources/models/user.py,sha256=N5mwuZN0Saxiro2UXYcCxLL6jrpIU83crHhmrdAcgE8,1080
23
+ masstack_python_client/resources/utils/serialize.py,sha256=F6JxqR2M9HH0TpYKaJritnppWkYlpPztZ9ZC43FdPLg,251
24
+ masstack_python_client-0.0.3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
25
+ masstack_python_client-0.0.3.dist-info/METADATA,sha256=lIkct6n2EgZkeXZ4u1GJv4UIqpJjk9KvMIc4KjEjPoU,3713
26
+ masstack_python_client-0.0.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
27
+ masstack_python_client-0.0.3.dist-info/top_level.txt,sha256=q_iYlqJq22lhg_2O2iktARr7Mzz3QfjaW4l6J4vwyE8,23
28
+ masstack_python_client-0.0.3.dist-info/RECORD,,