changes
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -209,19 +209,43 @@ class DocumentGenerator:
|
|||||||
if not obj:
|
if not obj:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
import re
|
||||||
parts = field_path.split('.')
|
parts = field_path.split('.')
|
||||||
value = obj
|
value = obj
|
||||||
for part in parts:
|
for part in parts:
|
||||||
if value is None:
|
if value is None:
|
||||||
break
|
break
|
||||||
|
|
||||||
# Lấy thuộc tính từ object
|
# 1. Kiểm tra nếu part chứa index mảng, ví dụ: "payment_plan[0]"
|
||||||
|
array_match = re.match(r"(\w+)\[(\d+)\]", part)
|
||||||
|
|
||||||
|
if array_match:
|
||||||
|
attr_name = array_match.group(1) # Lấy "payment_plan"
|
||||||
|
index = int(array_match.group(2)) # Lấy 0
|
||||||
|
|
||||||
|
# Lấy list từ object
|
||||||
|
value = getattr(value, attr_name, None)
|
||||||
|
|
||||||
|
# Truy cập phần tử theo index
|
||||||
|
try:
|
||||||
|
if isinstance(value, (list, tuple)):
|
||||||
|
value = value[index]
|
||||||
|
elif hasattr(value, 'all'): # QuerySet
|
||||||
|
value = value[index]
|
||||||
|
except (IndexError, TypeError):
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
# 2. Xử lý truy cập thuộc tính hoặc key của Dict (JSON)
|
||||||
|
if isinstance(value, dict):
|
||||||
|
# Nếu là dict (phần tử trong JSONField), dùng .get()
|
||||||
|
value = value.get(part)
|
||||||
|
else:
|
||||||
|
# Nếu là object, dùng getattr()
|
||||||
value = getattr(value, part, None)
|
value = getattr(value, part, None)
|
||||||
|
|
||||||
# KIỂM TRA NẾU LÀ QUAN HỆ NGƯỢC (ForeignKey ngược hoặc ManyToMany)
|
# 3. Hỗ trợ lấy bản ghi đầu tiên nếu gặp Quan hệ ngược (Manager)
|
||||||
# Trong Django, các quan hệ này trả về một Manager (có method 'all')
|
|
||||||
if hasattr(value, 'all') and not isinstance(value, models.Model):
|
if hasattr(value, 'all') and not isinstance(value, models.Model):
|
||||||
value = value.first() # Tự động lấy bản ghi đầu tiên
|
value = value.first()
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2026-01-04 17:54
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('app', '0345_alter_co_ownership_transaction'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='co_ownership',
|
||||||
|
name='code',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1964,7 +1964,6 @@ class Transaction_Discount(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class Co_Ownership(models.Model):
|
class Co_Ownership(models.Model):
|
||||||
code = models.CharField(max_length=30, null=False, unique=True)
|
|
||||||
transaction = models.ForeignKey(Transaction, null=False, related_name='co_op', on_delete=models.PROTECT)
|
transaction = models.ForeignKey(Transaction, null=False, related_name='co_op', on_delete=models.PROTECT)
|
||||||
people = models.ForeignKey(People, null=False, related_name='+', on_delete=models.PROTECT)
|
people = models.ForeignKey(People, null=False, related_name='+', on_delete=models.PROTECT)
|
||||||
create_time = models.DateTimeField(null=True, auto_now_add=True)
|
create_time = models.DateTimeField(null=True, auto_now_add=True)
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ def evaluate_rule(rule: Rule, context: dict):
|
|||||||
|
|
||||||
print(f" Evaluating Rule: {left} {op} {right}")
|
print(f" Evaluating Rule: {left} {op} {right}")
|
||||||
|
|
||||||
|
if op == "IN" and left not in right: return False
|
||||||
if op == "==" and left != right: return False
|
if op == "==" and left != right: return False
|
||||||
if op == "!=" and left == right: return False
|
if op == "!=" and left == right: return False
|
||||||
if op == ">" and not (left > right): return False
|
if op == ">" and not (left > right): return False
|
||||||
|
|||||||
+28
-2
@@ -1,6 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
def resolve_value(expr, context):
|
def resolve_value(expr, context):
|
||||||
"""
|
"""
|
||||||
@@ -64,10 +64,36 @@ def resolve_value(expr, context):
|
|||||||
|
|
||||||
root, *rest = key_path.split(".")
|
root, *rest = key_path.split(".")
|
||||||
val = context.get(root)
|
val = context.get(root)
|
||||||
|
|
||||||
for r in rest:
|
for r in rest:
|
||||||
if val is None:
|
if val is None:
|
||||||
return None
|
return None
|
||||||
val = getattr(val, r, None) if not isinstance(val, dict) else val.get(r)
|
|
||||||
|
# 1. Xử lý truy cập index mảng, ví dụ: payment_plan[0]
|
||||||
|
array_match = re.match(r"(\w+)\[(\d+)\]", r)
|
||||||
|
if array_match:
|
||||||
|
attr_name = array_match.group(1)
|
||||||
|
index = int(array_match.group(2))
|
||||||
|
# Lấy list/queryset
|
||||||
|
val = getattr(val, attr_name, None) if not isinstance(val, dict) else val.get(attr_name)
|
||||||
|
try:
|
||||||
|
if hasattr(val, 'all'): # Django QuerySet/Manager
|
||||||
|
val = val[index]
|
||||||
|
else: # List thông thường
|
||||||
|
val = val[index]
|
||||||
|
except (IndexError, TypeError, KeyError):
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
# 2. Xử lý truy cập thuộc tính hoặc dict key
|
||||||
|
if isinstance(val, dict):
|
||||||
|
val = val.get(r)
|
||||||
|
else:
|
||||||
|
val = getattr(val, r, None)
|
||||||
|
|
||||||
|
# 3. Hỗ trợ tự động lấy bản ghi đầu tiên nếu là Manager (1-n)
|
||||||
|
if hasattr(val, 'all') and not isinstance(val, models.Model):
|
||||||
|
val = val.first()
|
||||||
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
# =============================================
|
# =============================================
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
,kumduy,duy-pc,04.01.2026 23:48,file:///home/kumduy/.config/libreoffice/4;
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user