[IMP] HORILLA: Updated FileField in models to use dynamic upload path via upload_path function
This commit is contained in:
@@ -12,7 +12,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
from base.horilla_company_manager import HorillaCompanyManager
|
||||
from base.models import Company
|
||||
from employee.models import Employee
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
|
||||
|
||||
class AssetCategory(HorillaModel):
|
||||
@@ -188,9 +188,7 @@ class AssetDocuments(HorillaModel):
|
||||
asset_report = models.ForeignKey(
|
||||
"AssetReport", related_name="documents", on_delete=models.CASCADE
|
||||
)
|
||||
file = models.FileField(
|
||||
upload_to="asset/asset_report/documents/", blank=True, null=True
|
||||
)
|
||||
file = models.FileField(upload_to=upload_path, blank=True, null=True)
|
||||
objects = models.Manager()
|
||||
|
||||
class Meta:
|
||||
@@ -209,7 +207,7 @@ class ReturnImages(HorillaModel):
|
||||
- image: A FileField for uploading the image file (optional).
|
||||
"""
|
||||
|
||||
image = models.FileField(upload_to="asset/return_images/", blank=True, null=True)
|
||||
image = models.FileField(upload_to=upload_path, blank=True, null=True)
|
||||
|
||||
|
||||
class AssetAssignment(HorillaModel):
|
||||
|
||||
@@ -32,7 +32,7 @@ from base.methods import is_company_leave, is_holiday
|
||||
from base.models import Company, EmployeeShift, EmployeeShiftDay, WorkType
|
||||
from employee.models import Employee
|
||||
from horilla.methods import get_horilla_model_class
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
|
||||
# to skip the migration issue with the old migrations
|
||||
@@ -575,7 +575,7 @@ class Attendance(HorillaModel):
|
||||
|
||||
|
||||
class AttendanceRequestFile(HorillaModel):
|
||||
file = models.FileField(upload_to="attendance/request_files")
|
||||
file = models.FileField(upload_to=upload_path)
|
||||
|
||||
|
||||
class AttendanceRequestComment(HorillaModel):
|
||||
|
||||
@@ -19,7 +19,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
from base.horilla_company_manager import HorillaCompanyManager
|
||||
from horilla import horilla_middlewares
|
||||
from horilla.horilla_middlewares import _thread_locals
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
|
||||
# Create your models here.
|
||||
@@ -78,7 +78,7 @@ class Company(HorillaModel):
|
||||
city = models.CharField(max_length=50)
|
||||
zip = models.CharField(max_length=20)
|
||||
icon = models.FileField(
|
||||
upload_to="base/icon",
|
||||
upload_to=upload_path,
|
||||
null=True,
|
||||
)
|
||||
objects = models.Manager()
|
||||
@@ -826,7 +826,7 @@ class RotatingShiftAssign(HorillaModel):
|
||||
|
||||
|
||||
class BaserequestFile(models.Model):
|
||||
file = models.FileField(upload_to="base/request_files")
|
||||
file = models.FileField(upload_to=upload_path)
|
||||
objects = models.Manager()
|
||||
|
||||
|
||||
@@ -1487,7 +1487,7 @@ class Attachment(models.Model):
|
||||
Attachment model for multiple attachments in announcements.
|
||||
"""
|
||||
|
||||
file = models.FileField(upload_to="attachments/")
|
||||
file = models.FileField(upload_to=upload_path)
|
||||
|
||||
def __str__(self):
|
||||
return self.file.name
|
||||
|
||||
@@ -34,7 +34,7 @@ from base.models import (
|
||||
from employee.methods.duration_methods import format_time, strtime_seconds
|
||||
from horilla import horilla_middlewares
|
||||
from horilla.methods import get_horilla_model_class
|
||||
from horilla.models import HorillaModel, has_xss
|
||||
from horilla.models import HorillaModel, has_xss, upload_path
|
||||
from horilla_audit.methods import get_diff
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
|
||||
@@ -78,9 +78,7 @@ class Employee(models.Model):
|
||||
employee_last_name = models.CharField(
|
||||
max_length=200, null=True, blank=True, verbose_name=_("Last Name")
|
||||
)
|
||||
employee_profile = models.ImageField(
|
||||
upload_to="employee/profile", null=True, blank=True
|
||||
)
|
||||
employee_profile = models.ImageField(upload_to=upload_path, null=True, blank=True)
|
||||
email = models.EmailField(max_length=254, unique=True)
|
||||
phone = models.CharField(
|
||||
max_length=25,
|
||||
@@ -775,7 +773,7 @@ class EmployeeBankDetails(HorillaModel):
|
||||
|
||||
|
||||
class NoteFiles(HorillaModel):
|
||||
files = models.FileField(upload_to="employee/NoteFiles", blank=True, null=True)
|
||||
files = models.FileField(upload_to=upload_path, blank=True, null=True)
|
||||
objects = models.Manager()
|
||||
|
||||
def __str__(self):
|
||||
@@ -810,7 +808,7 @@ class PolicyMultipleFile(HorillaModel):
|
||||
PoliciesMultipleFile model
|
||||
"""
|
||||
|
||||
attachment = models.FileField(upload_to="employee/policies")
|
||||
attachment = models.FileField(upload_to=upload_path)
|
||||
|
||||
|
||||
class Policy(HorillaModel):
|
||||
@@ -942,9 +940,7 @@ class DisciplinaryAction(HorillaModel):
|
||||
validators=[validate_time_format],
|
||||
)
|
||||
start_date = models.DateField(null=True)
|
||||
attachment = models.FileField(
|
||||
upload_to="employee/discipline", null=True, blank=True
|
||||
)
|
||||
attachment = models.FileField(upload_to=upload_path, null=True, blank=True)
|
||||
objects = HorillaCompanyManager("employee_id__employee_work_info__company_id")
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
||||
@@ -11,7 +11,7 @@ from base.horilla_company_manager import HorillaCompanyManager
|
||||
from base.models import Company, Department, JobPosition, Tags
|
||||
from employee.models import Employee
|
||||
from horilla import horilla_middlewares
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_audit.methods import get_diff
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
|
||||
@@ -211,7 +211,7 @@ class Comment(HorillaModel):
|
||||
|
||||
|
||||
class Attachment(HorillaModel):
|
||||
file = models.FileField(upload_to="Tickets/Attachment")
|
||||
file = models.FileField(upload_to=upload_path)
|
||||
description = models.CharField(max_length=100, blank=True, null=True)
|
||||
format = models.CharField(max_length=50, blank=True, null=True)
|
||||
ticket = models.ForeignKey(
|
||||
|
||||
@@ -9,6 +9,7 @@ information, audit logging, and active/inactive status management.
|
||||
"""
|
||||
|
||||
import re
|
||||
from uuid import uuid4
|
||||
|
||||
from auditlog.models import AuditlogHistoryField
|
||||
from auditlog.registry import auditlog
|
||||
@@ -17,6 +18,7 @@ from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.db.models.fields.files import FieldFile
|
||||
from django.urls import reverse
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from horilla.horilla_middlewares import _thread_locals
|
||||
@@ -45,6 +47,33 @@ def has_xss(value):
|
||||
return bool(xss_pattern.search(value))
|
||||
|
||||
|
||||
def upload_path(instance, filename):
|
||||
"""
|
||||
Generates a unique file path for uploads in the format:
|
||||
app_label/model_name/field_name/originalfilename-uuid.ext
|
||||
"""
|
||||
ext = filename.split(".")[-1]
|
||||
base_name = ".".join(filename.split(".")[:-1]) or "file"
|
||||
unique_name = f"{slugify(base_name)}-{uuid4().hex[:8]}.{ext}"
|
||||
|
||||
# Try to find which field is uploading this file
|
||||
field_name = next(
|
||||
(
|
||||
k
|
||||
for k, v in instance.__dict__.items()
|
||||
if hasattr(v, "name") and v.name == filename
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
app_label = instance._meta.app_label
|
||||
model_name = instance._meta.model_name
|
||||
|
||||
if field_name:
|
||||
return f"{app_label}/{model_name}/{field_name}/{unique_name}"
|
||||
return f"{app_label}/{model_name}/{unique_name}"
|
||||
|
||||
|
||||
class HorillaModel(models.Model):
|
||||
"""
|
||||
An abstract base model that includes common fields and functionalities
|
||||
|
||||
@@ -26,7 +26,7 @@ from base.models import (
|
||||
)
|
||||
from employee.models import Employee, EmployeeWorkInformation
|
||||
from horilla import horilla_middlewares
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_audit.methods import get_diff
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
from leave.methods import (
|
||||
@@ -158,7 +158,7 @@ WEEK_DAYS = [
|
||||
|
||||
class LeaveType(HorillaModel):
|
||||
icon = models.ImageField(
|
||||
null=True, blank=True, upload_to="leave/leave_icon", verbose_name=_("Icon")
|
||||
null=True, blank=True, upload_to=upload_path, verbose_name=_("Icon")
|
||||
)
|
||||
name = models.CharField(max_length=30, null=False, verbose_name=_("Name"))
|
||||
color = models.CharField(null=True, max_length=30, verbose_name=_("Color"))
|
||||
@@ -652,7 +652,7 @@ class LeaveRequest(HorillaModel):
|
||||
attachment = models.FileField(
|
||||
null=True,
|
||||
blank=True,
|
||||
upload_to="leave/leave_attachment",
|
||||
upload_to=upload_path,
|
||||
verbose_name=_("Attachment"),
|
||||
)
|
||||
status = models.CharField(
|
||||
@@ -1195,7 +1195,7 @@ class LeaveRequest(HorillaModel):
|
||||
|
||||
|
||||
class LeaverequestFile(models.Model):
|
||||
file = models.FileField(upload_to="leave/request_files")
|
||||
file = models.FileField(upload_to=upload_path)
|
||||
|
||||
|
||||
class LeaverequestComment(HorillaModel):
|
||||
@@ -1227,7 +1227,7 @@ class LeaveAllocationRequest(HorillaModel):
|
||||
attachment = models.FileField(
|
||||
null=True,
|
||||
blank=True,
|
||||
upload_to="leave/leave_attachment",
|
||||
upload_to=upload_path,
|
||||
verbose_name=_("Attachment"),
|
||||
)
|
||||
status = models.CharField(
|
||||
|
||||
@@ -14,7 +14,7 @@ from employee.models import Employee
|
||||
from horilla import horilla_middlewares
|
||||
from horilla.horilla_middlewares import _thread_locals
|
||||
from horilla.methods import get_horilla_model_class
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
from notifications.signals import notify
|
||||
|
||||
@@ -111,7 +111,7 @@ class OffboardingStageMultipleFile(HorillaModel):
|
||||
OffboardingStageMultipleFile
|
||||
"""
|
||||
|
||||
attachment = models.FileField(upload_to="offboarding/attachments")
|
||||
attachment = models.FileField(upload_to=upload_path)
|
||||
|
||||
|
||||
class OffboardingEmployee(HorillaModel):
|
||||
|
||||
@@ -30,7 +30,7 @@ from base.models import (
|
||||
from employee.methods.duration_methods import strtime_seconds
|
||||
from employee.models import BonusPoint, Employee, EmployeeWorkInformation
|
||||
from horilla import horilla_middlewares
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -242,7 +242,7 @@ class Contract(HorillaModel):
|
||||
validators=[min_zero],
|
||||
verbose_name=_("Notice Period"),
|
||||
)
|
||||
contract_document = models.FileField(upload_to="uploads/", null=True, blank=True)
|
||||
contract_document = models.FileField(upload_to=upload_path, null=True, blank=True)
|
||||
deduct_leave_from_basic_pay = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name=_("Deduct From Basic Pay"),
|
||||
@@ -1570,7 +1570,7 @@ class ReimbursementMultipleAttachment(models.Model):
|
||||
ReimbursementMultipleAttachement Model
|
||||
"""
|
||||
|
||||
attachment = models.FileField(upload_to="payroll/reimbursements")
|
||||
attachment = models.FileField(upload_to=upload_path)
|
||||
objects = models.Manager()
|
||||
|
||||
|
||||
@@ -1600,7 +1600,7 @@ class Reimbursement(HorillaModel):
|
||||
Employee, on_delete=models.PROTECT, verbose_name="Employee"
|
||||
)
|
||||
allowance_on = models.DateField()
|
||||
attachment = models.FileField(upload_to="payroll/reimbursements", null=True)
|
||||
attachment = models.FileField(upload_to=upload_path, null=True)
|
||||
other_attachments = models.ManyToManyField(
|
||||
ReimbursementMultipleAttachment, blank=True, editable=False
|
||||
)
|
||||
@@ -1787,7 +1787,7 @@ class Reimbursement(HorillaModel):
|
||||
|
||||
|
||||
class ReimbursementFile(models.Model):
|
||||
file = models.FileField(upload_to="payroll/request_files")
|
||||
file = models.FileField(upload_to=upload_path)
|
||||
objects = models.Manager()
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from base.models import Company
|
||||
from employee.models import Employee
|
||||
from horilla import horilla_middlewares
|
||||
from horilla.horilla_middlewares import _thread_locals
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_views.cbv_methods import render_template
|
||||
|
||||
# Create your models here.
|
||||
@@ -75,7 +75,7 @@ class Project(HorillaModel):
|
||||
start_date = models.DateField(verbose_name=_("Start Date"))
|
||||
end_date = models.DateField(null=True, blank=True, verbose_name=_("End Date"))
|
||||
document = models.FileField(
|
||||
upload_to="project/files", blank=True, null=True, verbose_name=_("Project File")
|
||||
upload_to=upload_path, blank=True, null=True, verbose_name=_("Project File")
|
||||
)
|
||||
description = models.TextField(verbose_name=_("Description"))
|
||||
company_id = models.ForeignKey(
|
||||
@@ -355,7 +355,7 @@ class Task(HorillaModel):
|
||||
start_date = models.DateField(null=True, blank=True, verbose_name=_("Start Date"))
|
||||
end_date = models.DateField(null=True, blank=True, verbose_name=_("End Date"))
|
||||
document = models.FileField(
|
||||
upload_to="task/files", blank=True, null=True, verbose_name=_("Task File")
|
||||
upload_to=upload_path, blank=True, null=True, verbose_name=_("Task File")
|
||||
)
|
||||
description = models.TextField(verbose_name=_("Description"))
|
||||
sequence = models.IntegerField(default=0)
|
||||
|
||||
@@ -23,7 +23,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
from base.horilla_company_manager import HorillaCompanyManager
|
||||
from base.models import Company, JobPosition
|
||||
from employee.models import Employee
|
||||
from horilla.models import HorillaModel
|
||||
from horilla.models import HorillaModel, upload_path
|
||||
from horilla_audit.methods import get_diff
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
from horilla_views.cbv_methods import render_template
|
||||
@@ -370,7 +370,7 @@ class Candidate(HorillaModel):
|
||||
("other", _("Other")),
|
||||
]
|
||||
name = models.CharField(max_length=100, null=True, verbose_name=_("Name"))
|
||||
profile = models.ImageField(upload_to=candidate_upload_path, null=True) # 853
|
||||
profile = models.ImageField(upload_to=upload_path, null=True) # 853
|
||||
portfolio = models.URLField(max_length=200, blank=True)
|
||||
recruitment_id = models.ForeignKey(
|
||||
Recruitment,
|
||||
@@ -413,7 +413,7 @@ class Candidate(HorillaModel):
|
||||
verbose_name=_("Mobile"),
|
||||
)
|
||||
resume = models.FileField(
|
||||
upload_to=candidate_upload_path, # 853
|
||||
upload_to=upload_path, # 853
|
||||
validators=[
|
||||
validate_pdf,
|
||||
],
|
||||
@@ -709,7 +709,7 @@ class RejectedCandidate(HorillaModel):
|
||||
|
||||
|
||||
class StageFiles(HorillaModel):
|
||||
files = models.FileField(upload_to="recruitment/stageFiles", blank=True, null=True)
|
||||
files = models.FileField(upload_to=upload_path, blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.files.name.split("/")[-1]
|
||||
@@ -837,9 +837,7 @@ class RecruitmentSurveyAnswer(HorillaModel):
|
||||
null=True,
|
||||
)
|
||||
answer_json = models.JSONField()
|
||||
attachment = models.FileField(
|
||||
upload_to="recruitment_attachment", null=True, blank=True
|
||||
)
|
||||
attachment = models.FileField(upload_to=upload_path, null=True, blank=True)
|
||||
objects = HorillaCompanyManager(related_company_field="recruitment_id__company_id")
|
||||
|
||||
@property
|
||||
@@ -1000,7 +998,7 @@ class InterviewSchedule(HorillaModel):
|
||||
|
||||
class Resume(models.Model):
|
||||
file = models.FileField(
|
||||
upload_to="recruitment/resume",
|
||||
upload_to=upload_path,
|
||||
validators=[
|
||||
validate_pdf,
|
||||
],
|
||||
@@ -1054,7 +1052,7 @@ class CandidateDocument(HorillaModel):
|
||||
document_request_id = models.ForeignKey(
|
||||
CandidateDocumentRequest, on_delete=models.PROTECT, null=True
|
||||
)
|
||||
document = models.FileField(upload_to="candidate/documents", null=True)
|
||||
document = models.FileField(upload_to=upload_path, null=True)
|
||||
status = models.CharField(choices=STATUS, max_length=10, default="requested")
|
||||
reject_reason = models.TextField(blank=True, null=True, max_length=255)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user