QS Nach Deck

This commit is contained in:
Holger Trampe 2020-09-16 16:48:03 +02:00
parent 557b3fb0a4
commit 298ca23a5b
23 changed files with 584 additions and 391 deletions

View File

@ -24,7 +24,7 @@ class Areas(models.Model):
color = RGBColorField(colors=['#FFB900', '#E74856', '#0078D7', '#0099BC', '#7A7574'], default='#0099BC', blank=True) color = RGBColorField(colors=['#FFB900', '#E74856', '#0078D7', '#0099BC', '#7A7574'], default='#0099BC', blank=True)
desc = models.TextField(max_length=3000, blank=True) desc = models.TextField(max_length=3000, blank=True)
usersfield = models.ManyToManyField(User, blank=True, related_name='users_in_area') usersfield = models.ManyToManyField(User, blank=True, related_name='users_in_area')
created_area_by = models.ForeignKey(User, on_delete=models.PROTECT) created_area_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
created_area_date = models.DateField(default=datetime.date.today, blank=True) created_area_date = models.DateField(default=datetime.date.today, blank=True)
visible = models.BooleanField(default=True) visible = models.BooleanField(default=True)
areaorder = models.IntegerField(default=0) areaorder = models.IntegerField(default=0)

View File

@ -6,14 +6,14 @@
width: 100%; width: 100%;
} }
.icon-container { .icon-container {
width: 50px; width: 25px;
height: 50px; height: 25px;
position: relative; position: relative;
} }
.status-circle { .status-circle {
width: 15px; width: 5px;
height: 15px; height: 5px;
border-radius: 50%; border-radius: 50%;
bottom: 0; bottom: 0;
right: 0; right: 0;
@ -22,19 +22,12 @@
</style> </style>
<div class="card" style="position: fixed; right: 35px; bottom: 75px;"> <div class="card" style="position: fixed; right: 35px; bottom: 75px;">
<div class="card-body"> <div class="card-body">
<h4>Chat öffnen <!--<h5>Chat öffnen
<button class="btn btn-sm btn-secondary" style="float: right;" onclick="javascript:$('#chat_alluserscontent').fadeOut()"><small><i class="fas fa-times"></i></small></button> <button class="btn btn-sm btn-secondary" style="float: right;" onclick="javascript:$('#chat_alluserscontent').fadeOut()"><small><i class="fas fa-times"></i></small></button>
</h4> </h5>
<hr> <hr>-->
<div class="row" style="float: right">
<div class="col">
{% for user in usersofagency %} {% for user in usersofagency %}
{% if forloop.counter|divisibleby:6 %} <button class="btn btn-sm btn-light mb-2" style="float: right; min-width: 100%; text-align: left;" onclick="javascript:openChat({{user.pk}})">
</div>
<div class="col">
{% endif %}
<span style="padding: 20px;">
<div class='icon-container'> <div class='icon-container'>
<img class="img-profile roundimg" src="{{ user.profile.get_photo_url }}"> <img class="img-profile roundimg" src="{{ user.profile.get_photo_url }}">
<div class='status-circle' style="background-color: {% if user in onlineusers %} <div class='status-circle' style="background-color: {% if user in onlineusers %}
@ -51,12 +44,9 @@
</div> </div>
</div> </div>
{{user.first_name}} {{user.last_name}} {{user.first_name}} {{user.last_name}}
<button class="btn btn-sm btn-secondary" style="float: right;" onclick="javascript:openChat({{user.pk}})"><small><i class="far fa-comment"></i></small></button> </button>
</span>
<br /> <br />
{% endfor %} {% endfor %}
</div>
</div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
function openChat(userid){ function openChat(userid){

View File

@ -0,0 +1,86 @@
<style type="text/css">
.roundimg {
border-radius: 50%;
z-index: 999;
height: 100%;
width: 100%;
}
.icon-container {
width: 25px;
height: 25px;
position: relative;
}
.status-circle {
width: 5px;
height: 5px;
border-radius: 50%;
bottom: 0;
right: 0;
position: absolute;
}
</style>
<div class="card" style="position: fixed; right: 35px; bottom: 75px;">
<div class="card-body">
<h5>Chat öffnen
<button class="btn btn-sm btn-secondary" style="float: right;" onclick="javascript:$('#chat_alluserscontent').fadeOut()"><small><i class="fas fa-times"></i></small></button>
</h5>
<hr>
<div class="row" style="float: right">
<div class="col">
{% for user in usersofagency %}
{% if forloop.counter|divisibleby:6 %}
</div>
<div class="col">
{% endif %}
<span style="padding: 20px;">
<div class='icon-container'>
<img class="img-profile roundimg" src="{{ user.profile.get_photo_url }}">
<div class='status-circle' style="background-color: {% if user in onlineusers %}
{% if user.profile.onlinestatus == 0 %}
green
{% elif user.profile.onlinestatus == 1 %}
red
{% elif user.profile.onlinestatus == 2 %}
orange
{% elif user.profile.onlinestatus == 3 %}
grey
{% endif %}
{% else %} grey {% endif %};">
</div>
</div>
{{user.first_name}} {{user.last_name}}
<button class="btn btn-sm btn-secondary" style="float: right;" onclick="javascript:openChat({{user.pk}})"><small><i class="far fa-comment"></i></small></button>
</span>
<br />
{% endfor %}
</div>
</div>
</div>
<script type="text/javascript">
function openChat(userid){
$("#chat_alluserscontent").hide();
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "startnewchat_user_user",
new_chat_userid : userid,
is_basechat : 1
},
success: function( data )
{
$("#dynamicchatwindow_content").html(data);
$("#dynamicchatwindow").show();
localStorage.setItem("basechatid", userid);
}
});
}
</script>

View File

@ -56,18 +56,19 @@
</style> </style>
<div class="content-section col-12"> <div class="content-section col-12">
<h3>Chat&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Verwalten Sie hier Ihre Chatverläufe und starten Sie neue Unterhaltungen mit Mitarbeitern und anderen Agenturen. Alle Nachrichten werden verschlüsselt übertragen und in der Datenbank ebenfalls verschlüsselt gespeichert." class="far fa-question-circle"></i></small> <h3>Chat&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Verwalten Sie hier Ihre Chatverläufe und starten Sie neue Unterhaltungen mit Mitarbeitern und anderen Agenturen. Alle Nachrichten werden verschlüsselt übertragen und in der Datenbank ebenfalls verschlüsselt gespeichert." class="far fa-question-circle"></i></small>
<button class="btn btn-primary btn-sm" style="float: right; " data-toggle="tooltip" data-placement="top" title="Erstellen Sie einen Gruppenchat." onclick="window.location.href='{% url 'chat:chat-addgroup' %}'"><i class="fas fa-plus"></i>&nbsp;Chatraum</button>
</h3> </h3>
<hr> <hr>
</div> </div>
<div class="row col"> <div class="row">
<div class="col-3"> <div class="col-3" style="margin-top: -25px; margin-left: -8px;">
<!-- <div class="card-body">
<h5>Mitarbeiter</h5>
<hr>
{% for user in usersofagency %} {% for user in usersofagency %}
<div class="card mb-2 hoverchatcard" id="userchat_{{user.pk}}"> <div class="card hoverchatcard" id="userchat_{{user.pk}}">
<div class="card-body" style="margin: -15px !important;" > <div class="card-body" style="margin: -15px !important;" >
<div style="float: left;" class="col-12 "> <div style="float: left;" class="col-12 ">
<div class='icon-container mr-2'> <div class='icon-container mr-2'>
@ -90,14 +91,10 @@
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
<hr>
<h5>Chaträume
<button class="btn btn-primary btn-sm" style="float: right; margin-top: -6px !important;" data-toggle="tooltip" data-placement="top" title="Erstellen Sie einen Gruppenchat." onclick="window.location.href='{% url 'chat:chat-addgroup' %}'"><i class="fas fa-plus"></i></button>
</h5>
<hr>
{% for chatroom in chatrooms %} {% for chatroom in chatrooms %}
{% if user in chatroom.chatmembers.all or user in chatroom.chatmembers_admin.all or user == chatroom.creator and chatroom.chatroomtype == 1 %} {% if user in chatroom.chatmembers.all or user in chatroom.chatmembers_admin.all or user == chatroom.creator and chatroom.chatroomtype == 1 %}
<div class="card mb-2 hoverchatcard" id="groupchat_{{chatroom.pk}}"> <div class="card hoverchatcard" id="groupchat_{{chatroom.pk}}">
<div class="card-body" style="margin: -15px !important;"> <div class="card-body" style="margin: -15px !important;">
<div style="float: left;" class="col-12 "> <div style="float: left;" class="col-12 ">
<h5 class="mt-3">{{chatroom.roomname}} <h5 class="mt-3">{{chatroom.roomname}}
@ -111,86 +108,13 @@
</div> </div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
-->
<div id="accordion">
<div class="card">
<div class="card-header" id="users">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Mitarbeiter
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="users" data-parent="#accordion">
<div class="card-body">
{% for user in usersofagency %}
<div class="card mb-2 hoverchatcard" id="userchat_{{user.pk}}">
<div class="card-body" style="margin: -15px !important;" >
<div style="float: left;" class="col-12 ">
<div class='icon-container mr-2'>
<img class="img-profile roundimg" src="{{ user.profile.get_photo_url }}">
<div class='status-circle' id="userstatus_circle_{{user.pk}}" style="background-color: {% if user in onlineusers %}
{% if user.profile.onlinestatus == 0 %}
green
{% elif user.profile.onlinestatus == 1 %}
red
{% elif user.profile.onlinestatus == 2 %}
orange
{% elif user.profile.onlinestatus == 3 %}
grey
{% endif %}
{% else %} grey {% endif %};">
</div>
</div>
<h5 class="mt-3">{{user.first_name}} {{user.last_name}}</h5>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="card"> </div></div>
<div class="card-header" id="chatrooms"> <div class="col-9" style="float: left; position: relative; margin-left: -30px" id="mainchatcontent"></div><!-- END CHATAREA -->
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#rooms" aria-expanded="true" aria-controls="rooms">
Chaträume
</button>
<button class="btn btn-primary btn-sm" style="float: right; " data-toggle="tooltip" data-placement="top" title="Erstellen Sie einen Gruppenchat." onclick="window.location.href='{% url 'chat:chat-addgroup' %}'"><i class="fas fa-plus"></i></button>
</h5>
</div>
<div id="rooms" class="collapse" aria-labelledby="chatrooms" data-parent="#accordion">
<div class="card-body">
{% for chatroom in chatrooms %}
{% if user in chatroom.chatmembers.all or user in chatroom.chatmembers_admin.all or user == chatroom.creator and chatroom.chatroomtype == 1 %}
<div class="card mb-2 hoverchatcard" id="groupchat_{{chatroom.pk}}">
<div class="card-body" style="margin: -15px !important;">
<div style="float: left;" class="col-12 ">
<h5 class="mt-3">{{chatroom.roomname}}
</h5>
<small style="font-size: 10pt;">{% for member in chatroom.chatmembers.all %}
{{member.first_name}} {{member.last_name}}{% if forloop.counter < chatroom.chatmembers.all|length %}, {% endif %}
{% endfor %}
</small>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div> </div>
</div>
<div class="col-9" style="" id="mainchatcontent"></div><!-- END CHATAREA -->
</div> </div>
<!-- LOADER OVERLAY --> <!-- LOADER OVERLAY -->
<div id="overlay" style="display: none;"> <div id="overlay" style="display: none;">
<div class="loader"></div> <div class="loader"></div>

View File

@ -0,0 +1,340 @@
{% extends "users/base.html" %}
{% block content %}
{% if request.user.profile.agency.module_chat %}
<style type="text/css">
.roundimg {
border-radius: 50%;
z-index: 999;
height: 100%;
width: 100%;
border-radius: 50%;
}
.icon-container {
width: 50px;
height: 50px;
position: relative;
float: left;
}
.status-circle {
width: 15px;
height: 15px;
border-radius: 50%;
bottom: 0;
right: 0;
position: absolute;
}
.chatmessageele_breaker
{
float: right;
}
.chatmessageele_me
{
padding: 5px;
border-radius: 15px;
background-color: #cfe6f4;
float: right;
text-align: right;
}
.chatmessageele_other
{
padding: 5px;
border-radius: 15px;
background-color: #f8f9fc;
float: left;
text-align: left;
color: #000000;
}
.scroll {
max-height: 600px;
min-height: 600px;
overflow-y: auto;
}
</style>
<div class="content-section col-12">
<h3>Chat&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Verwalten Sie hier Ihre Chatverläufe und starten Sie neue Unterhaltungen mit Mitarbeitern und anderen Agenturen. Alle Nachrichten werden verschlüsselt übertragen und in der Datenbank ebenfalls verschlüsselt gespeichert." class="far fa-question-circle"></i></small>
</h3>
<hr>
</div>
<div class="row col">
<div class="col-3">
<!--
<h5>Mitarbeiter</h5>
<hr>
{% for user in usersofagency %}
<div class="card mb-2 hoverchatcard" id="userchat_{{user.pk}}">
<div class="card-body" style="margin: -15px !important;" >
<div style="float: left;" class="col-12 ">
<div class='icon-container mr-2'>
<img class="img-profile roundimg" src="{{ user.profile.get_photo_url }}">
<div class='status-circle' id="userstatus_circle_{{user.pk}}" style="background-color: {% if user in onlineusers %}
{% if user.profile.onlinestatus == 0 %}
green
{% elif user.profile.onlinestatus == 1 %}
red
{% elif user.profile.onlinestatus == 2 %}
orange
{% elif user.profile.onlinestatus == 3 %}
grey
{% endif %}
{% else %} grey {% endif %};">
</div>
</div>
<h5 class="mt-3">{{user.first_name}} {{user.last_name}}</h5>
</div>
</div>
</div>
{% endfor %}
<hr>
<h5>Chaträume
<button class="btn btn-primary btn-sm" style="float: right; margin-top: -6px !important;" data-toggle="tooltip" data-placement="top" title="Erstellen Sie einen Gruppenchat." onclick="window.location.href='{% url 'chat:chat-addgroup' %}'"><i class="fas fa-plus"></i></button>
</h5>
<hr>
{% for chatroom in chatrooms %}
{% if user in chatroom.chatmembers.all or user in chatroom.chatmembers_admin.all or user == chatroom.creator and chatroom.chatroomtype == 1 %}
<div class="card mb-2 hoverchatcard" id="groupchat_{{chatroom.pk}}">
<div class="card-body" style="margin: -15px !important;">
<div style="float: left;" class="col-12 ">
<h5 class="mt-3">{{chatroom.roomname}}
</h5>
<small style="font-size: 10pt;">{% for member in chatroom.chatmembers.all %}
{{member.first_name}} {{member.last_name}}{% if forloop.counter < chatroom.chatmembers.all|length %}, {% endif %}
{% endfor %}
</small>
</div>
</div>
</div>
{% endif %}
{% endfor %}
-->
<div id="accordion">
<div class="card">
<div class="card-header" id="users">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Mitarbeiter
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="users" data-parent="#accordion">
<div class="card-body">
{% for user in usersofagency %}
<div class="card mb-2 hoverchatcard" id="userchat_{{user.pk}}">
<div class="card-body" style="margin: -15px !important;" >
<div style="float: left;" class="col-12 ">
<div class='icon-container mr-2'>
<img class="img-profile roundimg" src="{{ user.profile.get_photo_url }}">
<div class='status-circle' id="userstatus_circle_{{user.pk}}" style="background-color: {% if user in onlineusers %}
{% if user.profile.onlinestatus == 0 %}
green
{% elif user.profile.onlinestatus == 1 %}
red
{% elif user.profile.onlinestatus == 2 %}
orange
{% elif user.profile.onlinestatus == 3 %}
grey
{% endif %}
{% else %} grey {% endif %};">
</div>
</div>
<h5 class="mt-3">{{user.first_name}} {{user.last_name}}</h5>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="chatrooms">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#rooms" aria-expanded="true" aria-controls="rooms">
Chaträume
</button>
<button class="btn btn-primary btn-sm" style="float: right; " data-toggle="tooltip" data-placement="top" title="Erstellen Sie einen Gruppenchat." onclick="window.location.href='{% url 'chat:chat-addgroup' %}'"><i class="fas fa-plus"></i></button>
</h5>
</div>
<div id="rooms" class="collapse" aria-labelledby="chatrooms" data-parent="#accordion">
<div class="card-body">
{% for chatroom in chatrooms %}
{% if user in chatroom.chatmembers.all or user in chatroom.chatmembers_admin.all or user == chatroom.creator and chatroom.chatroomtype == 1 %}
<div class="card mb-2 hoverchatcard" id="groupchat_{{chatroom.pk}}">
<div class="card-body" style="margin: -15px !important;">
<div style="float: left;" class="col-12 ">
<h5 class="mt-3">{{chatroom.roomname}}
</h5>
<small style="font-size: 10pt;">{% for member in chatroom.chatmembers.all %}
{{member.first_name}} {{member.last_name}}{% if forloop.counter < chatroom.chatmembers.all|length %}, {% endif %}
{% endfor %}
</small>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<div class="col-9" style="" id="mainchatcontent"></div><!-- END CHATAREA -->
</div>
<!-- LOADER OVERLAY -->
<div id="overlay" style="display: none;">
<div class="loader"></div>
</div>
<style>
.loader {
position: relative;
border: 7px solid #d3d3d3;
border-radius: 50%;
border-top: 7px solid red;
width: 70px;
height: 70px;
left:50%;
top:35%;
-webkit-animation: spin 1s linear infinite; /* Safari */
animation: spin 1s linear infinite;
}
#overlay{
position: absolute;
top:0px;
left:0px;
width: 100%;
height: 100%;
background: black;
opacity: .4;
}
.container{
position:relative;
height: 300px;
width: 200px;
border:1px solid red;
}
/* Safari */
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<script type="text/javascript">
creator_id = false;
chatmember_id = false;
$(".hoverchatcard").hover(function(){
var $this = $(this);
$this.data('bgcolor', $this.css('background-color')).css('background-color', '#f8f9fc');
}, function(){
var $this = $(this);
$this.data('bgcolor', $this.css('background-color')).css('background-color', '#FFFFFF');
}
)
$(".hoverchatcard").click(function(){
clickedroomtype = $(this)[0]["id"].split("_")[0];
clickedroomid = $(this)[0]["id"].split("_")[1];
if (clickedroomtype == "userchat"){
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "startnewchat_user_user",
new_chat_userid : $(this)[0]["id"].split("_")[1],
is_basechat : 0
},
beforeSend: function(request) {
$("#overlay").fadeIn();
},
success: function( data )
{
$("#overlay").fadeOut();
if(creator_id != false && chatmember_id != false){
chatwebsocket.close();
}
$("#mainchatcontent").html(data);
}
});
}
//Open Groupchat
else{
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "startnewchat_groupchat",
groupchatid : clickedroomid,
is_basechat : 0
},
beforeSend: function(request) {
$("#overlay").fadeIn();
},
success: function( data )
{
$("#overlay").fadeOut();
if(creator_id != false && chatmember_id != false){
chatwebsocket.close();
}
$("#mainchatcontent").html(data);
}
});
}
});
function updatePresenceLive() {
$.ajax(
{
type: "GET",
url: "{% url 'chat:chtaajax-getloggedusers-data' %}",
data : {
action : "getloggedusers"
},
success: function( data )
{
counter = 0;
$( ".status-circle" ).each(function( index ) {
if(data["user_online_final"].indexOf($(this)[0]["id"].split("_")[2]) !== -1){
$("#" + $(this)[0]["id"]).css("background-color", "green");
}
else if(data["user_besch_final"].indexOf($(this)[0]["id"].split("_")[2]) !== -1){
$("#" + $(this)[0]["id"]).css("background-color", "red");
}
else if(data["user_abw_final"].indexOf($(this)[0]["id"].split("_")[2]) !== -1){
$("#" + $(this)[0]["id"]).css("background-color", "orange");
}
else{
$("#" + $(this)[0]["id"]).css("background-color", "grey");
}
});
}
});
};
</script>
{% else %}
<h3>Das Module Chat wurde in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %}

