Files
ihrm/horilla_audit/methods.py
2024-03-10 14:07:46 +00:00

148 lines
4.3 KiB
Python

"""
methods.py
This module is used to write methods related to the history
"""
from django.db import models
from django.contrib.auth.models import User
class Bot:
def __init__(self) -> None:
self.__str__()
def __str__(self) -> str:
return "Horilla Bot"
def get_avatar(self):
return "https://ui-avatars.com/api/?name=Horilla+Bot&background=random"
def _check_and_delete(entry1, entry2, dry_run=False):
delta = entry1.diff_against(entry2)
if not delta.changed_fields:
if not dry_run:
entry1.delete()
return 1
return 0
def remove_duplicate_history(instance):
"""
This method is used to remove duplicate entries
"""
o_qs = instance.history_set.all()
entries_deleted = 0
# ordering is ('-history_date', '-history_id') so this is ok
f1 = o_qs.first()
if not f1:
return
for f2 in o_qs[1:]:
entries_deleted += _check_and_delete(
f1,
f2,
)
f1 = f2
def get_field_label(model_class, field_name):
# Check if the field exists in the model class
if hasattr(model_class, field_name):
field = model_class._meta.get_field(field_name)
return field.verbose_name.capitalize()
# Return None if the field does not exist
return None
def filter_history(histories, track_fields):
filtered_histories = []
for history in histories:
changes = history.get("changes", [])
filtered_changes = [
change for change in changes if change.get("field_name", "") in track_fields
]
if filtered_changes:
history["changes"] = filtered_changes
filtered_histories.append(history)
histories = filtered_histories
return histories
def get_diff(instance):
"""
This method is used to find the differences in the history
"""
remove_duplicate_history(instance)
history = instance.history_set.all()
history_list = list(history)
pairs = [
[history_list[i], history_list[i + 1]] for i in range(len(history_list) - 1)
]
delta_changes = []
create_history = history.filter(history_type="+").first()
for pair in pairs:
delta = pair[0].diff_against(pair[1])
diffs = []
class_name = pair[0].instance.__class__
for change in delta.changes:
old = change.old
new = change.new
field = instance._meta.get_field(change.field)
is_fk = False
if (
isinstance(field, models.fields.CharField)
and field.choices
and old
and new
):
choices = dict(field.choices)
old = choices[old]
new = choices[new]
if isinstance(field, models.ForeignKey):
is_fk = True
# old = getattr(pair[0], change.field)
# new = getattr(pair[1], change.field)
diffs.append(
{
"field": get_field_label(class_name, change.field),
"field_name": change.field,
"is_fk": is_fk,
"old": old,
"new": new,
}
)
updated_by = (
User.objects.get(id=pair[0].history_user.id).employee_get
if pair[0].history_user
else Bot()
)
delta_changes.append(
{
"type": "Changes",
"pair": pair,
"changes": diffs,
"updated_by": updated_by,
}
)
if create_history:
try:
updated_by = create_history.history_user.employee_get
except:
updated_by = Bot()
delta_changes.append(
{
"type": f"{create_history.instance.__class__._meta.verbose_name.capitalize()} created",
"pair": (create_history, create_history),
"updated_by": updated_by,
}
)
from .models import HistoryTrackingFields
history_tracking_instance = HistoryTrackingFields.objects.first()
if history_tracking_instance:
track_fields = history_tracking_instance.tracking_fields["tracking_fields"]
if track_fields:
delta_changes = filter_history(delta_changes, track_fields)
return delta_changes