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 @@
-
-