Sfoglia il codice sorgente

wip appointments blocked when inactive

master
Daniel 2 anni fa
parent
commit
61ad461226
19 ha cambiato i file con 363 aggiunte e 286 eliminazioni
  1. +8
    -4
      src/client/app/js/app/core/Dict.js
  2. +7
    -1
      src/client/app/js/app/model/Appointment.js
  3. +6
    -0
      src/client/app/js/app/model/Group.js
  4. +1
    -0
      src/client/app/js/app/state/GroupDetailEdit.js
  5. +24
    -19
      src/client/app/js/app/state/Home.js
  6. +1
    -2
      src/client/app/tmpl/auth-login.html
  7. +14
    -0
      src/client/app/tmpl/group-detail-edit.html
  8. +245
    -241
      src/client/app/tmpl/home-appointment-item.html
  9. +21
    -9
      src/client/app/tmpl/home.html
  10. +2
    -0
      src/server/server/control/TB_Server_Control_Appointment.php
  11. +1
    -1
      src/server/server/control/TB_Server_Control_Auth.php
  12. +2
    -1
      src/server/server/control/TB_Server_Control_Team.php
  13. +8
    -4
      src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php
  14. +4
    -4
      src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Profile.php
  15. +1
    -0
      src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Team.php
  16. +0
    -0
      tools/patches/1addActiveStateToProfile.php
  17. +0
    -0
      tools/patches/2addDbTermsConditionsToTeam.php
  18. +0
    -0
      tools/patches/3addTermsAcceptedToProfile.php
  19. +18
    -0
      tools/patches/4addDbNewUsersActive.php

+ 8
- 4
src/client/app/js/app/core/Dict.js Vedi File

@@ -240,6 +240,8 @@ app.core.Dict = {
"EDIT_GROUP" : "Gruppe bearbeiten",
"GROUP_NAME" : "Gruppenname",
"GROUP_DESCRIPTION" : "Beschreibung",
"GROUP_NEW_USERS_ACTIVE": "Erweiterte Sicherheit",
"GROUP_NEW_USERS_ACTIVE_CHECKBOX": "Hiermit deaktiviere ich die erweiterte Sicherheit im Anmeldeprozess und setze alle neuen Teilnehmer automatisch auf aktiv.",
"GROUP_TERMS": "Nutzungsbedingungen",
"GROUP_TERMS_ACCEPT": "akzeptieren",
"GROUP_TERMS_ACCEPTED": "Du hast die Nutzungsbedingungen akzeptiert",
@@ -420,14 +422,13 @@ app.core.Dict = {
"REGISTRATION_INCOMPLETE" : "Validierung fehlgeschlagen.",
"REGISTRATION_INCOMPLETE_INFO" : "Bitte melde dich beim ProBuddy Support Team.",
"REGISTRATION_EMAIL_PROVIDED" : "Du hast dich mit folgender Emailadresse registriert:",
"REGISTRATION_SUCCESS_EMAIL_CHECK_NOTE" : "Bitte prüfe, ob du die Emailadresse korrekt eingetragen hast bzw. ob es auch die richtige Emailadresse ist! Sollte die Emailadresse nicht korrekt sein, logge dich erneut mit der nicht korrekten Emailadresse ein. Nach dem Login hast die die Möglichkeit die Emailadresse zu ändern.",
"REGISTRATION_EMAIL_CHECK_NOTE" : "Bitte prüfe, ob du die Emailadresse korrekt eingetragen hast bzw. ob es auch die richtige Emailadresse ist!",
"REGISTRATION_EMAIL_CHANGE_NOTE" : "Du hast hier die Möglichkeit deine, noch nicht validierte, Emailadresse zu ändern. Wenn du deine Emailadresse geändert hast, versuche dich mit deiner neuen Emailadresse einzuloggen. Danach wirst du eine neue Verifizierungs-Email erhalten.",
"REGISTRATION_SUCCESS_EMAIL_CHECK_NOTE" : "Bitte prüfe, ob du die Emailadresse korrekt eingetragen hast bzw. ob diese korrekt ist! Sollte die Emailadresse nicht korrekt sein, logge dich dennoch erneut mit dieser Emailadresse ein. Nach dem Login hast die die Möglichkeit die Emailadresse zu ändern.",
"REGISTRATION_EMAIL_CHECK_NOTE" : "Ist diese Adresse korrekt? Sonst kannst Du Sie hier nochmals korrigieren, danach wird eine neue Verifizierungsmail versendet.",
"REGISTRATION_EMAIL_CHANGE_BTN" : "Email ändern",
"REGISTRATION_EMAIL_CHANGED_SUCCESS" : "Deine Emailadresse wurde erfolgreich geändert.",
"REGISTRATION_EMAIL_CHANGED_SUCCESS_INFO" : "Deine Emailadresse wurde erfolgreich geändert. Gehe nun zurück zum Login und versuche nun dich mit deiner neuen Emailadresse einzuloggen, um eine neue Verifizierungsmail zu erhalten.",
"ACCOUNT_NOT_VALIDATED" : "Email noch nicht validiert!",
"ACCOUNT_NOT_VALIDATED_DESCRIPTION" : "Bitte validiere zunächst deine Email Adresse. Wir haben dir gerade erneut einen Validierungslink per Mail zugeschickt. Bitte schau in deinem Postfach nach (ggf. auch im Spam-Ordner) und klicke auf den Button.",
"ACCOUNT_NOT_VALIDATED_DESCRIPTION" : "Bitte validiere zunächst deine Email Adresse. Wir haben dir gerade einen Validierungslink per Mail zugeschickt. Bitte schau in deinem Postfach nach (ggf. auch im Spam-Ordner) und klicke auf den Button.",
"LOGIN_FIRSTNAME" : "Vorname",
"LOGIN_LASTNAME" : "Nachname",
"DELETION_GROUP_OWNER_INFO_HEADLINE" : "Informationen zur Löschung deines Profils",
@@ -582,6 +583,9 @@ app.core.Dict = {
"HOME_MODAL_NOT_ACTIVATED_BUTTON" : "Profil vervollständigen",
"HOME_MODAL_TERMS_NOT_ACCEPTED_TITLE" : "Nutzungsbedingungen akzeptieren",
"HOME_MODAL_TERMS_NOT_ACCEPTED_TEXT" : "Folgende Gruppen haben Nutzungsbedingungen, die Du noch akzeptieren musst, um auf Deine Termine zugreifen zu können.",
"HOME_GROUPS_NOT_ACTIVE_TEXT1" : "Dein Profil ist für folgende Gruppen nicht aktiviert: ",
"HOME_GROUPS_NOT_ACTIVE_TEXT2" : "Deswegen kannst Du noch nicht zu Terminen zusagen oder Termindetails sehen. Bitte wende Dich an Deinen Gruppeninhaber oder Admin.",
"HOME_GROUPS_NOT_ACTIVE_BTN" : "Zur Gruppenübersicht",
},
"en" : {
}

+ 7
- 1
src/client/app/js/app/model/Appointment.js Vedi File

@@ -31,7 +31,8 @@ app.model.Appointment = function( appData, attendees, attendeeProfiles )
mStart = app.util.Helper.getMomentFromUTCTime( data.start_dt ),
mEnd = app.util.Helper.getMomentFromUTCTime( data.end_dt ),
mDeadline = app.util.Helper.getMomentFromUTCTime( data.deadline_dt ),
mDeadlineReject = app.util.Helper.getMomentFromUTCTime( data.deadline_reject_dt );
mDeadlineReject = app.util.Helper.getMomentFromUTCTime( data.deadline_reject_dt ),
v_profile_can_attend = data.v_profile_can_attend || null;
// Process attendee data in order to fix correct status date
for ( var ai = 0; ai < attendees.length; ai++ )
@@ -730,6 +731,11 @@ app.model.Appointment = function( appData, attendees, attendeeProfiles )
return cName;
};
this.getVProfileCanAttend = function ()
{
return v_profile_can_attend;
}
};
app.model.Appointment.ENUM_VISIBLE_FOR_ALL = 'ALL';

