Files
ihrm/asset/models.py

332 lines
9.8 KiB
Python
Raw Normal View History

2023-08-21 17:25:49 +05:30
"""
Models for Asset Management System
This module defines Django models to manage assets, their categories, assigning, and requests
within an Asset Management System.
"""
2023-08-21 17:25:49 +05:30
from django.core.exceptions import ValidationError
from django.db import models
2023-05-10 15:06:57 +05:30
from django.utils.translation import gettext_lazy as _
2023-12-01 15:36:51 +05:30
from base.horilla_company_manager import HorillaCompanyManager
from base.models import Company
2023-08-21 17:25:49 +05:30
from employee.models import Employee
from horilla.models import HorillaModel, upload_path
2023-05-10 15:06:57 +05:30
class AssetCategory(HorillaModel):
2023-08-21 17:25:49 +05:30
"""
Represents a category for different types of assets.
"""
asset_category_name = models.CharField(
max_length=255, unique=True, verbose_name=_("Name")
)
asset_category_description = models.TextField(
max_length=255, verbose_name=_("Description")
)
2023-08-21 17:25:49 +05:30
objects = models.Manager()
company_id = models.ManyToManyField(Company, blank=True, verbose_name=_("Company"))
objects = HorillaCompanyManager("company_id")
2023-08-08 10:13:50 +05:30
class Meta:
"""
Meta class to add additional options
"""
verbose_name = _("Asset Category")
verbose_name_plural = _("Asset Categories")
2023-05-10 15:06:57 +05:30
def __str__(self):
2023-08-08 10:13:50 +05:30
return f"{self.asset_category_name}"
2023-05-10 15:06:57 +05:30
class AssetLot(HorillaModel):
2023-08-21 17:25:49 +05:30
"""
Represents a lot associated with a collection of assets.
"""
lot_number = models.CharField(
max_length=30,
null=False,
blank=False,
unique=True,
verbose_name=_("Batch Number"),
)
lot_description = models.TextField(
null=True, blank=True, max_length=255, verbose_name=_("Description")
)
company_id = models.ManyToManyField(Company, blank=True, verbose_name=_("Company"))
2023-12-01 15:36:51 +05:30
objects = HorillaCompanyManager()
2023-08-08 10:13:50 +05:30
class Meta:
"""
Meta class to add additional options
"""
ordering = ["-created_at"]
verbose_name = _("Asset Batch")
verbose_name_plural = _("Asset Batches")
2023-05-10 15:06:57 +05:30
def __str__(self):
2023-08-08 10:13:50 +05:30
return f"{self.lot_number}"
2023-05-10 15:06:57 +05:30
class Asset(HorillaModel):
2023-08-21 17:25:49 +05:30
"""
Represents a asset with various attributes.
"""
2023-05-10 15:06:57 +05:30
ASSET_STATUS = [
("In use", _("In Use")),
2023-08-08 10:13:50 +05:30
("Available", _("Available")),
("Not-Available", _("Not-Available")),
2023-05-10 15:06:57 +05:30
]
asset_name = models.CharField(max_length=255, verbose_name=_("Asset Name"))
owner = models.ForeignKey(
Employee,
on_delete=models.PROTECT,
null=True,
blank=True,
verbose_name=_("Current User"),
)
asset_description = models.TextField(
null=True, blank=True, max_length=255, verbose_name=_("Description")
)
asset_tracking_id = models.CharField(
max_length=30, null=False, unique=True, verbose_name=_("Tracking Id")
)
asset_purchase_date = models.DateField(verbose_name=_("Purchase Date"))
asset_purchase_cost = models.DecimalField(
max_digits=10, decimal_places=2, verbose_name=_("Cost")
)
asset_category_id = models.ForeignKey(
AssetCategory, on_delete=models.PROTECT, verbose_name=_("Category")
)
2023-08-08 10:13:50 +05:30
asset_status = models.CharField(
choices=ASSET_STATUS,
default="Available",
max_length=40,
verbose_name=_("Status"),
2023-08-08 10:13:50 +05:30
)
asset_lot_number_id = models.ForeignKey(
AssetLot,
on_delete=models.PROTECT,
null=True,
blank=True,
verbose_name=_("Batch No"),
)
expiry_date = models.DateField(null=True, blank=True, verbose_name=_("Expiry Date"))
notify_before = models.IntegerField(
default=1, null=True, verbose_name=_("Notify Before (days)")
2023-08-08 10:13:50 +05:30
)
2023-12-01 15:36:51 +05:30
objects = HorillaCompanyManager("asset_category_id__company_id")
2023-08-08 10:13:50 +05:30
class Meta:
ordering = ["-created_at"]
verbose_name = _("Asset")
verbose_name_plural = _("Assets")
2023-05-10 15:06:57 +05:30
def __str__(self):
2023-08-08 10:13:50 +05:30
return f"{self.asset_name}-{self.asset_tracking_id}"
2023-08-21 17:25:49 +05:30
def clean(self):
existing_asset = Asset.objects.filter(
asset_tracking_id=self.asset_tracking_id
).exclude(
id=self.pk
) # Exclude the current instance if updating
if existing_asset.exists():
raise ValidationError(
{
"asset_description": _(
"An asset with this tracking ID already exists."
)
}
)
return super().clean()
2023-05-10 15:06:57 +05:30
class AssetReport(HorillaModel):
"""
Model representing a report for an asset.
Attributes:
- title: A CharField for the title of the report (optional).
- asset_id: A ForeignKey to the Asset model, linking the report to a specific asset.
"""
title = models.CharField(max_length=255, blank=True, null=True)
asset_id = models.ForeignKey(
Asset, related_name="asset_report", on_delete=models.CASCADE
)
def __str__(self):
"""
Returns a string representation of the AssetReport instance.
If a title is present, it returns "asset_id - title".
Otherwise, it returns "report for asset_id".
"""
return (
f"{self.asset_id} - {self.title}"
if self.title
else f"report for {self.asset_id}"
)
class AssetDocuments(HorillaModel):
"""
Model representing documents associated with an asset report.
Attributes:
- asset_report: A ForeignKey to the AssetReport model, linking the document to
a specific asset report.
- file: A FileField for uploading the document file (optional).
"""
asset_report = models.ForeignKey(
"AssetReport", related_name="documents", on_delete=models.CASCADE
)
file = models.FileField(upload_to=upload_path, blank=True, null=True)
objects = models.Manager()
class Meta:
verbose_name = _("Asset Document")
verbose_name_plural = _("Asset Documents")
def __str__(self):
return f"document for {self.asset_report}"
class ReturnImages(HorillaModel):
"""
Model representing images associated with a returned asset.
Attributes:
- image: A FileField for uploading the image file (optional).
"""
image = models.FileField(upload_to=upload_path, blank=True, null=True)
2024-02-07 13:00:09 +05:30
class AssetAssignment(HorillaModel):
2023-08-21 17:25:49 +05:30
"""
Represents the allocation and return of assets to and from employees.
"""
2023-05-10 15:06:57 +05:30
STATUS = [
2023-08-08 10:13:50 +05:30
("Minor damage", _("Minor damage")),
("Major damage", _("Major damage")),
("Healthy", _("Healthy")),
2023-05-10 15:06:57 +05:30
]
2023-08-08 10:13:50 +05:30
asset_id = models.ForeignKey(
Asset, on_delete=models.PROTECT, verbose_name=_("Asset")
2023-08-08 10:13:50 +05:30
)
assigned_to_employee_id = models.ForeignKey(
Employee,
on_delete=models.PROTECT,
related_name="allocated_employee",
verbose_name=_("Assigned To"),
2023-08-08 10:13:50 +05:30
)
2023-05-10 15:06:57 +05:30
assigned_date = models.DateField(auto_now_add=True)
2023-08-08 10:13:50 +05:30
assigned_by_employee_id = models.ForeignKey(
Employee,
on_delete=models.PROTECT,
related_name="assigned_by",
verbose_name=_("Assigned By"),
)
return_date = models.DateField(null=True, blank=True, verbose_name=_("Return Date"))
return_condition = models.TextField(
null=True, blank=True, max_length=255, verbose_name=_("Return Condition")
2023-08-08 10:13:50 +05:30
)
return_status = models.CharField(
choices=STATUS,
max_length=30,
null=True,
blank=True,
verbose_name=_("Return Status"),
2023-08-08 10:13:50 +05:30
)
return_request = models.BooleanField(default=False)
2023-12-01 15:36:51 +05:30
objects = HorillaCompanyManager("asset_id__asset_lot_number_id__company_id")
return_images = models.ManyToManyField(
ReturnImages, blank=True, related_name="return_images"
)
assign_images = models.ManyToManyField(
ReturnImages,
blank=True,
related_name="assign_images",
verbose_name=_("Assign Condition Images"),
)
objects = HorillaCompanyManager(
"assigned_to_employee_id__employee_work_info__company_id"
)
2024-02-07 13:00:09 +05:30
class Meta:
"""Meta class for AssetAssignment model"""
ordering = ["-id"]
verbose_name = _("Asset Allocation")
verbose_name_plural = _("Asset Allocations")
2024-02-07 13:00:09 +05:30
def __str__(self):
return f"{self.assigned_to_employee_id} --- {self.asset_id} --- {self.return_status}"
2023-08-08 10:13:50 +05:30
2023-05-10 15:06:57 +05:30
class AssetRequest(HorillaModel):
2023-08-21 17:25:49 +05:30
"""
Represents a request for assets made by employees.
"""
2023-08-08 10:13:50 +05:30
STATUS = [
("Requested", _("Requested")),
("Approved", _("Approved")),
("Rejected", _("Rejected")),
2023-05-10 15:06:57 +05:30
]
2023-08-08 10:13:50 +05:30
requested_employee_id = models.ForeignKey(
Employee,
2023-09-19 15:56:53 +05:30
on_delete=models.PROTECT,
2023-08-08 10:13:50 +05:30
related_name="requested_employee",
null=False,
blank=False,
verbose_name=_("Requesting User"),
2023-08-08 10:13:50 +05:30
)
[IMP] Remove inter module dependency (#274) 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
2024-08-05 14:22:44 +05:30
asset_category_id = models.ForeignKey(
AssetCategory, on_delete=models.PROTECT, verbose_name=_("Asset Category")
)
2023-05-10 15:06:57 +05:30
asset_request_date = models.DateField(auto_now_add=True)
description = models.TextField(
null=True, blank=True, max_length=255, verbose_name=_("Description")
)
2023-08-08 10:13:50 +05:30
asset_request_status = models.CharField(
max_length=30, choices=STATUS, default="Requested", null=True, blank=True
)
objects = HorillaCompanyManager(
"requested_employee_id__employee_work_info__company_id"
)
class Meta:
"""Meta class for AssetRequest model"""
ordering = ["-id"]
verbose_name = _("Asset Request")
verbose_name_plural = _("Asset Requests")
def status_html_class(self):
COLOR_CLASS = {
"Approved": "oh-dot--success",
"Requested": "oh-dot--info",
"Rejected": "oh-dot--danger",
}
LINK_CLASS = {
"Approved": "link-success",
"Requested": "link-info",
"Rejected": "link-danger",
}
status = self.asset_request_status
return {
"color": COLOR_CLASS.get(status),
"link": LINK_CLASS.get(status),
}