...
This module will use a "generic contribution" to get the required parameters and the json_ext
database field will be used to save the parameters (generic backend feature). Finally, a signal will trigger the calculation action.
...
The left part, if there is no reachable technical solution will be hardcoded by having the contribution “knowing“ which are the related class (e.g CPB for PH insuree and contract detail and calculation for Contribution)
Solution
This module will rely heavily on the django signals
...
This module won't have ad-hoc authorities.
Entities
CalculationRules (HistoryBusinessModel)
CalculationClassName(varchar)*Status (int)*Description (varchar)Priority (int)
sub table CalculationRulesDetails (HistoryModel)
CalculationRulesUUID (fk_UUID)*Status (int)ClassNameMain (bool)Params (Json)ClassParams(json)TyperightsRelevanceconditions
Detailed design
Calculations Backend Module
...
relevance and condition are Nice to have.
Methods
getRuleDetails(classname)
NEED TO BE DEFINED ON ABSTRACT CLASS LEVEL
For object in listObject
if object.class == classname
return object
ready()
NEED TO BE DEFINED ON RULE LEVEL
This method makes sure the calculation is registered in the calculation table (if not the line should be added with "inactive status") and register the signals only if it is active
all rules, if active will have to register to the signal sent by “getRuleDetails”
activeForObject(object, context)
...
This function is required because the same class can have different calculation based on the object members values (like product ….)
runCalculationRules(instance, context)
NEED TO BE DEFINED ON RULE LEVEL
this function will be register to the module signal via the ready function if the rule is active
1- getRuleDetails(instance.__class__)
2 if activeForObject(instance)
calculate(instance)
(TDC)calculateEvent(sender, instance, user, **kwargs)
...
that function will return the possible instance that can have a link to the calculation
...
getParamteres(ClassName, instance)
NEED TO BE DEFINED ON MODULE LEVEL
getRuleDetails(classname)
define which calculation has param for the class name
Return the data contained on the JSON so the frontend can ask the parameters for a new object of the ClassName.
for active_calculation_rule
for active_calculation_rule.objects
OR
CalculationRulesDetailsModel.objects.filter(calulation_rule__status='active').filter(calulation_rule__dateValidFrom__lte=now()).filter(Q(calulation_rule__dateValidTo__gte=now())|Q(calulation_rule__dateValidTo__isnull=True)).filter(class_name=ClassName)
...
RULE LEVEL
#className is the class name of the object where the calculation param need to be added
#instance is where the link with a calculation need to be found, like the CPB in case of PH insuree or Contract Details
This function has two steps
1- getRuleDetails(className)
2- define if the calculation should be used
for each “eligible“ ruleDetails,
checkCalculation(instance) #check if the calculation is really concerning the class for that context
Module function/Service
NEED TO BE DEFINED ON MODULE LEVEL
getRuleDetails(classname)
this function will send a signal and the rules will reply if they have object matching the classname in their list of object
listruledetails = []
for all calculation rules (send signal):
if result_signal != []
merge listruledetails and result_signal
return listruledetails
runCalculationRules(instance, context)
1- getRuleDetails(instance.__class__)
2- for each rule
if activeForObject(instance)
...
for all calculation rules (send signal):
runCalculationRules(instance, context)
no return
getParamteres(ClassName, instance)
#className is the class name of the object where the calculation param need to be added
#instance is where the link with a calculation need to be found, like the CPB in case of PH insuree or Contract Details
This function has two steps
1- getRuleDetails(className)
2- define if the calculation should be used
for each “eligible“ ruleDetails,
checkCalculation(instance) #check if the calculation is really concerning the class for that context
listparameters = []
for all calculation rules (send signal):
if result_signal != []
merge listparameters and result_signal
return the ruleDetails that are valid to classname and related to instance
(should have)getLinkedClass(List[ClassName] = None)
#List[ClassName] is send from FE, by checking the class used in page where the user ave access if None (in case too difficult to do on the FE) all liked class will be retrieve
for all calculation rules (send signal):
...
returnListClass = []
if listClass == None
sendsignal getLinkedClass(none)
if result_signal != []
merge returnListClass and result_signal
else
for class in listclasss
sendsignal getLinkedClass(none)
if result_signal != []
merge returnListClass and result_signal
return all the returnListClass
Authorities
Calculation (prefix 153)
...
Calculations Frontend Module
...
(NICE TO HAVE, or via Django Admin)Calculation management page
...