Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add engines model #219

Merged
merged 5 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions eox_nelp/migrations/0012_add_pearson_engines_register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.25 on 2024-09-30 18:02

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('eox_nelp', '0011_pearsonrtenevent_course'),
]

operations = [
migrations.CreateModel(
name='PearsonEngine',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('rti_triggers', models.PositiveIntegerField(default=0)),
('cdd_triggers', models.PositiveIntegerField(default=0)),
('ead_triggers', models.PositiveIntegerField(default=0)),
('courses', models.JSONField(default=dict)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
35 changes: 34 additions & 1 deletion eox_nelp/pearson_vue/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.contrib import admin
from django.contrib.auth import get_user_model

from eox_nelp.pearson_vue.models import PearsonRTENEvent
from eox_nelp.pearson_vue.models import PearsonEngine, PearsonRTENEvent

User = get_user_model()

Expand All @@ -27,4 +27,37 @@ class PearsonRTENEventAdmin(admin.ModelAdmin):
list_filter = ["event_type"]


class PearsonEngineAdmin(admin.ModelAdmin):
"""Admin class for PearsonEngineAdmin.

attributes:
list_display: Fields to be shown in admin interface.
search_fields: fields that use to search and find matches.
"""
@admin.display(ordering="user__username", description="User")
def get_user_username(self, obj) -> str:
"""Return username from User instance"""
return obj.user.username

list_display = (
"get_user_username",
"rti_triggers",
"cdd_triggers",
"ead_triggers",
"courses",
"created_at",
"updated_at",
)
search_fields = ("user__username",)
raw_id_fields = ("user",)
ordering = ("-updated_at",)
readonly_fields = (
"rti_triggers",
"cdd_triggers",
"ead_triggers",
"courses",
)


admin.site.register(PearsonRTENEvent, PearsonRTENEventAdmin)
admin.site.register(PearsonEngine, PearsonEngineAdmin)
175 changes: 175 additions & 0 deletions eox_nelp/pearson_vue/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

Classes:
PearsonRTENEvent: A model representing an event for the Pearson VUE RTEN service.
PearsonEngine: A model representing the send to the PearsonEngine service per user.

Constants:
EVENT_TYPE_CHOICES: A list of tuples representing the possible choices
Expand Down Expand Up @@ -52,3 +53,177 @@ class PearsonRTENEvent(models.Model):
event_type = models.CharField(max_length=20, choices=EVENT_TYPE_CHOICES)
candidate = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
course = models.ForeignKey(CourseOverview, null=True, on_delete=models.DO_NOTHING)


class PearsonEngine(models.Model):
"""
This model contains data related to user and the integration with PearsonVue engine service.

Attributes:
user (User): OneToOne relationship with User model.
rti_triggers (int): Number of RTI triggers.
cdd_triggers (int): Number of CDD triggers.
ead_triggers (int): Number of EAD triggers.
courses (dict): JSON field storing EAD course data.
created_at (datetime): Timestamp of model instance creation.
updated_at (datetime): Timestamp of last model instance update.
"""

user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
rti_triggers = models.PositiveIntegerField(default=0)
cdd_triggers = models.PositiveIntegerField(default=0)
ead_triggers = models.PositiveIntegerField(default=0)
courses = models.JSONField(default=dict)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def get_triggers(self, trigger_type):
johanseto marked this conversation as resolved.
Show resolved Hide resolved
"""
Get the number of triggers for a specific type.

Args:
trigger_type (str): The type of trigger ('rti', 'cdd', or 'ead').

Returns:
int: The number of triggers for the specified type.

Raises:
ValueError: If an invalid trigger type is provided.
"""
trigger_name = f"{trigger_type}_triggers"

if not hasattr(self, trigger_name):
raise ValueError(f"Invalid trigger name: {trigger_name}")

return getattr(self, trigger_name, None)

def set_triggers(self, trigger_type, value):
johanseto marked this conversation as resolved.
Show resolved Hide resolved
"""
Set the number of triggers for a specific type.

Args:
trigger_type (str): The type of trigger ('rti', 'cdd', or 'ead').
value (int): The new value for the trigger count.

Raises:
ValueError: If the value is not a non-negative integer or if an invalid trigger type is provided.
"""
trigger_name = f"{trigger_type}_triggers"

if not isinstance(value, int) or value < 0:
raise ValueError("Trigger value must be a non-negative integer")

if not hasattr(self, trigger_name):
raise ValueError(f"Invalid trigger name: {trigger_name}")

setattr(self, trigger_name, value)
self.save()

def increment_trigger(self, trigger_type, increment=1):
"""
Increment the number of triggers for a specific type.

Args:
trigger_type (str): The type of trigger ('rti', 'cdd', or 'ead').
increment (int, optional): The amount to increment. Defaults to 1.
"""
current_value = self.get_triggers(trigger_type)
self.set_triggers(trigger_type, current_value + increment)
johanseto marked this conversation as resolved.
Show resolved Hide resolved

def get_courses(self):
"""
Get the courses for a specific action type.

Returns:
dict: The courses for the specified action type.

"""
return self.courses

def get_course_value(self, course_id):
"""
Get the value of a specific course.

Args:
course_id (str): The ID of the course.

Returns:
int: The value of the specified course, or 0 if not found.
"""
courses = self.get_courses()
return courses.get(course_id, 0)

def set_course_value(self, course_id, value):
"""
Set the value of a specific course.

Args:
course_id (str): The ID of the course.
value (int or float): The new value for the course.

Raises:
ValueError: If the value is not a non-negative number.
"""
if not isinstance(value, (int, float)) or value < 0:
raise ValueError("Course value must be a non-negative number")
courses = self.get_courses()
courses[course_id] = value
self.courses = courses
self.save()

def increment_course_value(self, course_id, increment=1):
"""
Increment the value of a specific course.

Args:
course_id (str): The ID of the course.
increment (int or float, optional): The amount to increment. Defaults to 1.
"""
current_value = self.get_course_value(course_id)
self.set_course_value(course_id, current_value + increment)

def remove_course(self, course_id):
"""
Remove a course from the specified action type.

Args:
course_id (str): The ID of the course to remove.

Raises:
ValueError: If the course is not found in the specified action type.
"""
courses = self.get_courses()
if course_id in courses:
del courses[course_id]
self.courses = courses
self.save()
else:
raise ValueError(f"Course {course_id} not found in courses")

def get_course_ids(self):
"""
Get all course IDs for a specific action type.

Returns:
list: A list of all course IDs for the specified action type.
"""
return list(self.get_courses().keys())

def get_total_course_value(self):
"""
Get the total value of all courses for a specific action type.

Returns:
float: The sum of all course values for the specified action type.
"""
return sum(self.get_courses().values())

@property
def total_triggers(self):
"""
Get the total number of triggers across all types.

Returns:
int: The sum of RTI, CDD, and EAD triggers.
"""
return self.rti_triggers + self.cdd_triggers + self.ead_triggers
Loading
Loading