Calculate weighted score from Salesforce data in Django

137 views Asked by At

I'm looking to connect my website with Salesforce and have a view that shows a breakdown of a user's activities in Salesforce, then calculate an overall score based on assigned weights to each activity. I'm using Django-Salesforce to initiate the connection and extend the Activity model, but I'm not sure I've setup the Activity or OverallScore classes correctly.

Below is my code for what I already have. Based on other questions I've seen that are similar, it seems like a custom save method is the suggested result, but my concern is that my database would quickly become massive, as the connection will refresh every 5 minutes.

The biggest question I have is how to setup the "weighted_score" attribute of the Activity class, as I doubt what I have currently is correct.

class Activity(salesforce.models.Model):
    owner = models.ManyToManyField(Profile)
    name = models.CharField(verbose_name='Name', max_length=264, 
           unique=True)
    weight = models.DecimalField(verbose_name='Weight', decimal_places=2, 
         default=0)
    score = models.IntegerField(verbose_name='Score', default=0)
    weighted_score = weight*score

    def __str__(self):
        return self.name


class OverallScore(models.Model):
    factors = models.ManyToManyField(Activity)
    score = Activity.objects.aggregate(Sum('weighted_score'))

    def __str__(self):
        return "OverallScore"

The ideal end result would be each user logged in gets a "live" look at their activity scores and one overall score which is refreshed every 5 minutes from the Salesforce connection, then at the end of the day I would run a cron job to save the end of day results to the database.

1

There are 1 answers

0
hynekcer On

Excuse a late partial response only to parts of question that are clear.

The implementation of arithmetic on fields in weighted_score depends on your preferences if your prefer an expression on Django side or on Salesforce side.

The easiest, but very limited solution is by @property decorator on a method.

class Activity(salesforce.models.Model):
    ... # the same fields
    @property
    def weighted_score(self)
        return self.weight * self.score

This can be used in Python code as self.weighted_score, but it can not be passed any way to SOQL and it gives you not more power than if you would write a longer (self.weight * self.score) on the same place.

Salesforce SOQL does not support arithmetic expressions in SELECT clause, but you can define a custom "Formula" field in Salesforce setup of the Activity object and use it as normal numeric read only field in Django. If the Activity would be a Master-Detail Relationship of any other Salesforce object you can apply very fast Sum, max or average formula on that object.

ManyToMany field require to create the binding object in Salesforce Setup manually and to assign it to the through attribute of the ManyToMany field. An example is on wiki Foreign Key Support. As a rule of thumb your object definition must first exist in Salesforce with useful relationships (it can be Lookup Relationship or Lookup Relationship) and manageable data structure. Then you can run python manage.py inspectdb --database=salesforce ... table names (optionally a list of API Names of used tables, separated by spaces) That is much code to prune many unnecessary fields and choices, but still easier and reliably functional than to ask someone. Salesforce has no special form of custom ManyToMany relationship, therefore everything is written by ForeignKey in models.py. Master-Detail is only a comment on the ForeignKey. You can finally create a ManyToMany field manually, but it is mainly only a syntactic sugar to have nice mnemonic name for a forward and reverse traversing by the two foreign keys on the "through=" binding object.

(The rest of question was too broad and unclear for me.)