This commit is contained in:
holger.trampe 2021-02-19 12:01:09 +01:00
parent f78a6a68f5
commit 6fcdbce2aa
20 changed files with 162 additions and 34 deletions

View File

@ -17,6 +17,7 @@ class MainStatistic(models.Model):
allfiles = models.IntegerField(default=0)
allfiles_storage = models.FloatField(default=0.0)
logins = models.IntegerField(default=0)
mrr = models.FloatField(default=0.0)
class MainSalesMonth(models.Model):
salesmonthdate = models.DateField(default=timezone.now)

View File

@ -1,6 +1,7 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load adm_tags %}
{% load humanize %}
{% load mathfilters %}
<div class="content-section col-12">
{% if statistik|length > 0 %}
@ -15,6 +16,9 @@
<canvas id="all_stats"></canvas>
</div>
<hr>
{% getMRR as finalmrr %}
<h5>MRR: {{finalmrr|floatformat:2|intcomma}} €</h5>
<hr>
<h5>Monatliche Umsätze</h5>
<table>
<thead>
@ -99,6 +103,16 @@ new Chart(document.getElementById("all_stats"),{
"borderColor":"#FA746A",
"lineTension":0.1
},
{"label":"MRR",
"data":[
{% for ele in statistik %}
{{ele.mrr|stringformat:".2f"}},
{% endfor %}
],
"fill":false,
"borderColor":"#FA746A",
"lineTension":0.1
},
{"label":"Chatnachrichten",
"data":[
{% for ele in statistik %}

View File

@ -70,6 +70,25 @@ def loadBillValue(bill):
return returnvalue
'''
Hier wird der aktuelle Umsatz berechnet anhand Abos und Mitarbeiterzahlen
'''
@register.simple_tag
def getMRR():
# Berechnung das MRR
finalmrr = 0
allag_withabo = Agency.objects.filter(paymentplan=1)
abos = len(allag_withabo) * 21
extrausercount = 0
for ag in allag_withabo:
user_ag = User.objects.filter(profile__agency=ag)
if len(user_ag) > 3:
extrausercount += len(user_ag) - 3
finalmrr = abos + 3*extrausercount
return finalmrr

View File

@ -503,7 +503,19 @@ def statisticCronJob(request, code):
nm = MainSalesMonth(value=monthvalue, salesmonthdate=lastmonth)
nm.save()
newMainS = MainStatistic(agencys=agencycount,users=usercount,standards=standardcount,chatmessages=chatmesscount, active_abos=abocount, absenceobjects=absenceobjects, user_active_timemanagement=user_active_timemanagement, organizerobjects=organizerobjects, agency_recoverobjects=agency_recoverobjects, allfiles=allfiles, allfiles_storage=allfiles_storage, logins=logins)
# Monatlicher MRR
finalrma = 0
allag_withabo = Agency.objects.filter(paymentplan=1)
abos = len(allag_withabo) * 21
extrausercount = 0
for ag in allag_withabo:
user_ag = User.objects.filter(profile__agency=ag)
if len(user_ag) > 3:
extrausercount += len(user_ag) - 3
finalmrr = abos + 3*extrausercount
newMainS = MainStatistic(agencys=agencycount,users=usercount,standards=standardcount,chatmessages=chatmesscount, active_abos=abocount, absenceobjects=absenceobjects, user_active_timemanagement=user_active_timemanagement, organizerobjects=organizerobjects, agency_recoverobjects=agency_recoverobjects, allfiles=allfiles, allfiles_storage=allfiles_storage, logins=logins, mrr=finalmrr)
newMainS.save()
data.update({"status" : "success"})
else:

View File

@ -22,7 +22,7 @@ class AgencyNetworkForm(forms.ModelForm):
fields = ['name', 'publicjoin']
labels = {
"name" : "Name des Agentuverbunds",
"name" : "Name des Agenturverbunds",
"publicjoin" : "Beitritt ohne Bestätigung"
}

BIN
dump.rdb

Binary file not shown.

View File

@ -243,10 +243,12 @@
</div>
</div></div>
<p>Wenn ein Standard erstellt/bearbeitet wurde, kann er nur von einer Person mit dem Recht <i>Standards bearbeiten und freischalten</i> veröffentlicht werden.</p>
{% if perms.users.standardmanager %}
{{ normalForm.public }} Veröffentlichen
{% if perms.users.standardgopublic %}
<p>{{ normalForm.public }} Veröffentlichen</p>
{% else %}
<p>Wenn ein Standard erstellt/bearbeitet wurde, kann er nur von einer Person mit dem Recht <i>Standards freischalten</i> veröffentlicht werden.</p>
{% endif %}
<hr>

View File

@ -137,7 +137,7 @@
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
</a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
{% if perms.users.standardmanager %}
{% if perms.users.standardgopublic %}
{% if standard.public %}
<a class="dropdown-item" href="{% url 'standard-status' standard.pk %}">Veröffentlichung aufheben</a>
{% else %}
@ -148,9 +148,9 @@
{% endif %}
{% if standard.created_standard_by == request.user or perms.users.standardmanager %}
<a class="dropdown-item" href="{% url 'standard-add' standard.pk %}">Bearbeiten</a>
{% endif %}
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="{% url 'standard-delete' standard.pk %}" >Löschen</a>
{% endif %}
</div>
</div>
</td>

View File

@ -64,11 +64,25 @@ def getbool():
global groupbool
return groupbool
# Zähler ungelesener Nachrichten
@register.simple_tag
def getmesscounter(user):
return len(Message.objects.filter(target_user=user))
# Zähler unveröffentlichter Standards
@register.simple_tag
def getUnpubStandards(user):
unpubstandards = 0
if user.has_perm("users.standardgopublic"):
unpubstandards = len(Standards.objects.filter(agency=user.profile.agency, public=False))
return unpubstandards
@register.simple_tag
def getAbsenceAsks(user):
unconfirmedab = len(Absence.objects.filter(agency=user.profile.agency, confirm_status=1))
return unconfirmedab
# WORKDAY HISTORY
# TASK: Hier flag prüfen, ob der User selbst den Tag bearbeitet hat - aktuell werden nur fremde Änderugnen angezeigt
@register.simple_tag
@ -291,6 +305,16 @@ def getifuserdidcomment(standard, user):
return didcomment
'''
Hier wird der dynamische Steckbrief generiert. Es wird geprüft, ob Nutzer in Standards verlinkt sind bzw. in Gruppen
representative_group = models.ManyToManyField(AgencyGroup, blank=True, related_name="group_rep")
executor_group = models.ManyToManyField(AgencyGroup, blank=True, related_name="group_ex")
authority_group = models.ManyToManyField(AgencyGroup, blank=True, related_name="group_aut")
'''
@register.simple_tag
def isUserInAuth(task, area, user_id):
@ -300,10 +324,19 @@ def isUserInAuth(task, area, user_id):
#st_auth = Standards.objects.filter(agency=user.profile.agency, task=task, area=area)
st_auth = Standards.objects.filter(agency=user.profile.agency, task=task, area=area, authority__in=[user])
found = False
user_to_check = User.objects.get(pk=user_id)
if len(st_auth) > 0:
found = True
# Wenn der User noch nicht gefunden wurde, werden die Gruppen der Standards durchgearbeitet
if found == False:
standards_to_check = Standards.objects.filter(agency=user.profile.agency, task=task, area=area)
for s in standards_to_check:
for group in s.authority_group.all():
if user.groups.filter(name = group.group.name).exists():
found = True
return found
@register.simple_tag
@ -320,6 +353,14 @@ def isUserInEx(task, area, user_id):
if len(st_auth) > 0:
found = True
# Wenn der User noch nicht gefunden wurde, werden die Gruppen der Standards durchgearbeitet
if found == False:
standards_to_check = Standards.objects.filter(agency=user.profile.agency, task=task, area=area)
for s in standards_to_check:
for group in s.executor_group.all():
if user.groups.filter(name = group.group.name).exists():
found = True
return found
@ -335,6 +376,14 @@ def isUserInRep(task, area, user_id):
if len(st_auth) > 0:
found = True
# Wenn der User noch nicht gefunden wurde, werden die Gruppen der Standards durchgearbeitet
if found == False:
standards_to_check = Standards.objects.filter(agency=user.profile.agency, task=task, area=area)
for s in standards_to_check:
for group in s.representative_group.all():
if user.groups.filter(name = group.group.name).exists():
found = True
return found
# REALTIME
@ -1051,13 +1100,8 @@ def getTrialDays(agency):
return finaldays
@register.simple_tag
def getAbsenceLastHistory(absence):
return absence.history.first()

View File

@ -16,6 +16,8 @@ class Workday(models.Model):
end = models.DateTimeField(default=None, null=True, blank=True)
target = models.FloatField(default=8.0)
freefield = models.TextField(max_length=10000, default="", blank=True)
lastManualChangeUser = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, default=None, related_name="manuelChangeUser")
lastManualChangeDate = models.DateTimeField(default=None, null=True, blank=True)
history = HistoricalRecords()
class Breaks(models.Model):

View File

@ -9,7 +9,7 @@
<hr>
{% if user|usergperm:"absencemanager" %}
{% if user|usergperm:"timemanager" %}
<div>
<ul class="nav nav-tabs " id="absencetabs" role="tablist" >
{% if user.usertime.usetime == True %}
@ -287,6 +287,9 @@ $('#absencetabs a').on('click', function (e) {
$('#confirm-delete_{{workday.pk}}').on('hidden.bs.modal', function (e) {
$("#errorDelWorkday").modal("toggle");
});
},
error: function(xhr){
location.href = location.href;
}
});
});

