channel-app 0.0.131__py3-none-any.whl → 0.0.135__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.
Files changed (61) hide show
  1. channel_app/app/product/service.py +16 -0
  2. channel_app/core/commands.py +3 -1
  3. channel_app/core/tests.py +15 -164
  4. channel_app/omnitron/commands/tests/test_products.py +494 -0
  5. {channel_app-0.0.131.dist-info → channel_app-0.0.135.dist-info}/METADATA +1 -1
  6. channel_app-0.0.135.dist-info/RECORD +60 -0
  7. {channel_app-0.0.131.dist-info → channel_app-0.0.135.dist-info}/WHEEL +1 -1
  8. channel_app/channel_app/app/__init__.py +0 -0
  9. channel_app/channel_app/app/order/__init__.py +0 -0
  10. channel_app/channel_app/app/order/service.py +0 -230
  11. channel_app/channel_app/app/product/__init__.py +0 -0
  12. channel_app/channel_app/app/product/service.py +0 -237
  13. channel_app/channel_app/app/product_price/__init__.py +0 -0
  14. channel_app/channel_app/app/product_price/service.py +0 -254
  15. channel_app/channel_app/app/product_stock/__init__.py +0 -0
  16. channel_app/channel_app/app/product_stock/service.py +0 -258
  17. channel_app/channel_app/app/setup/__init__.py +0 -0
  18. channel_app/channel_app/app/setup/service.py +0 -61
  19. channel_app/channel_app/channel/__init__.py +0 -0
  20. channel_app/channel_app/channel/commands/__init__.py +0 -0
  21. channel_app/channel_app/channel/commands/orders/__init__.py +0 -0
  22. channel_app/channel_app/channel/commands/orders/orders.py +0 -329
  23. channel_app/channel_app/channel/commands/product_categories.py +0 -1
  24. channel_app/channel_app/channel/commands/product_images.py +0 -1
  25. channel_app/channel_app/channel/commands/product_prices.py +0 -148
  26. channel_app/channel_app/channel/commands/product_stocks.py +0 -220
  27. channel_app/channel_app/channel/commands/products.py +0 -161
  28. channel_app/channel_app/channel/commands/setup.py +0 -948
  29. channel_app/channel_app/channel/integration.py +0 -84
  30. channel_app/channel_app/core/__init__.py +0 -0
  31. channel_app/channel_app/core/clients.py +0 -12
  32. channel_app/channel_app/core/commands.py +0 -364
  33. channel_app/channel_app/core/data.py +0 -227
  34. channel_app/channel_app/core/integration.py +0 -74
  35. channel_app/channel_app/core/products.py +0 -64
  36. channel_app/channel_app/core/settings.py +0 -28
  37. channel_app/channel_app/core/utilities.py +0 -99
  38. channel_app/channel_app/omnitron/__init__.py +0 -0
  39. channel_app/channel_app/omnitron/batch_request.py +0 -82
  40. channel_app/channel_app/omnitron/commands/__init__.py +0 -0
  41. channel_app/channel_app/omnitron/commands/batch_requests.py +0 -281
  42. channel_app/channel_app/omnitron/commands/error_reports.py +0 -86
  43. channel_app/channel_app/omnitron/commands/integration_actions.py +0 -200
  44. channel_app/channel_app/omnitron/commands/orders/__init__.py +0 -0
  45. channel_app/channel_app/omnitron/commands/orders/addresses.py +0 -242
  46. channel_app/channel_app/omnitron/commands/orders/cargo_companies.py +0 -40
  47. channel_app/channel_app/omnitron/commands/orders/customers.py +0 -72
  48. channel_app/channel_app/omnitron/commands/orders/orders.py +0 -450
  49. channel_app/channel_app/omnitron/commands/product_categories.py +0 -1
  50. channel_app/channel_app/omnitron/commands/product_images.py +0 -1
  51. channel_app/channel_app/omnitron/commands/product_prices.py +0 -192
  52. channel_app/channel_app/omnitron/commands/product_stocks.py +0 -229
  53. channel_app/channel_app/omnitron/commands/products.py +0 -735
  54. channel_app/channel_app/omnitron/commands/setup.py +0 -839
  55. channel_app/channel_app/omnitron/constants.py +0 -98
  56. channel_app/channel_app/omnitron/exceptions.py +0 -42
  57. channel_app/channel_app/omnitron/integration.py +0 -159
  58. channel_app/setup.py +0 -21
  59. channel_app-0.0.131.dist-info/RECORD +0 -110
  60. /channel_app/{channel_app → omnitron/commands/tests}/__init__.py +0 -0
  61. {channel_app-0.0.131.dist-info → channel_app-0.0.135.dist-info}/top_level.txt +0 -0
