# Based on: http://springfans.com/ieeeSoftware/accChange.pdf class DecisionTable(models.Model): """Decision Table""" code = models.CharField(unique=True, max_length=8, verbose_name="Unique code for finding a decision table in code") name = models.CharField(blank=True, max_length=100, verbose_name="User friendly name for decision table") def __unicode__(self): return u"Table" class Rule(models.Model): table = models.ForeignKey(DecisionTable) code = models.CharField(unique=True, max_length=8, verbose_name="Unique code for looking up decision tables") name = models.CharField(max_length=128, verbose_name="User friendly description of decision table") priority = PositionField(collection="decision_table") def test(self, facts): for condition in self.condition.all(): if not condition.test(facts): return False return True def __unicode__(self): return u"R%d: %s" % (self.code, self.name) RESPONSE_CHOICES = ( ("Yes", True), ("No", False), ) class Condition(models.Model): """Boolean condition (e.g. condition must be true / condition must be false).""" rule = models.ForeignKey(Rule) name = models.CharField(blank=False, max_length=128, verbose_name="User friendly description of rule condition") value = models.BooleanField(required=True, default=False, choices=RESPONSE_CHOICES) def test(self, facts): return facts[self.name]==self.value def __unicode__(self): return u"C%d: %s" % (self.code, self.name) class Action(models.Model): """Data returned by rule""" rule = models.ForeignKey(Rule) code = models.CharField(unique=True, max_length=8, verbose_name="Unique code for identifying actions in code.") name = models.CharField(blank=False, max_length=128, verbose_name="User friendly description of rule action") order = PositionField("rule") def __unicode__(self): return u"A%d: %s" % (self.code, self.name)