View File

@ -17,7 +17,7 @@ class Data(models.Model):
file = models.FileField(null=True, max_length=255, upload_to=user_directory_path) file = models.FileField(null=True, max_length=255, upload_to=user_directory_path)
date_created = models.DateTimeField(default = timezone.now) date_created = models.DateTimeField(default = timezone.now)
date_last_modified = models.DateTimeField(default = timezone.now) date_last_modified = models.DateTimeField(default = timezone.now)
owner = models.ForeignKey(User, on_delete=models.PROTECT) owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, default=None) agency = models.ForeignKey(Agency, on_delete=models.CASCADE, default=None)
def __str__(self): def __str__(self):
@ -34,7 +34,7 @@ class DataDir(models.Model):
visibleby = models.ManyToManyField(AgencyGroup, blank=True, related_name='visible_by_user') visibleby = models.ManyToManyField(AgencyGroup, blank=True, related_name='visible_by_user')
date_created = models.DateTimeField(default = timezone.now) date_created = models.DateTimeField(default = timezone.now)
date_last_modified = models.DateTimeField(default = timezone.now) date_last_modified = models.DateTimeField(default = timezone.now)
owner = models.ForeignKey(User, on_delete=models.PROTECT, blank=True, null=True) owner = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE) agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
parent = models.ForeignKey('DataDir', on_delete=models.CASCADE, blank=True, null=True, related_name='dir_in_dir') parent = models.ForeignKey('DataDir', on_delete=models.CASCADE, blank=True, null=True, related_name='dir_in_dir')
@ -48,7 +48,7 @@ class DataFile(models.Model):
file = models.FileField(null=True, max_length=255, upload_to=user_directory_path, blank=True) file = models.FileField(null=True, max_length=255, upload_to=user_directory_path, blank=True)
date_created = models.DateTimeField(default = timezone.now) date_created = models.DateTimeField(default = timezone.now)
date_last_modified = models.DateTimeField(default = timezone.now) date_last_modified = models.DateTimeField(default = timezone.now)
owner = models.ForeignKey(User, on_delete=models.PROTECT, default=None, blank=True, null=True) owner = models.ForeignKey(User, on_delete=models.SET_NULL, default=None, blank=True, null=True)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, default=None, blank=True, null=True) agency = models.ForeignKey(Agency, on_delete=models.CASCADE, default=None, blank=True, null=True)
parent = models.ForeignKey(DataDir, on_delete=models.PROTECT, related_name='thisfileindir', blank=True, null=True) parent = models.ForeignKey(DataDir, on_delete=models.PROTECT, related_name='thisfileindir', blank=True, null=True)

