[PYTHON] Django shift table requires total daily working hours, overtime is overwritten

Looking at the shift table I am currently using, I checked whether it was necessary because there were working hours every day, and when the administrator was creating it, I heard that total time was necessary, so I changed the total field I will add it.

Consider having shift hours and overtime hours. It is possible to respond by entering a minus time when the shift time is less than the shift time when pulling early or late ...

Let's think about the merits of having it separately.

・ It is no longer necessary to have shift time in the field. ・ It seems that we can handle plus and minus ... ・ When copying the next month, you can copy except for overtime. ・ Easy overtime counting

Well, I feel like there is no decisive hit.

If you simply have it ・ Calculation processing is required when copying the next month ・ It is easy to understand overtime late because it directly corrects working hours. ・ Overtime calculation requires calculation processing

I have decided that there is not much merit to have.

Add fields to the model

python:schesule.models.py



from django.db import models
from shisetsu.models import *
from accounts.models import *
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator,MinValueValidator

# Create your models here.

class Shift(models.Model):
    id = models.AutoField(verbose_name='Shift ID',primary_key=True)
    name = models.CharField(verbose_name='Shift name', max_length=1)
    start_time = models.TimeField(verbose_name="Start time")
    end_time = models.TimeField(verbose_name="ending time")
    wrok_time = models.IntegerField(verbose_name='Working hours')

    def __str__(self):
        return self.name
    
class Schedule(models.Model):
    id = models.AutoField(verbose_name='Schedule ID',primary_key=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Employee name')
    date = models.DateField(verbose_name='date')
    year = models.PositiveIntegerField(validators=[MinValueValidator(1),])
    month = models.PositiveIntegerField(validators=[MaxValueValidator(12),MinValueValidator(1),])
    shift_name_1 = models.ForeignKey(Shift, verbose_name='1 shift name', related_name='shift_name1',on_delete=models.SET_NULL,null= True)
    shisetsu_name_1 = models.ForeignKey(Shisetsu, verbose_name='1 facility', related_name='shisetsu_name1',on_delete=models.SET_NULL,blank=True, null=True)
    shift_name_2 = models.ForeignKey(Shift, verbose_name='2 shift name', related_name='shift_name2',on_delete=models.SET_NULL,blank=True, null=True)
    shisetsu_name_2 = models.ForeignKey(Shisetsu, verbose_name='2 facilities', related_name='shisetsu_name2',on_delete=models.SET_NULL,blank=True, null=True)
    shift_name_3 = models.ForeignKey(Shift, verbose_name='3 shift name', related_name='shift_name3',on_delete=models.SET_NULL,blank=True, null=True)
    shisetsu_name_3 = models.ForeignKey(Shisetsu, verbose_name='3 facilities', related_name='shisetsu_name3',on_delete=models.SET_NULL,blank=True, null=True)
    shift_name_4 = models.ForeignKey(Shift, verbose_name='4 shift name', related_name='shift_name4',on_delete=models.SET_NULL,blank=True, null=True)
    shisetsu_name_4 = models.ForeignKey(Shisetsu, verbose_name='4 facilities', related_name='shisetsu_name4',on_delete=models.SET_NULL,blank=True, null=True)
    day_total_worktime = models.IntegerField(verbose_name='Daily working hours', default=0)) ###add to

Now that we've added the fields, we'll migrate

terminal


python3 manage.py makemigrations
python3 manage.py migrate

This completes the field! We will modify it so that the time is displayed from here. I want to go without any trouble, but I feel like something is happening (laughs)

First of all, I challenged to set the time every day. I don't understand html very much, so I can wrestle and display it for 2 to 3 hours.

The code is here.

schedule/month.html


{% extends 'schedule/base.html' %}
{% block header %}
{% endblock header %}

