diff --git a/modules/trade_finance/facility.py b/modules/trade_finance/facility.py index 0db653d..95b337d 100644 --- a/modules/trade_finance/facility.py +++ b/modules/trade_finance/facility.py @@ -210,13 +210,16 @@ class FacilityLimit(ModelSQL, ModelView): tenor = fields.Integer('Tenor (days)', help='Maximum duration of financing from drawdown to repayment') sequence = fields.Integer('Sequence') + path = fields.Char('Path', readonly=True, + help='Hierarchical sort key — auto-computed') + + _order = [('path', 'ASC')] is_global = fields.Function( fields.Boolean('Global Limit', states={'invisible': Bool(Eval('parent'))}, depends=['parent']), 'get_is_global') - level = fields.Function(fields.Integer('Level'), 'get_level') display_name = fields.Function(fields.Char('Name'), 'get_display_name') haircuts = fields.One2Many('trade_finance.facility_limit_haircut', 'limit', @@ -244,21 +247,69 @@ class FacilityLimit(ModelSQL, ModelView): if values.get('parent') and not values.get('facility'): parent = cls(values['parent']) values['facility'] = parent.facility.id - return super().create(vlist) + records = super().create(vlist) + cls._update_path(records) + return records + + @classmethod + def write(cls, *args): + super().write(*args) + records = [] + actions = iter(args) + for recs, _ in zip(actions, actions): + records.extend(recs) + cls._update_path(records) + + @classmethod + def _update_path(cls, records): + to_write = [] + for record in records: + path = cls._compute_path(record) + if record.path != path: + to_write.extend([[record], {'path': path}]) + if to_write: + # Use super().write to avoid recursion + super().write(*to_write) + # Also update all descendants + all_children = [] + for record in records: + all_children.extend(cls._get_descendants(record)) + if all_children: + descendant_writes = [] + for child in all_children: + path = cls._compute_path(child) + if child.path != path: + descendant_writes.extend([[child], {'path': path}]) + if descendant_writes: + super().write(*descendant_writes) + + @classmethod + def _compute_path(cls, record): + parts = [] + current = record + while current: + parts.append('%07d' % (current.sequence or 0)) + current = current.parent + parts.reverse() + return '/'.join(parts) + + @classmethod + def _get_descendants(cls, record): + result = [] + for child in record.children: + result.append(child) + result.extend(cls._get_descendants(child)) + return result def get_is_global(self, name): return self.parent is None - def get_level(self, name): + def get_display_name(self, name): level = 0 current = self while current.parent: level += 1 current = current.parent - return level - - def get_display_name(self, name): - level = self.get_level(None) prefix = '— ' * level return prefix + (self.name or '') diff --git a/modules/trade_finance/view/facility_limit_tree.xml b/modules/trade_finance/view/facility_limit_tree.xml index 5c85e14..e9f44ca 100644 --- a/modules/trade_finance/view/facility_limit_tree.xml +++ b/modules/trade_finance/view/facility_limit_tree.xml @@ -4,6 +4,4 @@ - -