View File

@ -19,7 +19,7 @@ class News(models.Model):
go_online_on = models.DateTimeField(default=timezone.now, blank=True) go_online_on = models.DateTimeField(default=timezone.now, blank=True)
# Default date plus two weeks # Default date plus two weeks
go_offline_on = models.DateTimeField(default=timezone.now()+timedelta(days=14), blank=True, null=True) go_offline_on = models.DateTimeField(default=timezone.now, blank=True, null=True)
last_modified_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='news_mod_by', default=None) last_modified_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='news_mod_by', default=None)
last_modified_on = models.DateTimeField(default=timezone.now, blank=True) last_modified_on = models.DateTimeField(default=timezone.now, blank=True)

View File

@ -23,6 +23,12 @@ $(document).ready(function() {
lang: "de-DE", lang: "de-DE",
disableDragAndDrop: true disableDragAndDrop: true
}); });
//Set offline-Datei plus 2 weeks
today = new Date();
today = new Date(today.setDate(today.getDate() + 14));
$("#id_go_offline_on").data("DateTimePicker").date(today);
}); });
</script> </script>
{% else %} {% else %}

View File

@ -18,7 +18,6 @@ users speichert alle primary-Keys der User, welche diesem Bereich zugeordnet sin
''' '''
class QuickLinks(models.Model): class QuickLinks(models.Model):
# Wenn die Area gelöscht wird, wird NICHT die Agency gelöscht
agency = models.ForeignKey(Agency, on_delete=models.PROTECT) agency = models.ForeignKey(Agency, on_delete=models.PROTECT)
name = models.CharField(max_length=200, blank=False) name = models.CharField(max_length=200, blank=False)
link = models.CharField(max_length=200, blank=False) link = models.CharField(max_length=200, blank=False)