{% block content %}
<table class="table table-striped table-bordered">
<thead>
    <tr align="center" class="info">    <!--date-->
        <th rowspan="2"></th>
        {% for item in calender_object %}
                <th class="day_{{ item.date }}">{{ item.date | date:"d" }}</th>
        {% endfor %}
    <tr align="center" class="info">   <!--Day of the week-->
        {% for item in youbi_object %}
            <th class="day_{{ item.date }}">{{ item }}</th>
        {% endfor %}
    </tr>
</thead>
<tbody>
{% for staff in user_list %}
    <tr align="center">
    <th rowspan="2" class="staff_name" staff_id="{{ staff.staff_id }}" width="200" >{{ staff.last_name }} {{ staff.first_name }}</th>  <!--staff_id element used in js-->
            {% for item in object_list %} 
                {% if item.user|stringformat:"s" == staff.username|stringformat:"s" %}<!--If the username is the same-->
                    <td class="day" id="s{{ staff.id }}d{{ item.date }}"> 
                        {% if item.shift_name_1 != None %}
                            {% if item.shift_name_1|stringformat:"s" == "Yes" or item.shift_name_1|stringformat:"s" == "Closed" %}
                                {{ item.shift_name_1 }}
                            {% else %}
                                {% for shisetsu in shisetsu_object %}
                                    {% if item.shisetsu_name_1|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                        <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_1 }}</span>
                                    {% endif %}
                                {% endfor %} 
                            {% endif %}    
                        {% endif %}
                {% if item.shift_name_2 != None %}
                    {% if item.shift_name_2|stringformat:"s" == "Yes" or item.shift_name_2|stringformat:"s" == "Closed" %}
                        {{ item.shift_name_2 }}
                    {% else %}
                        {% for shisetsu in shisetsu_object %}
                            {% if item.shisetsu_name_2|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                    <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_2 }}</span>
                            {% endif %}
                        {% endfor %} 
                    {% endif %}    
                {% endif %}
                {% if item.shift_name_3 != None %}
                    {% if item.shift_name_3|stringformat:"s" == "Yes" or item.shift_name_3|stringformat:"s" == "Closed" %}
                        {{ item.shift_name_3 }}
                    {% else %}
                        {% for shisetsu in shisetsu_object %}
                            {% if item.shisetsu_name_3|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_3 }}</span>
                            {% endif %}
                        {% endfor %} 
                    {% endif %}    
                {% endif %}
                {% if item.shift_name_4 != None %}
                    {% if item.shift_name_4|stringformat:"s" == "Yes" or item.shift_name_4|stringformat:"s" == "Closed" %}
                        {{ item.shift_name_4 }}
                    {% else %}
                        {% for shisetsu in shisetsu_object %}
                            {% if item.shisetsu_name_4|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_4 }}</span>
                            {% endif %}
                        {% endfor %} 
                    {% endif %}    
                {% endif %}                   
            {% endif %}            
        {% endfor %}
        </td>

        <tr align="center">
            {% for item in object_list %} 
                {% if item.user|stringformat:"s" == staff.username|stringformat:"s" %}<!--If the username is the same-->
                    <td class="day" id="s{{ staff.id }}d{{ item.date }}">
                    {{ item.day_total_worktime }} 
                    </td>
            {% endif %}            
        {% endfor %}
    </tr>
{% endfor %}
</tbody>
</table>
{% endblock content %}

From here, I will put in the total of the day. When I looked it up, I heard that django has a function to aggregate totals. I checked the annotate function and added it to views.

schedule/views.py


#Add this
from django.db.models import Sum
from django.contrib.auth.models import User

#Put the total time of the month for each user in the dictionary type
month_total = Schedule.objects.select_related('User').filter(year = year, month = month).values("user").order_by("user").annotate(month_total_worktime = Sum("day_total_worktime"))

    context = {

        'month_total': month_total,
    }
    return render(request,'schedule/month.html', {
    'month_total' : month_total,
    }, )

Pass it to the html template and modify the html to display it in html

schedule/month.py



{% extends 'schedule/base.html' %}
{% block header %}
{% endblock header %}

