Initial commit – AufmaßCreater v2.35
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
import json
|
||||
import re
|
||||
from app.extensions import db
|
||||
from app.models.lv import LVPosition
|
||||
|
||||
|
||||
def execute_rules(form_data, rules_json, company_id):
|
||||
rules = json.loads(rules_json) if isinstance(rules_json, str) else rules_json
|
||||
positions = []
|
||||
|
||||
for rule in rules:
|
||||
if not _evaluate_conditions(rule.get('conditions', {}), form_data):
|
||||
continue
|
||||
for action in rule.get('actions', []):
|
||||
pos = _create_position(action, form_data, company_id)
|
||||
if pos:
|
||||
positions.append(pos)
|
||||
|
||||
return positions
|
||||
|
||||
|
||||
def _evaluate_conditions(conditions, form_data):
|
||||
if not conditions or not conditions.get('items'):
|
||||
return True
|
||||
|
||||
operator = conditions.get('operator', 'and')
|
||||
items = conditions.get('items', [])
|
||||
|
||||
results = []
|
||||
for cond in items:
|
||||
field = cond.get('field', '')
|
||||
op = cond.get('operator', 'eq')
|
||||
value = cond.get('value', '')
|
||||
value2 = cond.get('value2', '')
|
||||
raw = form_data.get(field, '')
|
||||
|
||||
if op == 'is_checked':
|
||||
results.append(raw == 'an')
|
||||
elif op == 'is_empty':
|
||||
results.append(raw == '' or raw is None)
|
||||
elif op == 'not_empty':
|
||||
results.append(raw != '' and raw is not None)
|
||||
else:
|
||||
try:
|
||||
f_val = _to_float(raw)
|
||||
f_cond = _to_float(value)
|
||||
if op == 'eq':
|
||||
results.append(f_val == f_cond)
|
||||
elif op == 'neq':
|
||||
results.append(f_val != f_cond)
|
||||
elif op == 'gt':
|
||||
results.append(f_val > f_cond)
|
||||
elif op == 'gte':
|
||||
results.append(f_val >= f_cond)
|
||||
elif op == 'lt':
|
||||
results.append(f_val < f_cond)
|
||||
elif op == 'lte':
|
||||
results.append(f_val <= f_cond)
|
||||
elif op == 'between':
|
||||
f_val2 = _to_float(value2)
|
||||
results.append(f_cond <= f_val <= f_val2)
|
||||
else:
|
||||
results.append(str(raw) == str(value))
|
||||
except (ValueError, TypeError):
|
||||
results.append(str(raw) == str(value))
|
||||
|
||||
if operator == 'or':
|
||||
return any(results)
|
||||
return all(results)
|
||||
|
||||
|
||||
def _create_position(action, form_data, company_id):
|
||||
pos_nr = action.get('pos_nr', '')
|
||||
if not pos_nr:
|
||||
return None
|
||||
|
||||
lv_lookup = action.get('lv_lookup', True)
|
||||
columns = action.get('columns', {})
|
||||
|
||||
# Default values
|
||||
pos = {
|
||||
'pos_nr': pos_nr,
|
||||
'kurztext': '',
|
||||
'einheit': 'ST',
|
||||
'menge': 1,
|
||||
'faktor': 1,
|
||||
'laenge': 0,
|
||||
'breite': 0,
|
||||
'tiefe': 0,
|
||||
'bemerkung': '',
|
||||
'einzelpreis': 0,
|
||||
}
|
||||
|
||||
# LV lookup
|
||||
if lv_lookup:
|
||||
lv_pos = LVPosition.query.filter_by(company_id=company_id, pos_nr=pos_nr).first()
|
||||
if lv_pos:
|
||||
pos['kurztext'] = lv_pos.kurztext or ''
|
||||
pos['einheit'] = lv_pos.einheit or 'ST'
|
||||
pos['einzelpreis'] = lv_pos.einzelpreis or 0
|
||||
|
||||
# Apply overrides
|
||||
for col_key, col_def in columns.items():
|
||||
if col_key not in pos and col_key != 'pos_nr':
|
||||
continue
|
||||
val = _resolve_value(col_def, form_data)
|
||||
if val is not None:
|
||||
if col_key in ('menge', 'faktor', 'laenge', 'breite', 'tiefe', 'einzelpreis'):
|
||||
pos[col_key] = _to_float(val)
|
||||
else:
|
||||
pos[col_key] = str(val)
|
||||
|
||||
return pos
|
||||
|
||||
|
||||
def _resolve_value(col_def, form_data):
|
||||
if not col_def:
|
||||
return None
|
||||
ctype = col_def.get('type', 'fixed')
|
||||
value = col_def.get('value', '')
|
||||
|
||||
if ctype == 'fixed':
|
||||
return value
|
||||
elif ctype == 'field':
|
||||
return form_data.get(value, '')
|
||||
elif ctype == 'formula':
|
||||
return _eval_formula(value, form_data)
|
||||
return value
|
||||
|
||||
|
||||
def _eval_formula(expr, form_data):
|
||||
expr = str(expr)
|
||||
def _replace_field(m):
|
||||
fname = m.group(1)
|
||||
raw = form_data.get(fname, '0')
|
||||
return str(raw).replace(',', '.')
|
||||
expr = re.sub(r'\[([^\]]+)\]', _replace_field, expr)
|
||||
safe = re.sub(r'[^\d\+\-\*\/\(\)\. ]', '', expr)
|
||||
if not safe.strip():
|
||||
return 0
|
||||
try:
|
||||
return eval(safe, {'__builtins__': {}}, {})
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
|
||||
def _to_float(val):
|
||||
if val is None or val == '':
|
||||
return 0.0
|
||||
return float(str(val).replace(',', '.').replace(' ', ''))
|
||||
Reference in New Issue
Block a user