View File

@ -133,7 +133,7 @@ class StandardUpdateStandard(forms.ModelForm):
self.fields['task'].queryset = Tasks.objects.filter(area__id=areaid).order_by('name') self.fields['task'].queryset = Tasks.objects.filter(area__id=areaid).order_by('name')
except (ValueError, TypeError): except (ValueError, TypeError):
pass pass
elif loggeduser.pk and standard.area != None: elif loggeduser != None and standard.area != None:
self.fields['task'].queryset = Tasks.objects.filter(area__pk=standard.area.pk) self.fields['task'].queryset = Tasks.objects.filter(area__pk=standard.area.pk)
self.fields['area'].required = True self.fields['area'].required = True

View File

@ -12,7 +12,7 @@ from django.utils import timezone
class StandardCommentRate(models.Model): class StandardCommentRate(models.Model):
#standard = models.ForeignKey("Standards", on_delete=models.CASCADE) #standard = models.ForeignKey("Standards", on_delete=models.CASCADE)
rated_by = models.ForeignKey(User, on_delete=models.PROTECT) rated_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
rate_stats = models.IntegerField(default=0) rate_stats = models.IntegerField(default=0)
oncomment = models.ForeignKey("StandardComments", on_delete=models.CASCADE) oncomment = models.ForeignKey("StandardComments", on_delete=models.CASCADE)
@ -30,13 +30,13 @@ class Standards(models.Model):
name = models.CharField(max_length=200, blank=False, default="") name = models.CharField(max_length=200, blank=False, default="")
content = models.TextField(blank=True, verbose_name='Inhalt', default="") content = models.TextField(blank=True, verbose_name='Inhalt', default="")
created_standard_by = models.ForeignKey(User, on_delete=models.PROTECT) created_standard_by = models.ForeignKey(User, default=None, null=True, on_delete=models.SET_NULL)
created_standard_date = models.DateTimeField(default=timezone.now, blank=True) created_standard_date = models.DateTimeField(default=timezone.now, blank=True)
published_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name='user_published_standard', default=None) published_by = models.ForeignKey(User, on_delete=models.SET_NULL, related_name='user_published_standard', default=None, null=True)
published_on = models.DateTimeField(default=timezone.now, blank=True) published_on = models.DateTimeField(default=timezone.now, blank=True)
last_modified_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name='user_modified_standard', default=None) last_modified_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='user_modified_standard', default=None)
last_modified_on = models.DateTimeField(default=timezone.now, blank=True) last_modified_on = models.DateTimeField(default=timezone.now, blank=True)
public = models.BooleanField(default=False) public = models.BooleanField(default=False)