{% block content %}
<table class="table table-striped table-bordered">
<thead>
    <tr align="center" class="info">    <!--date-->
        <th rowspan="2"></th>
        {% for item in calender_object %}
                <th class="day_{{ item.date }}">{{ item.date | date:"d" }}</th>
        {% endfor %}
    <tr align="center" class="info">   <!--Day of the week-->
        {% for item in youbi_object %}
            <th class="day_{{ item.date }}">{{ item }}</th>
        {% endfor %}
    </tr>
</thead>
<tbody>
{% for staff in user_list %}
    <tr align="center">
    <th rowspan="1" class="staff_name" staff_id="{{ staff.staff_id }}" width="200" >{{ staff.last_name }} {{ staff.first_name }}</th>  <!--staff_id element used in js-->
            {% for item in object_list %} 
                {% if item.user|stringformat:"s" == staff.username|stringformat:"s" %}<!--If the username is the same-->
                    <td class="day" id="s{{ staff.id }}d{{ item.date }}"> 
                        {% if item.shift_name_1 != None %}
                            {% if item.shift_name_1|stringformat:"s" == "Yes" or item.shift_name_1|stringformat:"s" == "Closed" %}
                                {{ item.shift_name_1 }}
                            {% else %}
                                {% for shisetsu in shisetsu_object %}
                                    {% if item.shisetsu_name_1|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                        <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_1 }}</span>
                                    {% endif %}
                                {% endfor %} 
                            {% endif %}    
                        {% endif %}
                {% if item.shift_name_2 != None %}
                    {% if item.shift_name_2|stringformat:"s" == "Yes" or item.shift_name_2|stringformat:"s" == "Closed" %}
                        {{ item.shift_name_2 }}
                    {% else %}
                        {% for shisetsu in shisetsu_object %}
                            {% if item.shisetsu_name_2|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                    <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_2 }}</span>
                            {% endif %}
                        {% endfor %} 
                    {% endif %}    
                {% endif %}
                {% if item.shift_name_3 != None %}
                    {% if item.shift_name_3|stringformat:"s" == "Yes" or item.shift_name_3|stringformat:"s" == "Closed" %}
                        {{ item.shift_name_3 }}
                    {% else %}
                        {% for shisetsu in shisetsu_object %}
                            {% if item.shisetsu_name_3|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_3 }}</span>
                            {% endif %}
                        {% endfor %} 
                    {% endif %}    
                {% endif %}
                {% if item.shift_name_4 != None %}
                    {% if item.shift_name_4|stringformat:"s" == "Yes" or item.shift_name_4|stringformat:"s" == "Closed" %}
                        {{ item.shift_name_4 }}
                    {% else %}
                        {% for shisetsu in shisetsu_object %}
                            {% if item.shisetsu_name_4|stringformat:"s" == shisetsu.name|stringformat:"s" %}                          
                                <span style="background-color:{{ shisetsu.color }}">{{ item.shift_name_4 }}</span>
                            {% endif %}
                        {% endfor %} 
                    {% endif %}    
                {% endif %}                   
            {% endif %}            
        {% endfor %}
        </td>

        <tr align="center">
            {% for month in month_total %} 
                {% if month.user ==  staff.id %}<!--If the username is the same-->
                    <td><b>{{ month.month_total_worktime }}</b></td>
                {% endif %}
            {% endfor %}
            {% for item in object_list %} 
                {% if item.user|stringformat:"s" == staff.username|stringformat:"s" %}<!--If the username is the same-->
                    <td class="day" id="s{{ staff.id }}d{{ item.date }}">
                    {{ item.day_total_worktime }} 
                    </td>
            {% endif %}            
        {% endfor %}
    </tr>
{% endfor %}
</tbody>
</table>
{% endblock content %}

html was done after fighting for 1-2 hours!

Click here for results

image.png

No, it feels good! I feel that it is necessary to change the line to a thick line for each staff member and make fine adjustments, but it is great that what I was thinking of becomes a shape!

Recommended Posts

Django shift table requires total daily working hours, overtime is overwritten
Django Python shift table