SHOW:
|
|
- or go back to the newest paste.
1 | import re | |
2 | class AccountTree(): | |
3 | def __init__(self): | |
4 | self.struct = {} # На Всяко дете, кой е прекия родител | |
5 | self.children = None | |
6 | self.top_digits = {} # На коя сметка колко цифри има в първата група | |
7 | self.groups = {} # На коя сметка колко групи има | |
8 | self.top_group_min_digits_count = None # Беше None | |
9 | self.top_group_max_digits_count = None # Беше None | |
10 | - | self.top_group_min_digits_count = None # Беше None |
10 | + | self.max_groups_count = None # Беше None |
11 | - | self.top_group_max_digits_count = None # Беше None |
11 | + | |
12 | - | self.max_groups_count = None # Беше None |
12 | + | |
13 | - | self.max_depth = None |
13 | + | def add_code(self, code): # TODO IZPOLZWAM 1 Прави STRUCT !!! |
14 | - | self.all_accs = [] |
14 | + | |
15 | # "123-456-789" дава ["123", "456", "789"] | |
16 | groups_digits = re.findall('[0-9]+', code) | |
17 | - | def add_code(self, code): # TODO IZPOLZWAM 1 Прави STRUCT !!! |
17 | + | |
18 | groups_seps = re.findall('[^0-9]+', code) | |
19 | groups_digits_len = len(groups_digits) | |
20 | ||
21 | # Следим максималния брой аналитични сметки | |
22 | if self.max_groups_count is None: | |
23 | self.max_groups_count = groups_digits_len | |
24 | elif groups_digits_len > self.max_groups_count: # МОже би трябва да е IF ??? | |
25 | self.max_groups_count = groups_digits_len | |
26 | ||
27 | - | elif groups_digits_len > self.max_groups_count: # МОже би трябва да е IF ??? |
27 | + | |
28 | #1 | |
29 | #12 -------TODO----- ВАЖНО -> ТОП родителя е този, който е подаден от Excel с най-малко цифри !!! | |
30 | - | # 1 |
30 | + | #123 -------TODO---- -> Няма смисъл да раздробяваме на по-малки кодове сметките в Оборотната ведомост ! |
31 | - | # 12 -------TODO----- ВАЖНО -> ТОП родителя е този, който е подаден от Excel с най-малко цифри !!! |
31 | + | #123-456 |
32 | - | # 123 -------TODO---- -> Няма смисъл да раздробяваме на по-малки кодове сметките в Оборотната ведомост ! |
32 | + | #123-456-789 |
33 | - | # 123-456 |
33 | + | |
34 | - | # 123-456-789 |
34 | + | |
35 | top_group_digits = groups_digits[0] # Първата група | |
36 | #print("top_group_digits", top_group_digits) | |
37 | - | # print("top_group_digits", top_group_digits) |
37 | + | |
38 | ||
39 | # В ancestors ще трупаме [сметка, родител, пра-родител и т.н.] но по цели групи от цифри | |
40 | ancestors = [] | |
41 | ancestors_top_group_digits = [] | |
42 | ancestors_groups = [] | |
43 | # За ["123", "456", "789"] len1 ще мине през 3, 2, 1 | |
44 | for len1 in range(groups_digits_len, 0, -1): | |
45 | # len1=3 дава ["123", "456", "789"] | |
46 | # len1=2 дава ["123", "456"] | |
47 | # len1=1 дава ["123"] | |
48 | code1 = "" | |
49 | # len1=3, то idx ше мине през 0, 1, 2 | |
50 | # len1=2, то idx ше мине през 0, 1 | |
51 | # len1=1, то idx ше мине през 0 | |
52 | for idx in range(len1): | |
53 | if code1 != "": | |
54 | code1 += groups_seps[idx - 1] | |
55 | pass | |
56 | code1 += groups_digits[idx] | |
57 | ancestors.append(code1) | |
58 | ancestors_top_group_digits.append(top_group_digits_len) | |
59 | ancestors_groups.append(len1) | |
60 | ||
61 | # Следим коя е най-дългата първа група | |
62 | if self.top_group_max_digits_count is None: | |
63 | self.top_group_max_digits_count = top_group_digits_len | |
64 | elif top_group_digits_len > self.top_group_max_digits_count: | |
65 | self.top_group_max_digits_count = top_group_digits_len | |
66 | # Следим коя е най-късата първа група | |
67 | if self.top_group_min_digits_count is None: | |
68 | self.top_group_min_digits_count = top_group_digits_len | |
69 | elif top_group_digits_len < self.top_group_min_digits_count: | |
70 | self.top_group_min_digits_count = top_group_digits_len | |
71 | - | for len1 in range(top_group_digits_len - 1, 0, -1): |
71 | + | |
72 | - | # print("len1", len1) |
72 | + | |
73 | #print("top_group_digits_len", top_group_digits_len) | |
74 | for len1 in range(top_group_digits_len-1, 0, -1): | |
75 | #print("len1", len1) | |
76 | code1 = top_group_digits[0: len1] | |
77 | ancestors.append(code1) | |
78 | ancestors_top_group_digits.append(len1) | |
79 | ancestors_groups.append(1) | |
80 | - | if self.max_depth is None: |
80 | + | # print("След анализ на първата група: ancestors", ancestors) |
81 | - | self.max_depth = ancestors_len |
81 | + | |
82 | - | elif ancestors_len > self.max_depth: |
82 | + | |
83 | - | self.max_depth = ancestors_len |
83 | + | |
84 | ancestors_len = len(ancestors) | |
85 | for idx in range(ancestors_len): | |
86 | child = ancestors[idx] | |
87 | child_top_group_digits_len = ancestors_top_group_digits[idx] | |
88 | child_groups = ancestors_groups[idx] | |
89 | parent_idx = idx + 1 | |
90 | if parent_idx < ancestors_len: # Бащата присъства в списъка | |
91 | parent = ancestors[parent_idx] # Вземаме бащата от списъка | |
92 | else: # Бащата не е в списъка | |
93 | parent = "" # Затова бащата е коренът | |
94 | ||
95 | if child in self.struct: | |
96 | # Няма нужда са се минава нататък през родителите му, понеже те вече са вписани | |
97 | - | if len(child) > 0 and child not in self.all_accs: # TODO -> НЕ СЪДЪРЖА ВСИЧКИ СМЕТКИ !!! |
97 | + | #print(f"Вече е вписано, че {child} има родител {parent}, пропускаме останалото родословие") |
98 | - | self.all_accs.append(parent) |
98 | + | |
99 | - | if len(parent) > 0 and parent not in self.all_accs: |
99 | + | |
100 | - | self.all_accs.append(parent) |
100 | + | |
101 | self.top_digits[child] = child_top_group_digits_len | |
102 | self.groups[child] = child_groups | |
103 | # print('ancestors', ancestors) | |
104 | def get_max_groups_count(self): | |
105 | return self.max_groups_count | |
106 | ||
107 | def get_top_group_max_digits_count(self): | |
108 | return self.top_group_max_digits_count | |
109 | ||
110 | def get_top_group_digits(self, code): | |
111 | return self.top_digits[code] | |
112 | ||
113 | def get_groups(self, code): | |
114 | return self.groups[code] | |
115 | ||
116 | # Връща дълбочината на дадена сметка в дървото | |
117 | def get_depth(self, code): # TODO Izpolzwam 2 | |
118 | - | def get_max_depth(self): |
118 | + | |
119 | - | return self.max_depth |
119 | + | |
120 | # Такава сметка има | |
121 | depth = 0 | |
122 | next_code = code | |
123 | while next_code in self.struct: | |
124 | depth += 1 | |
125 | next_code = self.struct[next_code] | |
126 | ||
127 | return depth | |
128 | ||
129 | ||
130 | ||
131 | def print_struct(self): # TODO up_struct = children ???? | |
132 | print('struct', self.struct) # struct {'10-100-20-25': '10-100-20', '10-100-20': '10-100', '10-100': '10', '10': '1', '1': ''} | |
133 | - | def print_struct(self): # TODO up_struct = children ???? |
133 | + | |
134 | - | print('struct', self.struct) # struct {'10-100-20-25': '10-100-20', '10-100-20': '10-100', '10-100': '10', '10': '1', '1': ''} |
134 | + | |
135 | for key in self.struct: | |
136 | if self.struct[key] == self.struct[key]: | |
137 | key_up_struct = self.struct[key] | |
138 | if key_up_struct in up_struct: | |
139 | up_struct[key_up_struct] += [key] | |
140 | elif key_up_struct not in up_struct: | |
141 | up_struct[key_up_struct] = [key] | |
142 | # Сортиране на децата -> List in value | |
143 | for parent_acc in up_struct: | |
144 | up_struct[parent_acc].sort() | |
145 | ||
146 | print('up_struct', up_struct) | |
147 | ||
148 | ||
149 | # Връща list с само преките деца на даден code | |
150 | def get_children(self, code): | |
151 | ||
152 | if self.children is None: | |
153 | self.children = {} | |
154 | # Ще бъде речник с изброени преки деца на всяка сметка {"150": ["150-1", "150-2", ...], ...} | |
155 | for child in self.struct: | |
156 | parent = self.struct[child] | |
157 | - | if code in self.children: # Ако кодът има деца... |
157 | + | |
158 | self.children[parent] = [] | |
159 | self.children[parent].append(child) | |
160 | - | return [] # Затова връщаме празен списък |
160 | + | |
161 | if code in self.children: # Ако кодът има деца... | |
162 | return self.children[code] # връшаме ги Връща лист ! | |
163 | - | def get_all_children(self, code, max_depth=None): |
163 | + | |
164 | - | if max_depth is None: |
164 | + | |
165 | - | max_depth = self.max_depth |
165 | + | return [] # Затова връщаме празен списък |
166 | ||
167 | # Връща list с всички деца, внуци и т.н. на даден код | |
168 | def get_all_children(self, code, max_depth = 999): | |
169 | if max_depth == 0: | |
170 | return [] | |
171 | - | # print(f"АААААА {code} има за деца {children}") |
171 | + | |
172 | processed = [] | |
173 | children = self.get_children(code) | |
174 | - | # print(f"get_all_children() depth {depth}") |
174 | + | #print(f"АААААА {code} има за деца {children}") |
175 | depth = 0 | |
176 | - | children_on_this_depth = 0 |
176 | + | |
177 | children1 = [] | |
178 | for child in children: | |
179 | children1.append(child) | |
180 | if child in processed: # вече сме добавили преките деца на това дете | |
181 | continue # затова пропускаме | |
182 | - | # print(f"Ниво {depth}: {child} има за деца {children2}") |
182 | + | |
183 | - | children_on_this_depth += len(children2) |
183 | + | #print(f"Ниво {depth}: {child} има за деца {children2}") |
184 | processed.append(child) | |
185 | for child2 in children2: | |
186 | children1.append(child2) | |
187 | - | if children_on_this_depth == 0: |
187 | + | #print(f"Заместваме {children} с {children1}") |
188 | children = children1 | |
189 | depth += 1 | |
190 | return children | |
191 | ||
192 | def get_parent(self, acc_code): | |
193 | # print(f"acc_code {acc_code}") | |
194 | - | if acc_code is None or acc_code == '': |
194 | + | # print('self.struct[acc_code]: ', self.struct[acc_code]) |
195 | if acc_code is None: | |
196 | - | if acc_code in self.struct: # Писано от мен |
196 | + | |
197 | print(self.struct) | |
198 | # if acc_code in self.struct[acc_code]: # Писано от Владо | |
199 | - | def get_all_parents(self, acc_code): |
199 | + | if acc_code in self.struct: # Писано от мен |
200 | - | parents = [] |
200 | + | |
201 | - | # Почваме от даения код, вземаме родителя, после неговия родител и т.н. докато опрем в корена |
201 | + | |
202 | def get_ancestors(self, acc_code): | |
203 | ancestors = [] | |
204 | # Почваме от даения код, вземаме родителя, после неговия родител и т.н. | |
205 | # докато опрем в корена | |
206 | - | break # няма повече родители |
206 | + | |
207 | - | parents.append(parent) # Добавяме родителя в списъка с предци |
207 | + | |
208 | - | browse_code = parent |
208 | + | |
209 | - | return parents |
209 | + | |
210 | break # няма повече родители | |
211 | - | # Листа на дървото = тези които нямат деца = най-дълбоки деца |
211 | + | ancestors.push(parent) # Добавяме родителя в списъка с предци |
212 | - | def get_leaves(self): |
212 | + | return ancestors |
213 | - | # всички които имат родители са KEY в struct |
213 | + | |
214 | - | # всики които имат деца са VALUE в struct |
214 | + | # В TrialBalanceFilter на много места се искаме да знаем дали code1 е дете на code2. |
215 | - | # значи листа са тези които ги няма в стойностите, но ги има в ключовете |
215 | + | # Там правим сложни аналзи на групи цифри -- те трябва да се махнат. |
216 | - | values = self.struct.values() # list1 |
216 | + | # ТАМ има self.acc_tree, което е обект от клас AccountTree |
217 | - | keys = self.struct.keys() # list2 |
217 | + | # AccountTree tрябва да се сдобие с методи като is_child() по-долу, |
218 | - | #leaves = има в keys, но ги няма в values |
218 | + | # kойто да отговаря на тоя въпрос като използва своя self.struct |
219 | - | leaves = set(keys).difference(values) |
219 | + | def is_child(self, child, parent): |
220 | - | return leaves |
220 | + | # Трябва да връша true или false |
221 | pass | |
222 | - | def get_leaves_bycode(self, list_accs: list): |
222 | + | def is_parent(self, child, parent): |
223 | - | list_leaves_bycode = [] |
223 | + | # Трябва да връша true или false |
224 | - | # TODO -> Подавам код и проверяван дали е родител |
224 | + | pass |
225 | - | print('get_leaves_bycode list_accs: ', list_accs) |
225 | + | |
226 | - | for leaf in list_accs: |
226 | + | |
227 | - | is_parent = self.is_parent(leaf) |
227 | + | |
228 | - | if not is_parent: |
228 | + | |
229 | - | list_leaves_bycode.append(leaf) |
229 | + | acc_tree.add_code("100") |
230 | - | return list_leaves_bycode |
230 | + | |
231 | acc_tree.get_parent('100') | |
232 | - | def get_all_deepest_parents(self): |
232 | + |