View File

@ -14,7 +14,7 @@
<h2>{{standard.name}} <h2>{{standard.name}}
<span style="float: right"> <span style="float: right">
{% if standard.created_standard_by == user or perms.users.standardmanager %} {% if standard.created_standard_by != null and standard.created_standard_by == user or perms.users.standardmanager %}
<a style="float: right" class="btn btn-secondary btn-sm ml-2" href="{% url 'standard-delete' standard.pk %}"><small><i class="fas fa-trash"></i></small></a> <a style="float: right" class="btn btn-secondary btn-sm ml-2" href="{% url 'standard-delete' standard.pk %}"><small><i class="fas fa-trash"></i></small></a>
<a style="float: right" class="btn btn-secondary btn-sm " href="{% url 'standard-add' standard.pk %}"><small><i class="fas fa-pen"></i></small></a> <a style="float: right" class="btn btn-secondary btn-sm " href="{% url 'standard-add' standard.pk %}"><small><i class="fas fa-pen"></i></small></a>
{% endif %} {% endif %}
@ -193,8 +193,9 @@
</div> </div>
<div class="mt-2"> <div class="mt-2">
<small> <small>
Erstellt durch <a href="{% url 'orga-single' standard.created_standard_by.pk %}">{{standard.created_standard_by.first_name}} {{standard.created_standard_by.last_name}}</a> am {{standard.created_standard_date}} | Zuletzt bearbeitet von <a href="{% url 'orga-single' standard.last_modified_by.pk %}">{{ standard.last_modified_by.first_name}} {{ standard.last_modified_by.last_name}}</a> am {{ standard.last_modified_on}} {% if not standard.created_standard_by %} Erstellt von gelöschtem Mitarbeiter {% else %} Erstellt durch <a href="{% url 'orga-single' standard.created_standard_by.pk %}">{{standard.created_standard_by.first_name}} {{standard.created_standard_by.last_name}}</a> {% endif %} am {{standard.created_standard_date}} | {% if not standard.last_modified_by %} Zuletzt bearbeitet von gelöschtem Benutzer {% else %} Zuletzt bearbeitet von <a href="{% url 'orga-single' standard.last_modified_by.pk %}">{{ standard.last_modified_by.first_name}} {{ standard.last_modified_by.last_name}}</a>{% endif %} am {{ standard.last_modified_on}}
</small> </small>
</div> </div>
</div> </div>

View File

@ -125,8 +125,7 @@
{% getcommentsup comment.pk as cup %} {% getcommentsup comment.pk as cup %}
{% if cup > 0 %}{{cup}}{% endif %} {% if cup > 0 %}{{cup}}{% endif %}
{% if comment.comment_by == request.user or (standard.created_standard_by != none and standard.created_standard_by == request.user) or standard.last_modified_by == request.user %}
{% if comment.comment_by == request.user or standard.created_standard_by == request.user or standard.last_modified_by == request.user %}
<span style="float: right;"> <span style="float: right;">
<button type="button" class="btn btn-sm btn-secondary" onclick="javascript:delComment({{comment.pk}})" ><i class="fa fa-trash"></i></button> <button type="button" class="btn btn-sm btn-secondary" onclick="javascript:delComment({{comment.pk}})" ><i class="fa fa-trash"></i></button>
</span> </span>

View File