View File

@ -44,8 +44,7 @@
{% else %}
{% for workday in workdays %}
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
{% getWorkDayHistory workday as wd_history %}
{% if wd_history.history_user != None %}
{% if workday.lastManualChangeUser != None %}
style="background-color: #fdcc98;"
{% endif %}
{% endif %}

View File

@ -51,8 +51,7 @@
{% else %}
{% for workday in workdays %}
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
{% getWorkDayHistory workday as wd_history %}
{% if wd_history.history_user != None %}
{% if workday.lastManualChangeUser != None %}
style="background-color: #fdcc98;"
{% endif %}
{% endif %}
@ -312,9 +311,8 @@
{% endif %}
{% counterWDUp %}
{% getWorkDayHistory workday as wd_history %}
{% if wd_history.history_user != None %}
{% if workday.lastManualChangeUser != None %}
<a href="#/" onclick="javascript:$('#wd_history_{{workday.pk}}').modal('toggle');"><i class="fas fa-user-edit"></i></a>
<div class="modal fade" id="wd_history_{{workday.pk}}" tabindex="-1" role="dialog" data-backdrop="static">
@ -327,7 +325,7 @@
</button>
</div>
<div class="modal-body" style="text-align: left;">
<p>Geändert am {{wd_history.history_date|date:"d.m.Y, H:i"}} von {{wd_history.history_user.first_name}} {{wd_history.history_user.last_name}}</p>
<p>Geändert am {{workday.lastManualChangeDate|date:"d.m.Y, H:i"}} von {{workday.lastManualChangeUser.first_name}} {{workday.lastManualChangeUser.last_name}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Schließen</button>

View File

@ -38,19 +38,34 @@
{{form.representator|as_crispy_field}}
</div>
</div>
<div class="row">
<div class="col-12">
<h5>Begründung</h5>
<p>{{absence.info}}</p>
<p>{% if absence.info|length > 0 %}
{{absence.info}}
{% else %}
Keine Begründung
{% endif %}</p>
</div>
</div>
<hr>
<div class="row">
<div class="col-12">
<h5>An- oder Ablehnung</h5>
<p>{{absence.confirm_info}}</p>
<p> {% if absence.confirm_info|length > 0 %}
{{absence.confirm_info}}
{% else %}
Kein Hinweis
{% endif %}
</p>
</div>
</div>
<hr>
{% getAbsenceLastHistory absence as ab_history %}
{% if ab_history != None %}
<small>Zuletzt geändert am {{ab_history.history_date|date:"d.m.Y, H:i"}} von {{ab_history.history_user.get_full_name}}</small>
{% endif %}
</div>
<div class="col-5 ml-3">

View File

@ -288,7 +288,7 @@ def AbsenceManagmenet(request, activemonth=False, activeyear=False):
@login_required
def TimeManagementTeamSingle(request, pk, activemonth=False, activeyear=False):
if(request.user.has_perm("users.usermanager")):
if(request.user.has_perm("users.timemanager")):
# Setzt die Monatsausgabe auf Deutsch
locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8')
user = User.objects.get(pk=pk)
@ -403,7 +403,7 @@ def TimeManagement(request, activemonth=False, activeyear=False):
"workdays" : Workday.objects.filter(agency=request.user.profile.agency, user=request.user, start__month=activemonth, start__year=active_year).order_by("start").exclude(end=None),
"userhasworkdays" : user_has_workdays
}
if(request.user.has_perm("users.usermanager")):
if(request.user.has_perm("users.timemanager")):
context.update({"usersofagencytm" : User.objects.filter(profile__agency=request.user.profile.agency).order_by('last_name')})
return render(request, 'timemanagement/timemanagement_management.html', context)
@ -427,6 +427,11 @@ def TimeUpdate(request, pk, team=0):
workday.end = end
workday.freefield = form["freefield"].value()
workday.target = form["target"].value()
# Speichern, das jemand den Arbeitstag bearbeitet hat
workday.lastManualChangeUser = request.user
workday.lastManualChangeDate = datetime.datetime.now()
workday.save()
messages.success(request, f'Arbeitstag aktualisiert')
if(team == 1):

