brynq-sdk-vplan 0.1.0__tar.gz → 0.2.0__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.
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/PKG-INFO +1 -1
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/__init__.py +4 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/get_data.py +4 -1
- brynq_sdk_vplan-0.2.0/brynq_sdk/vplan/order.py +166 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk_vplan.egg-info/PKG-INFO +1 -1
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk_vplan.egg-info/SOURCES.txt +1 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/setup.py +1 -1
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/activity.py +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/item.py +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/project.py +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/resource.py +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/time_tracking.py +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk/vplan/user.py +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk_vplan.egg-info/dependency_links.txt +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk_vplan.egg-info/not-zip-safe +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk_vplan.egg-info/requires.txt +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk_vplan.egg-info/top_level.txt +0 -0
- {brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/setup.cfg +0 -0
|
@@ -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
|
|
@@ -18,8 +20,10 @@ class VPlan(BrynQ):
|
|
|
18
20
|
super().__init__()
|
|
19
21
|
self.headers = self._get_credentials(label)
|
|
20
22
|
self.base_url = 'https://api.vplan.com/v1/'
|
|
23
|
+
self.get = GetData(self)
|
|
21
24
|
self.activity = Activity(self)
|
|
22
25
|
self.item = Item(self)
|
|
26
|
+
self.order = Order(self)
|
|
23
27
|
self.project = Project(self)
|
|
24
28
|
self.resource = Resource(self)
|
|
25
29
|
self.time_tracking = TimeTracking(self)
|
|
@@ -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:
|
|
@@ -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.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.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)))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{brynq_sdk_vplan-0.1.0 → brynq_sdk_vplan-0.2.0}/brynq_sdk_vplan.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|