brynq-sdk-vplan 0.1.0__tar.gz → 0.2.1__tar.gz

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.
Files changed (18) hide show
  1. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/PKG-INFO +1 -1
  2. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/__init__.py +6 -1
  3. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/activity.py +2 -2
  4. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/get_data.py +4 -1
  5. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/item.py +2 -2
  6. brynq_sdk_vplan-0.2.1/brynq_sdk/vplan/order.py +166 -0
  7. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/project.py +2 -2
  8. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/resource.py +2 -2
  9. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/time_tracking.py +2 -2
  10. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk/vplan/user.py +2 -2
  11. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk_vplan.egg-info/PKG-INFO +1 -1
  12. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk_vplan.egg-info/SOURCES.txt +1 -0
  13. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/setup.py +1 -1
  14. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk_vplan.egg-info/dependency_links.txt +0 -0
  15. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk_vplan.egg-info/not-zip-safe +0 -0
  16. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk_vplan.egg-info/requires.txt +0 -0
  17. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/brynq_sdk_vplan.egg-info/top_level.txt +0 -0
  18. {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: brynq_sdk_vplan
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: vPlan wrapper from BrynQ
5
5
  Home-page: UNKNOWN
6
6
  Author: BrynQ
@@ -2,8 +2,10 @@ import requests
2
2
  import json
3
3
  from typing import List, Union
4
4
  from brynq_sdk.brynq import BrynQ
5
+ from brynq_sdk.vplan.get_data import GetData
5
6
  from brynq_sdk.vplan.activity import Activity
6
7
  from brynq_sdk.vplan.item import Item
8
+ from brynq_sdk.vplan.order import Order
7
9
  from brynq_sdk.vplan.project import Project
8
10
  from brynq_sdk.vplan.resource import Resource
9
11
  from brynq_sdk.vplan.time_tracking import TimeTracking
@@ -17,15 +19,18 @@ class VPlan(BrynQ):
17
19
  """
18
20
  super().__init__()
19
21
  self.headers = self._get_credentials(label)
22
+ self.post_headers = {**self.headers, 'Content-Type': 'application/json'}
20
23
  self.base_url = 'https://api.vplan.com/v1/'
24
+ self.get = GetData(self)
21
25
  self.activity = Activity(self)
22
26
  self.item = Item(self)
27
+ self.order = Order(self)
23
28
  self.project = Project(self)
24
29
  self.resource = Resource(self)
25
30
  self.time_tracking = TimeTracking(self)
26
31
  self.user = User(self)
27
32
 
28
- def _get_credentials(self, label) -> str:
33
+ def _get_credentials(self, label) -> dict:
29
34
  """
30
35
  Retrieve API key and env from the system credentials.
31
36
  Args: label (Union[str, List]): The label or list of labels to get the credentials.
@@ -75,7 +75,7 @@ class Activity:
75
75
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
76
76
  base_body.update({"archive": data['archive']}) if 'archive' in data else base_body
77
77
 
78
- response = requests.request('POST', url, headers=self.vplan.headers, data=base_body)
78
+ response = requests.request('POST', url, headers=self.vplan.post_headers, data=base_body)
79
79
  return response
80
80
 
81
81
  def update_activity(self, activity_id: str, data: dict) -> requests.Response:
@@ -106,7 +106,7 @@ class Activity:
106
106
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
107
107
  base_body.update({"archive": data['archive']}) if 'archive' in data else base_body
108
108
 
109
- response = requests.request('PUT', url, headers=self.vplan.headers, json=base_body)
109
+ response = requests.request('PUT', url, headers=self.vplan.post_headers, json=base_body)
110
110
  return response
111
111
 
112
112
  def delete_activity(self, activity_id):
@@ -1,4 +1,5 @@
1
1
  import pandas as pd
2
+ from typing import List, Any
2
3
  import requests
3
4
 
4
5
 
@@ -10,7 +11,7 @@ class GetData:
10
11
  """
11
12
  self.vplan = vplan
12
13
 
13
- def get_data(self, endpoint: str, limit: int = 1000, filter: str = None, show: str = None, hide: str = None, archived: bool = False) -> pd.DataFrame:
14
+ def get_data(self, endpoint: str, limit: int = 1000, filter: str = None, with_array: str = None, show: str = None, hide: str = None, archived: bool = False) -> pd.DataFrame:
14
15
  """
15
16
  Fetch data from a specified table from vPlan
16
17
 
@@ -53,6 +54,8 @@ class GetData:
53
54
  url += f'limit={limit}&'
54
55
  if filter:
55
56
  url += f'filter={filter}&'
57
+ if with_array:
58
+ url += f'with={with_array}&'
56
59
  if show:
57
60
  url += f'show={show}&'
58
61
  if hide:
@@ -79,7 +79,7 @@ class Item:
79
79
  base_body.update({"note": data['note']}) if 'note' in data else base_body
80
80
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
81
81
 
82
- response = requests.request('POST', url, headers=self.vplan.headers, data=base_body)
82
+ response = requests.request('POST', url, headers=self.vplan.post_headers, data=base_body)
83
83
  return response
84
84
 
85
85
  def update_item(self, item_id: str, data: dict) -> requests.Response:
@@ -114,7 +114,7 @@ class Item:
114
114
  base_body.update({"note": data['note']}) if 'note' in data else base_body
115
115
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
116
116
 
117
- response = requests.request('PUT', url, headers=self.vplan.headers, json=base_body)
117
+ response = requests.request('PUT', url, headers=self.vplan.post_headers, json=base_body)
118
118
  return response
119
119
 
120
120
  def delete_item(self, item_id):
@@ -0,0 +1,166 @@
1
+ import requests
2
+ from typing import Union, List, Any
3
+ import warnings
4
+ import json
5
+ from brynq_sdk.vplan.get_data import GetData
6
+
7
+
8
+ class Order:
9
+ def __init__(self, vplan):
10
+ """
11
+ Initialize the GetData class.
12
+ Args: vplan: contains the vplan object with the headers and base_url
13
+ """
14
+ self.vplan = vplan
15
+ self.get_data = GetData(vplan)
16
+
17
+ def get_order_list(self, filter: str = None, with_array: str = None, show: str = None, hide: str = None):
18
+ """
19
+ Get all the orders from vPlan: https://developer.vplan.com/documentation/#tag/Order/paths/~1order/get
20
+ Args: filter (str, optional): On the list endpoints it is possible to filter the result set given. To apply a filter use the filter query parameter with the format: field:operator:value
21
+ Example: ?filter=created_at:gt:2020-09-26,and,(id:not:starts_with:0000,or,id:contains:FFFF)
22
+
23
+ Colon : is the separator between the field, operator(s) and value.
24
+ Comma , can be used to combine filter statements by using ,and, or ,or,.
25
+ Braces (...) can be used to group filter statements.
26
+
27
+ The following operators are supported
28
+
29
+ operator description
30
+ eq equal to the given value
31
+ gt greater than the given value
32
+ gte greater than or equal to the given value
33
+ lt lesser than the given value
34
+ lte lesser than or equal to the given value
35
+ not negation of the operator that follows it
36
+ contains has occurrence of the given value
37
+ starts_with starts with the given value
38
+ end_with ends with the given value
39
+
40
+ warning: Currently the comma , and colon : are not supported within the filter value
41
+
42
+ with_array (list, optional): object(s) included in the dataset, Possible options are: address, item, order_rows, collection, project, relation, warehouse, board, contact, user, activity, order, item, project, relation, warehouse, supplies_order_rows
43
+ show (str, optional): On the list endpoints it is possible to select the fields that should be returned. To apply a show use the show query parameter with the format: field1,field2,field3
44
+ hide (str, optional): On the list endpoints it is possible to hide the fields that should not be returned. To apply a hide use the hide query parameter with the format: field1,field2,field3
45
+
46
+ Returns: pd.DataFrame: The fetched data as a pandas DataFrame.
47
+ """
48
+ df = self.get_data.get_data(endpoint='order', filter=filter, with_array=with_array, show=show, hide=hide)
49
+ return df
50
+
51
+ def post_order(self, data: dict) -> requests.Response:
52
+ """
53
+ Create a new order in vPlan: https://developer.vplan.com/documentation/#tag/order/paths/~1order/post
54
+
55
+ This method constructs a request URL based on the endpoint and sends a POST request
56
+ to the vPlan API with the provided data.
57
+
58
+ Args: endpoint (str): The name of the endpoint to create a new order in.
59
+ data (dict): The data to create the new order with.
60
+
61
+ Returns: requests.Response: The response from the vPlan API.
62
+ """
63
+ required_fields = ['type', 'code', 'description']
64
+ allowed_fields = ['quantity', 'external_url', 'sub_type', 'status', 'note', 'contact', 'relation_ref', 'date', 'desired_date', 'promised_date',
65
+ 'delivered_date', 'collection_id', 'item_id', 'project_id', 'relation_id', 'warehouse_id', 'external_ref', 'board_id']
66
+ self.__check_fields(data=data, required_fields=required_fields, allowed_fields=allowed_fields)
67
+
68
+ url = f"{self.vplan.base_url}order"
69
+
70
+ base_body = {
71
+ "type": data['type'],
72
+ "code": data['code'],
73
+ "description": data['description']
74
+ }
75
+ # Add fields that you want to update a dict (adding to body itself is too much text)
76
+ base_body.update({"quantity": data['quantity']}) if 'quantity' in data else base_body
77
+ base_body.update({"external_url": data['external_url']}) if 'external_url' in data else base_body
78
+ base_body.update({"sub_type": data['sub_type']}) if 'sub_type' in data else base_body
79
+ base_body.update({"status": data['status']}) if 'status' in data else base_body
80
+ base_body.update({"note": data['note']}) if 'note' in data else base_body
81
+ base_body.update({"contact": data['contact']}) if 'contact' in data else base_body
82
+ base_body.update({"relation_ref": data['relation_ref']}) if 'relation_ref' in data else base_body
83
+ base_body.update({"date": data['date']}) if 'date' in data else base_body
84
+ base_body.update({"desired_date": data['desired_date']}) if 'desired_date' in data else base_body
85
+ base_body.update({"promised_date": data['promised_date']}) if 'promised_date' in data else base_body
86
+ base_body.update({"delivered_date": data['delivered_date']}) if 'delivered_date' in data else base_body
87
+ base_body.update({"collection_id": data['collection_id']}) if 'collection_id' in data else base_body
88
+ base_body.update({"item_id": data['item_id']}) if 'item_id' in data else base_body
89
+ base_body.update({"project_id": data['project_id']}) if 'project_id' in data else base_body
90
+ base_body.update({"relation_id": data['relation_id']}) if 'relation_id' in data else base_body
91
+ base_body.update({"warehouse_id": data['warehouse_id']}) if 'warehouse_id' in data else base_body
92
+ base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
93
+ base_body.update({"board_id": data['board_id']}) if 'board_id' in data else base_body
94
+
95
+ response = requests.request('POST', url, headers=self.vplan.post_headers, data=base_body)
96
+ return response
97
+
98
+ def update_order(self, order_id: str, data: dict) -> requests.Response:
99
+ """
100
+ Update an existing order in vPlan: https://developer.vplan.com/documentation/#tag/order/paths/~1order~1%7Border_id%7D/put
101
+
102
+ This method constructs a request URL based on the endpoint and sends a POST request
103
+ to the vPlan API with the provided data.
104
+
105
+ Args: endpoint (str): The name of the endpoint to create a new order in.
106
+ data (dict): The data to create the new order with.
107
+
108
+ Returns: requests.Response: The response from the vPlan API.
109
+ """
110
+ required_fields = []
111
+ allowed_fields = ['description' 'type', 'code', 'quantity', 'external_url', 'sub_type', 'status', 'note', 'contact', 'relation_ref', 'date', 'desired_date',
112
+ 'promised_date', 'delivered_date', 'collection_id', 'item_id', 'project_id', 'relation_id', 'warehouse_id', 'external_ref', 'board_id']
113
+ self.__check_fields(data=data, required_fields=required_fields, allowed_fields=allowed_fields)
114
+
115
+ url = f"{self.vplan.base_url}order/{order_id}"
116
+
117
+ base_body = {
118
+ }
119
+ # Add fields that you want to update a dict (adding to body itself is too much text)
120
+ base_body.update({"code": data['code']}) if 'code' in data else base_body
121
+ base_body.update({"description": data['description']}) if 'description' in data else base_body
122
+ base_body.update({"type": data['type']}) if 'type' in data else base_body
123
+ base_body.update({"quantity": data['quantity']}) if 'quantity' in data else base_body
124
+ base_body.update({"external_url": data['external_url']}) if 'external_url' in data else base_body
125
+ base_body.update({"sub_type": data['sub_type']}) if 'sub_type' in data else base_body
126
+ base_body.update({"status": data['status']}) if 'status' in data else base_body
127
+ base_body.update({"note": data['note']}) if 'note' in data else base_body
128
+ base_body.update({"contact": data['contact']}) if 'contact' in data else base_body
129
+ base_body.update({"relation_ref": data['relation_ref']}) if 'relation_ref' in data else base_body
130
+ base_body.update({"date": data['date']}) if 'date' in data else base_body
131
+ base_body.update({"desired_date": data['desired_date']}) if 'desired_date' in data else base_body
132
+ base_body.update({"promised_date": data['promised_date']}) if 'promised_date' in data else base_body
133
+ base_body.update({"delivered_date": data['delivered_date']}) if 'delivered_date' in data else base_body
134
+ base_body.update({"collection_id": data['collection_id']}) if 'collection_id' in data else base_body
135
+ base_body.update({"item_id": data['item_id']}) if 'item_id' in data else base_body
136
+ base_body.update({"project_id": data['project_id']}) if 'project_id' in data else base_body
137
+ base_body.update({"relation_id": data['relation_id']}) if 'relation_id' in data else base_body
138
+ base_body.update({"warehouse_id": data['warehouse_id']}) if 'warehouse_id' in data else base_body
139
+ base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
140
+ base_body.update({"board_id": data['board_id']}) if 'board_id' in data else base_body
141
+
142
+ response = requests.request('PUT', url, headers=self.vplan.post_headers, json=base_body)
143
+ return response
144
+
145
+ def delete_order(self, order_id):
146
+ """
147
+ Delete an existing order in vPlan: https://developer.vplan.com/documentation/#tag/order/paths/~1order~1%7Border_id%7D/delete
148
+ This method constructs a request URL based on the endpoint and sends a DELETE request to the vPlan API.
149
+ """
150
+ url = f"{self.vplan.base_url}order/{order_id}"
151
+ response = requests.request('DELETE', url, headers=self.vplan.headers)
152
+ return response
153
+
154
+
155
+ @staticmethod
156
+ def __check_fields(data: Union[dict, List], required_fields: List, allowed_fields: List):
157
+ if isinstance(data, dict):
158
+ data = data.keys()
159
+
160
+ for field in data:
161
+ if field not in allowed_fields and field not in required_fields:
162
+ warnings.warn('Field {field} is not implemented. Optional fields are: {allowed_fields}'.format(field=field, allowed_fields=tuple(allowed_fields)))
163
+
164
+ for field in required_fields:
165
+ if field not in data:
166
+ raise ValueError('Field {field} is required. Required fields are: {required_fields}'.format(field=field, required_fields=tuple(required_fields)))
@@ -74,7 +74,7 @@ class Project:
74
74
  base_body.update({"description": data['description']}) if 'description' in data else base_body
75
75
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
76
76
 
77
- response = requests.request('POST', url, headers=self.vplan.headers, data=base_body)
77
+ response = requests.request('POST', url, headers=self.vplan.post_headers, data=base_body)
78
78
  return response
79
79
 
80
80
  def update_project(self, project_id: str, data: dict) -> requests.Response:
@@ -103,7 +103,7 @@ class Project:
103
103
  base_body.update({"description": data['description']}) if 'description' in data else base_body
104
104
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
105
105
 
106
- response = requests.request('PUT', url, headers=self.vplan.headers, json=base_body)
106
+ response = requests.request('PUT', url, headers=self.vplan.post_headers, json=base_body)
107
107
  return response
108
108
 
109
109
  def delete_project(self, project_id):
@@ -80,7 +80,7 @@ class Resource:
80
80
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
81
81
  base_body.update({"archive": data['archive']}) if 'archive' in data else base_body
82
82
 
83
- response = requests.request('POST', url, headers=self.vplan.headers, data=json.dumps(base_body))
83
+ response = requests.request('POST', url, headers=self.vplan.post_headers, data=json.dumps(base_body))
84
84
  return response
85
85
 
86
86
  def update_resource(self, resource_id: str, data: dict) -> requests.Response:
@@ -116,7 +116,7 @@ class Resource:
116
116
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
117
117
  base_body.update({"archive": data['archive']}) if 'archive' in data else base_body
118
118
 
119
- response = requests.request('PUT', url, headers=self.vplan.headers, json=json.dumps(base_body))
119
+ response = requests.request('PUT', url, headers=self.vplan.post_headers, json=json.dumps(base_body))
120
120
  return response
121
121
 
122
122
  def delete_resource(self, resource_id):
@@ -82,7 +82,7 @@ class TimeTracking:
82
82
  base_body.update({"external_note": data['external_note']}) if 'external_note' in data else base_body
83
83
  base_body.update({"external_failed": data['external_failed']}) if 'external_failed' in data else base_body
84
84
 
85
- response = requests.request('POST', url, headers=self.vplan.headers, data=base_body)
85
+ response = requests.request('POST', url, headers=self.vplan.post_headers, data=base_body)
86
86
  return response
87
87
 
88
88
  def update_time_tracking(self, time_tracking_id: str, data: dict) -> requests.Response:
@@ -117,7 +117,7 @@ class TimeTracking:
117
117
  base_body.update({"note": data['note']}) if 'note' in data else base_body
118
118
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
119
119
 
120
- response = requests.request('PUT', url, headers=self.vplan.headers, json=base_body)
120
+ response = requests.request('PUT', url, headers=self.vplan.post_headers, json=base_body)
121
121
  return response
122
122
 
123
123
  def delete_time_tracking(self, time_tracking_id):
@@ -79,7 +79,7 @@ class User:
79
79
  base_body.update({"note": data['note']}) if 'note' in data else base_body
80
80
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
81
81
 
82
- response = requests.request('POST', url, headers=self.vplan.headers, data=base_body)
82
+ response = requests.request('POST', url, headers=self.vplan.post_headers, data=base_body)
83
83
  return response
84
84
 
85
85
  def update_user(self, user_id: str, data: dict) -> requests.Response:
@@ -114,7 +114,7 @@ class User:
114
114
  base_body.update({"note": data['note']}) if 'note' in data else base_body
115
115
  base_body.update({"external_ref": data['external_ref']}) if 'external_ref' in data else base_body
116
116
 
117
- response = requests.request('PUT', url, headers=self.vplan.headers, json=base_body)
117
+ response = requests.request('PUT', url, headers=self.vplan.post_headers, json=base_body)
118
118
  return response
119
119
 
120
120
  def delete_user(self, user_id):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: brynq-sdk-vplan
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: vPlan wrapper from BrynQ
5
5
  Home-page: UNKNOWN
6
6
  Author: BrynQ
@@ -3,6 +3,7 @@ brynq_sdk/vplan/__init__.py
3
3
  brynq_sdk/vplan/activity.py
4
4
  brynq_sdk/vplan/get_data.py
5
5
  brynq_sdk/vplan/item.py
6
+ brynq_sdk/vplan/order.py
6
7
  brynq_sdk/vplan/project.py
7
8
  brynq_sdk/vplan/resource.py
8
9
  brynq_sdk/vplan/time_tracking.py
@@ -2,7 +2,7 @@ from setuptools import setup
2
2
 
3
3
  setup(
4
4
  name='brynq_sdk_vplan',
5
- version='0.1.0',
5
+ version='0.2.1',
6
6
  description='vPlan wrapper from BrynQ',
7
7
  long_description='vPlan wrapper from BrynQ',
8
8
  author='BrynQ',