View File

@ -490,7 +490,8 @@ class AgencyGroup(models.Model):
('usermanager', 'Mitarbeiter bearbeiten'),
('groupmanager', 'Gruppen bearbeiten'),
('structuremanager', 'Struktur bearbeiten'),
('standardmanager', 'Standards bearbeiten und freischalten'),
('standardmanager', 'Standards bearbeiten'),
('standardgopublic', 'Standards freischalten'),
('modulenews', 'News bearbeiten und veröffentlichen'),
('modulesconfig', 'Module verwalten'),
('moduleorganizer', 'Organizer bearbeiten'),
@ -498,6 +499,7 @@ class AgencyGroup(models.Model):
('filedirmanager', 'Ordner bearbeiten'),
('filesviewer', 'Dateien lesen'),
('absencemanager', 'Abwesenheiten verwalten'),
('timemanager', 'Zeiterfassung verwalten'),
('recoverdirmanager', 'Notfallhilfe verwalten')
]

View File

@ -156,6 +156,8 @@
Agentur
</div>
{% getUnpubStandards request.user as standardUnPubCount %}
{% if active_link == 'standards' %}
<li class="nav-item active">
{% else%}
@ -163,8 +165,11 @@
{%endif%}
<a class="nav-link " href="{% url 'standards' %}" aria-expanded="true">
<i class="fas fa-fw fa-lightbulb"></i>
<!-- TASK: Anzahl unveröffentlicher Standards als Bubble hier rein -->
<span>Standards</span>
<span>Standards
{% if standardUnPubCount > 0 %}
<span class="badge badge-primary badge-counter" id="messcounter_badge" style="margin-right: 95px;"><span id="messcounter">{{standardUnPubCount}}</span></span>&nbsp;
{% endif %}
</span>
</a>
</li>
@ -245,6 +250,9 @@
-->
{% if request.user.profile.agency.module_timemanagement %}
{% getAbsenceAsks request.user as ab_ask %}
{% if active_link == 'abscence' %}
<li class="nav-item active">
{% else%}
@ -253,7 +261,11 @@
<a class="nav-link " href="{% url 'tma-management' %}" aria-expanded="true">
<i class="fas fa-umbrella-beach"></i>
<!-- TASK: Anzahl ausstehender Anträge hier rein -->
<span>Abwesenheiten&nbsp;<sup>BETA</sup></span>
<span>Abwesenheiten&nbsp;
{% if ab_ask > 0 and request.user|usergperm:"absencemanager" %}
<span class="badge badge-primary badge-counter" id="messcounter_badge" style="margin-right: 62px;"><span id="messcounter">{{ab_ask}}</span></span>&nbsp;
{% endif %}
</span>
</a>
</li>
{% endif %}