oneCInteraction 1.2.3__tar.gz → 1.2.4__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 (26) hide show
  1. {onecinteraction-1.2.3/src/oneCInteraction.egg-info → onecinteraction-1.2.4}/PKG-INFO +15 -10
  2. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/README.md +14 -9
  3. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/nomenclature.py +86 -8
  4. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/structures.py +3 -1
  5. {onecinteraction-1.2.3 → onecinteraction-1.2.4/src/oneCInteraction.egg-info}/PKG-INFO +15 -10
  6. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction.egg-info/scm_version.json +2 -2
  7. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/tests/test_lib.py +11 -1
  8. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/.github/workflows/publish.yml +0 -0
  9. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/.gitignore +0 -0
  10. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/LICENSE +0 -0
  11. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/pyproject.toml +0 -0
  12. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/setup.cfg +0 -0
  13. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/__init__.py +0 -0
  14. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/categories.py +0 -0
  15. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/characteristics.py +0 -0
  16. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/connection.py +0 -0
  17. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/customers.py +0 -0
  18. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/discounts.py +0 -0
  19. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/groups.py +0 -0
  20. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/log.py +0 -0
  21. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction/orders.py +0 -0
  22. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction.egg-info/SOURCES.txt +0 -0
  23. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction.egg-info/dependency_links.txt +0 -0
  24. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction.egg-info/requires.txt +0 -0
  25. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction.egg-info/scm_file_list.json +0 -0
  26. {onecinteraction-1.2.3 → onecinteraction-1.2.4}/src/oneCInteraction.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oneCInteraction
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: A Python library for interacting with 1C:Enterprise databases via COM connection.
5
5
  Author: agcl
6
6
  Classifier: Programming Language :: Python :: 3
