You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
13 KiB
Python

from django.db import models
from django.contrib.auth.models import User
from colorfield.fields import ColorField
from datetime import datetime
from django.db.models import Max
from django.utils import timezone
from django.db.models import Sum, F
from datetime import timedelta
# Create your models here.
class Reference(models.Model):
name = models.CharField(max_length=50)
date = models.CharField(max_length=200)
def __str__(self):
return self.name
def formatted_date(self):
# Assuming start_date is stored as "day-month-year"
parts = self.date.split('-')
return f"{parts[2]}-{parts[1]}-{parts[0]}"
class Tag(models.Model):
name = models.CharField(max_length=50)
class BusinessType(models.Model):
name = models.CharField(max_length=50)
class Business(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField(unique=True)
financial_number = models.CharField(max_length=50)
vat = models.BooleanField(default=False)
commercial_registration = models.CharField(max_length=50)
phone_number = models.CharField(max_length=50)
website = models.URLField(null=True)
type = models.ForeignKey(BusinessType, on_delete=models.CASCADE, null=True, blank=True)
logo = models.ImageField()
business_id = models.CharField(max_length=20, null=True, blank=True) # Allow null and blank for initial creation
class Meta:
verbose_name_plural = u'Businesses'
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.business_id:
# Get the last two digits of the current year
current_year = str(datetime.now().year)[-2:]
# Find the maximum project ID in the database and increment it
max_id = Business.objects.aggregate(models.Max('business_id'))['business_id__max']
new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001'
self.business_id = 'B' + current_year + new_id # Add 'p' prefix
super(Business, self).save(*args, **kwargs)
class CustomerProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
mobile_number = models.CharField(max_length=50, blank=True)
personal_website = models.URLField(null=True, blank=True)
STATUS_CHOICES = (
('Active', 'Active'),
('Suspended', 'Suspended'),
('Terminated', 'Terminated'),
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES, blank=True)
reference = models.ForeignKey(Reference, on_delete=models.CASCADE, null=True, blank=True)
business = models.ForeignKey(Business, on_delete=models.CASCADE, null=True, blank=True)
customer_id = models.CharField(max_length=20, null=True, blank=True)
def __str__(self):
return self.user.username
def save(self, *args, **kwargs):
if not self.customer_id:
# Get the last two digits of the current year
current_year = str(datetime.now().year)[-2:]
# Find the maximum project ID in the database and increment it
max_id = CustomerProfile.objects.aggregate(models.Max('customer_id'))['customer_id__max']
new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001'
self.customer_id = current_year + new_id # Add 'p' prefix
super(CustomerProfile, self).save(*args, **kwargs)
class StaffPosition(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class StaffProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(null=True, blank=True)
mobile_number = models.CharField(max_length=50)
staff_position = models.ForeignKey(StaffPosition, on_delete=models.CASCADE, null=True, blank=True)
intern = models.BooleanField(default=False)
active = models.BooleanField(default=True)
staff_id = models.CharField(max_length=20, null=True, blank=True) # Allow null and blank for initial creation
def __str__(self):
return self.user.username
def save(self, *args, **kwargs):
if not self.staff_id:
# Get the last two digits of the current year
current_year = str(datetime.now().year)[-2:]
# Find the maximum project ID in the database and increment it
max_id = StaffProfile.objects.aggregate(models.Max('staff_id'))['staff_id__max']
new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001'
self.staff_id = 'O' + current_year + new_id # Add 'p' prefix
super(StaffProfile, self).save(*args, **kwargs)
class ProjectType(models.Model):
name = models.CharField(max_length=50)
class Project(models.Model):
name = models.CharField(max_length=50)
customer = models.ForeignKey(CustomerProfile, on_delete=models.CASCADE, null=True)
manager = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True)
project_type = models.ManyToManyField('ProjectType', default='', related_name='manager_project')
details = models.TextField()
members = models.ManyToManyField('StaffProfile', default='', related_name='members_project')
STATUS_CHOICES = (
('Active', 'Active'),
('Completed', 'Completed'),
('Pending', 'Pending'),
('Cancelled', 'Cancelled'),
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES)
start_date = models.CharField(max_length=200)
end_date = models.CharField(max_length=200)
project_id = models.CharField(max_length=20, null=True, blank=True) # Allow null and blank for initial creation
def save(self, *args, **kwargs):
if not self.project_id:
# Get the last two digits of the current year
current_year = str(datetime.now().year)[-2:]
# Find the maximum project ID in the database and increment it
max_id = Project.objects.aggregate(models.Max('project_id'))['project_id__max']
new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001'
self.project_id = 'P' + current_year + new_id # Add 'p' prefix
super(Project, self).save(*args, **kwargs)
class Milestone(models.Model):
title = models.CharField(max_length=150)
description = models.TextField()
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
start_date = models.DateField()
end_date = models.DateField()
class Epic(models.Model):
title = models.CharField(max_length=150)
STATUS_CHOICES = (
('Open', 'Open'),
('Closed', 'Closed')
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
description = models.TextField()
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
start_date = models.CharField(max_length=200)
end_date = models.CharField(max_length=200)
class ProjectRequirement(models.Model):
content = models.CharField(max_length=350)
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
date = models.DateField(null=True, auto_now=True)
added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
class ProjectFile(models.Model):
name = models.CharField(max_length=350)
file = models.FileField(blank=True)
date = models.DateField()
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
class ProjectCredential(models.Model):
emailorusername = models.CharField(max_length=350)
password = models.CharField(max_length=350)
usedfor = models.CharField(max_length=350)
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
class Note(models.Model):
text = models.TextField(blank=True)
date = models.DateTimeField(null=True,blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True,blank=True)
color = ColorField(default='#FF0000',blank=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True)
class Task(models.Model):
name = models.CharField(max_length=250)
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
epic = models.ForeignKey(Epic, on_delete=models.CASCADE, null=True)
requirement = models.ForeignKey(ProjectRequirement, on_delete=models.CASCADE, null=True, blank=True)
STATUS_CHOICES = (
('Open', 'Open'),
('Working On', 'Working On'),
('Closed', 'Closed')
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
status_date = models.DateTimeField(default=timezone.now)
extra = models.BooleanField(default=False)
description = models.TextField()
start_date = models.CharField(max_length=200)
end_date = models.CharField(max_length=200)
assigned_to = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True)
requirement = models.ForeignKey(ProjectRequirement, on_delete=models.SET_NULL, null=True)
task_id = models.CharField(max_length=20, null=True, blank=True)
def save(self, *args, **kwargs):
if not self.task_id:
# Get the last two digits of the current year
current_year = str(datetime.now().year)[-2:]
# Find the maximum project ID in the database and increment it
max_id = Task.objects.aggregate(models.Max('task_id'))['task_id__max']
new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001'
self.task_id = 'T' + current_year + new_id # Add 'p' prefix
if self.pk is not None:
original_task = Task.objects.get(pk=self.pk)
if original_task.status != self.status:
self.status_date = timezone.now()
super(Task, self).save(*args, **kwargs)
def formatted_start_date(self):
# Assuming start_date is stored as "day-month-year"
parts = self.start_date.split('-')
return f"{parts[2]}-{parts[1]}-{parts[0]}"
def formatted_end_date(self):
# Assuming end_date is stored as "day-month-year"
parts = self.end_date.split('-')
return f"{parts[2]}-{parts[1]}-{parts[0]}"
class Point(models.Model):
text = models.TextField(blank=True)
STATUS_CHOICES = (
('Not Completed', 'Not Completed'),
('Working On', 'Working On'),
('Paused', 'Paused'),
('Completed', 'Completed')
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
task = models.ForeignKey(Task, on_delete=models.CASCADE, null=True)
def total_time(self):
# Calculate the total time for ongoing activities
ongoing_total_time_timedelta = timedelta()
ongoing_activities = self.pointactivity_set.filter(end_time__isnull=True)
for activity in ongoing_activities:
start_time_aware = activity.start_time
current_time_aware = timezone.now()
ongoing_total_time_timedelta += current_time_aware - start_time_aware
# Calculate the total time for completed activities
completed_total_time_timedelta = self.pointactivity_set.filter(end_time__isnull=False).aggregate(
total_time=Sum(F('end_time') - F('start_time'))
)['total_time']
# Handle the case when there are no ongoing or completed activities
if not ongoing_activities.exists() and completed_total_time_timedelta is None:
return 0, 0, 0
# Add the total times together
total_time_timedelta = ongoing_total_time_timedelta + (completed_total_time_timedelta or timedelta())
# Convert total seconds to timedelta
total_time_timedelta = timedelta(seconds=total_time_timedelta.total_seconds())
# Extract hours, minutes, and seconds from timedelta
hours, remainder = divmod(total_time_timedelta.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# Return the total time as a tuple (hours, minutes, seconds)
return hours, minutes, seconds
class PointActivity(models.Model):
point = models.ForeignKey(Point, on_delete=models.CASCADE, null=True)
start_time = models.DateTimeField()
end_time = models.DateTimeField(null=True, blank=True)
class Status(models.Model):
text = models.TextField(blank=True)
date = models.CharField(max_length=40)
time = models.CharField(max_length=40)
staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True,blank=True, related_name='staff')
class DailyReport(models.Model):
text = models.TextField(blank=True)
date = models.CharField(max_length=40)
time = models.CharField(max_length=40)
staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True,blank=True, related_name='dailyreport_staff')