producteca 1.0.14__py3-none-any.whl → 2.0.57__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.
- producteca/__init__.py +3 -0
- producteca/abstract/abstract_dataclass.py +20 -18
- producteca/client.py +8 -21
- producteca/config/__init__.py +0 -1
- producteca/payments/payments.py +4 -16
- producteca/payments/tests/test_payments.py +21 -5
- producteca/products/__init__.py +0 -1
- producteca/products/products.py +237 -81
- producteca/products/search_products.py +136 -0
- producteca/products/tests/test_products.py +111 -38
- producteca/{search/tests/test_search.py → products/tests/test_search_products.py} +15 -86
- producteca/sales_orders/__init__.py +0 -1
- producteca/sales_orders/sales_orders.py +292 -118
- producteca/sales_orders/search_sale_orders.py +152 -0
- producteca/sales_orders/tests/search.json +137 -0
- producteca/sales_orders/tests/test_sales_orders.py +55 -26
- producteca/sales_orders/tests/test_search_so.py +46 -0
- producteca/shipments/shipment.py +0 -14
- producteca/shipments/tests/test_shipment.py +28 -23
- producteca/utils.py +50 -0
- producteca-2.0.57.dist-info/LICENSE +661 -0
- {producteca-1.0.14.dist-info → producteca-2.0.57.dist-info}/METADATA +33 -2
- producteca-2.0.57.dist-info/RECORD +33 -0
- producteca/search/__init__.py +0 -0
- producteca/search/search.py +0 -149
- producteca/search/search_sale_orders.py +0 -170
- producteca/search/tests/__init__.py +0 -0
- producteca-1.0.14.dist-info/RECORD +0 -31
- {producteca-1.0.14.dist-info → producteca-2.0.57.dist-info}/WHEEL +0 -0
- {producteca-1.0.14.dist-info → producteca-2.0.57.dist-info}/entry_points.txt +0 -0
|
@@ -1,83 +1,97 @@
|
|
|
1
1
|
from pydantic import BaseModel, Field
|
|
2
2
|
from typing import List, Optional
|
|
3
3
|
import requests
|
|
4
|
-
from
|
|
4
|
+
from producteca.abstract.abstract_dataclass import BaseService
|
|
5
|
+
from producteca.sales_orders.search_sale_orders import SearchSalesOrderParams, SearchSalesOrder
|
|
6
|
+
from producteca.payments.payments import Payment
|
|
7
|
+
from producteca.shipments.shipment import Shipment
|
|
8
|
+
from producteca.utils import clean_model_dump
|
|
9
|
+
from dataclasses import dataclass
|
|
5
10
|
import logging
|
|
6
11
|
_logger = logging.getLogger(__name__)
|
|
7
12
|
|
|
13
|
+
|
|
8
14
|
class SaleOrderLocation(BaseModel):
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
street_name: Optional[str] = Field(None, alias="streetName")
|
|
16
|
+
street_number: Optional[str] = Field(None, alias="streetNumber")
|
|
17
|
+
address_notes: Optional[str] = Field(None, alias="addressNotes")
|
|
12
18
|
state: Optional[str] = None
|
|
13
19
|
city: Optional[str] = None
|
|
14
20
|
neighborhood: Optional[str] = None
|
|
15
|
-
|
|
21
|
+
zip_code: Optional[str] = Field(None, alias="zipCode")
|
|
22
|
+
|
|
16
23
|
|
|
17
24
|
class SaleOrderBillingInfo(BaseModel):
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
doc_type: Optional[str] = Field(None, alias="docType")
|
|
26
|
+
doc_number: Optional[str] = Field(None, alias="docNumber")
|
|
27
|
+
street_name: Optional[str] = Field(None, alias="streetName")
|
|
28
|
+
street_number: Optional[str] = Field(None, alias="streetNumber")
|
|
22
29
|
comment: Optional[str] = None
|
|
23
|
-
|
|
30
|
+
zip_code: Optional[str] = Field(None, alias="zipCode")
|
|
24
31
|
city: Optional[str] = None
|
|
25
32
|
state: Optional[str] = None
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
state_registration: Optional[str] = Field(None, alias="stateRegistration")
|
|
34
|
+
tax_payer_type: Optional[str] = Field(None, alias="taxPayerType")
|
|
35
|
+
first_name: Optional[str] = Field(None, alias="firstName")
|
|
36
|
+
last_name: Optional[str] = Field(None, alias="lastName")
|
|
37
|
+
business_name: Optional[str] = Field(None, alias="businessName")
|
|
38
|
+
|
|
31
39
|
|
|
32
40
|
class SaleOrderProfile(BaseModel):
|
|
33
41
|
app: int
|
|
34
|
-
|
|
42
|
+
integration_id: str = Field(alias="integrationId")
|
|
35
43
|
nickname: Optional[str] = None
|
|
36
44
|
|
|
45
|
+
|
|
37
46
|
class SaleOrderContact(BaseModel):
|
|
38
47
|
id: int
|
|
39
48
|
name: str
|
|
40
|
-
|
|
49
|
+
contact_person: Optional[str] = Field(None, alias="contactPerson")
|
|
41
50
|
mail: Optional[str] = None
|
|
42
|
-
|
|
43
|
-
|
|
51
|
+
phone_number: Optional[str] = Field(None, alias="phoneNumber")
|
|
52
|
+
tax_id: Optional[str] = Field(None, alias="taxId")
|
|
44
53
|
location: Optional[SaleOrderLocation] = None
|
|
45
54
|
notes: Optional[str] = None
|
|
46
55
|
type: Optional[str] = None
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
price_list: Optional[str] = Field(None, alias="priceList")
|
|
57
|
+
price_list_id: Optional[str] = Field(None, alias="priceListId")
|
|
49
58
|
profile: Optional[SaleOrderProfile] = None
|
|
50
|
-
|
|
59
|
+
billing_info: Optional[SaleOrderBillingInfo] = Field(None, alias="billingInfo")
|
|
60
|
+
|
|
51
61
|
|
|
52
62
|
class SaleOrderIntegrationId(BaseModel):
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
alternate_id: Optional[str] = Field(None, alias="alternateId")
|
|
64
|
+
integration_id: str = Field(alias="integrationId")
|
|
55
65
|
app: int
|
|
56
66
|
|
|
67
|
+
|
|
57
68
|
class SaleOrderVariationPicture(BaseModel):
|
|
58
69
|
url: str
|
|
59
70
|
id: Optional[int] = None
|
|
60
71
|
|
|
72
|
+
|
|
61
73
|
class SaleOrderVariationStock(BaseModel):
|
|
62
|
-
|
|
74
|
+
warehouse_id: Optional[int] = Field(None, alias="warehouseId")
|
|
63
75
|
warehouse: str
|
|
64
76
|
quantity: int
|
|
65
77
|
reserved: int
|
|
66
|
-
|
|
78
|
+
last_modified: Optional[str] = Field(None, alias="lastModified")
|
|
67
79
|
available: int
|
|
68
80
|
|
|
81
|
+
|
|
69
82
|
class SaleOrderVariationAttribute(BaseModel):
|
|
70
83
|
key: str
|
|
71
84
|
value: str
|
|
72
85
|
|
|
86
|
+
|
|
73
87
|
class SaleOrderVariation(BaseModel):
|
|
74
|
-
|
|
88
|
+
supplier_code: Optional[str] = Field(None, alias="supplierCode")
|
|
75
89
|
pictures: Optional[List[SaleOrderVariationPicture]] = None
|
|
76
90
|
stocks: Optional[List[SaleOrderVariationStock]] = None
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
integration_id: Optional[int] = Field(None, alias="integrationId")
|
|
92
|
+
attributes_hash: Optional[str] = Field(None, alias="attributesHash")
|
|
93
|
+
primary_color: Optional[str] = Field(None, alias="primaryColor")
|
|
94
|
+
secondary_color: Optional[str] = Field(None, alias="secondaryColor")
|
|
81
95
|
size: Optional[str] = None
|
|
82
96
|
thumbnail: Optional[str] = None
|
|
83
97
|
attributes: Optional[List[SaleOrderVariationAttribute]] = None
|
|
@@ -86,57 +100,69 @@ class SaleOrderVariation(BaseModel):
|
|
|
86
100
|
sku: str
|
|
87
101
|
barcode: Optional[str] = None
|
|
88
102
|
|
|
103
|
+
|
|
89
104
|
class SaleOrderProduct(BaseModel):
|
|
90
105
|
name: str
|
|
91
106
|
code: str
|
|
92
107
|
brand: Optional[str] = None
|
|
93
108
|
id: int
|
|
94
109
|
|
|
110
|
+
|
|
111
|
+
class SaleOrderQuestion(BaseModel):
|
|
112
|
+
text: Optional[str] = None
|
|
113
|
+
answer: Optional[str] = None
|
|
114
|
+
|
|
115
|
+
|
|
95
116
|
class SaleOrderConversation(BaseModel):
|
|
96
|
-
questions: Optional[List[
|
|
117
|
+
questions: Optional[List[SaleOrderQuestion]] = None
|
|
118
|
+
|
|
97
119
|
|
|
98
120
|
class SaleOrderLine(BaseModel):
|
|
99
121
|
price: float
|
|
100
|
-
|
|
101
|
-
|
|
122
|
+
original_price: Optional[float] = Field(None, alias="originalPrice")
|
|
123
|
+
transaction_fee: Optional[float] = Field(None, alias="transactionFee")
|
|
102
124
|
product: SaleOrderProduct
|
|
103
125
|
variation: SaleOrderVariation
|
|
104
|
-
|
|
126
|
+
order_variation_integration_id: Optional[str] = Field(None, alias="orderVariationIntegrationId")
|
|
105
127
|
quantity: int
|
|
106
128
|
conversation: Optional[SaleOrderConversation] = None
|
|
107
129
|
reserved: Optional[int] = None
|
|
108
130
|
id: int
|
|
109
131
|
|
|
132
|
+
|
|
110
133
|
class SaleOrderCard(BaseModel):
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
134
|
+
payment_network: Optional[str] = Field(None, alias="paymentNetwork")
|
|
135
|
+
first_six_digits: Optional[int] = Field(None, alias="firstSixDigits")
|
|
136
|
+
last_four_digits: Optional[int] = Field(None, alias="lastFourDigits")
|
|
137
|
+
cardholder_identification_number: Optional[str] = Field(None, alias="cardholderIdentificationNumber")
|
|
138
|
+
cardholder_identification_type: Optional[str] = Field(None, alias="cardholderIdentificationType")
|
|
139
|
+
cardholder_name: Optional[str] = Field(None, alias="cardholderName")
|
|
140
|
+
|
|
117
141
|
|
|
118
142
|
class SaleOrderPaymentIntegration(BaseModel):
|
|
119
|
-
|
|
143
|
+
integration_id: str = Field(alias="integrationId")
|
|
120
144
|
app: int
|
|
121
145
|
|
|
146
|
+
|
|
122
147
|
class SaleOrderPayment(BaseModel):
|
|
123
148
|
date: Optional[str] = None
|
|
124
149
|
amount: float
|
|
125
|
-
|
|
150
|
+
coupon_amount: Optional[float] = Field(None, alias="couponAmount")
|
|
126
151
|
status: Optional[str] = None
|
|
127
152
|
method: Optional[str] = None
|
|
128
153
|
integration: Optional[SaleOrderPaymentIntegration] = None
|
|
129
|
-
|
|
154
|
+
transaction_fee: Optional[float] = Field(None, alias="transactionFee")
|
|
130
155
|
installments: Optional[int] = None
|
|
131
156
|
card: Optional[SaleOrderCard] = None
|
|
132
157
|
notes: Optional[str] = None
|
|
133
|
-
|
|
134
|
-
|
|
158
|
+
authorization_code: Optional[str] = Field(None, alias="authorizationCode")
|
|
159
|
+
has_cancelable_status: Optional[bool] = Field(None, alias="hasCancelableStatus")
|
|
135
160
|
id: Optional[int] = None
|
|
136
161
|
|
|
162
|
+
|
|
137
163
|
class SaleOrderShipmentMethod(BaseModel):
|
|
138
|
-
|
|
139
|
-
|
|
164
|
+
tracking_number: Optional[str] = Field(None, alias="trackingNumber")
|
|
165
|
+
tracking_url: Optional[str] = Field(None, alias="trackingUrl")
|
|
140
166
|
courier: Optional[str] = None
|
|
141
167
|
mode: Optional[str] = None
|
|
142
168
|
cost: Optional[float] = None
|
|
@@ -144,17 +170,20 @@ class SaleOrderShipmentMethod(BaseModel):
|
|
|
144
170
|
eta: Optional[int] = None
|
|
145
171
|
status: Optional[str] = None
|
|
146
172
|
|
|
173
|
+
|
|
147
174
|
class SaleOrderShipmentProduct(BaseModel):
|
|
148
175
|
product: int
|
|
149
176
|
variation: int
|
|
150
177
|
quantity: int
|
|
151
178
|
|
|
179
|
+
|
|
152
180
|
class SaleOrderShipmentIntegration(BaseModel):
|
|
153
181
|
app: int
|
|
154
|
-
|
|
182
|
+
integration_id: str = Field(alias="integrationId")
|
|
155
183
|
status: str
|
|
156
184
|
id: int
|
|
157
185
|
|
|
186
|
+
|
|
158
187
|
class SaleOrderShipment(BaseModel):
|
|
159
188
|
date: str
|
|
160
189
|
products: List[SaleOrderShipmentProduct]
|
|
@@ -163,93 +192,238 @@ class SaleOrderShipment(BaseModel):
|
|
|
163
192
|
receiver: Optional[dict] = None
|
|
164
193
|
id: int
|
|
165
194
|
|
|
166
|
-
|
|
195
|
+
|
|
196
|
+
class SaleOrderInvoiceIntegrationAbstract(BaseModel):
|
|
167
197
|
id: Optional[int] = None
|
|
168
|
-
|
|
198
|
+
integration_id: Optional[str] = Field(None, alias="integrationId")
|
|
169
199
|
app: Optional[int] = None
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
200
|
+
created_at: Optional[str] = Field(None, alias="createdAt")
|
|
201
|
+
decrease_stock: Optional[bool] = Field(None, alias="decreaseStock")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class SaleOrderInvoiceIntegration(SaleOrderInvoiceIntegrationAbstract):
|
|
205
|
+
document_url: Optional[str] = Field(None, alias="documentUrl")
|
|
206
|
+
xml_url: Optional[str] = Field(None, alias="xmlUrl")
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class SaleOrderInvoiceIntegrationPut(SaleOrderInvoiceIntegrationAbstract):
|
|
210
|
+
document_url: Optional[str] = Field(None, alias="documentUrl")
|
|
211
|
+
xml_url: Optional[str] = Field(None, alias="xmlUrl")
|
|
212
|
+
|
|
213
|
+
class SaleOrderWarehouseIntegration(BaseModel):
|
|
214
|
+
app: Optional[int] = None
|
|
215
|
+
status: Optional[str] = None
|
|
216
|
+
integration_id: Optional[str] = Field(None, alias="integrationId")
|
|
217
|
+
|
|
174
218
|
|
|
175
219
|
class SaleOrder(BaseModel):
|
|
176
220
|
tags: Optional[List[str]] = None
|
|
177
221
|
integrations: Optional[List[SaleOrderIntegrationId]] = None
|
|
178
|
-
|
|
222
|
+
invoice_integration: Optional[SaleOrderInvoiceIntegration] = Field(None, alias="invoiceIntegration")
|
|
179
223
|
channel: Optional[str] = None
|
|
180
|
-
|
|
224
|
+
pii_expired: Optional[bool] = Field(None, alias="piiExpired")
|
|
181
225
|
contact: Optional[SaleOrderContact] = None
|
|
182
226
|
lines: Optional[List[SaleOrderLine]] = None
|
|
183
227
|
warehouse: Optional[str] = None
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
228
|
+
warehouse_id: Optional[int] = Field(None, alias="warehouseId")
|
|
229
|
+
warehouse_integration: Optional[SaleOrderWarehouseIntegration] = Field(None, alias="warehouseIntegration")
|
|
230
|
+
pick_up_store: Optional[str] = Field(None, alias="pickUpStore")
|
|
187
231
|
payments: Optional[List[SaleOrderPayment]] = None
|
|
188
232
|
shipments: Optional[List[SaleOrderShipment]] = None
|
|
189
233
|
amount: Optional[float] = None
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
234
|
+
shipping_cost: Optional[float] = Field(None, alias="shippingCost")
|
|
235
|
+
financial_cost: Optional[float] = Field(None, alias="financialCost")
|
|
236
|
+
paid_approved: Optional[float] = Field(None, alias="paidApproved")
|
|
237
|
+
payment_status: Optional[str] = Field(None, alias="paymentStatus")
|
|
238
|
+
delivery_status: Optional[str] = Field(None, alias="deliveryStatus")
|
|
239
|
+
payment_fulfillment_status: Optional[str] = Field(None, alias="paymentFulfillmentStatus")
|
|
240
|
+
delivery_fulfillment_status: Optional[str] = Field(None, alias="deliveryFulfillmentStatus")
|
|
241
|
+
delivery_method: Optional[str] = Field(None, alias="deliveryMethod")
|
|
242
|
+
payment_term: Optional[str] = Field(None, alias="paymentTerm")
|
|
199
243
|
currency: Optional[str] = None
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
244
|
+
custom_id: Optional[str] = Field(None, alias="customId")
|
|
245
|
+
is_open: Optional[bool] = Field(None, alias="isOpen")
|
|
246
|
+
is_canceled: Optional[bool] = Field(None, alias="isCanceled")
|
|
247
|
+
cart_id: Optional[str] = Field(None, alias="cartId")
|
|
204
248
|
draft: Optional[bool] = None
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
249
|
+
promise_delivery_date: Optional[str] = Field(None, alias="promiseDeliveryDate")
|
|
250
|
+
promise_dispatch_date: Optional[str] = Field(None, alias="promiseDispatchDate")
|
|
251
|
+
has_any_shipments: Optional[bool] = Field(None, alias="hasAnyShipments")
|
|
252
|
+
has_any_payments: Optional[bool] = Field(None, alias="hasAnyPayments")
|
|
209
253
|
date: Optional[str] = None
|
|
210
254
|
notes: Optional[str] = None
|
|
211
255
|
id: int
|
|
212
256
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
257
|
+
|
|
258
|
+
class SaleOrderSynchronize(BaseModel):
|
|
259
|
+
id: int
|
|
260
|
+
invoice_integration: SaleOrderInvoiceIntegration = Field(alias="invoiceIntegration")
|
|
261
|
+
notes: Optional[str] = None
|
|
262
|
+
tags: Optional[List[str]] = None
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class UpdateStatus(BaseModel):
|
|
266
|
+
updated: bool = False
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class SaleOrderSyncResponse(BaseModel):
|
|
270
|
+
basic: UpdateStatus = Field(default_factory=UpdateStatus)
|
|
271
|
+
contact: UpdateStatus = Field(default_factory=UpdateStatus)
|
|
272
|
+
shipments: UpdateStatus = Field(default_factory=UpdateStatus)
|
|
273
|
+
payments: UpdateStatus = Field(default_factory=UpdateStatus)
|
|
274
|
+
invoice_integration: UpdateStatus = Field(alias="invoiceIntegration", default_factory=UpdateStatus)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@dataclass
|
|
278
|
+
class SaleOrderService(BaseService):
|
|
279
|
+
endpoint: str = 'salesorders'
|
|
280
|
+
|
|
281
|
+
def __call__(self, **payload):
|
|
282
|
+
self._record = SaleOrder(**payload)
|
|
283
|
+
return self
|
|
284
|
+
|
|
285
|
+
def __repr__(self):
|
|
286
|
+
return repr(self._record)
|
|
287
|
+
|
|
288
|
+
def get(self, sale_order_id: int) -> "SaleOrderService":
|
|
289
|
+
endpoint = f'{self.endpoint}/{sale_order_id}'
|
|
290
|
+
url = self.config.get_endpoint(endpoint)
|
|
291
|
+
_logger.info(f"GET {url} - Headers: {self.config.headers}")
|
|
292
|
+
response = requests.get(url, headers=self.config.headers)
|
|
293
|
+
if not response.ok:
|
|
294
|
+
raise Exception(f"Order {sale_order_id} could not be fetched. Error {response.status_code} {response.text}")
|
|
295
|
+
response_data = response.json()
|
|
296
|
+
return self(**response_data)
|
|
297
|
+
|
|
298
|
+
def get_shipping_labels(self):
|
|
299
|
+
if not self._record:
|
|
300
|
+
raise Exception("You need to add a record id")
|
|
301
|
+
endpoint = f'{self.endpoint}/{self._record.id}/labels'
|
|
302
|
+
url = self.config.get_endpoint(endpoint)
|
|
303
|
+
_logger.info(f"GET {url} - Headers: {self.config.headers}")
|
|
304
|
+
response = requests.get(url, headers=self.config.headers)
|
|
305
|
+
if not response.ok:
|
|
306
|
+
raise Exception("labels could not be gotten")
|
|
225
307
|
return response.json()
|
|
226
308
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
endpoint = f'
|
|
251
|
-
url = config.get_endpoint(endpoint)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
309
|
+
def close(self):
|
|
310
|
+
if not self._record:
|
|
311
|
+
raise Exception("You need to add a record id")
|
|
312
|
+
endpoint = f'{self.endpoint}/{self._record.id}/close'
|
|
313
|
+
url = self.config.get_endpoint(endpoint)
|
|
314
|
+
_logger.info(f"POST {url} - Headers: {self.config.headers}")
|
|
315
|
+
response = requests.post(url, headers=self.config.headers)
|
|
316
|
+
if not response.ok:
|
|
317
|
+
raise Exception("Order could not be closed")
|
|
318
|
+
|
|
319
|
+
def cancel(self):
|
|
320
|
+
if not self._record:
|
|
321
|
+
raise Exception("You need to add a record id")
|
|
322
|
+
endpoint = f'{self.endpoint}/{self._record.id}/cancel'
|
|
323
|
+
url = self.config.get_endpoint(endpoint)
|
|
324
|
+
_logger.info(f"POST {url} - Headers: {self.config.headers}")
|
|
325
|
+
response = requests.post(url, headers=self.config.headers)
|
|
326
|
+
if not response.ok:
|
|
327
|
+
raise Exception("Order could not be cancelled")
|
|
328
|
+
|
|
329
|
+
def synchronize(self) -> "SaleOrderService":
|
|
330
|
+
if not self._record:
|
|
331
|
+
raise Exception("You need to add a record by calling the resource and adding info")
|
|
332
|
+
endpoint = f'{self.endpoint}/synchronize'
|
|
333
|
+
url = self.config.get_endpoint(endpoint)
|
|
334
|
+
# TODO: Check what can we sync, and what can we not sync
|
|
335
|
+
sync_body = SaleOrderSynchronize(**clean_model_dump(self._record))
|
|
336
|
+
sync_data = clean_model_dump(sync_body)
|
|
337
|
+
_logger.info(f"POST {url} - Headers: {self.config.headers} - Data: {sync_data}")
|
|
338
|
+
response = requests.post(url, json=sync_data, headers=self.config.headers)
|
|
339
|
+
if not response.ok:
|
|
340
|
+
raise Exception(f"Synchronize error {response.status_code} {response.text}")
|
|
341
|
+
sync_res = SaleOrderSyncResponse(**response.json()) # noqa
|
|
342
|
+
return self
|
|
343
|
+
|
|
344
|
+
def invoice_integration(self):
|
|
345
|
+
if not self._record:
|
|
346
|
+
raise Exception("You need to add a record id")
|
|
347
|
+
|
|
348
|
+
invoice_integration_data = clean_model_dump(self._record.invoice_integration)
|
|
349
|
+
|
|
350
|
+
if self._record.invoice_integration.id:
|
|
351
|
+
endpoint = f'{self.endpoint}/{self._record.id}/invoiceIntegration'
|
|
352
|
+
url = self.config.get_endpoint(endpoint)
|
|
353
|
+
_logger.info(f"PUT {url} - Headers: {self.config.headers} - Data: {invoice_integration_data}")
|
|
354
|
+
response = requests.put(url, headers=self.config.headers,
|
|
355
|
+
json=invoice_integration_data)
|
|
356
|
+
else:
|
|
357
|
+
endpoint = f'{self.endpoint}/synchronize'
|
|
358
|
+
url = self.config.get_endpoint(endpoint)
|
|
359
|
+
sync_data = {"id": self._record.id, "invoiceIntegration": invoice_integration_data}
|
|
360
|
+
_logger.info(f"POST {url} - Headers: {self.config.headers} - Data: {sync_data}")
|
|
361
|
+
response = requests.post(url, headers=self.config.headers,
|
|
362
|
+
json=sync_data)
|
|
363
|
+
|
|
364
|
+
if not response.ok:
|
|
365
|
+
raise Exception(f"Error on resposne {response.text}")
|
|
366
|
+
return response.ok
|
|
367
|
+
|
|
368
|
+
def search(self, params: SearchSalesOrderParams):
|
|
369
|
+
endpoint: str = f"search/{self.endpoint}"
|
|
370
|
+
headers = self.config.headers
|
|
371
|
+
url = self.config.get_endpoint(endpoint)
|
|
372
|
+
new_url = f"{url}?$filter={params.filter}&top={params.top}&skip={params.skip}"
|
|
373
|
+
_logger.info(f"GET {new_url} - Headers: {headers}")
|
|
374
|
+
response = requests.get(
|
|
375
|
+
new_url,
|
|
376
|
+
headers=headers,
|
|
377
|
+
)
|
|
378
|
+
if not response.ok:
|
|
379
|
+
raise Exception(f"Error on resposne {response.status_code} - {response.text}")
|
|
380
|
+
response_data = response.json()
|
|
381
|
+
return SearchSalesOrder(**response_data)
|
|
382
|
+
|
|
383
|
+
def add_payment(self, payload) -> Payment:
|
|
384
|
+
if not self._record:
|
|
385
|
+
raise Exception("You need to add a record id")
|
|
386
|
+
payment = Payment(**payload)
|
|
387
|
+
url = self.config.get_endpoint(f"{self.endpoint}/{self._record.id}/payments")
|
|
388
|
+
payment_data = clean_model_dump(payment)
|
|
389
|
+
_logger.info(f"POST {url} - Headers: {self.config.headers} - Data: {payment_data}")
|
|
390
|
+
res = requests.post(url, json=payment_data, headers=self.config.headers)
|
|
391
|
+
if not res.ok:
|
|
392
|
+
raise Exception(f"Error on resposne {res.text}")
|
|
393
|
+
return Payment(**res.json())
|
|
394
|
+
|
|
395
|
+
def update_payment(self, payment_id: int, payload) -> "Payment":
|
|
396
|
+
if not self._record:
|
|
397
|
+
raise Exception("You need to add a record id")
|
|
398
|
+
payment = Payment(**payload)
|
|
399
|
+
url = self.config.get_endpoint(f"{self.endpoint}/{self._record.id}/payments/{payment_id}")
|
|
400
|
+
payment_data = clean_model_dump(payment)
|
|
401
|
+
_logger.info(f"PUT {url} - Headers: {self.config.headers} - Data: {payment_data}")
|
|
402
|
+
res = requests.put(url, json=payment_data, headers=self.config.headers)
|
|
403
|
+
if not res.ok:
|
|
404
|
+
raise Exception(f"Error on payment update {res.text}")
|
|
405
|
+
return Payment(**res.json())
|
|
406
|
+
|
|
407
|
+
def add_shipment(self, payload) -> "Shipment":
|
|
408
|
+
if not self._record:
|
|
409
|
+
raise Exception("You need to add a record id")
|
|
410
|
+
shipment = Shipment(**payload)
|
|
411
|
+
url = self.config.get_endpoint(f"{self.endpoint}/{self._record.id}/shipments")
|
|
412
|
+
shipment_data = clean_model_dump(shipment)
|
|
413
|
+
_logger.info(f"POST {url} - Headers: {self.config.headers} - Data: {shipment_data}")
|
|
414
|
+
res = requests.post(url, json=shipment_data, headers=self.config.headers)
|
|
415
|
+
if not res.ok:
|
|
416
|
+
raise Exception(f"Error on shipment add {res.text}")
|
|
417
|
+
return Shipment(**res.json())
|
|
418
|
+
|
|
419
|
+
def update_shipment(self, shipment_id: str, payload) -> "Shipment":
|
|
420
|
+
if not self._record:
|
|
421
|
+
raise Exception("You need to add a record id")
|
|
422
|
+
shipment = Shipment(**payload)
|
|
423
|
+
url = self.config.get_endpoint(f"{self.endpoint}/{self._record.id}/shipments/{shipment_id}")
|
|
424
|
+
shipment_data = clean_model_dump(shipment)
|
|
425
|
+
_logger.info(f"PUT {url} - Headers: {self.config.headers} - Data: {shipment_data}")
|
|
426
|
+
res = requests.put(url, json=shipment_data, headers=self.config.headers)
|
|
427
|
+
if not res.ok:
|
|
428
|
+
raise Exception(f"Error on shipment update {res.text}")
|
|
429
|
+
return Shipment(**res.json())
|