@@ -68,7 +68,7 @@ def __init__(self, s_oneCDatabasePathIn: str, s_usernameIn: str, s_passwordIn: s
68
68
  - `s_warehouse_code` (str): 1C warehouse code for new orders.
69
69
  - `s_counteragent_code` (str): 1C counteragent (customer) code for new orders.
70
70
  - `s_organisation_code` (str): 1C organization code for new orders.
71
- - `sl_price_types` (list): List of price type names to cache automatically (defaults to `["Розничная", "Оптовая"]`).
71
+ - `sl_price_types` (list): List of price type names to cache automatically (defaults to `["Розничная", "Оптовая", "Закупочная"]`).
72
72
  - `c_v8`: The active 1C COM connection object (equals `None` if not connected).
73
73
 
74
74
  #### Methods:
@@ -92,6 +92,7 @@ Represents a product.
92
92
  - `s_uuid` (str): Unique identifier (UUID) of the product in 1C.
93
93
  - `s_code` (str): 1C product code.
94
94
  - `l_images` (list): List of image UUIDs associated with the product in 1C.
95
+ - `dt_last_arrival` (datetime): Date of the last physical arrival of the product to the warehouse from 1C.
95
96
 
96
97
  #### `Price`
97
98
  Represents a price with its value, assignment date, and type.
@@ -153,6 +154,8 @@ A buyer's order.
153
154
  - `s_status` (str): Status of the order in 1C.
154
155
  - `s_date` (str): Order creation date (automatically generated).
155
156
  - `n_orderCode` (str / int): Order number in 1C.
157
+ - `s_price_type` (str): Price type name used for the order (e.g. `"Розничная"`, `"Оптовая"`, `"Закупочная"`).
158
+ - `s_comment` (str): Additional comment/notes for the order (often parsed to extract Telegram ID).
156
159
 
157
160
  Calling `str(order_obj)` returns a nicely formatted HTML string suitable for sending to a Telegram bot.
158
161
 
@@ -170,13 +173,15 @@ Represents a group of nomenclature discounts.
170
173
  Defined in [nomenclature.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/src/oneCInteraction/nomenclature.py).
171
174
 
172
175
  - `get(s_articleIn: str = "", s_nameIn: str = "", s_codeIn: str = "") -> Nomenclature | None`
173
- Searches for and returns a product by its article, name, or code. Fetches retail/wholesale prices, stock balances by warehouses, and characteristics.
176
+ Searches for and returns a product by its article, name, or code. Fetches retail, wholesale, and purchase prices, stock balances by warehouses, characteristics, and the parent group's UUID (`s_parent_uuid`).
177
+ - `search(s_queryIn: str, s_searchByIn: str = "all") -> list`
178
+ Searches for nomenclature items by a query string matching the name, article, code, or all of them. Returns a list of `Nomenclature` objects (without full detailed price/stock breakdown, but containing basic fields).
174
179
  - `get_images(c_productObjIn: Nomenclature, s_imageDirIn: str = None) -> list`
175
180
  Downloads all attached images for a product from 1C. Saves them in the specified directory `s_imageDirIn` (defaults to `data/images`). Returns a list of the saved filenames (e.g., `["[uuid]_0.jpg"]`).
176
181
  - `get_by_group(c_groupRefIn) -> list`
177
182
  Batch fetches all products within a specific 1C group. Using optimized COM queries, this method minimizes DB requests and operates significantly faster than calling `get()` sequentially in a loop.
178
- - `get_by_category(c_categoryIn, s_attributeNameIn: str = "ВидНоменклатуры", s_catalogNameIn: str = "ВидыНоменклатуры") -> list`
179
- Batch fetches all products within a specific 1C category (by default using the `ВидНоменклатуры` attribute in the `ВидыНоменклатуры` catalog). `c_categoryIn` can be a COM reference object or a string representing the category name.
183
+ - `get_by_category(c_categoryIn) -> list`
184
+ Batch fetches all products within a specific 1C category. `c_categoryIn` can be a COM reference object or a string representing the category name (searched within `Справочник.КатегорииОбъектов`).
180
185
 
181
186
  ---
182
187
 
@@ -196,9 +201,9 @@ Defined in [groups.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/
196
201
  Defined in [categories.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/src/oneCInteraction/categories.py).
197
202
 
198
203
  - `get(s_codeIn: str = "", s_nameIn: str = "") -> Category | None`
199
- Finds a single Category by its code or name in the `ВидыНоменклатуры` catalog.
204
+ Finds a single Category by its code or name in the `КатегорииОбъектов` (Object Categories) catalog.
200
205
  - `create(s_nameIn: str) -> Category | None`
201
- Creates a new Category with the specified name in `Справочник.ВидыНоменклатуры` and returns it.
206
+ Creates a new Category with the specified name in `Справочник.КатегорииОбъектов` and returns it.
202
207
 
203
208
  ---
204
209
 
@@ -220,12 +225,12 @@ Defined in [orders.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/
220
225
  - `push(c_orderObjIn: Order) -> str`
221
226
  Creates a new `"Заказ покупателя"` (Buyer's Order) document in 1C.
222
227
  - Automatically queries the warehouse, counteragent, and organization based on codes specified in the `Connection` object.
223
- - Sets the retail price type, document currency (Hryvnia, code `"980"`), and organization's primary bank account.
224
- - Adds products from the order, queries the exact price for the specific characteristic selected, and computes totals.
228
+ - Sets the price type (defaulting to `"Розничная"` or using `s_price_type` from the order), document currency (Hryvnia, code `"980"`), and organization's primary bank account.
229
+ - Adds products from the order, queries/compares the exact price for the specific characteristic selected (using `s_price_type` to determine retail, wholesale, or purchase price), and computes totals.
225
230
  - Attempts to post the document (`Posting`). If posting fails, it writes the document in draft/save mode (`Write`).
226
231
  - Returns the number of the created document in 1C (or an empty string on error).
227
232
  - `get(s_codeIn: str) -> Order | None`
228
- Retrieves a buyer's order by its 1C document number and parses it into an `Order` object. The comment field is parsed to retrieve the Telegram ID.
233
+ Retrieves a buyer's order by its 1C document number and parses it into an `Order` object. The comment field is parsed to retrieve the Telegram ID, and the price type is retrieved.
229
234
  - `get_today() -> list`
230
235
  Returns a list of all today's orders created for the configured bot counteragent (filtered by current date and counteragent code).
231
236
  - `update_info(c_orderObjIn: Order) -> bool`
@@ -53,7 +53,7 @@ def __init__(self, s_oneCDatabasePathIn: str, s_usernameIn: str, s_passwordIn: s
53
53
  - `s_warehouse_code` (str): 1C warehouse code for new orders.
54
54
  - `s_counteragent_code` (str): 1C counteragent (customer) code for new orders.
55
55
  - `s_organisation_code` (str): 1C organization code for new orders.
56
- - `sl_price_types` (list): List of price type names to cache automatically (defaults to `["Розничная", "Оптовая"]`).
56
+ - `sl_price_types` (list): List of price type names to cache automatically (defaults to `["Розничная", "Оптовая", "Закупочная"]`).
57
57
  - `c_v8`: The active 1C COM connection object (equals `None` if not connected).
58
58
 
59
59
  #### Methods:
@@ -77,6 +77,7 @@ Represents a product.
77
77
  - `s_uuid` (str): Unique identifier (UUID) of the product in 1C.
78
78
  - `s_code` (str): 1C product code.
79
79
  - `l_images` (list): List of image UUIDs associated with the product in 1C.
80
+ - `dt_last_arrival` (datetime): Date of the last physical arrival of the product to the warehouse from 1C.
80
81
 
81
82
  #### `Price`
82
83
  Represents a price with its value, assignment date, and type.
@@ -138,6 +139,8 @@ A buyer's order.
138
139
  - `s_status` (str): Status of the order in 1C.
139
140
  - `s_date` (str): Order creation date (automatically generated).
140
141
  - `n_orderCode` (str / int): Order number in 1C.
142
+ - `s_price_type` (str): Price type name used for the order (e.g. `"Розничная"`, `"Оптовая"`, `"Закупочная"`).
143
+ - `s_comment` (str): Additional comment/notes for the order (often parsed to extract Telegram ID).
141
144
 
142
145
  Calling `str(order_obj)` returns a nicely formatted HTML string suitable for sending to a Telegram bot.
143
146
 
@@ -155,13 +158,15 @@ Represents a group of nomenclature discounts.
155
158
  Defined in [nomenclature.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/src/oneCInteraction/nomenclature.py).
156
159
 
157
160
  - `get(s_articleIn: str = "", s_nameIn: str = "", s_codeIn: str = "") -> Nomenclature | None`
158
- Searches for and returns a product by its article, name, or code. Fetches retail/wholesale prices, stock balances by warehouses, and characteristics.
161
+ Searches for and returns a product by its article, name, or code. Fetches retail, wholesale, and purchase prices, stock balances by warehouses, characteristics, and the parent group's UUID (`s_parent_uuid`).
162
+ - `search(s_queryIn: str, s_searchByIn: str = "all") -> list`
163
+ Searches for nomenclature items by a query string matching the name, article, code, or all of them. Returns a list of `Nomenclature` objects (without full detailed price/stock breakdown, but containing basic fields).
159
164
  - `get_images(c_productObjIn: Nomenclature, s_imageDirIn: str = None) -> list`
160
165
  Downloads all attached images for a product from 1C. Saves them in the specified directory `s_imageDirIn` (defaults to `data/images`). Returns a list of the saved filenames (e.g., `["[uuid]_0.jpg"]`).
161
166
  - `get_by_group(c_groupRefIn) -> list`
162
167
  Batch fetches all products within a specific 1C group. Using optimized COM queries, this method minimizes DB requests and operates significantly faster than calling `get()` sequentially in a loop.
163
- - `get_by_category(c_categoryIn, s_attributeNameIn: str = "ВидНоменклатуры", s_catalogNameIn: str = "ВидыНоменклатуры") -> list`
164
- Batch fetches all products within a specific 1C category (by default using the `ВидНоменклатуры` attribute in the `ВидыНоменклатуры` catalog). `c_categoryIn` can be a COM reference object or a string representing the category name.
168
+ - `get_by_category(c_categoryIn) -> list`
169
+ Batch fetches all products within a specific 1C category. `c_categoryIn` can be a COM reference object or a string representing the category name (searched within `Справочник.КатегорииОбъектов`).
165
170
 
166
171
  ---
167
172
 
@@ -181,9 +186,9 @@ Defined in [groups.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/
181
186
  Defined in [categories.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/src/oneCInteraction/categories.py).
182
187
 
183
188
  - `get(s_codeIn: str = "", s_nameIn: str = "") -> Category | None`
184
- Finds a single Category by its code or name in the `ВидыНоменклатуры` catalog.
189
+ Finds a single Category by its code or name in the `КатегорииОбъектов` (Object Categories) catalog.
185
190
  - `create(s_nameIn: str) -> Category | None`
186
- Creates a new Category with the specified name in `Справочник.ВидыНоменклатуры` and returns it.
191
+ Creates a new Category with the specified name in `Справочник.КатегорииОбъектов` and returns it.
187
192
 
188
193
  ---
189
194
 
@@ -205,12 +210,12 @@ Defined in [orders.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/
205
210
  - `push(c_orderObjIn: Order) -> str`
206
211
  Creates a new `"Заказ покупателя"` (Buyer's Order) document in 1C.
207
212
  - Automatically queries the warehouse, counteragent, and organization based on codes specified in the `Connection` object.
208
- - Sets the retail price type, document currency (Hryvnia, code `"980"`), and organization's primary bank account.
209
- - Adds products from the order, queries the exact price for the specific characteristic selected, and computes totals.
213
+ - Sets the price type (defaulting to `"Розничная"` or using `s_price_type` from the order), document currency (Hryvnia, code `"980"`), and organization's primary bank account.
214
+ - Adds products from the order, queries/compares the exact price for the specific characteristic selected (using `s_price_type` to determine retail, wholesale, or purchase price), and computes totals.
210
215
  - Attempts to post the document (`Posting`). If posting fails, it writes the document in draft/save mode (`Write`).
211
216
  - Returns the number of the created document in 1C (or an empty string on error).
212
217
  - `get(s_codeIn: str) -> Order | None`
213
- Retrieves a buyer's order by its 1C document number and parses it into an `Order` object. The comment field is parsed to retrieve the Telegram ID.
218
+ Retrieves a buyer's order by its 1C document number and parses it into an `Order` object. The comment field is parsed to retrieve the Telegram ID, and the price type is retrieved.
214
219
  - `get_today() -> list`
215
220
  Returns a list of all today's orders created for the configured bot counteragent (filtered by current date and counteragent code).
216
221
  - `update_info(c_orderObjIn: Order) -> bool`
@@ -54,7 +54,8 @@ class NomenclatureManager:
54
54
  Артикул AS Article,
55
55
  ISNULL(ДополнительноеОписаниеНоменклатуры, "") AS FullDescription,
56
56
  ISNULL(НаименованиеПолное, "") AS FullName,
57
- ISNULL(ЕдиницаХраненияОстатков.Наименование, "шт.") AS Unit
57
+ ISNULL(ЕдиницаХраненияОстатков.Наименование, "шт.") AS Unit,
58
+ Родитель.Ссылка AS ParentRef
58
59
  FROM Справочник.Номенклатура
59
60
  WHERE ({" OR ".join(where_clauses)}) AND ЭтоГруппа = ЛОЖЬ AND ПометкаУдаления = ЛОЖЬ
60
61
  """
@@ -71,6 +72,8 @@ class NomenclatureManager:
71
72
  if not s_description:
72
73
  s_description = self.c_v8.String(c_selection.FullName)
73
74
 
75
+ s_parent_uuid = self.c_v8.String(c_selection.ParentRef.UUID()) if not c_selection.ParentRef.IsEmpty() else ""
76
+
74
77
  log_sys(f"Nomenclature found: Name='{c_selection.Name}', Article='{c_selection.Article}'")
75
78
  return self._fetch_details(
76
79
  c_selection.Ref,
@@ -78,8 +81,9 @@ class NomenclatureManager:
78
81
  c_selection.Article,
79
82
  s_description,
80
83
  getattr(c_selection, "Unit", "шт."),
81
- self.c_v8.String(c_selection.Ref.UUID()),
82
- self.c_v8.String(c_selection.Code)
84
+ self.c_v8.String(c_selection.Ref.UUID()),
85
+ self.c_v8.String(c_selection.Code),
86
+ s_parent_uuidIn=s_parent_uuid
83
87
  )
84
88
  except Exception as e:
85
89
  log_sys(f"Error in NomenclatureManager.get: {e}", 1)
@@ -162,6 +166,7 @@ class NomenclatureManager:
162
166
  return []
163
167
 
164
168
  d_batchDetails = self._fetch_batch_details(l_productRefs)
169
+ d_batchArrivals = self._fetch_batch_last_arrivals(l_productRefs)
165
170
 
166
171
  l_allCharRefs = []
167
172
  for s_productUuid in d_batchDetails:
@@ -216,7 +221,8 @@ class NomenclatureManager:
216
221
  s_unitIn=d_item["unit"],
217
222
  s_uuidIn=s_productUuid,
218
223
  s_codeIn=self.c_v8.String(d_item["code"]),
219
- l_imagesIn=d_batchImages.get(s_productUuid, [])
224
+ l_imagesIn=d_batchImages.get(s_productUuid, []),
225
+ dt_last_arrivalIn=d_batchArrivals.get(s_productUuid)
220
226
  ))
221
227
 
222
228
  log_sys(f"Successfully processed {len(l_nomenclatures)} items in search mode.")
@@ -347,6 +353,47 @@ class NomenclatureManager:
347
353
 
348
354
  return d_batchData
349
355
 
356
+ def _fetch_batch_last_arrivals(self, l_productRefsIn: list) -> dict:
357
+ """Batch fetches the last physical arrival date for a list of product references."""
358
+ if not self.c_v8 or not l_productRefsIn:
359
+ return {}
360
+
361
+ log_sys(f"Batch fetching last arrival dates for {len(l_productRefsIn)} items...")
362
+
363
+ c_productRefsV8 = self.c_v8.NewObject("ValueList")
364
+ for c_ref in l_productRefsIn:
365
+ c_productRefsV8.Add(c_ref)
366
+
367
+ c_query = self.c_v8.NewObject("Query")
368
+ c_query.Text = """
369
+ SELECT
370
+ ТоварыНаСкладах.Номенклатура AS ProductRef,
371
+ MAX(ТоварыНаСкладах.Период) AS LastArrivalDate
372
+ FROM
373
+ РегистрНакопления.ТоварыНаСкладах AS ТоварыНаСкладах
374
+ WHERE
375
+ ТоварыНаСкладах.Номенклатура В (&ProductRefs)
376
+ AND ТоварыНаСкладах.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
377
+ GROUP BY
378
+ ТоварыНаСкладах.Номенклатура
379
+ """
380
+ c_query.SetParameter("ProductRefs", c_productRefsV8)
381
+
382
+ d_arrivals = {}
383
+ try:
384
+ c_result = c_query.Execute()
385
+ if c_result is not None and not c_result.IsEmpty():
386
+ c_sel = c_result.Select()
387
+ while c_sel.Next():
388
+ s_productUuid = self.c_v8.String(c_sel.ProductRef.UUID())
389
+ dt_last_arrival = _parse_1c_date(c_sel.LastArrivalDate)
390
+ if dt_last_arrival:
391
+ d_arrivals[s_productUuid] = dt_last_arrival
392
+ except Exception as e:
393
+ log_sys(f"Error in batch last arrivals query execution: {e}", 1)
394
+
395
+ return d_arrivals
396
+
350
397
  def _fetch_batch_image_metadata(self, l_productRefsIn: list) -> dict:
351
398
  """Batch fetches image references (UUIDs) for a list of product references."""
352
399
  if not self.c_v8 or not l_productRefsIn:
@@ -389,7 +436,8 @@ class NomenclatureManager:
389
436
  s_descriptionIn: str,
390
437
  s_unitIn: str = "шт.",
391
438
  s_uuidIn: str = "",
392
- s_codeIn: str = ""
439
+ s_codeIn: str = "",
440
+ s_parent_uuidIn: str = ""
393
441
  ):
394
442
  """Fetches details (prices, stock, characteristics) for a single Nomenclature."""
395
443
  c_retailPtRef = self.c_connection.get_price_type_ref("Розничная")
@@ -527,6 +575,28 @@ class NomenclatureManager:
527
575
  )
528
576
  ))
529
577
 
578
+ # Fetch last arrival date
579
+ dt_last_arrival = None
580
+ try:
581
+ c_arrivalQuery = self.c_v8.NewObject("Query")
582
+ c_arrivalQuery.Text = """
583
+ SELECT
584
+ MAX(ТоварыНаСкладах.Период) AS LastArrivalDate
585
+ FROM
586
+ РегистрНакопления.ТоварыНаСкладах AS ТоварыНаСкладах
587
+ WHERE
588
+ ТоварыНаСкладах.Номенклатура = &ProductRef
589
+ AND ТоварыНаСкладах.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
590
+ """
591
+ c_arrivalQuery.SetParameter("ProductRef", c_productRefIn)
592
+ c_arrivalResult = c_arrivalQuery.Execute()
593
+ if c_arrivalResult is not None and not c_arrivalResult.IsEmpty():
594
+ c_arrivalSel = c_arrivalResult.Select()
595
+ if c_arrivalSel.Next():
596
+ dt_last_arrival = _parse_1c_date(c_arrivalSel.LastArrivalDate)
597
+ except Exception as e:
598
+ log_sys(f"Error fetching last arrival date for {s_articleIn}: {e}", 1)
599
+
530
600
  return structures.Nomenclature(
531
601
  s_nameIn=s_nameIn,
532
602
  s_articleIn=s_articleIn,
@@ -534,7 +604,9 @@ class NomenclatureManager:
534
604
  s_descriptionIn=s_descriptionIn,
535
605
  s_unitIn=s_unitIn,
536
606
  s_uuidIn=s_uuidIn,
537
- s_codeIn=s_codeIn
607
+ s_codeIn=s_codeIn,
608
+ s_parent_uuidIn=s_parent_uuidIn,
609
+ dt_last_arrivalIn=dt_last_arrival
538
610
  )
539
611
 
540
612
  def get_images(self, c_productObjIn, s_imageDirIn: str = None) -> list:
@@ -665,6 +737,7 @@ class NomenclatureManager:
665
737
 
666
738
 
667
739
  d_batchDetails = self._fetch_batch_details(l_productRefs)
740
+ d_batchArrivals = self._fetch_batch_last_arrivals(l_productRefs)
668
741
 
669
742
 
670
743
  l_allCharRefs = []
@@ -721,8 +794,10 @@ class NomenclatureManager:
721
794
  l_varietyIn=l_varieties,
722
795
  s_descriptionIn=d_item["description"],
723
796
  s_unitIn=d_item["unit"],
797
+ s_uuidIn=s_productUuid,
724
798
  s_codeIn=self.c_v8.String(d_item["code"]),
725
- l_imagesIn=d_batchImages.get(s_productUuid, [])
799
+ l_imagesIn=d_batchImages.get(s_productUuid, []),
800
+ dt_last_arrivalIn=d_batchArrivals.get(s_productUuid)
726
801
  ))
727
802
 
728
803
  log_sys(f"Successfully processed {len(l_nomenclatures)} items in batch mode.")
@@ -818,6 +893,7 @@ class NomenclatureManager:
818
893
 
819
894
 
820
895
  d_batchDetails = self._fetch_batch_details(l_productRefs)
896
+ d_batchArrivals = self._fetch_batch_last_arrivals(l_productRefs)
821
897
 
822
898
 
823
899
  l_allCharRefs = []
@@ -874,8 +950,10 @@ class NomenclatureManager:
874
950
  l_varietyIn=l_varieties,
875
951
  s_descriptionIn=d_item["description"],
876
952
  s_unitIn=d_item["unit"],
953
+ s_uuidIn=s_productUuid,
877
954
  s_codeIn=self.c_v8.String(d_item["code"]),
878
- l_imagesIn=d_batchImages.get(s_productUuid, [])
955
+ l_imagesIn=d_batchImages.get(s_productUuid, []),
956
+ dt_last_arrivalIn=d_batchArrivals.get(s_productUuid)
879
957
  ))
880
958
 
881
959
  log_sys(f"Successfully processed {len(l_nomenclatures)} items in batch mode.")
@@ -11,7 +11,8 @@ class Nomenclature:
11
11
  s_parent_uuidIn: str = "",
12
12
  s_uuidIn: str = "",
13
13
  s_codeIn: str = "",
14
- l_imagesIn: list = None
14
+ l_imagesIn: list = None,
15
+ dt_last_arrivalIn: datetime = None
15
16
  ):
16
17
  self.s_name = s_nameIn
17
18
  self.s_article = s_articleIn
@@ -22,6 +23,7 @@ class Nomenclature:
22
23
  self.s_uuid = s_uuidIn
23
24
  self.s_code = s_codeIn
24
25
  self.l_images = l_imagesIn if l_imagesIn is not None else []
26
+ self.dt_last_arrival = dt_last_arrivalIn
25
27
 
26
28
  class Price:
27
29
  def __init__(self, n_value: float, dt_assigned: datetime = None, s_type: str = ""):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oneCInteraction
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: A Python library for interacting with 1C:Enterprise databases via COM connection.
5
5
  Author: agcl
6
6
  Classifier: Programming Language :: Python :: 3
@@ -68,7 +68,7 @@ def __init__(self, s_oneCDatabasePathIn: str, s_usernameIn: str, s_passwordIn: s
68
68
  - `s_warehouse_code` (str): 1C warehouse code for new orders.
69
69
  - `s_counteragent_code` (str): 1C counteragent (customer) code for new orders.
70
70
  - `s_organisation_code` (str): 1C organization code for new orders.
71
- - `sl_price_types` (list): List of price type names to cache automatically (defaults to `["Розничная", "Оптовая"]`).
71
+ - `sl_price_types` (list): List of price type names to cache automatically (defaults to `["Розничная", "Оптовая", "Закупочная"]`).
72
72
  - `c_v8`: The active 1C COM connection object (equals `None` if not connected).
73
73
 
74
74
  #### Methods:
@@ -92,6 +92,7 @@ Represents a product.
92
92
  - `s_uuid` (str): Unique identifier (UUID) of the product in 1C.
93
93
  - `s_code` (str): 1C product code.
94
94
  - `l_images` (list): List of image UUIDs associated with the product in 1C.
95
+ - `dt_last_arrival` (datetime): Date of the last physical arrival of the product to the warehouse from 1C.
95
96
 
96
97
  #### `Price`
97
98
  Represents a price with its value, assignment date, and type.
@@ -153,6 +154,8 @@ A buyer's order.
153
154
  - `s_status` (str): Status of the order in 1C.
154
155
  - `s_date` (str): Order creation date (automatically generated).
155
156
  - `n_orderCode` (str / int): Order number in 1C.
157
+ - `s_price_type` (str): Price type name used for the order (e.g. `"Розничная"`, `"Оптовая"`, `"Закупочная"`).
158
+ - `s_comment` (str): Additional comment/notes for the order (often parsed to extract Telegram ID).
156
159
 
157
160
  Calling `str(order_obj)` returns a nicely formatted HTML string suitable for sending to a Telegram bot.
158
161
 
@@ -170,13 +173,15 @@ Represents a group of nomenclature discounts.
170
173
  Defined in [nomenclature.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/src/oneCInteraction/nomenclature.py).
171
174
 
172
175
  - `get(s_articleIn: str = "", s_nameIn: str = "", s_codeIn: str = "") -> Nomenclature | None`
173
- Searches for and returns a product by its article, name, or code. Fetches retail/wholesale prices, stock balances by warehouses, and characteristics.
176
+ Searches for and returns a product by its article, name, or code. Fetches retail, wholesale, and purchase prices, stock balances by warehouses, characteristics, and the parent group's UUID (`s_parent_uuid`).
177
+ - `search(s_queryIn: str, s_searchByIn: str = "all") -> list`
178
+ Searches for nomenclature items by a query string matching the name, article, code, or all of them. Returns a list of `Nomenclature` objects (without full detailed price/stock breakdown, but containing basic fields).
174
179
  - `get_images(c_productObjIn: Nomenclature, s_imageDirIn: str = None) -> list`
175
180
  Downloads all attached images for a product from 1C. Saves them in the specified directory `s_imageDirIn` (defaults to `data/images`). Returns a list of the saved filenames (e.g., `["[uuid]_0.jpg"]`).
176
181
  - `get_by_group(c_groupRefIn) -> list`
177
182
  Batch fetches all products within a specific 1C group. Using optimized COM queries, this method minimizes DB requests and operates significantly faster than calling `get()` sequentially in a loop.
178
- - `get_by_category(c_categoryIn, s_attributeNameIn: str = "ВидНоменклатуры", s_catalogNameIn: str = "ВидыНоменклатуры") -> list`
179
- Batch fetches all products within a specific 1C category (by default using the `ВидНоменклатуры` attribute in the `ВидыНоменклатуры` catalog). `c_categoryIn` can be a COM reference object or a string representing the category name.
183
+ - `get_by_category(c_categoryIn) -> list`
184
+ Batch fetches all products within a specific 1C category. `c_categoryIn` can be a COM reference object or a string representing the category name (searched within `Справочник.КатегорииОбъектов`).
180
185
 
181
186
  ---
182
187
 
@@ -196,9 +201,9 @@ Defined in [groups.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/
196
201
  Defined in [categories.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/src/oneCInteraction/categories.py).
197
202
 
198
203
  - `get(s_codeIn: str = "", s_nameIn: str = "") -> Category | None`
199
- Finds a single Category by its code or name in the `ВидыНоменклатуры` catalog.
204
+ Finds a single Category by its code or name in the `КатегорииОбъектов` (Object Categories) catalog.
200
205
  - `create(s_nameIn: str) -> Category | None`
201
- Creates a new Category with the specified name in `Справочник.ВидыНоменклатуры` and returns it.
206
+ Creates a new Category with the specified name in `Справочник.КатегорииОбъектов` and returns it.
202
207
 
203
208
  ---
204
209
 
@@ -220,12 +225,12 @@ Defined in [orders.py](file:///c:/Users/agcl/PycharmProjects/oneCInteractionLib/
220
225
  - `push(c_orderObjIn: Order) -> str`
221
226
  Creates a new `"Заказ покупателя"` (Buyer's Order) document in 1C.
222
227
  - Automatically queries the warehouse, counteragent, and organization based on codes specified in the `Connection` object.
223
- - Sets the retail price type, document currency (Hryvnia, code `"980"`), and organization's primary bank account.
224
- - Adds products from the order, queries the exact price for the specific characteristic selected, and computes totals.
228
+ - Sets the price type (defaulting to `"Розничная"` or using `s_price_type` from the order), document currency (Hryvnia, code `"980"`), and organization's primary bank account.
229
+ - Adds products from the order, queries/compares the exact price for the specific characteristic selected (using `s_price_type` to determine retail, wholesale, or purchase price), and computes totals.
225
230
  - Attempts to post the document (`Posting`). If posting fails, it writes the document in draft/save mode (`Write`).
226
231
  - Returns the number of the created document in 1C (or an empty string on error).
227
232
  - `get(s_codeIn: str) -> Order | None`
228
- Retrieves a buyer's order by its 1C document number and parses it into an `Order` object. The comment field is parsed to retrieve the Telegram ID.
233
+ Retrieves a buyer's order by its 1C document number and parses it into an `Order` object. The comment field is parsed to retrieve the Telegram ID, and the price type is retrieved.
229
234
  - `get_today() -> list`
230
235
  Returns a list of all today's orders created for the configured bot counteragent (filtered by current date and counteragent code).
231
236
  - `update_info(c_orderObjIn: Order) -> bool`
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "1.2.3",
2
+ "tag": "1.2.4",
3
3
  "distance": 0,
4
- "node": "gf2c9f1c0e0280923eb11b1c941bd21defdb76dd6",
4
+ "node": "g5ad73510167072830cfef203bb46a98009fc3c21",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-07-13"
@@ -81,7 +81,17 @@ try:
81
81
  c_var = c_var_no_char
82
82
 
83
83
  c_nom = Nomenclature(s_nameIn="Product 1", s_articleIn="ART001", l_varietyIn=[c_var])
84
- print("Success: Nomenclature instantiated.")
84
+ assert c_nom.dt_last_arrival is None
85
+
86
+ dt_now = datetime.now()
87
+ c_nom_with_arrival = Nomenclature(
88
+ s_nameIn="Product 2",
89
+ s_articleIn="ART002",
90
+ l_varietyIn=[c_var],
91
+ dt_last_arrivalIn=dt_now
92
+ )
93
+ assert c_nom_with_arrival.dt_last_arrival == dt_now
94
+ print("Success: Nomenclature instantiated and verified with dt_last_arrival.")
85
95
 
86
96
  c_cat = Category(s_categoryNameIn="Shoes", l_nomenclaturesIn=[c_nom])
87
97
  print("Success: Category instantiated.")
File without changes