oneCInteraction 1.2.0__tar.gz → 1.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {onecinteraction-1.2.0/src/oneCInteraction.egg-info → onecinteraction-1.2.1}/PKG-INFO +1 -1
  2. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/__init__.py +4 -2
  3. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/connection.py +2 -0
  4. onecinteraction-1.2.1/src/oneCInteraction/discounts.py +103 -0
  5. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/structures.py +16 -0
  6. {onecinteraction-1.2.0 → onecinteraction-1.2.1/src/oneCInteraction.egg-info}/PKG-INFO +1 -1
  7. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction.egg-info/SOURCES.txt +1 -0
  8. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction.egg-info/scm_file_list.json +1 -0
  9. onecinteraction-1.2.1/src/oneCInteraction.egg-info/scm_version.json +8 -0
  10. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/tests/test_lib.py +22 -1
  11. onecinteraction-1.2.0/src/oneCInteraction.egg-info/scm_version.json +0 -8
  12. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/.github/workflows/publish.yml +0 -0
  13. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/.gitignore +0 -0
  14. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/LICENSE +0 -0
  15. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/README.md +0 -0
  16. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/pyproject.toml +0 -0
  17. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/setup.cfg +0 -0
  18. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/categories.py +0 -0
  19. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/characteristics.py +0 -0
  20. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/customers.py +0 -0
  21. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/groups.py +0 -0
  22. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/log.py +0 -0
  23. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/nomenclature.py +0 -0
  24. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction/orders.py +0 -0
  25. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction.egg-info/dependency_links.txt +0 -0
  26. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/src/oneCInteraction.egg-info/requires.txt +0 -0
  27. {onecinteraction-1.2.0 → onecinteraction-1.2.1}/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.0
3
+ Version: 1.2.1
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
@@ -8,7 +8,8 @@ from .structures import (
8
8
  Category,
9
9
  Customer,
10
10
  OrderItem,
11
- Order
11
+ Order,
12
+ DiscountGroup
12
13
  )
13
14
 
