This commit introduces significant changes to the architecture of the Horilla HRMS system by decoupling interdependent modules. The following modifications were made: 1. **Module Independence**: Each module has been refactored to eliminate reliance on other modules, promoting a more modular and maintainable codebase. 2. **Refactored Imports and Dependencies**: Adjusted import statements and dependency injections to support independent module operation. 3. **Compatibility and Functionality**: Ensured that all modules are compatible with existing systems and maintain their intended functionality both independently and when integrated with other modules. These changes enhance the modularity, maintainability, and scalability of the Horilla HRMS, allowing developers to work on individual modules without affecting the entire system. Future development and deployment will be more efficient and less prone to issues arising from tightly coupled code. **NOTE** For existing Horilla users, if you face any issues during the migrations, please run the following command and try again the migrations. - `python3 manage.py makemigrations` - `python3 manage.py migrate base` - `python3 manage.py migrate` * [IMP] ASSET: Asset module dependency removal from other Horilla apps * [IMP] ATTENDANCE: Attendance module dependency removal from other Horilla apps * [IMP] BASE: Base module dependency removal from other Horilla apps * [IMP] EMPLOYEE: Employee module dependency removal from other Horilla apps * [IMP] HELPDESK: Helpdesk module dependency removal from other Horilla apps * [IMP] HORILLA AUDIT: Horilla Audit module dependency removal from other Horilla apps * [IMP] HORILLA CRUMBS: Horilla Crumbs module dependency removal from other Horilla apps * [IMP] HORILLA AUTOMATIONS: Horilla Automations module dependency removal from other Horilla apps * [IMP] HORILLA VIEWS: Horilla Views module dependency removal from other Horilla apps * [IMP] LEAVE: Leave module dependency removal from other Horilla apps * [IMP] OFFBOARDING: Offboarding module dependency removal from other Horilla apps * [IMP] ONBOARDING: Onboarding module dependency removal from other Horilla apps * [IMP] PMS: PMS module dependency removal from other Horilla apps * [IMP] PAYROLL: Payroll module dependency removal from other Horilla apps * [IMP] RECRUITMENT: Recruitment module dependency removal from other Horilla apps * [IMP] HORILLA: Dependency removal updates * [IMP] TEMPLATES: Dependency removal updates * [IMP] STATIC: Dependency removal updates * [IMP] HORILLA DOCUMENTS: Horilla Documents module dependency removal from other Horilla apps * [ADD] HORILLA: methods.py * [UPDT] HORILLA: Settings.py * [FIX] EMPLOYEE: About tab issue * Update horilla_settings.py * Remove dummy db init password
701 lines
22 KiB
Python
701 lines
22 KiB
Python
"""
|
|
forms.py
|
|
|
|
This module contains the form classes used in the application.
|
|
|
|
Each form represents a specific functionality or data input in the
|
|
application. They are responsible for validating
|
|
and processing user input data.
|
|
|
|
Classes:
|
|
- YourForm: Represents a form for handling specific data input.
|
|
|
|
Usage:
|
|
from django import forms
|
|
|
|
class YourForm(forms.Form):
|
|
field_name = forms.CharField()
|
|
|
|
def clean_field_name(self):
|
|
# Custom validation logic goes here
|
|
pass
|
|
"""
|
|
|
|
import logging
|
|
import re
|
|
from datetime import date
|
|
from typing import Any
|
|
|
|
from django import forms
|
|
from django.contrib.auth.models import User
|
|
from django.db.models import Q
|
|
from django.forms import DateInput, TextInput
|
|
from django.template.loader import render_to_string
|
|
from django.utils.translation import gettext as _
|
|
from django.utils.translation import gettext_lazy as trans
|
|
|
|
from base.methods import reload_queryset
|
|
from employee.models import (
|
|
Actiontype,
|
|
BonusPoint,
|
|
DisciplinaryAction,
|
|
Employee,
|
|
EmployeeBankDetails,
|
|
EmployeeNote,
|
|
EmployeeTag,
|
|
EmployeeWorkInformation,
|
|
NoteFiles,
|
|
Policy,
|
|
PolicyMultipleFile,
|
|
)
|
|
from horilla import horilla_middlewares
|
|
from horilla_audit.models import AccountBlockUnblock
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ModelForm(forms.ModelForm):
|
|
"""
|
|
Overriding django default model form to apply some styles
|
|
"""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
request = getattr(horilla_middlewares._thread_locals, "request", None)
|
|
reload_queryset(self.fields)
|
|
for _, field in self.fields.items():
|
|
widget = field.widget
|
|
if isinstance(widget, (forms.DateInput)):
|
|
field.initial = date.today()
|
|
|
|
if isinstance(
|
|
widget,
|
|
(forms.NumberInput, forms.EmailInput, forms.TextInput, forms.FileInput),
|
|
):
|
|
label = trans(field.label.title())
|
|
field.widget.attrs.update(
|
|
{"class": "oh-input w-100", "placeholder": label}
|
|
)
|
|
elif isinstance(widget, (forms.Select,)):
|
|
label = ""
|
|
if field.label is not None:
|
|
label = trans(field.label)
|
|
field.empty_label = trans("---Choose {label}---").format(label=label)
|
|
field.widget.attrs.update(
|
|
{"class": "oh-select oh-select-2 select2-hidden-accessible"}
|
|
)
|
|
elif isinstance(widget, (forms.Textarea)):
|
|
if field.label is not None:
|
|
label = trans(field.label)
|
|
field.widget.attrs.update(
|
|
{
|
|
"class": "oh-input w-100",
|
|
"placeholder": label,
|
|
"rows": 2,
|
|
"cols": 40,
|
|
}
|
|
)
|
|
elif isinstance(
|
|
widget,
|
|
(
|
|
forms.CheckboxInput,
|
|
forms.CheckboxSelectMultiple,
|
|
),
|
|
):
|
|
field.widget.attrs.update({"class": "oh-switch__checkbox"})
|
|
|
|
try:
|
|
if self._meta.model.__name__ not in ["DisciplinaryAction"]:
|
|
self.fields["employee_id"].initial = request.user.employee_get
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
self.fields["company_id"].initial = (
|
|
request.user.employee_get.get_company
|
|
)
|
|
except:
|
|
pass
|
|
|
|
|
|
class UserForm(ModelForm):
|
|
"""
|
|
Form for User model
|
|
"""
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
fields = ("groups",)
|
|
model = User
|
|
|
|
|
|
class UserPermissionForm(ModelForm):
|
|
"""
|
|
Form for User model
|
|
"""
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
fields = ("groups", "user_permissions")
|
|
model = User
|
|
|
|
|
|
class EmployeeForm(ModelForm):
|
|
"""
|
|
Form for Employee model
|
|
"""
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
model = Employee
|
|
fields = "__all__"
|
|
exclude = (
|
|
"employee_user_id",
|
|
"additional_info",
|
|
)
|
|
widgets = {
|
|
"dob": TextInput(attrs={"type": "date", "id": "dob"}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["email"].widget.attrs["autocomplete"] = "email"
|
|
self.fields["phone"].widget.attrs["autocomplete"] = "phone"
|
|
self.fields["address"].widget.attrs["autocomplete"] = "address"
|
|
if instance := kwargs.get("instance"):
|
|
# ----
|
|
# django forms not showing value inside the date, time html element.
|
|
# so here overriding default forms instance method to set initial value
|
|
# ----
|
|
initial = {}
|
|
if instance.dob is not None:
|
|
initial["dob"] = instance.dob.strftime("%H:%M")
|
|
kwargs["initial"] = initial
|
|
else:
|
|
self.initial = {"badge_id": self.get_next_badge_id()}
|
|
|
|
def as_p(self, *args, **kwargs):
|
|
context = {"form": self}
|
|
return render_to_string("employee/create_form/personal_info_as_p.html", context)
|
|
|
|
def get_next_badge_id(self):
|
|
"""
|
|
This method is used to generate badge id
|
|
"""
|
|
from base.context_processors import get_initial_prefix
|
|
from employee.methods.methods import get_ordered_badge_ids
|
|
|
|
prefix = get_initial_prefix(None)["get_initial_prefix"]
|
|
data = get_ordered_badge_ids()
|
|
result = []
|
|
try:
|
|
for sublist in data:
|
|
for item in sublist:
|
|
if isinstance(item, str) and item.lower().startswith(
|
|
prefix.lower()
|
|
):
|
|
# Find the index of the item in the sublist
|
|
index = sublist.index(item)
|
|
# Check if there is a next item in the sublist
|
|
if index + 1 < len(sublist):
|
|
result = sublist[index + 1]
|
|
result = re.findall(r"[a-zA-Z]+|\d+|[^a-zA-Z\d\s]", result)
|
|
|
|
if result:
|
|
prefix = []
|
|
incremented = False
|
|
for item in reversed(result):
|
|
total_letters = len(item)
|
|
total_zero_leads = 0
|
|
for letter in item:
|
|
if letter == "0":
|
|
total_zero_leads = total_zero_leads + 1
|
|
continue
|
|
break
|
|
|
|
if total_zero_leads:
|
|
item = item[total_zero_leads:]
|
|
if isinstance(item, list):
|
|
item = item[-1]
|
|
if not incremented and isinstance(eval(str(item)), int):
|
|
item = int(item) + 1
|
|
incremented = True
|
|
if isinstance(item, int):
|
|
item = "{:0{}d}".format(item, total_letters)
|
|
prefix.insert(0, str(item))
|
|
prefix = "".join(prefix)
|
|
except Exception as e:
|
|
logger.exception(e)
|
|
prefix = get_initial_prefix(None)["get_initial_prefix"]
|
|
return prefix
|
|
|
|
def clean_badge_id(self):
|
|
"""
|
|
This method is used to clean the badge id
|
|
"""
|
|
badge_id = self.cleaned_data["badge_id"]
|
|
if badge_id:
|
|
queryset = Employee.objects.filter(badge_id=badge_id).exclude(
|
|
pk=self.instance.pk if self.instance else None
|
|
)
|
|
if queryset.exists():
|
|
raise forms.ValidationError(trans("Badge ID must be unique."))
|
|
if not re.search(r"\d", badge_id):
|
|
raise forms.ValidationError(
|
|
trans("Badge ID must contain at least one digit.")
|
|
)
|
|
return badge_id
|
|
|
|
|
|
class EmployeeWorkInformationForm(ModelForm):
|
|
"""
|
|
Form for EmployeeWorkInformation model
|
|
"""
|
|
|
|
employees = Employee.objects.filter(employee_work_info=None)
|
|
employee_id = forms.ModelChoiceField(queryset=employees)
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
model = EmployeeWorkInformation
|
|
fields = "__all__"
|
|
widgets = {
|
|
"date_joining": DateInput(attrs={"type": "date"}),
|
|
"contract_end_date": DateInput(attrs={"type": "date"}),
|
|
}
|
|
|
|
def __init__(self, *args, disable=False, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["email"].widget.attrs["autocomplete"] = "email"
|
|
|
|
self.fields["job_position_id"].widget.attrs.update(
|
|
{
|
|
"onchange": "jobChange($(this))",
|
|
}
|
|
)
|
|
|
|
for field in self.fields:
|
|
self.fields[field].widget.attrs["placeholder"] = self.fields[field].label
|
|
if disable:
|
|
self.fields[field].disabled = True
|
|
field_names = {
|
|
"Department": "department",
|
|
"Job Position": "job_position",
|
|
"Job Role": "job_role",
|
|
"Work Type": "work_type",
|
|
"Employee Type": "employee_type",
|
|
"Shift": "employee_shift",
|
|
}
|
|
urls = {
|
|
"Department": "#dynamicDept",
|
|
"Job Position": "#dynamicJobPosition",
|
|
"Job Role": "#dynamicJobRole",
|
|
"Work Type": "#dynamicWorkType",
|
|
"Employee Type": "#dynamicEmployeeType",
|
|
"Shift": "#dynamicShift",
|
|
}
|
|
|
|
for label, field in self.fields.items():
|
|
if isinstance(field, forms.ModelChoiceField) and field.label in field_names:
|
|
if field.label is not None:
|
|
field_name = field_names.get(field.label)
|
|
if field.queryset.model != Employee and field_name:
|
|
translated_label = _(field.label)
|
|
empty_label = _("---Choose {label}---").format(
|
|
label=translated_label
|
|
)
|
|
self.fields[label] = forms.ChoiceField(
|
|
choices=[("", empty_label)]
|
|
+ list(field.queryset.values_list("id", f"{field_name}")),
|
|
required=field.required,
|
|
label=translated_label,
|
|
initial=field.initial,
|
|
widget=forms.Select(
|
|
attrs={
|
|
"class": "oh-select oh-select-2 select2-hidden-accessible",
|
|
"onchange": f'onDynamicCreate(this.value,"{urls.get(field.label)}");',
|
|
}
|
|
),
|
|
)
|
|
self.fields[label].choices += [
|
|
("create", _("Create New {} ").format(translated_label))
|
|
]
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
if "employee_id" in self.errors:
|
|
del self.errors["employee_id"]
|
|
return cleaned_data
|
|
|
|
|
|
class EmployeeWorkInformationUpdateForm(ModelForm):
|
|
"""
|
|
Form for EmployeeWorkInformation model
|
|
"""
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
model = EmployeeWorkInformation
|
|
fields = "__all__"
|
|
exclude = ("employee_id",)
|
|
|
|
widgets = {
|
|
"date_joining": DateInput(attrs={"type": "date"}),
|
|
"contract_end_date": DateInput(attrs={"type": "date"}),
|
|
}
|
|
|
|
|
|
class EmployeeBankDetailsForm(ModelForm):
|
|
"""
|
|
Form for EmployeeBankDetails model
|
|
"""
|
|
|
|
address = forms.CharField(widget=forms.Textarea(attrs={"rows": 2, "cols": 40}))
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
model = EmployeeBankDetails
|
|
fields = "__all__"
|
|
exclude = [
|
|
"employee_id",
|
|
"is_active",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["address"].widget.attrs["autocomplete"] = "address"
|
|
for visible in self.visible_fields():
|
|
visible.field.widget.attrs["class"] = "oh-input w-100"
|
|
|
|
|
|
class EmployeeBankDetailsUpdateForm(ModelForm):
|
|
"""
|
|
Form for EmployeeBankDetails model
|
|
"""
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
model = EmployeeBankDetails
|
|
fields = "__all__"
|
|
exclude = [
|
|
"employee_id",
|
|
"is_active",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
for visible in self.visible_fields():
|
|
visible.field.widget.attrs["class"] = "oh-input w-100"
|
|
for field in self.fields:
|
|
self.fields[field].widget.attrs["placeholder"] = self.fields[field].label
|
|
|
|
|
|
excel_columns = [
|
|
("badge_id", trans("Badge ID")),
|
|
("employee_first_name", trans("First Name")),
|
|
("employee_last_name", trans("Last Name")),
|
|
("email", trans("Email")),
|
|
("phone", trans("Phone")),
|
|
("experience", trans("Experience")),
|
|
("gender", trans("Gender")),
|
|
("dob", trans("Date of Birth")),
|
|
("country", trans("Country")),
|
|
("state", trans("State")),
|
|
("city", trans("City")),
|
|
("address", trans("Address")),
|
|
("zip", trans("Zip Code")),
|
|
("marital_status", trans("Marital Status")),
|
|
("children", trans("Children")),
|
|
("is_active", trans("Is active")),
|
|
("emergency_contact", trans("Emergency Contact")),
|
|
("emergency_contact_name", trans("Emergency Contact Name")),
|
|
("emergency_contact_relation", trans("Emergency Contact Relation")),
|
|
("employee_work_info__email", trans("Work Email")),
|
|
("employee_work_info__mobile", trans("Work Phone")),
|
|
("employee_work_info__department_id", trans("Department")),
|
|
("employee_work_info__job_position_id", trans("Job Position")),
|
|
("employee_work_info__job_role_id", trans("Job Role")),
|
|
("employee_work_info__shift_id", trans("Shift")),
|
|
("employee_work_info__work_type_id", trans("Work Type")),
|
|
("employee_work_info__reporting_manager_id", trans("Reporting Manager")),
|
|
("employee_work_info__employee_type_id", trans("Employee Type")),
|
|
("employee_work_info__location", trans("Work Location")),
|
|
("employee_work_info__date_joining", trans("Date Joining")),
|
|
("employee_work_info__company_id", trans("Company")),
|
|
("employee_bank_details__bank_name", trans("Bank Name")),
|
|
("employee_bank_details__branch", trans("Branch")),
|
|
("employee_bank_details__account_number", trans("Account Number")),
|
|
("employee_bank_details__any_other_code1", trans("Bank Code #1")),
|
|
("employee_bank_details__any_other_code2", trans("Bank Code #2")),
|
|
("employee_bank_details__country", trans("Bank Country")),
|
|
("employee_bank_details__state", trans("Bank State")),
|
|
("employee_bank_details__city", trans("Bank City")),
|
|
]
|
|
fields_to_remove = [
|
|
"badge_id",
|
|
"employee_first_name",
|
|
"employee_last_name",
|
|
"is_active",
|
|
"email",
|
|
"phone",
|
|
"employee_bank_details__account_number",
|
|
]
|
|
|
|
|
|
class EmployeeExportExcelForm(forms.Form):
|
|
selected_fields = forms.MultipleChoiceField(
|
|
choices=excel_columns,
|
|
widget=forms.CheckboxSelectMultiple,
|
|
initial=[
|
|
"badge_id",
|
|
"employee_first_name",
|
|
"employee_last_name",
|
|
"email",
|
|
"phone",
|
|
"gender",
|
|
"employee_work_info__department_id",
|
|
"employee_work_info__job_position_id",
|
|
"employee_work_info__job_role_id",
|
|
"employee_work_info__shift_id",
|
|
"employee_work_info__work_type_id",
|
|
"employee_work_info__reporting_manager_id",
|
|
"employee_work_info__employee_type_id",
|
|
"employee_work_info__company_id",
|
|
],
|
|
)
|
|
|
|
|
|
class BulkUpdateFieldForm(forms.Form):
|
|
update_fields = forms.MultipleChoiceField(
|
|
choices=excel_columns, label=_("Select Fields to Update")
|
|
)
|
|
bulk_employee_ids = forms.CharField(widget=forms.HiddenInput())
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
updated_choices = [
|
|
(value, label)
|
|
for value, label in self.fields["update_fields"].choices
|
|
if value not in fields_to_remove
|
|
]
|
|
self.fields["update_fields"].choices = updated_choices
|
|
for visible in self.visible_fields():
|
|
visible.field.widget.attrs["class"] = (
|
|
"oh-select oh-select-2 select2-hidden-accessible oh-input w-100"
|
|
)
|
|
|
|
|
|
class EmployeeNoteForm(ModelForm):
|
|
"""
|
|
Form for EmployeeNote model
|
|
"""
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class to add the additional info
|
|
"""
|
|
|
|
model = EmployeeNote
|
|
fields = ("description",)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["note_files"] = MultipleFileField(label="files")
|
|
self.fields["note_files"].required = False
|
|
|
|
def save(self, commit: bool = ...) -> Any:
|
|
attachement = []
|
|
multiple_attachment_ids = []
|
|
attachements = None
|
|
if self.files.getlist("note_files"):
|
|
attachements = self.files.getlist("note_files")
|
|
self.instance.attachement = attachements[0]
|
|
multiple_attachment_ids = []
|
|
|
|
for attachement in attachements:
|
|
file_instance = NoteFiles()
|
|
file_instance.files = attachement
|
|
file_instance.save()
|
|
multiple_attachment_ids.append(file_instance.pk)
|
|
instance = super().save(commit)
|
|
if commit:
|
|
instance.note_files.add(*multiple_attachment_ids)
|
|
return instance, multiple_attachment_ids
|
|
|
|
|
|
class MultipleFileInput(forms.ClearableFileInput):
|
|
allow_multiple_selected = True
|
|
|
|
|
|
class MultipleFileField(forms.FileField):
|
|
def __init__(self, *args, **kwargs):
|
|
kwargs.setdefault("widget", MultipleFileInput())
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def clean(self, data, initial=None):
|
|
single_file_clean = super().clean
|
|
if isinstance(data, (list, tuple)):
|
|
result = [single_file_clean(d, initial) for d in data]
|
|
else:
|
|
result = [single_file_clean(data, initial)]
|
|
if len(result) == 0:
|
|
result = [[]]
|
|
return result[0]
|
|
|
|
|
|
class PolicyForm(ModelForm):
|
|
"""
|
|
PolicyForm
|
|
"""
|
|
|
|
class Meta:
|
|
model = Policy
|
|
fields = "__all__"
|
|
exclude = ["attachments", "is_active"]
|
|
widgets = {
|
|
"body": forms.Textarea(
|
|
attrs={"data-summernote": "", "style": "display:none;"}
|
|
),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["attachment"] = MultipleFileField(
|
|
label="Attachements", required=False
|
|
)
|
|
|
|
def save(self, *args, commit=True, **kwargs):
|
|
attachemnt = []
|
|
multiple_attachment_ids = []
|
|
attachemnts = None
|
|
if self.files.getlist("attachment"):
|
|
attachemnts = self.files.getlist("attachment")
|
|
multiple_attachment_ids = []
|
|
for attachemnt in attachemnts:
|
|
file_instance = PolicyMultipleFile()
|
|
file_instance.attachment = attachemnt
|
|
file_instance.save()
|
|
multiple_attachment_ids.append(file_instance.pk)
|
|
instance = super().save(commit)
|
|
if commit:
|
|
instance.attachments.add(*multiple_attachment_ids)
|
|
return instance, attachemnts
|
|
|
|
|
|
class BonusPointAddForm(ModelForm):
|
|
class Meta:
|
|
model = BonusPoint
|
|
fields = ["points", "reason"]
|
|
widgets = {
|
|
"reason": forms.TextInput(attrs={"required": "required"}),
|
|
}
|
|
|
|
|
|
class BonusPointRedeemForm(ModelForm):
|
|
class Meta:
|
|
model = BonusPoint
|
|
fields = ["points"]
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
available_points = BonusPoint.objects.filter(
|
|
employee_id=self.instance.employee_id
|
|
).first()
|
|
if available_points.points < cleaned_data["points"]:
|
|
raise forms.ValidationError({"points": "Not enough bonus points to redeem"})
|
|
if cleaned_data["points"] <= 0:
|
|
raise forms.ValidationError(
|
|
{"points": "Points must be greater than zero to redeem."}
|
|
)
|
|
|
|
|
|
class DisciplinaryActionForm(ModelForm):
|
|
class Meta:
|
|
model = DisciplinaryAction
|
|
fields = "__all__"
|
|
exclude = ["company_id", "objects", "is_active"]
|
|
widgets = {
|
|
"start_date": forms.DateInput(attrs={"type": "date"}),
|
|
}
|
|
|
|
action = forms.ModelChoiceField(
|
|
queryset=Actiontype.objects.all(),
|
|
label=_("Action"),
|
|
widget=forms.Select(
|
|
attrs={
|
|
"class": "oh-select oh-select-2 select2-hidden-accessible",
|
|
"onchange": "actionTypeChange($(this))",
|
|
}
|
|
),
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
action_choices = [("", _("---Choose Action---"))] + list(
|
|
self.fields["action"].queryset.values_list("id", "title")
|
|
)
|
|
self.fields["action"].choices = action_choices
|
|
if self.instance.pk is None:
|
|
self.fields["action"].choices += [("create", _("Create new action type "))]
|
|
|
|
def as_p(self):
|
|
"""
|
|
Render the form fields as HTML table rows with Bootstrap styling.
|
|
"""
|
|
context = {"form": self}
|
|
table_html = render_to_string("common_form.html", context)
|
|
return table_html
|
|
|
|
|
|
class ActiontypeForm(ModelForm):
|
|
class Meta:
|
|
model = Actiontype
|
|
fields = "__all__"
|
|
exclude = ["is_active"]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields["action_type"].widget.attrs.update(
|
|
{
|
|
"onchange": "actionChange($(this))",
|
|
}
|
|
)
|
|
|
|
|
|
class EmployeeTagForm(ModelForm):
|
|
"""
|
|
Employee Tags form
|
|
"""
|
|
|
|
class Meta:
|
|
"""
|
|
Meta class for additional options
|
|
"""
|
|
|
|
model = EmployeeTag
|
|
fields = "__all__"
|
|
exclude = ["is_active"]
|
|
widgets = {"color": TextInput(attrs={"type": "color", "style": "height:50px"})}
|