Count the leave days and display them in django admin model - django

I am learning django or a month now. I created a model called "Leave" to mark employees leave. Then I created a model called "Salarie".In this I need to create a field like "Total_Leave" which will show an employees leave count in a month.( In january 2020 how many leave a particular employee took) ( If i mention the "Employee_Name" as "Samantha" in salary model, it need to show samantas' leave in the particular month,year)
I tried to do it like this and tried some coding but nothing worked.
#property
def Total_Leave(self):
return self.
Can anyone explain me how to do that please?
Models.py
class Leave(models.Model):
Leave_ID = models.CharField(max_length=5, primary_key=True,default=" ")
Employee_Name = models.ForeignKey('Employee_Detail',models.DO_NOTHING)
Dept_Name = models.ForeignKey('Department', models.DO_NOTHING)
l = (
("Paid","Paid"),("Non-Paid","Non-Paid")
)
Leave_Type = models.CharField(max_length=10, choices= l, default="Non-Paid")
m = (
("January","January"),("February","February"),("March","March"),("April","April"),("May","May"),("June","June"),("July","July"),("August","August"),("September","September"),("October","October"),("November","November"),("December","december")
)
Month = models.CharField(max_length=10, choices= m)
Year = models.IntegerField(max_length=4)
Start_Date = models.DateField()
End_Date = models.DateField(null=True, blank = True)
Reason = models.CharField(max_length=200)
s = (
("Accepted","Accepted"),("Pending","Pending"),("Canceled","Canceled")
)
Status = models.CharField(max_length=10, choices= s, default="Pending")
def __str__(self):
return str(self.Employee_Name)
class Salarie(models.Model):
Salarie_ID = models.CharField(max_length=5,primary_key=True,default=" ")
Employee_Name = models.ForeignKey('Employee_Detail', models.DO_NOTHING)
Dept_Name = models.ForeignKey('Department', models.DO_NOTHING)
Basic_Salary = models.IntegerField(default=0)
Extra_Hours = models.IntegerField(default=0)
#property
def Extra_Payment(self):
return self.Extra_Hours * 350
Bonus = models.IntegerField(default=0)
#property
def Total_Payment(self):
return self.Extra_Payment + self.Basic_Salary + self.Bonus
m = (
("January","January"),("February","February"),("March","March"),("April","April"),("May","May"),("June","June"),("July","July"),("August","August"),("September","September"),("October","October"),("November","November"),("December","december")
)
Month = models.CharField(max_length=10, choices= m)
Year = models.IntegerField(max_length=4)
Status = models.BooleanField()
Paid_Date = models.DateField(null=True,blank=True)
def __str__(self):
return str(self.Employee_Name)
class Employee_Detail(models.Model):
Employee_ID = models.CharField(primary_key=True, max_length=6)
Employee_Name = models.CharField(unique=True, max_length=30)
Primary_Phone = models.IntegerField(unique=True, max_length=10)
p = (
("Manager","Manager"),("Supervisor","Supervisor"),("Employee","Employee")
)
Position = models.CharField(max_length=15, choices= p, default="Employee")
Address = models.TextField(max_length=500)
Email = models.EmailField(max_length=50, unique=True)
def __str__(self):
return str(self.Employee_Name)

You can do this by using annotate or aggregate
If you want leave count for all the employees then
from django.db.models import Count
employees = Employee_Detail.objects.filter(leave__Status='Accepted').annotate(leave_count=Count('leave'))
you can access this by <employee Obj>.leave_count
If you want leave count for all employee order_by Month then
employees = Employee_Detail.objects.filter(leave__Status='Accepted').order_by('leave__Month').annotate(leave_count=Count('leave')).values('leave_Month','leave_count')
And last you want leave count for a particular employee for a particular month than in your employee model write #property function like this
#property
def get_leave_count(self):
leaves = Employee_Detail.objects.filter(id=self.id,leave__Status='Accepted').aggregate(leave_count=Count('leave'))
return leaves['leave_count']
for month and year wise provide month and year and then
month = 'January' #For example
leaves = Employee_Detail.objects.filter(id=employee_id,leave__Month=month,leave__Status='Accepted').aggregate(leave_count=Count('leave'))
#{'leave_count':3}
year = '2020' #For example
leaves = Employee_Detail.objects.filter(id=employee_id,leave__Year=year,leave__Status='Accepted').aggregate(leave_count=Count('leave'))
#{'leave_count':13}

I tried something like this, maybe of some use.
def total_leave(emp_name,month,year):
leaves = Leave.objects.filter(Emp_name= emp_name,Month=month,Year=year)
Count=0
for leave in leaves:
if leaves.status== "Accepted":
Count +=1
return Count
Like if you only need to get leave count for the year, just use year as a parameter for function.

Related

How to import a object of another model (A) inside model (B) in Django?

I want to create a new object in ModelB when specific condition are met in ModelA. I am new to Django so that I am unable to figure out how exactly I can achieve this.
For example I have two models(Product and ProductVariant), when specific condition on ProductVariant is met then I want to calculate new object value in Product model.
My Product model is like this:
PRODUCT_TYPE = (
('s', 'simple'),
('v', 'varaible')
)
class Products(models.Model):
name = models.CharField(max_length=250,null=True, blank=True,)
slug = models.SlugField(max_length=200, unique=True,null=True)
short_description = HTMLField()
description = HTMLField()
category = models.ForeignKey(Categories, related_name="products",on_delete=models.SET_NULL,null=True,blank=True,)
brand = models.ForeignKey(Brands,on_delete=models.CASCADE, default=None, null=True, blank=True,)
warranty_support = HTMLField()
product_type = models.CharField(choices=PRODUCT_TYPE, default='simple', max_length=50)
And my Product Attribute Model is like this:
class ProductVariant(models.Model):
product = models.ForeignKey(Products,on_delete=models.CASCADE)
variant = models.ForeignKey(ProductAttribute,on_delete=models.CASCADE, null = True, default=None)
managed_stock = models.IntegerField(choices=STOCK_MANAGED, default=0)
stock = models.IntegerField(default=None)
stock_threshold = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
sku = models.CharField(max_length= 250, default=None)
sale_price = models.DecimalField(max_digits=10, decimal_places=2)
sale_start_date=models.DateField(auto_now_add=False, auto_now=False, default=None)
sale_end_date=models.DateField(auto_now_add=False, auto_now=False,default=None)
I am trying to create regular_price and sale_price on Product model if product_type is variable and if sale_end_date is greater than today. I want to set the price from the variant which has the lowest price.
I tried doing like this on Product model:
def clean(self):
if self.product_type == 'varaible' and ProductVariant.objects.filter(product=self, variant_count__gt = 1):
self.min_price = ProductVariant.objects.filter(product=self).Min('price')
self.max_price = ProductVariant.objects.filter(product=self).Max('price')
but I am not able to achieve what I want,
How can I do this?
After some research and analysis I found solution to my problem, I am posting the solution here so that someone with similar problem could be benefited.
#property
def get_price(self):
result = dict()
variants = ProductVariant.objects.filter(product=self)
count = variants.count()
if count > 1:
min_variant = variants.order_by('price').first()
max_variant = variants.order_by('-price').first()
result['min_price'] = min_variant.price
result['max_price'] = max_variant.price
elif count == 1:
variant = variants.first()
if variant.sale_price:
result['price'] = variant.price
result['sale_price'] = variant.sale_price
sale_variant = variants.order_by('sale_price').first()
result['lowest_sale_price'] = sale_variant.sale_price
result['regular_price'] = sale_variant.price
today = datetime.date.today()
if variant.sale_start_date <= today and variant.sale_end_date >= today:
result['sale_end_date'] = variant.sale_end_date
else:
result['price'] = variant.price

Django: multply, sum and groupby using two models

Good day,
I am trying to build a system that creates an order and allows a user to add pieces. Here are the two models:
class Order(models.Model):
order_slug = models.SlugField(unique=True, blank=True)
machine = models.ForeignKey(Machine, blank=True,on_delete=models.DO_NOTHING)
production_type = models.CharField(choices=PRODUCTION_TYPE_CHOICES, max_length=30)
production_bond = models.CharField(choices=PRODUCTION_BOND_CHOICES, max_length=50)
profile = models.CharField(choices=PROFILE_CHOICES, max_length=50)
order_number = models.CharField(max_length=50)
order_colour = models.CharField(choices=ORDER_COLOUR_CHOICES, max_length=50)
order_finish = models.CharField(choices=ORDER_FINISH_CHOICES, max_length=10)
order_gauge = models.IntegerField(choices=ORDER_GAUGE_CHOICES)
order_width = models.IntegerField()
date_received = models.DateTimeField(default=datetime.now)
class Meta:
ordering = ["date_received", "-profile"]
def __str__(self):
return (str(self.order_slug))
class Piece(models.Model):
order = models.ForeignKey(Order,on_delete=models.CASCADE)
coil = models.ForeignKey(Cut_Material ,on_delete=models.CASCADE)
piece_length = models.DecimalField(max_digits=4, decimal_places=2)
prime_pieces = models.IntegerField()
reject_pieces = models.IntegerField()
coil_constant = models.IntegerField(blank=True)
def __str__(self):
return (str(self.piece_length))
class Meta:
ordering = ["-order","piece_length"]
Here is what I want to do.
Multiply the prime_pieces by the piece_length to get running_meters for each column
I want to group the pieces by order_gauge, order_number, and sum the running_meters.
Proposed solution
piece = Piece.objects.all()
order = Order.objects.all()
For step 1
rm_data = Piece.objects.annotate(running_meters=ExpressionWrapper(F('piece_length') * F('prime_pieces'), output_field=FloatField())).values()
For step 2
I am not sure
Can someone help me please?
I have tried this and it seems to work after scratching my head:
order.values('order_number','order_gauge').annotate(
running_meters=Sum(ExpressionWrapper(F('piece__piece_length')*F('piece__prime_pieces'),output_field=FloatField())))

Getting list of many to many objects

class Team(models.Model):
team_name = models.CharField(max_length=50, null=False)
def __str__(self):
return self.team_name
class Tournament(models.Model):
types = (
('Round', 'Round'),
('Knockout', 'Knockout'),
)
teams = models.ManyToManyField(Team, related_name='tournament_teams')
tournament_name = models.CharField(max_length=50, null=False)
tournament_type = models.CharField(choices=types, max_length=40, null=False)
def __str__(self):
return self.tournament_name
class MatchRound(models.Model):
team_a_id = models.ForeignKey(Team, related_name="team_a")
team_b_id = models.ForeignKey(Team)
date = models.DateTimeField(null=True)
team_a_score = models.IntegerField(null=True)
team_b_score = models.IntegerField(null=True)
tournament_id = models.ForeignKey(Tournament, on_delete=models.CASCADE, null=True)
#receiver(post_save, sender=Tournament)
def create_match_round(sender, **kwargs):
type = kwargs.get('instance').tournament_type
if type == 'Round' and kwargs.get('created', False):
teams = kwargs.get('instance').teams.all()
schedule = create_schedule(teams)
for round in schedule:
for match in round:
team_a_id = match[0]
team_b_id = match[1]
tournament_id = kwargs.get('instance')
game = MatchRound.objects.create(team_a_id=team_a_id, team_b_id=team_b_id,
tournament_id=tournament_id)
I am trying to create a schedule for a tournament. So, I set up a trigger on MatchRound model and I am trying to get the teams of the tournament when it's created. However, the following line
teams = kwargs.get('instance').teams.all()
returns to an empty query set. I couldn't figure it out the problem.

how to filter values_list in django

class Office(models.Model):
person = models.ForeignKey(Person, verbose_name="Person")
department = models.ForeignKey(Department, verbose_name="Department")
office_desc = models.CharField('Office', max_length=100,unique=True)
office_acronym = models.CharField('Office Acronym', max_length=20,blank=True,help_text="Add acronym if any, not required")
location = models.CharField('Location',max_length=100,blank=True)
trunkline = models.CharField('Trunk Line',max_length=30,blank=True)
directline = models.CharField('Direct Line',max_length=30,blank=True)
localnumber = models.CharField('Local Number',max_length=30,blank=True)
telefax = models.CharField('Telefax',max_length=30,blank=True)
active = models.BooleanField('Active',default=True)
class Department(models.Model):
department_desc = models.CharField('Department', max_length=100,unique=True)
department_acronym = models.CharField('Department Acronym', max_length=20,blank=True,help_text="Add acronym if any, not required")
active = models.BooleanField('Active',default=True)
class Person(models.Model):
GENDER = (
('M','Male'),
('F','Female'),
)
first_name = models.CharField("First Name", max_length=100)
last_name = models.CharField("Last Name",max_length=100)
middle_name = models.CharField("Middle Name", max_length=100, blank=True)
salutation = models.ForeignKey(Salutation, verbose_name="Salutation", null=True, blank=True) #
suffix_name = models.ManyToManyField(SuffixName, verbose_name="Suffix Name",null=True, blank=True) #
job_title = models.ManyToManyField(JobTitle, verbose_name="Job Title",null=True, blank=True) #
gender = models.CharField(max_length=1, choices=GENDER,default='Male')
birthdate = models.DateField('Birthdate',null=True,blank=True)
image = models.ImageField('Image',upload_to='persons',blank=True)
email = models.EmailField('Email',blank=True)
street = models.CharField('Street',max_length=100, blank=True)
brgy = models.CharField('Barangay',max_length=100, blank=True)
town_city = models.CharField('Town/City',max_length=100, blank=True)
zip_code = models.IntegerField('ZIP Code',null=True, blank=True)
department = models.ManyToManyField(Department, verbose_name="Department",null=True, blank=True) #
office = models.ManyToManyField(Office, verbose_name="Office", null=True, blank=True) #
sql_query
select pd.department_desc, pp.last_name, o.office_desc from person_person as pp
INNER JOIN person_person_department as ppd on pp.id = ppd.person_id
INNER JOIN person_department as pd on pd.id = ppd.id
INNER JOIN person_office as o on o.department_id = pd.id
where pd.department_desc = 'Executive'
views code:
per = Person.objects
qry_name = per.values_list('salutation__salutation_desc','first_name','middle_name','last_name', 'office__office_desc', 'office__location','office__localnumber','office__trunkline','office__directline','office__telefax').filter(department__department_desc='Executive')
Result: query result includes person with different department
Expected result: only person with Executive department
If I query directly from the database I get the correct result but when I translate the query into django code it's returning different queryset. Query returns ok if certain person has a single office but if a person has multiple office thats where the inconsistency starts .Query returns list with different description other than what was specified. Am I doing the translation of the query to python right?
A closer representation of the sql query would be:
from django.db.models import F
qry_name = Person.objects.filter(
department__department_desc='Executive',
office__department=F('department')
).values_list(<..FIELDS..>)
Let know if this works.

Get Foreign Key Value

How can I get the foreign key values? I have a common vehicle model that links to the year, series, engine type, body style, transmission and drive train...all as foreign keys. I'd like to get the values of these fields for my app, but I'm stuck as to how I'd go about them. Any ideas will be highly appreciated.
class Model(models.Model):
model = models.CharField(max_length=15, blank=False)
manufacturer = models.ForeignKey(Manufacturer)
date_added = models.DateField()
def __unicode__(self):
name = ''+str(self.manufacturer)+" "+str(self.model)
return name
class Year(models.Model):
ALPHA_NUMERIC_CHOICES = (
('1', 'Numeric'),
('A', 'Alphabetic'),
)
year = models.PositiveSmallIntegerField()
position_7_char = models.CharField(max_length=1, choices=ALPHA_NUMERIC_CHOICES)
position_10 = models.CharField(max_length=1, blank=False)
def __unicode__(self):
return unicode(self.year)
class Series(models.Model):
series = models.CharField(max_length=20, blank=True)
model = models.ForeignKey(Model)
date_added = models.DateField()
def __unicode__(self):
name = str(self.model)+" "+str(self.series)
return name
class CommonVehicle(models.Model):
year = models.ForeignKey(Year)
series = models.ForeignKey(Series)
engine = models.ForeignKey(Engine)
body_style = models.ForeignKey(BodyStyle)
transmission = models.ForeignKey(Transmission)
drive_train = models.ForeignKey(DriveTrain)
def __unicode__(self):
name = ''+str(self.year)+" "+str(self.series)
return name
class Vehicle(models.Model):
stock_number = models.CharField(max_length=6, blank=False)
vin = models.CharField(max_length=17, blank=False)
common_vehicle = models.ForeignKey(CommonVehicle)
exterior_colour = models.ForeignKey(ExteriorColour)
interior_colour = models.ForeignKey(InteriorColour)
interior_type = models.ForeignKey(InteriorType)
odometer_unit = models.ForeignKey(OdometerUnit)
status = models.ForeignKey(Status)
odometer_reading = models.PositiveIntegerField()
selling_price = models.PositiveIntegerField()
purchase_date = models.DateField()
sales_description = models.CharField(max_length=60, blank=False)
def __unicode__(self):
return self.stock_numberodels.ForeignKey(CommonVehicle)
You need the actual IDs? Try something like my_vehicle_ref.series.id.
Also, I hope you know that the series attribute right there is really an instance of Series, so you could access any of it's properties, e.g., my_vehicle_ref.series.model.model.