added parent is_productive field
This commit is contained in:
parent
3b4ae7a55a
commit
6ff3f05272
18
dispatcher/migrations/0007_parent_is_productive.py
Normal file
18
dispatcher/migrations/0007_parent_is_productive.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-02-02 16:35
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dispatcher', '0006_alter_parent_project_num'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='parent',
|
||||||
|
name='is_productive',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,38 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-02-02 17:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dispatcher', '0007_parent_is_productive'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='clocking',
|
||||||
|
name='in_am',
|
||||||
|
field=models.TimeField(default=None, null=True, verbose_name='Clock in AM'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='clocking',
|
||||||
|
name='in_pm',
|
||||||
|
field=models.TimeField(default=None, null=True, verbose_name='Clock in PM'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='clocking',
|
||||||
|
name='out_am',
|
||||||
|
field=models.TimeField(default=None, null=True, verbose_name='Clock out AM'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='clocking',
|
||||||
|
name='out_pm',
|
||||||
|
field=models.TimeField(default=None, null=True, verbose_name='Clock out PM'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='parent',
|
||||||
|
name='project_num',
|
||||||
|
field=models.CharField(blank=True, max_length=32, verbose_name='Project number'),
|
||||||
|
),
|
||||||
|
]
|
@ -1,8 +1,9 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class Parent(models.Model):
|
class Parent(models.Model):
|
||||||
project_num = models.CharField(max_length=32, blank=True)
|
project_num = models.CharField(max_length=32, blank=True, verbose_name="Project number")
|
||||||
name = models.CharField(max_length=256)
|
name = models.CharField(max_length=256)
|
||||||
|
is_productive = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -34,8 +35,8 @@ class Task(models.Model):
|
|||||||
|
|
||||||
class Clocking(models.Model):
|
class Clocking(models.Model):
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
in_am = models.TimeField(null=True, default=None)
|
in_am = models.TimeField(null=True, default=None, verbose_name="Clock in AM")
|
||||||
out_am = models.TimeField(null=True, default=None)
|
out_am = models.TimeField(null=True, default=None, verbose_name="Clock out AM")
|
||||||
in_pm = models.TimeField(null=True, default=None)
|
in_pm = models.TimeField(null=True, default=None, verbose_name="Clock in PM")
|
||||||
out_pm = models.TimeField(null=True, default=None)
|
out_pm = models.TimeField(null=True, default=None, verbose_name="Clock out PM")
|
||||||
remote = models.TimeField(null=True, default=None)
|
remote = models.TimeField(null=True, default=None)
|
@ -27,4 +27,27 @@ form label {
|
|||||||
form button {
|
form button {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
padding: 0.4em 1.2em;
|
padding: 0.4em 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
form input[type="checkbox"] {
|
||||||
|
width: 1.6em;
|
||||||
|
height: 1.6em;
|
||||||
|
border: solid var(--light1) 2px;
|
||||||
|
appearance: none;
|
||||||
|
background: none;
|
||||||
|
border-radius: 0;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
form input[type="checkbox"]:checked::after {
|
||||||
|
content: "";
|
||||||
|
background-color: #69c935;
|
||||||
|
width: 80%;
|
||||||
|
height: 80%;
|
||||||
|
border-radius: 10%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
@ -13,6 +13,7 @@
|
|||||||
marker: none;
|
marker: none;
|
||||||
gap: 0.8em;
|
gap: 0.8em;
|
||||||
border: solid var(--dark4) 1px;
|
border: solid var(--dark4) 1px;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list li .actions {
|
.list li .actions {
|
||||||
|
3
dispatcher/static/parents.css
Normal file
3
dispatcher/static/parents.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.productive {
|
||||||
|
box-shadow: 0.2em 0 0 #69c935 inset;
|
||||||
|
}
|
@ -127,11 +127,14 @@ class Table {
|
|||||||
weekTotalCell.colSpan = length
|
weekTotalCell.colSpan = length
|
||||||
}
|
}
|
||||||
|
|
||||||
addProject(id, name, sagexNum, times, isParent=false) {
|
addProject(id, name, sagexNum, times, isParent=false, isProductive=false) {
|
||||||
let row = this.times.insertRow(-1)
|
let row = this.times.insertRow(-1)
|
||||||
row.classList.add("project")
|
row.classList.add("project")
|
||||||
if (isParent) {
|
if (isParent) {
|
||||||
row.classList.add("parent")
|
row.classList.add("parent")
|
||||||
|
if (isProductive) {
|
||||||
|
row.classList.add("productive")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
row.dataset.id = id
|
row.dataset.id = id
|
||||||
row.insertCell(-1).innerText = name
|
row.insertCell(-1).innerText = name
|
||||||
@ -155,11 +158,13 @@ class Table {
|
|||||||
|
|
||||||
if (isParent) {
|
if (isParent) {
|
||||||
row.dataset.total = total
|
row.dataset.total = total
|
||||||
this.totalProjects += total
|
if (isProductive) {
|
||||||
row.insertCell(-1)
|
this.totalProjects += total
|
||||||
row.insertCell(-1)
|
}
|
||||||
row.insertCell(-1)
|
|
||||||
}
|
}
|
||||||
|
row.insertCell(-1)
|
||||||
|
row.insertCell(-1)
|
||||||
|
row.insertCell(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
addMonth(anchorDate) {
|
addMonth(anchorDate) {
|
||||||
@ -230,7 +235,8 @@ class Table {
|
|||||||
parent.name,
|
parent.name,
|
||||||
parent.project_num,
|
parent.project_num,
|
||||||
parentDurations.map(v => v === 0 ? "" : v),
|
parentDurations.map(v => v === 0 ? "" : v),
|
||||||
true
|
true,
|
||||||
|
parent.is_productive
|
||||||
)
|
)
|
||||||
|
|
||||||
projects.forEach(project => {
|
projects.forEach(project => {
|
||||||
@ -319,7 +325,7 @@ class Table {
|
|||||||
console.log("Total projects = 0")
|
console.log("Total projects = 0")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.times.querySelectorAll(".project.parent").forEach(parent => {
|
this.times.querySelectorAll(".project.parent.productive").forEach(parent => {
|
||||||
let total = +parent.dataset.total
|
let total = +parent.dataset.total
|
||||||
let workingTimeRatio = total / totalClockings
|
let workingTimeRatio = total / totalClockings
|
||||||
let imputedTimeRatio = total / totalProjects
|
let imputedTimeRatio = total / totalProjects
|
||||||
|
@ -70,7 +70,6 @@ def set_parent(request, id):
|
|||||||
return JsonResponse({"status": "success"})
|
return JsonResponse({"status": "success"})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def import_view(request):
|
def import_view(request):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = ImportForm(request.POST, request.FILES)
|
form = ImportForm(request.POST, request.FILES)
|
||||||
@ -168,6 +167,7 @@ def get_table_data(request, start_date: datetime.date, end_date: datetime.date):
|
|||||||
"id": parent.id,
|
"id": parent.id,
|
||||||
"name": parent.name,
|
"name": parent.name,
|
||||||
"project_num": parent.project_num,
|
"project_num": parent.project_num,
|
||||||
|
"is_productive": parent.is_productive,
|
||||||
"projects": [
|
"projects": [
|
||||||
{
|
{
|
||||||
"id": project.id,
|
"id": project.id,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
{% block main %}
|
{% block main %}
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
{% for element in elements %}
|
{% for element in elements %}
|
||||||
<li data-id="{{ element.id }}">
|
<li data-id="{{ element.id }}" class="{% block extra-class %}{% endblock %}">
|
||||||
{% block element %}{% endblock %}
|
{% block element %}{% endblock %}
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
{% block actions %}{% endblock %}
|
{% block actions %}{% endblock %}
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
{% block title %}Parents{% endblock %}
|
{% block title %}Parents{% endblock %}
|
||||||
{% block element_name %}parent{% endblock %}
|
{% block element_name %}parent{% endblock %}
|
||||||
{% block extra-head %}
|
{% block extra-head %}
|
||||||
|
<link rel="stylesheet" href="{% static "parents.css" %}">
|
||||||
<script src="{% static "parents.js" %}"></script>
|
<script src="{% static "parents.js" %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% block extra-class %}{% if element.is_productive %}productive{% endif %}{% endblock %}
|
||||||
{% block element %}
|
{% block element %}
|
||||||
<div class="name">{{ element.name }}</div>
|
<div class="name">{{ element.name }}</div>
|
||||||
<div class="project_num">({{ element.project_num }})</div>
|
<div class="project_num">({{ element.project_num }})</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user