14
15
  __all__ = [
@@ -21,5 +22,6 @@ __all__ = [
21
22
  'Category',
22
23
  'Customer',
23
24
  'OrderItem',
24
- 'Order'
25
+ 'Order',
26
+ 'DiscountGroup'
25
27
  ]
@@ -8,6 +8,7 @@ from .orders import OrdersManager
8
8
  from .characteristics import CharacteristicsManager
9
9
  from .categories import CategoriesManager
10
10
  from .customers import CustomersManager
11
+ from .discounts import DiscountsManager
11
12
 
12
13
 
13
14
  class Connection:
@@ -39,6 +40,7 @@ class Connection:
39
40
  self.characteristics = CharacteristicsManager(self)
40
41
  self.categories = CategoriesManager(self)
41
42
  self.customers = CustomersManager(self)
43
+ self.discounts = DiscountsManager(self)
42
44
 
43
45
  def initiate_connection(self) -> None:
44
46
  """Establishes COM connection to 1C and caches price type references."""
@@ -0,0 +1,103 @@
1
+ from datetime import datetime
2
+ from .log import log_sys
3
+ from . import structures
4
+
5
+ class DiscountsManager:
6
+ def __init__(self, c_connectionIn):
7
+ self.c_connection = c_connectionIn
8
+
9
+ @property
10
+ def c_v8(self):
11
+ return self.c_connection.c_v8
12
+
13
+ def get_active_groups(self) -> list:
14
+ """Retrieves and groups all active nomenclature discounts into DiscountGroup structures."""
15
+ if not self.c_v8:
16
+ log_sys("Failed to get active discount groups: No connection to 1C.", 1)
17
+ return []
18
+
19
+ try:
20
+ log_sys("Fetching active nomenclature discounts from 1C...")
21
+ query = self.c_v8.NewObject("Query")
22
+ query.Text = """
23
+ SELECT
24
+ Скидки.Регистратор.Номер КАК DocNumber,
25
+ ISNULL(Скидки.Регистратор.ТипСкидкиНаценки.Наименование, "Знижка") КАК DiscountName,
26
+ ISNULL(Скидки.Регистратор.ТипСкидкиНаценки.Код, "") КАК DiscountTypeCode,
27
+ Скидки.ПроцентСкидкиНаценки КАК DiscountPercent,
28
+ Скидки.Номенклатура КАК ProductRef,
29
+ Скидки.Номенклатура.Код КАК ProductCode,
30
+ Скидки.Номенклатура.Наименование КАК ProductName,
31
+ ISNULL(Скидки.ХарактеристикаНоменклатуры.Наименование, "") AS CharName,
32
+ ISNULL(Скидки.Регистратор.Комментарий, "") AS DocComment
33
+ FROM
34
+ РегистрСведений.СкидкиНаценкиНоменклатуры.СрезПоследних(&CurrentDate, ) КАК Скидки
35
+ WHERE
36
+ Скидки.ПроцентСкидкиНаценки > 0
37
+ """
38
+
39
+ c_currDate = datetime.now(self.c_connection.tz_kiev).replace(tzinfo=None)
40
+ query.SetParameter("CurrentDate", c_currDate)
41
+
42
+ c_result = query.Execute()
43
+ if c_result is None or c_result.IsEmpty():
44
+ log_sys("No active discounts found in register.")
45
+ return []
46
+
47
+ # Group the results by (DocNumber, DiscountTypeCode, DiscountPercent)
48
+ d_groups = {} # {(doc_num, type_code, percent): {"name": str, "comment": str, "items": list}}
49
+
50
+ c_selection = c_result.Select()
51
+ while c_selection.Next():
52
+ s_doc_number = self.c_v8.String(c_selection.DocNumber)
53
+ s_type_code = self.c_v8.String(c_selection.DiscountTypeCode)
54
+ n_percent = float(c_selection.DiscountPercent)
55
+ s_name = self.c_v8.String(c_selection.DiscountName)
56
+ s_comment = self.c_v8.String(c_selection.DocComment)
57
+
58
+ s_product_code = self.c_v8.String(c_selection.ProductCode)
59
+ s_product_name = self.c_v8.String(c_selection.ProductName)
60
+ s_char_name = self.c_v8.String(c_selection.CharName)
61
+ s_product_uuid = self.c_v8.String(c_selection.ProductRef.UUID())
62
+
63
+ key = (s_doc_number, s_type_code, n_percent)
64
+ if key not in d_groups:
65
+ d_groups[key] = {
66
+ "name": s_name,
67
+ "comment": s_comment,
68
+ "items": []
69
+ }
70
+
71
+ d_groups[key]["items"].append({
72
+ "code": s_product_code,
73
+ "name": s_product_name,
74
+ "uuid": s_product_uuid,
75
+ "char_name": s_char_name if s_char_name else None
76
+ })
77
+
78
+ # Convert dictionary groups into structures.DiscountGroup objects
79
+ l_discount_groups = []
80
+ type_counters = {}
81
+ for (s_doc_number, s_type_code, n_percent), d_group_data in d_groups.items():
82
+ s_comment = d_group_data["comment"].strip()
83
+ if s_comment:
84
+ s_display_name = s_comment
85
+ else:
86
+ s_type_name = d_group_data["name"]
87
+ type_counters[s_type_code] = type_counters.get(s_type_code, 0) + 1
88
+ s_display_name = f"{s_type_name} {type_counters[s_type_code]}"
89
+
90
+ l_discount_groups.append(structures.DiscountGroup(
91
+ s_nameIn=s_display_name,
92
+ s_document_numberIn=s_doc_number,
93
+ s_discount_type_codeIn=s_type_code,
94
+ n_discount_percentIn=n_percent,
95
+ l_nomenclaturesIn=d_group_data["items"]
96
+ ))
97
+
98
+ log_sys(f"Successfully retrieved {len(l_discount_groups)} active discount groups.")
99
+ return l_discount_groups
100
+
101
+ except Exception as e:
102
+ log_sys(f"Error in DiscountsManager.get_active_groups: {e}", 1)
103
+ return []
@@ -134,3 +134,19 @@ class Order:
134
134
  self.s_price_type = s_price_typeIn
135
135
  self.s_comment = s_commentIn
136
136
 
137
+
138
+ class DiscountGroup:
139
+ def __init__(
140
+ self,
141
+ s_nameIn: str,
142
+ s_document_numberIn: str,
143
+ s_discount_type_codeIn: str,
144
+ n_discount_percentIn: float,
145
+ l_nomenclaturesIn: list
146
+ ):
147
+ self.s_name = s_nameIn
148
+ self.s_document_number = s_document_numberIn
149
+ self.s_discount_type_code = s_discount_type_codeIn
150
+ self.n_discount_percent = float(n_discount_percentIn)
151
+ self.l_nomenclatures = l_nomenclaturesIn
152
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oneCInteraction
3
- Version: 1.2.0
3
+ Version: 1.2.1
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
@@ -8,6 +8,7 @@ src/oneCInteraction/categories.py
8
8
  src/oneCInteraction/characteristics.py
9
9
  src/oneCInteraction/connection.py
10
10
  src/oneCInteraction/customers.py
11
+ src/oneCInteraction/discounts.py
11
12
  src/oneCInteraction/groups.py
12
13
  src/oneCInteraction/log.py
13
14
  src/oneCInteraction/nomenclature.py
@@ -7,6 +7,7 @@
7
7
  "src/oneCInteraction/groups.py",
8
8
  "src/oneCInteraction/__init__.py",
9
9
  "src/oneCInteraction/orders.py",
10
+ "src/oneCInteraction/discounts.py",
10
11
  "src/oneCInteraction/structures.py",
11
12
  "src/oneCInteraction/log.py",
12
13
  "src/oneCInteraction/customers.py",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.2.1",
3
+ "distance": 0,
4
+ "node": "g091321de2f563ed05b75c38b33a5e1982999ef72",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-07-11"
8
+ }
@@ -10,7 +10,7 @@ if hasattr(sys.stdout, 'reconfigure'):
10
10
 
