-
-
Save onjin/2acc27efe96926d7d9e8 to your computer and use it in GitHub Desktop.
# pip install business-rules | |
from decimal import Decimal | |
from pprint import pprint | |
from business_rules import ( | |
variables, actions, fields, export_rule_data, run_all | |
) | |
class Request(object): | |
def __init__(self, contractor, cart): | |
self.contractor = contractor | |
self.cart = cart | |
class Contractor(object): | |
def __init__(self, symbol): | |
self.symbol = symbol | |
class Cart(object): | |
def __init__(self, total): | |
self.total = total | |
def get_total(self): | |
return self.total | |
class PaymentMethod(object): | |
def __init__(self, symbol, gateway_symbol, amount, is_active): | |
self.symbol = symbol | |
self.gateway_symbol = gateway_symbol | |
self.amount = amount | |
self.is_active = is_active | |
class PaymentMethodVariables(variables.BaseVariables): | |
def __init__(self, request, method): | |
self.method = method | |
self.request = request | |
@variables.string_rule_variable() | |
def current_contractor(self): | |
return getattr(self.request.contractor, 'symbol') | |
@variables.string_rule_variable() | |
def method_symbol(self): | |
return self.method.symbol | |
@variables.string_rule_variable() | |
def gateway_symbol(self): | |
return self.method.gateway.symbol | |
@variables.numeric_rule_variable() | |
def cart_total(self): | |
return self.request.cart.get_total() | |
class PaymentMethodActions(actions.BaseActions): | |
def __init__(self, request, method): | |
self.method = method | |
self.request = request | |
@actions.rule_action(params={ | |
'active': fields.FIELD_SELECT_MULTIPLE | |
}) | |
def change_active(self, active): | |
self.method.is_active = active | |
@actions.rule_action(params={ | |
'amount': fields.FIELD_NUMERIC, | |
}) | |
def set_amount(self, amount): | |
self.method.amount = amount | |
if __name__ == '__main__': | |
request = Request(Contractor('stefan'), Cart(Decimal('101'))) | |
method = PaymentMethod('cash', 'general', Decimal('1.12'), True) | |
rules = export_rule_data(PaymentMethodVariables, PaymentMethodActions) | |
pprint(rules) | |
run_all( | |
rule_list=[ | |
{ | |
'conditions': { | |
'all': [ | |
{ | |
'name': 'current_contractor', | |
'operator': 'equal_to', | |
'value': 'stefan', | |
}, | |
], | |
}, | |
'actions': [ | |
{ | |
'name': 'change_active', | |
'params': { | |
'active': False, | |
}, | |
}, | |
] | |
}, | |
{ | |
'conditions': { | |
'all': [ | |
{ | |
'name': 'cart_total', | |
'operator': 'greater_than', | |
'value': Decimal('100'), | |
}, | |
], | |
}, | |
'actions': [ | |
{ | |
'name': 'change_active', | |
'params': { | |
'active': True, | |
}, | |
}, | |
{ | |
'name': 'set_amount', | |
'params': { | |
'amount': Decimal('0'), | |
}, | |
}, | |
] | |
}, | |
], | |
defined_variables=PaymentMethodVariables(request, method), | |
defined_actions=PaymentMethodActions(request, method), | |
stop_on_first_trigger=False | |
) | |
pprint(method.__dict__) |
It should be working as tipo_vinculaction == Asociado or (numero_salarios_minimo >= 1 and actividad_economica = Asalariado)
It should be working as
tipo_vinculaction == Asociado or (numero_salarios_minimo >= 1 and actividad_economica = Asalariado)
It's not working, look at this.
My rule list
rule_list = [
{
'actions': [{'name': 'aplica_o_no_aplica'}],
'conditions': {
'any': [
{
'name': 'tipo_vinculacion',
'operator': 'equal_to',
'value': 'Asociado',
},
],
'all': [
{
'name': 'numero_salarios_minimo',
'operator': 'greater_than_or_equal_to',
'value': 1,
},
{
'name': 'actividad_economica',
'operator': 'equal_to',
'value': 'Asalariado',
},
],
},
},
]
My main
if __name__ == '__main__':
rule3 = Rule("Asociado", "Asalariado", 1)
rules_to_evaluate = [rule3]
for rule in rules_to_evaluate:
run_all(rule_list=rule_list,
defined_variables=RuleVariables(rule),
defined_actions=RuleActions(rule),
stop_on_first_trigger=True
)
for rule in rules_to_evaluate:
print(rule)
And i get this error
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-13-0c85c2a5a640> in <module>
8 defined_variables=RuleVariables(rule),
9 defined_actions=RuleActions(rule),
---> 10 stop_on_first_trigger=True
11 )
12
c:\users\pronostica\documents\projects\bancoomeva-api\env\lib\site-packages\business_rules\engine.py in run_all(rule_list, defined_variables, defined_actions, stop_on_first_trigger)
8 rule_was_triggered = False
9 for rule in rule_list:
---> 10 result = run(rule, defined_variables, defined_actions)
11 if result:
12 rule_was_triggered = True
c:\users\pronostica\documents\projects\bancoomeva-api\env\lib\site-packages\business_rules\engine.py in run(rule, defined_variables, defined_actions)
17 def run(rule, defined_variables, defined_actions):
18 conditions, actions = rule['conditions'], rule['actions']
---> 19 rule_triggered = check_conditions_recursively(conditions, defined_variables)
20 if rule_triggered:
21 do_actions(actions, defined_actions)
c:\users\pronostica\documents\projects\bancoomeva-api\env\lib\site-packages\business_rules\engine.py in check_conditions_recursively(conditions, defined_variables)
43 # help prevent errors - any and all can only be in the condition dict
44 # if they're the only item
---> 45 assert not ('any' in keys or 'all' in keys)
46 return check_condition(conditions, defined_variables)
47
AssertionError:
I checked the documentation (https://github.com/venmo/business-rules) and they recommend to form the list of dicts like this...
# current_inventory < 5 OR (current_month = "December" AND current_inventory < 20)
{ "conditions": { "any": [
{ "name": "current_inventory",
"operator": "less_than",
"value": 5,
},
]},
{ "all": [
{ "name": "current_month",
"operator": "equal_to",
"value": "December",
},
{ "name": "current_inventory",
"operator": "less_than",
"value": 20,
}
]},
},
"actions": [
{ "name": "order_more",
"params":{"number_to_order": 40},
},
],
}]
The "all" dict is out of "conditions" key... it's not working that way neither
ou, I see now. The example in README has a syntax error, but I've found proper example in tests,
so try this one
{
"conditions": {
"any": [
{
"name": "tipo_vinculacion",
"operator": "equal_to",
"value": "Asociado",
},
{
"all": [
{
"name": "numero_salarios_minimo",
"operator": "greater_than_or_equal_to",
"value": 1,
},
{
"name": "actividad_economica",
"operator": "equal_to",
"value": "Asalariado",
},
],
},
],
},
"actions": [{"name": "aplica_o_no_aplica"}],
},
]```
ou, I see now. The example in README has a syntax error, but I've found proper example in tests,
so try this one
{ "conditions": { "any": [ { "name": "tipo_vinculacion", "operator": "equal_to", "value": "Asociado", }, { "all": [ { "name": "numero_salarios_minimo", "operator": "greater_than_or_equal_to", "value": 1, }, { "name": "actividad_economica", "operator": "equal_to", "value": "Asalariado", }, ], }, ], }, "actions": [{"name": "aplica_o_no_aplica"}], }, ]```
Ohh, finally it worked, thanks a lot!!
That's great :) you welcome.
Hi there, thanks for you example.
I want to use an "Any" or "o" options to my rules, how can i do that?
I have this rule_list but it's not working, thanks a lot.
`rule_list = [
{
'actions': [{'name': 'aplica_o_no_aplica'}],
]`