@ -557,6 +557,19 @@ def gettimeoveralldiff(workday, user):
Es werden nur Tage berücksichtigt, die in der Vergangenheit liegen! Es werden nur Tage berücksichtigt, die in der Vergangenheit liegen!
''' '''
def format_timedelta(td):
hours, remainder = divmod(td.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
hours, minutes, seconds = int(hours), int(minutes), int(seconds)
if hours < 10:
hours = '0%s' % int(hours)
if minutes < 10:
minutes = '0%s' % minutes
if seconds < 10:
seconds = '0%s' % seconds
return '%s:%s:%s' % (hours, minutes, seconds)
@register.simple_tag @register.simple_tag
def loadaccounttime(user): def loadaccounttime(user):
status = 0 status = 0
@ -591,14 +604,13 @@ def loadaccounttime(user):
# Wenn GLeitzeit NEGATIV ist # Wenn GLeitzeit NEGATIV ist
if(finalaccounttimesum.total_seconds() < 0): if(finalaccounttimesum.total_seconds() < 0):
status = 1 status = 1
final_info_data = str(datetime.timedelta(seconds=finalaccounttimesum.total_seconds()*(-1))).split(":") final_info_data = format_timedelta(datetime.timedelta(seconds=finalaccounttimesum.total_seconds()*(-1)))
else: else:
status = 0 status = 0
final_info_data = str(datetime.timedelta(seconds=finalaccounttimesum.total_seconds())).split(":") final_info_data = format_timedelta(datetime.timedelta(seconds=finalaccounttimesum.total_seconds()))
final_info = str(final_info_data[0]) + ":" + str(final_info_data[1]) #final_info = str(final_info_data[0]) + ":" + str(final_info_data[1])
return [final_info_data, status]
return [final_info, status]
''' '''

View File

@ -607,6 +607,7 @@ def StandardSingle(request, pk):
'active_link':'standards', 'active_link':'standards',
'standard' : standard 'standard' : standard
} }
return render(request, 'standards/standards_single.html', context) return render(request, 'standards/standards_single.html', context)
else: else:
context = { context = {

View File

@ -18,7 +18,7 @@ class Tasks(models.Model):
name = models.CharField(max_length=200, blank=False, default="") name = models.CharField(max_length=200, blank=False, default="")
desc = models.TextField(max_length=3000, blank=True) desc = models.TextField(max_length=3000, blank=True)
usersfield = models.ManyToManyField(User, blank=True, related_name='users_in_task') usersfield = models.ManyToManyField(User, blank=True, related_name='users_in_task')
created_area_by = models.ForeignKey(User, on_delete=models.PROTECT) created_area_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
created_area_date = models.DateField(default=datetime.date.today, blank=True) created_area_date = models.DateField(default=datetime.date.today, blank=True)
visible = models.BooleanField(default=True) visible = models.BooleanField(default=True)

View File

@ -428,15 +428,14 @@ function recalculateChoosenDays(userid=false){
$("#id_start").data("DateTimePicker").date(date_start); $("#id_start").data("DateTimePicker").date(date_start);
$("#id_end").data("DateTimePicker").date(date_end); $("#id_end").data("DateTimePicker").date(date_end);
localStorage.setItem("ab_userid", userid);
console.log(userid);
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: "{% url 'tm-ajax' %}", url: "{% url 'tm-ajax' %}",
data:{ data:{
action : "getrestholidays", action : "getrestholidays",
userid : userid, userid : localStorage.getItem("ab_userid"),
startdate : date_start.getFullYear() + "__" + (date_start.getMonth()+1) + "__" + date_start.getDate(), startdate : date_start.getFullYear() + "__" + (date_start.getMonth()+1) + "__" + date_start.getDate(),
enddate : date_end.getFullYear() + "__" + (date_end.getMonth()+1) + "__" + date_end.getDate(), enddate : date_end.getFullYear() + "__" + (date_end.getMonth()+1) + "__" + date_end.getDate(),
//start_half : $("#id_start_ishalf").prop("checked"), //start_half : $("#id_start_ishalf").prop("checked"),
@ -462,8 +461,6 @@ function recalculateChoosenDays(userid=false){
$("#ownholidays").hide(); $("#ownholidays").hide();
} }
$("#startAbsenceProgress").modal("show"); $("#startAbsenceProgress").modal("show");
@ -504,8 +501,6 @@ function recalculateChoosenDays(userid=false){
} }
function recalculateChoosenDaysAfterInit(){ function recalculateChoosenDaysAfterInit(){
console.log("CHANGE!")
console.log(userid);
new_start = $("#id_start").datepicker().val(); new_start = $("#id_start").datepicker().val();
new_end = $("#id_end").datepicker().val(); new_end = $("#id_end").datepicker().val();
@ -515,10 +510,10 @@ function recalculateChoosenDaysAfterInit(){
behindcheck_start = new Date(new_start[2], (parseInt(new_start[1])-1), new_start[0]); behindcheck_start = new Date(new_start[2], (parseInt(new_start[1])-1), new_start[0]);
behindcheck_end = new Date(new_end[2], (parseInt(new_end[1])-1), new_end[0]); behindcheck_end = new Date(new_end[2], (parseInt(new_end[1])-1), new_end[0]);
if(sameday){ //if(sameday){
behindcheck_end = behindcheck_start; // behindcheck_end = behindcheck_start;
new_end = new_start; // new_end = new_start;
} //}
$.ajax({ $.ajax({
@ -526,7 +521,7 @@ function recalculateChoosenDaysAfterInit(){
url: "{% url 'tm-ajax' %}", url: "{% url 'tm-ajax' %}",
data:{ data:{
action : "getrestholidays", action : "getrestholidays",
userid : userid, userid : localStorage.getItem("ab_userid"),
startdate : new_start[2] + "__" + new_start[1] + "__" + new_start[0], startdate : new_start[2] + "__" + new_start[1] + "__" + new_start[0],
enddate : new_end[2] + "__" + new_end[1] + "__" + new_end[0], enddate : new_end[2] + "__" + new_end[1] + "__" + new_end[0],
//start_half : $("#id_start_ishalf").prop("checked"), //start_half : $("#id_start_ishalf").prop("checked"),

View File

@ -1,229 +0,0 @@
'''
@receiver(post_save, sender=DataDir)
def save_dir(sender, instance, **kwargs):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
# CREATED
if(kwargs["created"]):
for user in usersofagency:
if(user.usernotifications.filedir_created_mail):
notificationtext = " es gibt neue Ordner: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.filedir_created_push):
newnotification = UserNotification(touser=user, notificationtext="Neuer Ordner: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Ordner | Neuer Ordner: " + instance.name})
# UPDATED
else:
for user in usersofagency:
if(user.usernotifications.filedir_update_mail):
notificationtext = " Ordner wurden aktualisiert: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.filedir_update_push):
newnotification = UserNotification(touser=user, notificationtext="Aktualisierter Ordner: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Ordner | Aktualisierter Ordner: " + instance.name})
'''
'''
@receiver(pre_delete, sender=DataDir)
def del_dir(sender, instance, **kwargs):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
for user in usersofagency:
if(user.usernotifications.filedir_delete_mail):
notificationtext = " ein Ordner wurde gelöscht: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.filedir_delete_push):
newnotification = UserNotification(touser=user, notificationtext="Ordner gelöscht: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Ordner | Ordner gelöscht: " + instance.name})
'''
@receiver(pre_delete, sender=DataFile)
def del_file(sender, instance, **kwargs):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
for user in usersofagency:
if(user.usernotifications.filedir_delete_mail):
notificationtext = " eine Datei wurde gelöscht: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.filedir_delete_push):
newnotification = UserNotification(touser=user, notificationtext="Datei gelöscht: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Dateiein | Datei gelöscht: " + instance.name})
# Signals for FILES
@receiver(post_save, sender=DataFile)
def save_file(sender, instance, **kwargs):
if(kwargs["created"] and len(instance.name) > 0):
newNotifiyPush(0, instance, " es gibt eine neue Datei: ", "Neue Datei: ", "Dateien | ", "", "")
elif(len(instance.name) > 0):
newNotifiyPush(1, instance, " Datei wurde aktualisiert: ", "Aktualisierter Datei: ", "Dateien | ", "", "")
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
# CREATED
if(kwargs["created"]):
for user in usersofagency:
if(user.usernotifications.filedir_created_mail):
notificationtext = " es gibt eine neue Datei: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.filedir_created_push):
newnotification = UserNotification(touser=user, notificationtext="Neue Datei: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Dateien | Neue Datei: " + instance.name})
# UPDATED
else:
for user in usersofagency:
if(user.usernotifications.filedir_update_mail):
notificationtext = " Datei wurden aktualisiert: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.filedir_update_push):
newnotification = UserNotification(touser=user, notificationtext="Aktualisierte Datei: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Dateien | Aktualisierte Datei: " + instance.name})
@receiver(post_save, sender=QuickLinks)
def save_ql(sender, instance, **kwargs):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
# CREATED
if(kwargs["created"]):
for user in usersofagency:
if(user.usernotifications.ql_created_mail):
notificationtext = " es gibt einen neuen Quicklink: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.ql_created_push):
newnotification = UserNotification(touser=user, notificationtext="Neuer Quicklink: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Organizer | Neuer Quicklink: " + instance.name})
# UPDATED
else:
for user in usersofagency:
if(user.usernotifications.ql_update_mail):
notificationtext = " Quicklink wurde aktualisiert: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.ql_update_push):
newnotification = UserNotification(touser=user, notificationtext="Quicklink aktualisiert: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Organizer | Aktualisierter Quicklink: " + instance.name})
@receiver(pre_delete, sender=QuickLinks)
def del_ql(sender, instance, **kwargs):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
for user in usersofagency:
if(user.usernotifications.ql_delete_mail):
notificationtext = " ein Quicklink wurde gelöscht: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.ql_delete_push):
newnotification = UserNotification(touser=user, notificationtext="Quicklink gelöscht: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Organizer | Quicklink gelöscht: " + instance.name})
@receiver(post_save, sender=Standards)
def save_standard(sender, instance, **kwargs):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
targeturl = settings.BASE_URL + "standards/standard/" + str(instance.pk) + "/single"
# NEW STANDARD
if(kwargs["created"]):
if(instance.public):
for user in usersofagency:
if(user.usernotifications.standard_created_mail):
notificationtext = " es wurde ein neuer Agenturstandard erstellt: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.standard_created_push):
newnotification = UserNotification(touser=user, notificationtext="Neuer Agenturstandard: " + instance.name, notificationtype="newstandard", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Standards | Neuer Agenturstandard: " + instance.name})
else:
for user in usersofagency:
if(user.has_perm("users.standardmanager") and user.usernotifications.standard_created_unpub_push):
newnotification = UserNotification(touser=user, notificationtext="Neuer unveröffentlichter Agenturstandard: " + instance.name, notificationtype="newstandard", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Standards | Neuer unveröffentlichter Agenturstandard: " + instance.name})
if(user.has_perm("users.standardmanager") and user.usernotifications.standard_created_unpub_mail):
notificationtext = " es wurde ein neuer unveröffentlichter Agenturstandard erstellt: " + instance.name
sendMailNoti(notificationtext, user)
# Standard wurde aktualisiert
else:
for user in usersofagency:
if(user.usernotifications.standard_update_mail):
notificationtext = " es wurde ein neuer Agenturstandard aktualisiert: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.standard_update_push):
newnotification = UserNotification(touser=user, notificationtext="Agenturstandard aktualisiert: " + instance.name, notificationtype="newstandard", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Standards | Agenturstandard aktualisiert: " + instance.name})
# DELETE
@receiver(pre_delete, sender=Standards)
def delete_standard(sender, instance, **kwargs):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
for user in usersofagency:
if(user.usernotifications.standard_delete_mail):
notificationtext = " es wurde ein neuer Agenturstandard gelöscht: " + instance.name
sendMailNoti(notificationtext, user)
if(user.usernotifications.standard_delete_push):
newnotification = UserNotification(touser=user, notificationtext="Agenturstandard gelöscht: " + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Standards | Agenturstandard gelöscht: " + instance.name})

View File

@ -23,9 +23,9 @@
</style> </style>
<div class="card col-2" style="position: fixed; right: 35px; bottom: 75px;"> <div class="card col-2" style="position: fixed; right: 35px; bottom: 75px;">
<div class="card-body"> <div class="card-body">
<h4>Chat starten <h5>Chat starten
<button class="btn btn-sm btn-secondary" style="float: right;" onclick="javascript:$('#chat_alluserscontent').fadeOut()"><small><i class="fas fa-times"></i></small></button> <button class="btn btn-sm btn-secondary" style="float: right;" onclick="javascript:$('#chat_alluserscontent').fadeOut()"><small><i class="fas fa-times"></i></small></button>
</h4> </h5>
<hr> <hr>
{% for user in usersofagency %} {% for user in usersofagency %}
<span> <span>

View File

@ -10,13 +10,22 @@
</div> </div>
</div> </div>
<!-- Für das Speichern der Bilder enctype --> <!-- Für das Speichern der Bilder enctype -->
<!-- TASK: Hinzufügen von Zeiterfassung und Urlaub! -->
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
<p>Alle vom Benutzer erstellen Standards werden dem aktuellen Benutzer zugewiesen.<br /><small>(Aktuller Benutzer: {{request.user.pre_name}} {{request.user.last_name}})</small></p> <p>Alle vom Benutzer erstellen Informationen (Standards, Dateien usw.) bleiben bestehen, jedoch werden die Verweise auf einen Nutzer entfernt. Alle Chat-Nachrichten werden unwiederruflich gelöscht! Soeben wurden alle Vertragsdaten (Abwesenheit und Zeiterfassung), wenn vorhanden, als CSV heruntergeladen. Diese können Sie archivieren und entsprechend Ihrer agenturinternen Gegebenheiten bzgl. Datenspeicherung aufbewahren.<br /></p>
<a href="{% url 'users-delete-getdata' user.pk %}" id="downloadFileAction" download>Daten erneut herunterladen</a>
<hr>
<div class="form-group"> <div class="form-group">
<button type="submit" class="btn btn-primary">Benutzer löschen</button>&nbsp; <button type="submit" class="btn btn-primary">Benutzer löschen</button>&nbsp;
<a href="{% url 'dasettings' %}" class="btn">Abbrechen</a> <a href="{% url 'dasettings' %}" class="btn">Abbrechen</a>
</div> </div>
</form> </form>
</div> </div>
<script type="text/javascript">
//Auto-Download the file
$(document).ready(function(){
location.href = "{% url 'users-delete-getdata' user.pk %}"
})
</script>
{% endblock content %} {% endblock content %}

View File

@ -23,6 +23,7 @@ urlpatterns = [
#path('usersman/<int:pk>/', permission_required('users.usermanager')(ProfileUpdateView.as_view()), name='users-update'), #path('usersman/<int:pk>/', permission_required('users.usermanager')(ProfileUpdateView.as_view()), name='users-update'),
path('usersman/<int:pk>/perms', permission_required('users.usermanager')(UsersPermUpdateView.as_view()), name='users-perm-update'), path('usersman/<int:pk>/perms', permission_required('users.usermanager')(UsersPermUpdateView.as_view()), name='users-perm-update'),
path('usersman/<int:pk>/delete', permission_required('users.usermanager')(ProfileDeleteView.as_view()), name='users-delete'), path('usersman/<int:pk>/delete', permission_required('users.usermanager')(ProfileDeleteView.as_view()), name='users-delete'),
path('usersman/gd/<int:pk>', views.getDataFromToDelUser, name="users-delete-getdata"),
#path('agencyinfo/', views.agency, name='agencyinfo'), #path('agencyinfo/', views.agency, name='agencyinfo'),
#path('agencyinfo/<int:pk>/', permission_required('users.agency_change')(AgencyUpdateView.as_view()), name='agency-manage'), #path('agencyinfo/<int:pk>/', permission_required('users.agency_change')(AgencyUpdateView.as_view()), name='agency-manage'),
path('usersman/<int:pk>/prio', views.UsersPrio, name='users-prio'), path('usersman/<int:pk>/prio', views.UsersPrio, name='users-prio'),
@ -37,7 +38,8 @@ urlpatterns = [
path('sendpassmail/', views.sendpassmail, name="users-sendpassmail"), path('sendpassmail/', views.sendpassmail, name="users-sendpassmail"),
path('changeonlinestat/', views.changeonlinestat, name="users-updateonlinestat"), path('changeonlinestat/', views.changeonlinestat, name="users-updateonlinestat"),
path('dacron/<slug:code>', views.cronactions, name="cronmain"), path('dacron/<slug:code>', views.cronactions, name="cronmain"),
path('dacrondaily/<slug:code>', views.cronactionsdaily, name="cronmaindaily") path('dacrondaily/<slug:code>', views.cronactionsdaily, name="cronmaindaily"),
] ]

View File

@ -41,7 +41,7 @@ from channels_presence.models import Room
from channels_presence.models import Presence from channels_presence.models import Presence
import channels.layers import channels.layers
from datetime import date, timedelta from datetime import date, timedelta
from timemanagement.models import Workday, Absence from timemanagement.models import Workday, Absence, Breaks
import base64 import base64
import filetype import filetype
from django.db.models.signals import m2m_changed from django.db.models.signals import m2m_changed
@ -507,15 +507,73 @@ def changeonlinestat(request):
zugeschrieben, welcher eingeloggt ist. Das passiert VOR dem löschen! zugeschrieben, welcher eingeloggt ist. Das passiert VOR dem löschen!
''' '''
import csv
@login_required
def getDataFromToDelUser(request, pk):
if(request.method == "GET"):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="newfile.csv"'
writer = csv.writer(response)
# LOAD ABSENCE OBJECTES
user = User.objects.get(pk=pk)
# TASK: Hier besprechen, ob das Recht als Benutzermanager ausreicht!
if(request.user.has_perm("users.usermanager") and user.profile.agency == request.user.profile.agency):
user_absences = Absence.objects.filter(agency=request.user.profile.agency, user=user).order_by("-start")
for ab in user_absences:
status = "OK"
if(ab.confirm_status == 1 or ab.confirm_status == 2):
status = "Abgelehnt"
writer.writerow(['Abwesenheit', str(ab.start), str(ab.end), 'Grund: '+ab.reason.name, 'Status: '+status])
user_workdays = Workday.objects.filter(agency=request.user.profile.agency, user=user).order_by("-start")
for wd in user_workdays:
breaks = Breaks.objects.filter(agency=request.user.profile.agency, user=user, workday=wd)
breaks_string = ""
for b in breaks:
breaks_string += str(b.start) + " bis " + str(b.end) + ", "
writer.writerow(['Arbeitstag', str(wd.start), str(wd.end), 'Pausen: ' + breaks_string])
return response
else:
pass
class ProfileDeleteView(LoginRequiredMixin, DeleteView): class ProfileDeleteView(LoginRequiredMixin, DeleteView):
model = User model = User
success_url = '/dasettings/main' success_url = '/dasettings/main'
template_name = 'users/user_confirm_delete.html' template_name = 'users/user_confirm_delete.html'
# Adding active_link
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Hier Daten zusammenstellen, damit alle Daten bzgl Vertrag nicht verloren gehen (Zeiterfassung, Urlaub und Abwesenheiten)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="file.csv"'
writer = csv.writer(response)
writer.writerow(['1001', 'John', 'Domil', 'CA'])
writer.writerow(['1002', 'Amit', 'Mukharji', 'LA', '"Testing"'])
context.update({"response" : response})
print(response)
return context
def delete(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs):
user = User.objects.get(pk=kwargs['pk']) user = User.objects.get(pk=kwargs['pk'])
logged_user = request.user logged_user = request.user
''' ALTER LÖSCHBEREICH - User wird einfach entfernt '''
'''
areas_fs = Areas.objects.filter(created_area_by=user) areas_fs = Areas.objects.filter(created_area_by=user)
for a in areas_fs: for a in areas_fs:
a.created_area_by = logged_user a.created_area_by = logged_user
@ -542,6 +600,7 @@ class ProfileDeleteView(LoginRequiredMixin, DeleteView):
for a in standards_fs: for a in standards_fs:
a.published_by = logged_user a.published_by = logged_user
a.save() a.save()
'''
response = super(ProfileDeleteView, self).delete(request, *args, **kwargs) response = super(ProfileDeleteView, self).delete(request, *args, **kwargs)
name = user.first_name + " " + user.last_name name = user.first_name + " " + user.last_name
@ -615,7 +674,6 @@ def UsersPrioUpdate(request):
else: else:
return HttpResponse("Request method is not a GET") return HttpResponse("Request method is not a GET")
import re import re