11
11
  try:
12
12
  from datetime import datetime
13
- from oneCInteraction import Connection, Customer, Order, OrderItem, Nomenclature, Variety, Price, Characteristic, Group, Category
13
+ from oneCInteraction import Connection, Customer, Order, OrderItem, Nomenclature, Variety, Price, Characteristic, Group, Category, DiscountGroup
14
14
  from oneCInteraction.log import log_sys, LOGS_DIR
15
15
 
16
16
  print("Success: Imported Connection and all structures successfully from oneCInteraction!")
@@ -86,6 +86,21 @@ try:
86
86
  c_cat = Category(s_categoryNameIn="Shoes", l_nomenclaturesIn=[c_nom])
87
87
  print("Success: Category instantiated.")
88
88
 
89
+ # Test DiscountGroup instantiation
90
+ c_dg = DiscountGroup(
91
+ s_nameIn="Гуртова акція",
92
+ s_document_numberIn="DOC001",
93
+ s_discount_type_codeIn="B2B",
94
+ n_discount_percentIn=10.0,
95
+ l_nomenclaturesIn=[{"code": "ART001", "name": "Product 1", "uuid": "uuid1", "char_name": None}]
96
+ )
97
+ assert c_dg.s_name == "Гуртова акція"
98
+ assert c_dg.s_document_number == "DOC001"
99
+ assert c_dg.s_discount_type_code == "B2B"
100
+ assert c_dg.n_discount_percent == 10.0
101
+ assert len(c_dg.l_nomenclatures) == 1
102
+ print("Success: DiscountGroup instantiated.")
103
+
89
104
  c_conn = Connection(s_oneCDatabasePathIn="test_db", s_usernameIn="admin", s_passwordIn="pass")
90
105
  print("Success: Connection class instantiated.")
91
106
 
@@ -95,7 +110,13 @@ try:
95
110
  assert c_conn.characteristics is not None
96
111
  assert c_conn.categories is not None
97
112
  assert c_conn.customers is not None
113
+ assert c_conn.discounts is not None
98
114
  print("Success: Checked all composition managers exist.")
115
+
116
+ # Test DiscountsManager when connection is not active
117
+ discounts_res = c_conn.discounts.get_active_groups()
118
+ assert isinstance(discounts_res, list) and len(discounts_res) == 0, f"Expected empty list since connection is not active, got {discounts_res}"
119
+ print("Success: DiscountsManager.get_active_groups tested with no active connection.")
99
120
 
100
121
  # Test CustomersManager when connection is not active
101
122
  cust_res = c_conn.customers.get("CUST001")
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "1.2.0",
3
- "distance": 0,
4
- "node": "g65e5ae7065d28fefdf225dbf3dfa54f65bfe84a0",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-07-08"
8
- }
File without changes