@@ -1,450 +0,0 @@
1
- from typing import List
2
-
3
- from omnisdk.omnitron.endpoints import (ChannelCreateOrderEndpoint,
4
- ChannelIntegrationActionEndpoint,
5
- ChannelOrderShippingInfoEndpoint,
6
- ChannelOrderItemEndpoint,
7
- ChannelBatchRequestEndpoint,
8
- ChannelOrderEndpoint,
9
- ChannelCargoEndpoint,
10
- ChannelCancellationRequestEndpoint)
11
- from omnisdk.omnitron.models import Order, OrderShippingInfo, \
12
- CancellationRequest
13
-
14
- from channel_app.core.commands import OmnitronCommandInterface
15
- from channel_app.core.data import (OrderBatchRequestResponseDto,
16
- OmnitronCreateOrderDto, OmnitronOrderDto,
17
- OrderItemDto, CancelOrderDto, ErrorReportDto)
18
- from channel_app.core.utilities import split_list
19
- from channel_app.omnitron.batch_request import ClientBatchRequest
20
- from channel_app.omnitron.commands.batch_requests import ProcessBatchRequests
21
- from channel_app.omnitron.constants import (ContentType, BatchRequestStatus)
22
-
23
-
24
- class GetOrders(OmnitronCommandInterface):
25
- endpoint = ChannelOrderEndpoint
26
- batch_service = ClientBatchRequest
27
- content_type = ContentType.order.value
28
- path = "updates"
29
- BATCH_SIZE = 100
30
-
31
- def get_data(self) -> List[Order]:
32
- orders = self.get_orders()
33
- return orders
34
-
35
- def get_orders(self) -> List[Order]:
36
- orders = self.endpoint(
37
- path=self.path, channel_id=self.integration.channel_id
38
- ).list(
39
- params={
40
- "limit": self.BATCH_SIZE
41
- }
42
- )
43
- orders = orders[:self.BATCH_SIZE]
44
-
45
- objects_data = self.create_batch_objects(
46
- data=orders, content_type=self.content_type)
47
- self.update_batch_request(objects_data=objects_data)
48
-
49
- return orders
50
-
51
-
52
- class GetOrderItems(OmnitronCommandInterface):
53
- endpoint = ChannelOrderItemEndpoint
54
-
55
- def get_data(self):
56
- order = self.objects
57
- order_items = self.get_order_items(order)
58
- for order_item in order_items:
59
- order_item.content_type = ContentType.order_item.value
60
- self.integration.do_action(key="get_integration_with_object_id",
61
- objects=order_items)
62
- return order_items
63
-
64
-
65
- class ProcessOrderBatchRequests(OmnitronCommandInterface, ProcessBatchRequests):
66
- """
67
- Not finalized batch requests with content type `order` is managed in this command
68
- """
69
- endpoint = ChannelBatchRequestEndpoint
70
- content_type = ContentType.order.value
71
- BATCH_SIZE = 100
72
- CHUNK_SIZE = 50
73
-
74
- def validated_data(self, data: List[OrderBatchRequestResponseDto]):
75
- for item in data:
76
- assert isinstance(item, OrderBatchRequestResponseDto)
77
- return data
78
-
79
- def send(self, validated_data):
80
- result = self.process_item(validated_data)
81
- return result
82
-
83
- @property
84
- def update_state(self, *args, **kwargs) -> BatchRequestStatus:
85
- return BatchRequestStatus.done
86
-
87
- def get_remote_order_number(self, obj, integration_actions):
88
- for integration_action in integration_actions:
89
- content_type = integration_action.content_type["model"]
90
- if content_type != "order":
91
- continue
92
- if integration_action.object_id == obj.pk:
93
- return integration_action.remote_id
94
-
95
- def get_channel_items_by_reference_object_ids(self, channel_response,
96
- model_items_by_content,
97
- integration_actions):
98
- channel_items_by_order_id = {}
99
- for order_id, order in model_items_by_content["order"].items():
100
- for channel_item in channel_response:
101
- # TODO: comment
102
- number = self.get_remote_order_number(obj=order,
103
- integration_actions=integration_actions)
104
- if channel_item.number != number:
105
- continue
106
- remote_item = channel_item
107
- channel_items_by_order_id[order_id] = remote_item
108
- break
109
- return channel_items_by_order_id
110
-
111
- def get_orders(self, id_list) -> dict:
112
- if not id_list:
113
- return {}
114
-
115
- end_point = ChannelOrderEndpoint(
116
- channel_id=self.integration.channel_id)
117
- orders = []
118
- for chunk_id_list in split_list(id_list, self.CHUNK_SIZE):
119
- orders_batch = end_point.list(
120
- params={"id__in": ",".join(chunk_id_list),
121
- "limit": len(chunk_id_list)})
122
- orders.extend(orders_batch)
123
- return {order.pk: order for order in orders}
124
-
125
- def group_model_items_by_content_type(self, items_by_content):
126
- batch_items = {}
127
- for model, model_pks in items_by_content.items():
128
- if model != "order":
129
- continue
130
- group_items = self.get_orders(model_pks)
131
- batch_items[model] = group_items
132
- return batch_items
133
-
134
-
135
- class CreateOrders(OmnitronCommandInterface):
136
- endpoint = ChannelCreateOrderEndpoint
137
- content_type = ContentType.order.value
138
- CHUNK_SIZE = 50
139
-
140
- def get_data(self) -> dict:
141
- assert isinstance(self.objects, OmnitronCreateOrderDto)
142
-
143
- order = self.objects.order
144
- order_item = self.objects.order_item
145
- order_items = self.prepare_order_items(order_items=order_item)
146
- extra_field = self.get_extra_field(order)
147
- data = {
148
- "order_item": order_items,
149
- "order": {
150
- "number": order.number[:128],
151
- "channel": self.integration.channel_id,
152
- "customer": order.customer,
153
- "shipping_address": order.shipping_address,
154
- "billing_address": order.billing_address,
155
- "currency": order.currency,
156
- "amount": order.amount,
157
- "shipping_amount": order.shipping_amount,
158
- "shipping_tax_rate": order.shipping_tax_rate,
159
- "extra_field": extra_field,
160
- "delivery_type": order.delivery_type,
161
- "cargo_company": order.cargo_company,
162
- "discount_amount": order.discount_amount or 0,
163
- "net_shipping_amount": order.net_shipping_amount,
164
- "tracking_number": order.tracking_number[:256],
165
- "carrier_shipping_code": order.carrier_shipping_code[:256],
166
- "remote_addr": order.remote_addr,
167
- "has_gift_box": order.has_gift_box,
168
- "gift_box_note": order.gift_box_note[:160],
169
- "client_type": "default",
170
- "language_code": order.language_code,
171
- "notes": order.notes[:320],
172
- "delivery_range": order.delivery_type,
173
- "shipping_option_slug": order.shipping_option_slug[:128],
174
- "date_placed": str(order.created_at)
175
- }
176
- }
177
- return data
178
-
179
- def get_extra_field(self, order: OmnitronOrderDto):
180
- extra_field = order.extra_field or {}
181
- if "id" not in extra_field and order.remote_id:
182
- extra_field.update({"id": order.remote_id})
183
- return extra_field
184
-
185
- def send(self, validated_data) -> object:
186
- order_obj = Order(**validated_data)
187
- order = self.endpoint(channel_id=self.integration.channel_id).create(
188
- item=order_obj)
189
- self._update_batch_request(order)
190
- return order
191
-
192
- def normalize_response(self, data, response) -> List[object]:
193
- return [data]
194
-
195
- def _update_batch_request(self, order):
196
- order.remote_id = order.extra_field.get("id")
197
- objects_data_order = self.create_batch_objects(data=[order],
198
- content_type=ContentType.order.value)
199
- order_items = self.get_order_items(order_pk=order.pk)
200
- for item in order_items:
201
- item.remote_id = item.extra_field["id"]
202
- objects_data_order_items = self.create_batch_objects(
203
- data=order_items,
204
- content_type=ContentType.order_item.value)
205
- objects_data = []
206
- objects_data.extend(objects_data_order)
207
- objects_data.extend(objects_data_order_items)
208
- self.update_batch_request(objects_data=objects_data)
209
-
210
- def get_order_items(self, order_pk):
211
- params = {"order": order_pk}
212
- endpoint = ChannelOrderItemEndpoint(
213
- channel_id=self.integration.channel_id)
214
- order_items = endpoint.list(params=params)
215
- for item in endpoint.iterator:
216
- if not item:
217
- break
218
- order_items.extend(item)
219
- return order_items
220
-
221
- @property
222
- def update_state(self, *args, **kwargs) -> BatchRequestStatus:
223
- return BatchRequestStatus.done
224
-
225
- def prepare_order_items(self, order_items: List[OrderItemDto]):
226
- product_dict = self.get_products(order_items)
227
- items = []
228
- for item in order_items:
229
- price_list = self.integration.catalog.price_list
230
- stock_list = self.integration.catalog.stock_list
231
- order_item_data = {
232
- "product": product_dict[item.product],
233
- "status": item.status or "400",
234
- "price_currency": item.price_currency,
235
- "price": item.price,
236
- "tax_rate": item.tax_rate,
237
- "extra_field": {
238
- "id": item.remote_id
239
- },
240
- "price_list": item.price_list or price_list,
241
- "stock_list": item.stock_list or stock_list,
242
- "tracking_number": item.tracking_number,
243
- "carrier_shipping_code": item.carrier_shipping_code[:256],
244
- "discount_amount": item.discount_amount,
245
- "retail_price": item.retail_price,
246
- "attributes": item.attributes or {},
247
- "attributes_kwargs": item.attributes_kwargs or {},
248
- "parent": item.parent,
249
- "delivered_date": item.delivered_date,
250
- "estimated_delivery_date": item.delivered_date,
251
- }
252
- items.append(order_item_data)
253
- return items
254
-
255
- def get_order_item_extra_field(self, order_item: OrderItemDto):
256
- extra_field = order_item.extra_field
257
- if "id" not in extra_field and order_item.remote_id:
258
- extra_field.update({"id": order_item.remote_id})
259
- return extra_field
260
-
261
- def get_products(self, order_items: List[OrderItemDto]) -> dict:
262
- product_remote_ids = self.get_product_remote_id_list(order_items)
263
- endpoint = ChannelIntegrationActionEndpoint(
264
- channel_id=self.integration.channel_id)
265
- product_integration_actions = []
266
- for chunk in split_list(product_remote_ids, self.CHUNK_SIZE):
267
- params = {"channel": self.integration.channel_id,
268
- "content_type_model": ContentType.product.value,
269
- "remote_id__in": ",".join(chunk)}
270
- ia = endpoint.list(params=params)
271
- product_integration_actions.extend(ia)
272
- return {ia.remote_id: ia.object_id for ia in
273
- product_integration_actions}
274
-
275
- def get_product_remote_id_list(self, order_items: List[OrderItemDto]):
276
- product_remote_ids = [item.product for item in order_items]
277
- return product_remote_ids
278
-
279
-
280
- class CreateOrderShippingInfo(OmnitronCommandInterface):
281
- endpoint = ChannelOrderShippingInfoEndpoint
282
-
283
- def get_data(self) -> dict:
284
- order: Order = self.objects
285
- cargo_is_send = self.integration.channel.conf.get(
286
- "send_shipping_info", False)
287
- shipping_company = self.get_shipping_company(
288
- cargo_company_id=order.cargo_company)
289
- data = {
290
- "order": order.pk,
291
- "order_number": order.number,
292
- "shipping_company": shipping_company,
293
- "is_send": cargo_is_send
294
- }
295
- return data
296
-
297
- def get_shipping_company(self, cargo_company_id):
298
- endpoint = ChannelCargoEndpoint(channel_id=self.integration.channel_id)
299
- cargo_company = endpoint.retrieve(id=cargo_company_id)
300
- return cargo_company
301
-
302
- def send(self, validated_data) -> object:
303
- """
304
- :param validated_data: data for order
305
- :return: order objects
306
- """
307
- order_shipping_info_obj = OrderShippingInfo(**validated_data)
308
- order = self.endpoint(channel_id=self.integration.channel_id).create(
309
- item=order_shipping_info_obj)
310
- return order
311
-
312
- def check_run(self, is_ok, formatted_data):
313
- if not is_ok:
314
- return False
315
- return True
316
-
317
-
318
- class CreateOrderCancel(OmnitronCommandInterface):
319
- endpoint = ChannelOrderEndpoint
320
- path = "{pk}/cancel"
321
-
322
- def get_data(self):
323
- assert isinstance(self.objects, CancelOrderDto)
324
- cancel_data = self.objects
325
- order_pk = self.get_order_pk(order_remote_id=cancel_data.order)
326
- order_item_dict = self.get_order_item_dict(
327
- cancel_items=cancel_data.cancel_items)
328
- order_item_pk_list = []
329
- for key, pk_list in order_item_dict.items():
330
- order_item_pk_list.extend(pk_list)
331
-
332
- reasons = self.get_reasons_data(order_item_dict=order_item_dict,
333
- reasons=cancel_data.reasons)
334
-
335
- data = {
336
- "cancel_items": order_item_pk_list,
337
- "order": order_pk,
338
- "reasons": reasons
339
- }
340
- return data
341
-
342
- def get_order_pk(self, order_remote_id):
343
- end_point = ChannelIntegrationActionEndpoint(
344
- channel_id=self.integration.channel_id)
345
- params = {"channel": self.integration.channel_id,
346
- "content_type_model": ContentType.order.value,
347
- "remote_id": order_remote_id}
348
- integration_actions = end_point.list(params=params)
349
- if not integration_actions:
350
- raise Exception(
351
- "Order not found: number={}".format(order_remote_id))
352
- if len(integration_actions) != 1:
353
- raise Exception(
354
- "CancelOrder.get_order_pk query incorrect: params={}".format(
355
- params))
356
-
357
- integration_action = integration_actions[0]
358
- object_id = integration_action.object_id
359
- return object_id
360
-
361
- def get_order_item_dict(self, cancel_items: List[str]) -> dict:
362
- """
363
- cancel_items: ["121", "232"] -> omnitron orderitem remote_id list
364
- :return: dict
365
- {orderitem_remote_id: [omnitron_id1, omnitronid2]}
366
- {"121": [1001]}
367
- {"232": [1002, 1003]}
368
- """
369
- end_point = ChannelIntegrationActionEndpoint(
370
- channel_id=self.integration.channel_id)
371
-
372
- object_ids = {}
373
- for order_item_remote_id in cancel_items:
374
- params = {"channel": self.integration.channel_id,
375
- "content_type_model": ContentType.order_item.value,
376
- "remote_id": order_item_remote_id}
377
- integration_actions = end_point.list(params=params)
378
- for item in end_point.iterator:
379
- if not item:
380
- break
381
- integration_actions.extend(item)
382
-
383
- if not integration_actions:
384
- raise Exception(
385
- "CreateOrderCancel: OrderItem not found, number={}".format(
386
- order_item_remote_id))
387
- ids = [integration_action.object_id
388
- for integration_action in integration_actions]
389
-
390
- object_ids[order_item_remote_id] = ids
391
-
392
- return object_ids
393
-
394
- def get_reasons_data(self, order_item_dict: dict, reasons: dict):
395
- """
396
- order_item_dict: dict # {remote_basketitem_id: [id1,id2]}
397
- reasons: dict # {order_item_remote_id: remote_reason_code}
398
- """
399
- reasons_dict = {} # order_item_id: reason_id
400
- for order_item_remote_id, reason_remote_code in reasons.items():
401
- order_item_id_list = order_item_dict[order_item_remote_id]
402
- reason_mapping = self.integration.channel.conf.get(
403
- "reason_mapping", {})
404
- try:
405
- cancellation_reason_id = reason_mapping[reason_remote_code]
406
- except KeyError:
407
- cancellation_reason_id = self.integration.channel.conf.get(
408
- "cancellation_reason_id")
409
-
410
- for order_item_id in order_item_id_list:
411
- reasons_dict[order_item_id] = cancellation_reason_id
412
- return reasons_dict
413
-
414
- def send(self, validated_data) -> Order:
415
- path = self.path.format(validated_data["order"])
416
- endpoint = self.endpoint(path=path,
417
- channel_id=self.integration.channel_id,
418
- raw=True)
419
- response = endpoint.create(item=validated_data)
420
- return response
421
-
422
- def normalize_response(self, data, response) -> List[object]:
423
- return [data]
424
-
425
-
426
- class GetCancellationRequest(OmnitronCommandInterface):
427
- endpoint = ChannelCancellationRequestEndpoint
428
- content_type = ContentType.cancellation_request.value
429
- CHUNK_SIZE = 50
430
-
431
- def get_data(self):
432
- """
433
- {"status": "approved", "cancellation_type": "refund or cancel", "order_item": 3212}
434
- """
435
- assert isinstance(self.objects, dict)
436
- query_params = self.objects
437
- if not query_params.get("limit", None):
438
- query_params["limit"] = self.CHUNK_SIZE
439
- return self.get_cancellation_requests(query_params=query_params)
440
-
441
- def get_cancellation_requests(self, query_params={}) -> List[
442
- CancellationRequest]:
443
- endpoint = self.endpoint(path=self.path,
444
- channel_id=self.integration.channel_id)
445
- cancellation_requests = endpoint.list(query_params)
446
- for batch in endpoint.iterator:
447
- if not batch:
448
- break
449
- cancellation_requests.extend(batch)
450
- return cancellation_requests
@@ -1 +0,0 @@
1
- #TODO omnitron product category integration
@@ -1 +0,0 @@
1
- #TODO omnitron image integration
@@ -1,192 +0,0 @@
1
- from typing import List
2
-
3
- from omnisdk.omnitron.endpoints import ChannelIntegrationActionEndpoint, \
4
- ChannelProductPriceEndpoint, ChannelBatchRequestEndpoint, \
5
- ChannelExtraProductPriceEndpoint
6
- from omnisdk.omnitron.models import ProductPrice
7
-
8
- from channel_app.core.commands import OmnitronCommandInterface
9
- from channel_app.core.data import BatchRequestResponseDto
10
- from channel_app.omnitron.commands.batch_requests import ProcessBatchRequests
11
- from channel_app.omnitron.constants import (ContentType, BatchRequestStatus,
12
- IntegrationActionStatus,
13
- FailedReasonType)
14
-
15
-
16
- class GetUpdatedProductPrices(OmnitronCommandInterface):
17
- endpoint = ChannelProductPriceEndpoint
18
- path = "updates"
19
- BATCH_SIZE = 100
20
- content_type = ContentType.product_price.value
21
-
22
- def get_data(self) -> List[ProductPrice]:
23
- prices = self.get_product_prices()
24
- prices = self.get_integration_actions(prices)
25
- return prices
26
-
27
- def get_product_prices(self) -> List[ProductPrice]:
28
- prices = self.endpoint(
29
- path=self.path,
30
- channel_id=self.integration.channel_id
31
- ).list(
32
- params={
33
- "limit": self.BATCH_SIZE
34
- }
35
- )
36
- prices = prices[:self.BATCH_SIZE]
37
- objects_data = self.create_batch_objects(data=prices,
38
- content_type=self.content_type)
39
- self.update_batch_request(objects_data=objects_data)
40
- return prices
41
-
42
- def get_integration_actions(self, prices: List[ProductPrice]):
43
- if not prices:
44
- return []
45
- endpoint = ChannelIntegrationActionEndpoint(
46
- channel_id=self.integration.channel_id)
47
- price_integration_actions = endpoint.list(
48
- params={
49
- "local_batch_id": self.integration.batch_request.local_batch_id,
50
- "status": IntegrationActionStatus.processing,
51
- "channel_id": self.integration.channel_id
52
- })
53
- for price_batch in endpoint.iterator:
54
- price_integration_actions.extend(price_batch)
55
- price_ia_dict = {ia.object_id: ia for ia in price_integration_actions}
56
- for price in prices:
57
- price_ia = price_ia_dict[price.pk]
58
- price.remote_id = price_ia.remote_id
59
- return prices
60
-
61
-
62
- class GetInsertedProductPrices(GetUpdatedProductPrices):
63
- path = "inserts"
64
-
65
- def get_integration_actions(self, prices: List[ProductPrice]):
66
- if not prices:
67
- return []
68
- endpoint = ChannelIntegrationActionEndpoint(
69
- channel_id=self.integration.channel_id)
70
- product_ids = [str(price.product) for price in prices]
71
- product_ias = endpoint.list(
72
- params={"object_id__in": ",".join(product_ids),
73
- "content_type_name": ContentType.product.value,
74
- "status": IntegrationActionStatus.success,
75
- "channel_id": self.integration.channel_id
76
- })
77
- for product_batch in endpoint.iterator:
78
- product_ias.extend(product_batch)
79
- product_integrations_by_id = {ia.object_id: ia for ia in product_ias}
80
-
81
- for price in prices:
82
- if price.product in product_integrations_by_id:
83
- product_ia = product_integrations_by_id[price.product]
84
- price.remote_id = product_ia.remote_id
85
- else:
86
- price.failed_reason_type = FailedReasonType.channel_app.value
87
- self.failed_object_list.append(
88
- (price, ContentType.product_price.value,
89
- "Product has not been sent"))
90
- return prices
91
-
92
-
93
- class GetInsertedProductPricesFromExtraPriceList(OmnitronCommandInterface):
94
- endpoint = ChannelExtraProductPriceEndpoint
95
- path = "inserts"
96
- BATCH_SIZE = 100
97
- content_type = ContentType.product_price.value
98
-
99
- def get_data(self) -> List[ProductPrice]:
100
- self.price_list_id = self.objects
101
- prices = self.get_product_prices()
102
- prices = self.get_integration_actions(prices)
103
- return prices
104
-
105
- def get_product_prices(self) -> List[ProductPrice]:
106
- endpoint = self.endpoint(path=self.path,
107
- channel_id=self.integration.channel_id)
108
- prices = endpoint.list(
109
- params={"price_list": self.price_list_id}
110
- )
111
- for price_batch in endpoint.iterator:
112
- prices.extend(price_batch)
113
- if len(prices) >= self.BATCH_SIZE:
114
- break
115
- prices = prices[:self.BATCH_SIZE]
116
- objects_data = self.create_batch_objects(data=prices,
117
- content_type=self.content_type)
118
- self.update_batch_request(objects_data=objects_data)
119
- return prices
120
-
121
- def get_integration_actions(self, prices: List[ProductPrice]):
122
- if not prices:
123
- return []
124
- endpoint = ChannelIntegrationActionEndpoint(
125
- channel_id=self.integration.channel_id)
126
- price_integration_actions = endpoint.list(
127
- params={
128
- "local_batch_id": self.integration.batch_request.local_batch_id,
129
- "status": IntegrationActionStatus.processing
130
- })
131
- for price_batch in endpoint.iterator:
132
- price_integration_actions.extend(price_batch)
133
- price_ia_dict = {ia.object_id: ia for ia in price_integration_actions}
134
- for price in prices:
135
- price_ia = price_ia_dict[price.pk]
136
- price.remote_id = price_ia.remote_id
137
- return prices
138
-
139
-
140
- class GetUpdatedProductPricesFromExtraPriceList(
141
- GetInsertedProductPricesFromExtraPriceList):
142
- path = "updates"
143
-
144
-
145
- class ProcessPriceBatchRequests(OmnitronCommandInterface, ProcessBatchRequests):
146
- endpoint = ChannelBatchRequestEndpoint
147
- content_type = ContentType.product_price.value
148
- CHUNK_SIZE = 50
149
- BATCH_SIZE = 100
150
-
151
- def get_data(self):
152
- return self.objects
153
-
154
- def validated_data(self, data: List[BatchRequestResponseDto]):
155
- for item in data:
156
- assert isinstance(item, BatchRequestResponseDto)
157
- return data
158
-
159
- def send(self, validated_data):
160
- result = self.process_item(validated_data)
161
- return result
162
-
163
- @property
164
- def update_state(self, *args, **kwargs) -> BatchRequestStatus:
165
- return BatchRequestStatus.done
166
-
167
- def check_run(self, is_ok, formatted_data):
168
- if not is_ok and self.is_batch_request:
169
- self.integration.batch_request.objects = None
170
- self.batch_service(self.integration.channel_id).to_fail(
171
- self.integration.batch_request)
172
- return False
173
-
174
- def get_channel_items_by_reference_object_ids(self, channel_response,
175
- model_items_by_content,
176
- integration_actions):
177
- product_ids = [str(item) for item in
178
- model_items_by_content["productprice"]]
179
-
180
- model_items_by_content_product = self.get_products(product_ids)
181
-
182
- channel_items_by_product_id = {}
183
- for product_id, product in model_items_by_content_product.items():
184
- for channel_item in channel_response:
185
- # TODO: comment
186
- sku = self.get_barcode(obj=product)
187
- if channel_item.sku != sku:
188
- continue
189
- remote_item = channel_item
190
- channel_items_by_product_id[product_id] = remote_item
191
- break
192
- return channel_items_by_product_id