+ 6
- 0
src/client/app/js/app/model/Group.js Vedi File

@@ -19,6 +19,7 @@ app.model.Group = function( data, memberData )
termsConditions = data.terms_conditions || null,
termsConditionsActive = data.terms_conditions_active == 1,
contactInformation = data.contact_information || null,
newUsersActive = data.new_users_active == 1,
emblemUrl = data.emblem_url || null,
emblem_cloud_id = data.emblem_cloud_id || null,
memberData = memberData || null,
@@ -118,6 +119,11 @@ app.model.Group = function( data, memberData )
return contactInformation;
};
this.getNewUsersActive = function()
{
return newUsersActive;
};
/**
*
* @returns {*}


+ 1
- 0
src/client/app/js/app/state/GroupDetailEdit.js Vedi File

@@ -41,6 +41,7 @@ app.state.GroupDetailEdit = function()
description: app.util.Helper.trim($form.find('[data-id="textarea-team-description"]').first().val()),
termsConditions: app.util.Helper.trim($form.find('[data-id="textarea-team-terms-conditions"]').first().val()),
termsConditionsActive: $form.find('[data-id="checkbox-team-terms-conditions-active"]').first().is(":checked"),
newUsersActive: $form.find('[data-id="checkbox-new-users-active"]').first().is(":checked"),
contactInformation: app.util.Helper.trim($form.find('[data-id="textarea-team-contactinformation"]').first().val()),
industry: $form.find('[data-id="select-team-industry"]').first().val()
},


+ 24
- 19
src/client/app/js/app/state/Home.js Vedi File

@@ -227,8 +227,9 @@ app.state.Home = function()
self = this,
filter = this.getStateSetting( 'filter' ),
isBackButton = app.core.StateManager.isPreviousState(),
scrollY = +this.getStateSetting( 'scrollY' );
groupsTermsNotAccepted = [];
scrollY = +this.getStateSetting( 'scrollY' ),
groupsTermsNotAccepted = [],
groupsNotActiveString = "";
// For paging
self.currentPage = 1;
@@ -258,6 +259,10 @@ app.state.Home = function()
groupsTermsNotAccepted.push(group);
}
if (groupData.status !== 'active') {
groupsNotActiveString += groupsNotActiveString === "" ? group.getName() : (" ," + group.getName());
}
gcgIds = userGroups[ ui ].getCourseCategories();
for ( var gci = 0; gci < gcgIds.length; gci++ )
{
@@ -465,7 +470,8 @@ app.state.Home = function()
{
appointments : pager.pageElements,
pager : pager,
filter : filter
filter : filter,
groupsNotActiveString: groupsNotActiveString,
}
)
);
@@ -1068,37 +1074,36 @@ app.state.Home = function()
sessionStorage.removeItem("g_ids_popup_shown");
}
if (groupsTermsNotAccepted.length > 0) {
// Show terms not accepted popup
if (showPopup) {
app.core.View.showModal({
title: _lc('HOME_MODAL_TERMS_NOT_ACCEPTED_TITLE'),
body: app.core.View.getTemplate('home-modal-terms-not-accepted', { groups: groupsTermsNotAccepted }),
title: _lc('HOME_MODAL_NOT_ACTIVATED_TITLE'),
body: app.core.View.getTemplate('home-modal-not-activated', { groupName: groupName }),
hideButtons: true,
hideCloseBtn: true,
prohibitCloseModal: true,
cancelButtonText: _lc('HOME_MODAL_NOT_ACTIVATED_BUTTON')
});
$("body").on( 'click', '[data-type="group-accept-link"]', function()
$("body").on( 'click', '[data-id="not-activated"]', function(e)
{
var groupId = $(this).data('group-id');
window.location.hash = "#/group/" + groupId + "/terms";
e.preventDefault();
app.core.View.closeModal();
window.location.href = $(this).attr("href");
});
} else if (showPopup) {
} else if (groupsTermsNotAccepted.length > 0) {
// Show terms not accepted popup
app.core.View.showModal({
title: _lc('HOME_MODAL_NOT_ACTIVATED_TITLE'),
body: app.core.View.getTemplate('home-modal-not-activated', { groupName: groupName }),
title: _lc('HOME_MODAL_TERMS_NOT_ACCEPTED_TITLE'),
body: app.core.View.getTemplate('home-modal-terms-not-accepted', { groups: groupsTermsNotAccepted }),
hideButtons: true,
hideCloseBtn: true,
cancelButtonText: _lc('HOME_MODAL_NOT_ACTIVATED_BUTTON')
prohibitCloseModal: true,
});
$("body").on( 'click', '[data-id="not-activated"]', function(e)
$("body").on( 'click', '[data-type="group-accept-link"]', function()
{
e.preventDefault();
var groupId = $(this).data('group-id');
window.location.hash = "#/group/" + groupId + "/terms";
app.core.View.closeModal();
window.location.href = $(this).attr("href");
});
}
}


+ 1
- 2
src/client/app/tmpl/auth-login.html Vedi File

@@ -78,8 +78,7 @@
<strong data-id="auth-change-registered-email" style="font-size: 20px;"></strong>
</p>
<p class="text-center" data-id="auth-change-registered-email-info">
<%=raw _lc( 'REGISTRATION_EMAIL_CHECK_NOTE' ) %><br />
<%=raw _lc( 'REGISTRATION_EMAIL_CHANGE_NOTE' ) %>
<%=raw _lc( 'REGISTRATION_EMAIL_CHECK_NOTE' ) %>
</p>
<p class="text-center pb_color-danger" data-id="auth-change-registered-email-info-changed">
<%=raw _lc( 'REGISTRATION_EMAIL_CHANGED_SUCCESS_INFO' ) %>


+ 14
- 0
src/client/app/tmpl/group-detail-edit.html Vedi File

@@ -85,6 +85,20 @@
class="form-control"
placeholder="<%= _lc( 'TEAM_DETAIL_TEAMDESCRIPTION_PLACEHOLDER' ) %>"><%= group.getDescription() ? group.getDescription() : '' %></textarea>
</div>
<div class="form-group">
<label><%= _lc( 'GROUP_NEW_USERS_ACTIVE' ) %></label>
<div class="custom-control custom-checkbox my-1 mr-sm-2">
<input type="checkbox"
name="checkbox-new-users-active"
data-id="checkbox-new-users-active"
id="checkbox-new-users-active"
class="custom-control-input"
<%= group.getNewUsersActive() ? 'checked' : '' %>
>
<label class="custom-control-label"
for="checkbox-new-users-active"><%= _lc( 'GROUP_NEW_USERS_ACTIVE_CHECKBOX' ) %></label>
</div>
</div>
<div class="form-group">
<label for="textarea-team-terms-conditions">
<%= _lc( 'GROUP_TERMS_DESCRIPTION' ) %>


+ 245
- 241
src/client/app/tmpl/home-appointment-item.html Vedi File

@@ -61,286 +61,290 @@
<i class="far fa-clock"></i> <%= displayedDateStart %> - <%= displayedDateEnd %> | <i class="far fa-thumbs-up"></i> <%= a.getNumAttendeesAccepted() %> <% if ( 0 < a.getMaxAttendees() ) { %> | <%= a.getMaxAttendees() - a.getNumAttendeesAccepted() %> verfügbar <% } %> | <%= group ? group.getName() : '' %>
</div>
</div>
<div data-type="appointment-rsvp-container"
data-appointment-id="<%= a.getId() %>"
class="col-appointment-response">
<% if ( a.getVProfileCanAttend() ) { %>
<div data-type="appointment-rsvp-container"
data-appointment-id="<%= a.getId() %>"
class="col-appointment-response">
<div class="container-rsvp-icon">
<div class="container-rsvp-icon">
<% if ( a.isDraft() ) { %>
<% if ( a.isDraft() ) { %>
<section data-type="section-rsvp-draft-icon">
<div class="rsvp-draft-icon">
<i class="fas fa-pencil-alt"></i>
</div>
</section>
<section data-type="section-rsvp-draft-icon">
<div class="rsvp-draft-icon">
<i class="fas fa-pencil-alt"></i>
</div>
</section>
<% } else { %>
<% } else { %>
<section data-type="section-rsvp-icon-unchecked"
style="display: <%= ( a.hasProfileIdStatus( currentProfile.getId(), "accepted" ) || a.hasProfileIdStatus( currentProfile.getId(), "waiting" ) ) ? 'none' : 'block' %>">
<button type="button"
data-type="rsvp-button-accept<%= multiple %>"
data-appointment-id="<%= a.getId() %>"
class="btn btn-rsvp-not-selected btn-circle btn-xl">
<i class="fas fa-thumbs-up"></i>
</button>
</section>
<section data-type="section-rsvp-icon-unchecked"
style="display: <%= ( a.hasProfileIdStatus( currentProfile.getId(), "accepted" ) || a.hasProfileIdStatus( currentProfile.getId(), "waiting" ) ) ? 'none' : 'block' %>">
<button type="button"
data-type="rsvp-button-accept<%= multiple %>"
data-appointment-id="<%= a.getId() %>"
class="btn btn-rsvp-not-selected btn-circle btn-xl">
<i class="fas fa-thumbs-up"></i>
</button>
</section>
<section data-type="section-rsvp-icon-loading"
style="display: none">
<div class="rsvp-loading-icon">
<i class="fas fa-circle-notch fa-spin"></i>
</div>
</section>
<section data-type="section-rsvp-icon-loading"
style="display: none">
<div class="rsvp-loading-icon">
<i class="fas fa-circle-notch fa-spin"></i>
</div>
</section>
<section data-type="section-rsvp-icon-accepted"
style="display: <%= a.hasProfileIdStatus( currentProfile.getId(), "accepted" ) ? 'block' : 'none' %>">
<div style="position:relative; width:52px; height:40px;">
<div data-type="rsvp-button-recall<%= multiple %>"
data-appointment-id="<%= a.getId() %>"
style="position: absolute;width:40px; height:40px;top:0;right:0">
<svg class="rsvp-checkmark"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 52 52">
<circle class="rsvp-checkmark__circle" cx="26" cy="26" r="25" fill="none"/>
<path class="rsvp-checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
<section data-type="section-rsvp-icon-accepted"
style="display: <%= a.hasProfileIdStatus( currentProfile.getId(), "accepted" ) ? 'block' : 'none' %>">
<div style="position:relative; width:52px; height:40px;">
<div data-type="rsvp-button-recall<%= multiple %>"
data-appointment-id="<%= a.getId() %>"
style="position: absolute;width:40px; height:40px;top:0;right:0">
<svg class="rsvp-checkmark"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 52 52">
<circle class="rsvp-checkmark__circle" cx="26" cy="26" r="25" fill="none"/>
<path class="rsvp-checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
</div>
</div>
</div>
</section>
</section>
<section data-type="section-rsvp-icon-waiting"
style="display: <%= a.hasProfileIdStatus( currentProfile.getId(), "waiting" ) ? 'block' : 'none' %>">
<div style="position:relative; width:52px; height:40px;">
<div data-type="rsvp-button-recall<%= multiple %>"
data-appointment-id="<%= a.getId() %>"
style="position: absolute;width:40px; height:40px;top:0;right:0">
<svg class="rsvp-checkmark rsvp-chcekmark-waiting"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 52 52">
<circle class="rsvp-checkmark__circle rsvp-checkmark__circle-waiting" cx="26" cy="26" r="25" fill="none"/>
<path class="rsvp-checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
<section data-type="section-rsvp-icon-waiting"
style="display: <%= a.hasProfileIdStatus( currentProfile.getId(), "waiting" ) ? 'block' : 'none' %>">
<div style="position:relative; width:52px; height:40px;">
<div data-type="rsvp-button-recall<%= multiple %>"
data-appointment-id="<%= a.getId() %>"
style="position: absolute;width:40px; height:40px;top:0;right:0">
<svg class="rsvp-checkmark rsvp-chcekmark-waiting"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 52 52">
<circle class="rsvp-checkmark__circle rsvp-checkmark__circle-waiting" cx="26" cy="26" r="25" fill="none"/>
<path class="rsvp-checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
</div>
</div>
</div>
</section>
</section>
<% } %>
<% } %>
</div>
</div>
</div>
<% } %>
</div>
<div class="collapse appointment-collapse-container"
data-type="appointment-detail-container"
data-appointment-id="<%= a.getId() %>">
<div class="row">
<div class="col">
<% if ( a.isCancelled() ) { %>
<div class="appointment-collapse-bar appointment-collapse-bar-cancelled">
<%= _lc( 'APPOINTMENT_HAS_BEEN_CANCELLED' ) %>
</div>
<% } else if ( !a.hasStarted() && a.isDeadlineOver() ) { %>
<div class="appointment-collapse-bar appointment-collapse-bar-deadlineover">
<%= _lc( 'DEADLINE_IS_OVER' ) %>
</div>
<% } else if ( a.isMaxAttendeesExceeded() ) { %>
<% var waitingPosition = a.getWaitingPositionForProfileId( app.model.SessionUser.getProfileId() ); %>
<div class="appointment-collapse-bar appointment-collapse-bar-waiting">
<% if ( waitingPosition > 0 ) { %>
<%= _lc( 'WAITING_LIST_USER_POSITION', [ waitingPosition ] ) %>
<% } else { %>
<%= _lc( 'BOOKED_OUT_ONLY_WAITING_LIST_AVAILABLE' ) %>
<% } %>
</div>
<% } else { %>
<hr style="margin-top: 0" />
<% } %>
</div>
</div>
<div class="row">
<div class="col">
<table class="table table-borderless">
<tr>
<td>
<%= _lc( 'DEADLINEREJECTTIME' ) %>
</td>
<td>
<%= mDeadlineReject.format( 'DD.MMM' ) %> <%= mDeadlineReject.format( 'HH:mm' ) %> Uhr
</td>
</tr>
<tr>
<td>
<%= _lc( 'DEADLINETIME' ) %>
</td>
<td>
<%= mDeadline.format( 'DD.MMM' ) %> <%= mDeadline.format( 'HH:mm' ) %> Uhr
</td>
</tr>
<tr>
<td>
Abrechnungsfaktor
</td>
<td>
<%= ('' + a.getPriceFactor().toFixed(2)).replace( '.', ',' ) %>
</td>
</tr>
<tr>
<td>
<%= _lc( 'LOCATION' ) %>
</td>
<td>
<%=raw a.getLocation() ? a.getLocation() : ( '<i>' + _lc( 'APPOINTMENT_NO_LOCATION' ) + '</i>' ) %>
</td>
</tr>
<tr>
<td>
<%= _lc( 'DETAILS' ) %>
</td>
<td>
<%=raw a.getComment() ? a.getComment() : ( '<i>' + _lc( 'APPOINTMENT_NO_COMMENT' ) + '</i>' ) %>
</td>
</tr>
</table>
<% if ( a.getVProfileCanAttend() ) { %>
<div class="collapse appointment-collapse-container"
data-type="appointment-detail-container"
data-appointment-id="<%= a.getId() %>">
<div class="row">
<div class="col">
<% if ( a.isCancelled() ) { %>
<div class="appointment-collapse-bar appointment-collapse-bar-cancelled">
<%= _lc( 'APPOINTMENT_HAS_BEEN_CANCELLED' ) %>
</div>
<% } else if ( !a.hasStarted() && a.isDeadlineOver() ) { %>
<div class="appointment-collapse-bar appointment-collapse-bar-deadlineover">
<%= _lc( 'DEADLINE_IS_OVER' ) %>
</div>
<% } else if ( a.isMaxAttendeesExceeded() ) { %>
<% var waitingPosition = a.getWaitingPositionForProfileId( app.model.SessionUser.getProfileId() ); %>
<div class="appointment-collapse-bar appointment-collapse-bar-waiting">
<% if ( waitingPosition > 0 ) { %>
<%= _lc( 'WAITING_LIST_USER_POSITION', [ waitingPosition ] ) %>
<% } else { %>
<%= _lc( 'BOOKED_OUT_ONLY_WAITING_LIST_AVAILABLE' ) %>
<% } %>
</div>
<% } else { %>
<hr style="margin-top: 0" />
<% } %>
</div>
</div>
<div class="col">
<table class="table table-borderless">
<tr>
<td>
<%= _lc( 'ACCEPTANCE' ) %>&nbsp;(<%= a.getNumAttendeesAccepted() %>)
</td>
<% let ad, m, cp; %>
<% ad = a.getAttendeeDataByStatus( "accepted" ); %>
<td>
<% if ( ad.length > 0 ) { %>
<div class="row">
<div class="col">
<table class="table table-borderless">
<tr>
<td>
<%= _lc( 'DEADLINEREJECTTIME' ) %>
</td>
<td>
<%= mDeadlineReject.format( 'DD.MMM' ) %> <%= mDeadlineReject.format( 'HH:mm' ) %> Uhr
</td>
</tr>
<tr>
<td>
<%= _lc( 'DEADLINETIME' ) %>
</td>
<td>
<%= mDeadline.format( 'DD.MMM' ) %> <%= mDeadline.format( 'HH:mm' ) %> Uhr
</td>
</tr>
<tr>
<td>
Abrechnungsfaktor
</td>
<td>
<%= ('' + a.getPriceFactor().toFixed(2)).replace( '.', ',' ) %>
</td>
</tr>
<tr>
<td>
<%= _lc( 'LOCATION' ) %>
</td>
<td>
<%=raw a.getLocation() ? a.getLocation() : ( '<i>' + _lc( 'APPOINTMENT_NO_LOCATION' ) + '</i>' ) %>
</td>
</tr>
<tr>
<td>
<%= _lc( 'DETAILS' ) %>
</td>
<td>
<%=raw a.getComment() ? a.getComment() : ( '<i>' + _lc( 'APPOINTMENT_NO_COMMENT' ) + '</i>' ) %>
</td>
</tr>
</table>
</div>
<div class="col">
<table class="table table-borderless">
<tr>
<td>
<%= _lc( 'ACCEPTANCE' ) %>&nbsp;(<%= a.getNumAttendeesAccepted() %>)
</td>
<% let ad, m, cp; %>
<% ad = a.getAttendeeDataByStatus( "accepted" ); %>
<td>
<% if ( ad.length > 0 ) { %>
<% for ( let ai = 0; ai < ad.length; ai++ ) { %>
<%= ai > 0 ? ' - ' : '' %>
<% m = homeState.getMemberByGroupAndProfileId( a.getTeamId(), ad[ ai ].profile_id ); %>
<% cp = m ? m.getChildProfileById( ad[ ai ].profile_child_id ) : null; %>
<% for ( let ai = 0; ai < ad.length; ai++ ) { %>
<%= ai > 0 ? ' - ' : '' %>
<% m = homeState.getMemberByGroupAndProfileId( a.getTeamId(), ad[ ai ].profile_id ); %>
<% cp = m ? m.getChildProfileById( ad[ ai ].profile_child_id ) : null; %>
<% if ( m ) { %>
<%= m.getName( a.getTeamId() ) %>
<% if ( cp ) { %>
[<%=raw m.getChildProfileHtmlTagById( cp.id ) %>]
<% if ( m ) { %>
<%= m.getName( a.getTeamId() ) %>
<% if ( cp ) { %>
[<%=raw m.getChildProfileHtmlTagById( cp.id ) %>]
<% } %>
<% } else { %>
<i>Gelöscht</i>
<% } %>
<% } else { %>
<i>Gelöscht</i>
<% } %>
<% } %>
<% } %>
</td>
</tr>
<tr>
<td>
<%= _lc( 'WAITINGLIST' ) %>&nbsp;(<%= a.hasWaitingList() ? a.getNumAttendeesWaiting() : '0' %>)
</td>
<% ad = a.getAttendeeDataByStatus( "waiting" ); %>
<td>
<% if ( ad.length > 0 ) { %>
<% for ( let ai = 0; ai < ad.length; ai++ ) { %>
<%= ai > 0 ? ' - ' : '' %>
<% m = homeState.getMemberByGroupAndProfileId( a.getTeamId(), ad[ ai ].profile_id ); %>
<% cp = m ? m.getChildProfileById( ad[ ai ].profile_child_id ) : null; %>
<% } %>
</td>
</tr>
<tr>
<td>
<%= _lc( 'WAITINGLIST' ) %>&nbsp;(<%= a.hasWaitingList() ? a.getNumAttendeesWaiting() : '0' %>)
</td>
<% ad = a.getAttendeeDataByStatus( "waiting" ); %>
<td>
<% if ( ad.length > 0 ) { %>
<% for ( let ai = 0; ai < ad.length; ai++ ) { %>
<%= ai > 0 ? ' - ' : '' %>
<% m = homeState.getMemberByGroupAndProfileId( a.getTeamId(), ad[ ai ].profile_id ); %>
<% cp = m ? m.getChildProfileById( ad[ ai ].profile_child_id ) : null; %>
<% if ( m ) { %>
<%= m.getName( a.getTeamId() ) %>
<% if ( cp ) { %>
[<%=raw m.getChildProfileHtmlTagById( cp.id ) %>]
<% if ( m ) { %>
<%= m.getName( a.getTeamId() ) %>
<% if ( cp ) { %>
[<%=raw m.getChildProfileHtmlTagById( cp.id ) %>]
<% } %>
<% } else { %>
<i>Gelöscht</i>
<% } %>
<% } else { %>
<i>Gelöscht</i>
<% } %>
<% } %>
<% } %>
</td>
</tr>
<tr>
<td>
Absagen&nbsp;(<%= a.getProfileIdsDeclined().length %>)
</td>
<% ad = a.getAttendeeDataByStatus( "declined" ); %>
<td>
<% if ( ad.length > 0 ) { %>
<% for ( let ai = 0; ai < ad.length; ai++ ) { %>
<%= ai > 0 ? ' - ' : '' %>
<% m = homeState.getMemberByGroupAndProfileId( a.getTeamId(), ad[ ai ].profile_id ); %>
<% cp = m ? m.getChildProfileById( ad[ ai ].profile_child_id ) : null; %>
<% if ( m ) { %>
<%= m.getName( a.getTeamId() ) %>
<% if ( cp ) { %>
[<%=raw m.getChildProfileHtmlTagById( cp.id ) %>]
<% } %>
</td>
</tr>
<tr>
<td>
Absagen&nbsp;(<%= a.getProfileIdsDeclined().length %>)
</td>
<% ad = a.getAttendeeDataByStatus( "declined" ); %>
<td>
<% if ( ad.length > 0 ) { %>
<% for ( let ai = 0; ai < ad.length; ai++ ) { %>
<%= ai > 0 ? ' - ' : '' %>
<% m = homeState.getMemberByGroupAndProfileId( a.getTeamId(), ad[ ai ].profile_id ); %>
<% cp = m ? m.getChildProfileById( ad[ ai ].profile_child_id ) : null; %>
<% if ( m ) { %>
<%= m.getName( a.getTeamId() ) %>
<% if ( cp ) { %>
[<%=raw m.getChildProfileHtmlTagById( cp.id ) %>]
<% } %>
<% } else { %>
<i>Gelöscht</i>
<% } %>
<% } else { %>
<i>Gelöscht</i>
<% } %>
<% } %>
<% } %>
</td>
</tr>
</table>
<% } %>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="row">
<div class="col">
<% if ( false === a.isDraft() ) { %>
<a href="#/appointment/<%= a.getId() %>"
class="btn btn-primary"><i class="fas fa-search"></i></a>
<a href="#/appointment/<%= a.getId() %>/attendee"
class="btn btn-primary"><i class="fas fa-users"></i></a>
<a href="#/appointment/<%= a.getId() %>/chat"
class="btn btn-primary"><i class="far fa-comments"></i></a>
<% } %>
<% if ( app.model.SessionUser.canAdministrateTeam( a.getTeamId() ) ) { %>
<div class="row">
<div class="col">
<% if ( false === a.isDraft() ) { %>
<a href="#/appointment/<%= a.getId() %>"
class="btn btn-primary"><i class="fas fa-search"></i></a>
<a href="#/appointment/<%= a.getId() %>/attendee"
class="btn btn-primary"><i class="fas fa-users"></i></a>
<a href="#/appointment/<%= a.getId() %>/chat"
class="btn btn-primary"><i class="far fa-comments"></i></a>
<% } %>
<% if ( app.model.SessionUser.canAdministrateTeam( a.getTeamId() ) ) { %>
<% if ( a.isDraft() ) { %>
<% if ( a.isDraft() ) { %>
<button data-type="btn-appoint-publish"
data-appointment-id="<%= a.getId() %>"
style="margin-left: 4px"
class="float-right btn btn-primary">
<%= _lc( 'BTN_PUBLISH_APPOINTMENT' ) %>
</button>
<button data-type="btn-appoint-publish"
data-appointment-id="<%= a.getId() %>"
style="margin-left: 4px"
class="float-right btn btn-primary">
<%= _lc( 'BTN_PUBLISH_APPOINTMENT' ) %>
</button>
<button href="#/appointment/edit/<%= a.getId() %>/attendee"
data-type="btn-appointment-edit-attendee"
data-appointment-id="<%= a.getId() %>"
style="margin-left: 4px"
class="float-right btn btn-primary">
<i class="fas fa-user-edit"></i>
</button>
<button href="#/appointment/edit/<%= a.getId() %>/attendee"
data-type="btn-appointment-edit-attendee"
data-appointment-id="<%= a.getId() %>"
style="margin-left: 4px"
class="float-right btn btn-primary">
<i class="fas fa-user-edit"></i>
</button>
<button
style="margin-left: 4px"
data-type="btn-appointment-edit"
data-appointment-id="<%= a.getId() %>"
class="float-right btn btn-primary">
<i class="far fa-edit"></i>
</button>
<button
style="margin-left: 4px"
data-type="btn-appointment-edit"
data-appointment-id="<%= a.getId() %>"
class="float-right btn btn-primary">
<i class="far fa-edit"></i>
</button>
<% } %>
<% } %>
<% if ( a.isCancelled() || a.isDraft() || a.isOver() ) { %>
<% if ( a.isCancelled() || a.isDraft() || a.isOver() ) { %>
<button data-type="btn-appoint-delete"
data-appointment-id="<%= a.getId() %>"
class="float-right btn btn-danger">
<i class="far fa-trash-alt"></i>
</button>
<button data-type="btn-appoint-delete"
data-appointment-id="<%= a.getId() %>"
class="float-right btn btn-danger">
<i class="far fa-trash-alt"></i>
</button>
<% } else { %>
<% } else { %>
<button data-type="btn-appoint-cancel"
data-appointment-id="<%= a.getId() %>"
class="float-right btn btn-danger"><i class="far fa-window-close"></i></button>
<button data-type="btn-appoint-cancel"
data-appointment-id="<%= a.getId() %>"
class="float-right btn btn-danger"><i class="far fa-window-close"></i></button>
<% } %>
<% } %>
<% } %>
<% } %>
</div>
</div>
</div>
</div>
<% } %>
</div>

+ 21
- 9
src/client/app/tmpl/home.html Vedi File

@@ -1,6 +1,20 @@
<% var data = this.stash; %>
<% var currentUser = app.model.SessionUser.getUserProfile(); %>
<% var groupsOwner = currentUser.getGroupsByRole( 'trainer' ), groupDataOwner = groupsOwner.length >= 1 ? groupsOwner[ 0 ] : null; %>
<% if ( "" !== groupsNotActiveString ) { %>
<div class="row">
<div class="col-sm-12">
<div class="alert alert-info">
<i class="fa fa-info-circle"></i>
<%= _lc( 'HOME_GROUPS_NOT_ACTIVE_TEXT1' ) %><strong><%= groupsNotActiveString %></strong><br/>
<%= _lc( 'HOME_GROUPS_NOT_ACTIVE_TEXT2' ) %>
<a class="btn btn-sm btn-info" href="#/groups"><%= _lc( 'HOME_GROUPS_NOT_ACTIVE_BTN' ) %></a>
</div>
</div>
</div>
<% } %>
<% if ( 0 === appointments.length ) { %>
<h4>
@@ -36,17 +50,15 @@
<% } else { %>
<% if ( true === currentUser.isOlderThanTwoWeeks() && false === currentUser.hasValidAddressData() ) { %>
<div class="row">
<div class="col-sm-12">
<div class="alert alert-info">
<i class="fa fa-info-circle"></i>&nbsp;Bitte vervollständigen Sie Ihre Adressdaten. <a class="btn btn-sm btn-info" href="#/configuration/account/edit-address">Adressdaten hinterlegen</a>
<% if ( true === currentUser.isOlderThanTwoWeeks() && false === currentUser.hasValidAddressData() ) { %>
<div class="row">
<div class="col-sm-12">
<div class="alert alert-info">
<i class="fa fa-info-circle"></i>&nbsp;Bitte vervollständigen Sie Ihre Adressdaten. <a class="btn btn-sm btn-info" href="#/configuration/account/edit-address">Adressdaten hinterlegen</a>
</div>
</div>
</div>
</div>
<% } %>
<% } %>
<% var monthHeader = null, weekHeader = null, currentMonth, currentWeek, currentWeekMoment, a, mStart, mEnd, mDeadline; %>


+ 2
- 0
src/server/server/control/TB_Server_Control_Appointment.php Vedi File

@@ -936,6 +936,8 @@ class TB_Server_Control_Appointment {
continue;
}
$appointment->v_profile_can_attend = $appointment->isAttendableByProfile($profile);
array_push( $accessibleAppointments, $appointment );
// Add attendee information


+ 1
- 1
src/server/server/control/TB_Server_Control_Auth.php Vedi File

@@ -297,7 +297,7 @@ class TB_Server_Control_Auth
}
// Create team data
$profile->joinTeam( $team->id );
$profile->joinTeam( $team );
$profile->save();
if ( 0 == $account->is_validated )


+ 2
- 1
src/server/server/control/TB_Server_Control_Team.php Vedi File

@@ -642,6 +642,7 @@ class TB_Server_Control_Team {
$team->description = _xss( $params->get( 'description' ) );
$team->terms_conditions = _xss( $params->get( 'termsConditions' ) );
$team->terms_conditions_active = $params->get( 'termsConditionsActive' ) === true ? 1 : 0;
$team->new_users_active = $params->get( 'newUsersActive' ) === true ? 1 : 0;
$team->contact_information = _xss( $params->get( 'contactInformation' ) );
$team->save();
@@ -1091,7 +1092,7 @@ class TB_Server_Control_Team {
throw new \Exception( 'Group not found.' );
}
$sessionProfile->joinTeam( $team->id );
$sessionProfile->joinTeam( $team );
$sessionProfile->save();
$resp->addData( 'profile', $sessionProfile );


+ 8
- 4
src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php Vedi File

@@ -23,6 +23,7 @@
* @property string|null $comment
* @property integer $price_factor
* @property string $state
* @property string $v_profile_can_attend
*/
class TB_Shared_Ent_TeamData_Appointment extends Francis_Db_Row
{
@@ -380,15 +381,18 @@ class TB_Shared_Ent_TeamData_Appointment extends Francis_Db_Row
}
}
}
return $isVisible;
}
// Check if user is not approved in group yet
public function isAttendableByProfile( TB_Shared_Ent_TeamData_Profile $profile )
{
$profileTeamData = $profile->getTeamsData($this->team_id);
// Check if user is not approved in group yet
if ($profileTeamData['status'] === TB_Shared_Ent_TeamData_Profile::STATUS_NOT_APPROVED ||
$profileTeamData['status'] === TB_Shared_Ent_TeamData_Profile::STATUS_INACTIVE) {
$isVisible = false;
return false;
}
return $isVisible;
return true;
}
/**


+ 4
- 4
src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Profile.php Vedi File

@@ -490,12 +490,12 @@ class TB_Shared_Ent_TeamData_Profile extends Francis_Db_Row {
/**
* @param $teamId
*/
public function joinTeam( $teamId )
public function joinTeam( TB_Shared_Ent_TeamData_Team $team )
{
// Note: right now - all joins are with role PLAYER only
$role = TB_Shared_Ent_TeamData_Profile::ROLE_PLAYER;
if ( $this->isInTeam( $teamId ) )
if ( $this->isInTeam( $team->id ) )
{
return;
}
@@ -506,11 +506,11 @@ class TB_Shared_Ent_TeamData_Profile extends Francis_Db_Row {
$teamsJson = array();
}
$teamsJson[] = array(
'team_id' => $teamId,
'team_id' => $team->id,
'role' => TB_Shared_Ent_TeamData_Profile::ROLE_PLAYER,
'is_anonymous' => 0,
'join_dt' => TB_Server_Utils_Helper::getUTCNowDateTime(),
'status' => self::STATUS_NOT_APPROVED,
'status' => $team->new_users_active ? self::STATUS_ACTIVE : self::STATUS_NOT_APPROVED,
'terms_accepted' => 0
);


+ 1
- 0
src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Team.php Vedi File

@@ -14,6 +14,7 @@
* @property string|NULL $contact_information
* @property string|NULL $terms_conditions
* @property bool $terms_conditions_active
* @property bool $new_users_active
* @property string $emblem_url
* @property string $emblem_cloud_id
* @property array|null $course_categories_js


tools/patches/addActiveStateToProfile.php → tools/patches/1addActiveStateToProfile.php Vedi File


tools/patches/addTermsConditionsToTeam.php → tools/patches/2addDbTermsConditionsToTeam.php Vedi File


tools/patches/addTermsAcceptedToProfile.php → tools/patches/3addTermsAcceptedToProfile.php Vedi File


+ 18
- 0
tools/patches/4addDbNewUsersActive.php Vedi File

@@ -0,0 +1,18 @@
<?php

require_once __DIR__ . '/../../src/server/server/config/boot_global.php';
require_once __DIR__ . '/../../src/server/server/config/boot_local.php';

function patch_addTermsConditionsToTeam()
{

$db = TB_Shared_Db_TeamData::get();

$sql = "ALTER TABLE team
ADD COLUMN new_users_active TINYINT(1) NOT NULL DEFAULT 0 AFTER terms_conditions_active;";
$stmt = $db->query( $sql );

echo "DONE...";
}

patch_addTermsConditionsToTeam();

Caricamento…
Annulla
Salva