#145: populate allPersons from other events with the same Group ID

This commit is contained in:
Davide Alberani 2016-07-03 14:13:27 +02:00
parent 06d49cf27e
commit 7d79d35992
5 changed files with 87 additions and 36 deletions

View file

@ -9,7 +9,7 @@
</button>
&nbsp;<button ng-if="event._id && hasPermission('event:tickets-all|create')" ng-click="$state.go('event.ticket.new', {id: event._id})" class="btn btn-success">
<span class="fa fa-user-plus vcenter"></span>
{{'Register' | translate}}
{{'Join this event' | translate}}
</button>
&nbsp;<span ng-if="hasPermission('event|create') && !event.title">{{'New event' | translate}}</span>{{event.title}}
</h1>
@ -77,6 +77,10 @@
<span class="input-group-addon min100">{{'Where' | translate}}</span>
<input type="text" class="form-control" placeholder="{{'Where' | translate}}" ng-model="event.where">
</div>
<div class="input-group input-group-lg top5">
<span class="input-group-addon min100">{{'Group ID' | translate}}</span>
<input type="text" class="form-control" placeholder="{{'Used to share persons amongst multiple events. Must be hard to guess (if empty, will be autogenerated)' | translate}}" ng-model="event.group_id">
</div>
</fieldset>

View file

@ -45,7 +45,7 @@
<thead>
<tr>
<th class="text-right nowrap">#</th>
<th class="nowrap">{{'Person' | translate}} <a ng-click="updateOrded('name')" href=""><i class="fa fa-caret-up"></i></a>{{'Name' | translate}}<a ng-click="updateOrded('-name')" href=""><i class="fa fa-caret-down"></i></a> <a ng-click="updateOrded('surname')" href=""><i class="fa fa-caret-up"></i></a>{{'Surname' | translate}}<a ng-click="updateOrded('-surname')" href=""><i class="fa fa-caret-down"></i></a></th>
<th class="nowrap"><a ng-click="updateOrded('name')" href=""><i class="fa fa-caret-up"></i></a>{{'Name' | translate}}<a ng-click="updateOrded('-name')" href=""><i class="fa fa-caret-down"></i></a> <a ng-click="updateOrded('surname')" href=""><i class="fa fa-caret-up"></i></a>{{'Surname' | translate}}<a ng-click="updateOrded('-surname')" href=""><i class="fa fa-caret-down"></i></a></th>
<th class="text-center nowrap"><a ng-click="updateOrded('-attended')" href=""><i class="fa fa-caret-up"></i></a>{{'Attended' | translate}}<a ng-click="updateOrded('attended')" href=""><i class="fa fa-caret-down"></i></a></th>
<th class="text-center nowrap" ng-repeat="col in customFields">
<a ng-click="updateOrded(col.key)" href=""><i class="fa fa-caret-up"></i></a>{{col.label | translate}}<a ng-click="updateOrded('-' + col.key)" href=""><i class="fa fa-caret-down"></i></a>
@ -61,11 +61,11 @@
<p ng-if="person.company || person.job_title"><i ng-if="person.job_title">{{person.job_title}}</i><span ng-if="person.company && person.job_title">&nbsp;@&nbsp;</span><i ng-if="person.company">{{person.company}}</i></p>
</td>
<td class="text-center">
<button class="btn btn-link" reset-focus name="switch-attended" ng-click="setPersonAttributeAndRefocus(person, 'attended', !person.attended)"><span class="fa fa-lg {{(person.attended) && 'fa-check-circle text-success' || 'fa-times-circle text-danger'}}"></span></button>
<button class="btn btn-link" reset-focus name="switch-attended" ng-click="setTicketAttributeAndRefocus(person, 'attended', !person.attended)"><span class="fa fa-lg {{(person.attended) && 'fa-check-circle text-success' || 'fa-times-circle text-danger'}}"></span></button>
</td>
<td class="text-center" ng-repeat="col in customFields">
<span ng-if="col.type == 'boolean'">
<button class="btn btn-link" ng-click="setPersonAttribute(person, col.key, !person[col.key])"><span class="fa fa-lg {{(person[col.key]) && 'fa-check-circle text-success' || 'fa-times-circle text-danger'}}"></span></button>
<button class="btn btn-link" ng-click="setTicketAttribute(person, col.key, !person[col.key])"><span class="fa fa-lg {{(person[col.key]) && 'fa-check-circle text-success' || 'fa-times-circle text-danger'}}"></span></button>
</span>
<span ng-if="col.type != 'boolean'">
{{person[col.key]}}

View file

@ -180,7 +180,7 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
// Managing the list of tickets.
if ($state.is('event.tickets')) {
$scope.allPersons = Person.all();
$scope.allPersons = Event.group_persons({id: $state.params.id});
// Handle WebSocket connection used to update the list of persons.
$scope.EventUpdates = EventUpdates;
@ -203,7 +203,6 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
var person_idx = $scope.event.persons.findIndex(function(el, idx, array) {
return data._id == el._id;
});
$log.debug(data);
if (person_idx != -1) {
$log.debug('_id ' + data._id + ' found');
} else {
@ -238,21 +237,43 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
/* Stuff to do when a ticket is added, modified or removed locally. */
$scope._localAddTicket = function(person) {
$scope._localAddTicket = function(ticket, original_person) {
var ret = true;
if (!$scope.event.persons) {
$scope.event.persons = [];
}
var person_idx = $scope.event.persons.findIndex(function(el, idx, array) {
return person._id == el._id;
var ticket_idx = $scope.event.persons.findIndex(function(el, idx, array) {
return ticket._id == el._id;
});
if (person_idx != -1) {
$log.debug('person already present: not added');
return false;
if (ticket_idx != -1) {
$log.warn('ticket already present: not added');
ret = false;
} else {
$scope.event.persons.push(ticket);
}
$scope.event.persons.push(person);
// Try to remove this person from the allPersons list using ID or email.
var field = null;
var field_value = null;
if (original_person && original_person._id) {
field = '_id';
field_value = original_person._id;
} else if (ticket.email) {
field = 'email';
field_value = ticket.email;
}
if (field) {
var all_person_idx = $scope.allPersons.findIndex(function(el, idx, array) {
return field_value == el[field];
});
if (all_person_idx != -1) {
$scope.allPersons.splice(all_person_idx, 1);
}
}
return ret;
};
$scope._localUpdateTicket(ticket) {
$scope._localUpdateTicket = function(ticket) {
if (!$scope.event.persons) {
$scope.event.persons = [];
}
@ -260,15 +281,13 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
return ticket._id == el._id;
});
if (ticket_idx == -1) {
$log.debug('person not present: not updated');
$log.warn('ticket not present: not updated');
return false;
}
$scope.event.persons[ticket_idx] = ticket;
});
};
$scope._localRemoveTicket = function(person) {
$log.debug('_localRemoveTicket');
$log.debug(person);
if (!(person && person._id && $scope.event.persons)) {
return;
}
@ -292,10 +311,8 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
}
};
$scope.setPersonAttribute = function(person, key, value, callback, hideMessage) {
$log.debug('EventDetailsCtrl.setPersonAttribute.event_id: ' + $state.params.id);
$log.debug('EventDetailsCtrl.setPersonAttribute._id: ' + person._id);
$log.debug('EventDetailsCtrl.setPersonAttribute.key: ' + key + ' value: ' + value);
$scope.setTicketAttribute = function(person, key, value, callback, hideMessage) {
$log.debug('setTicketAttribute for _id ' + person._id + ' key: ' + key + ' value: ' + value);
var newData = {event_id: $state.params.id, _id: person._id};
newData[key] = value;
EventTicket.update(newData, function(data) {
@ -328,20 +345,13 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
});
};
$scope.setPersonAttributeAndRefocus = function(person, key, value) {
$scope.setPersonAttribute(person, key, value);
$scope.setTicketAttributeAndRefocus = function(person, key, value) {
$scope.setTicketAttribute(person, key, value);
$scope.query = '';
};
$scope._setAttended = function(person) {
$scope.setPersonAttribute(person, 'attended', true, function() {
var all_person_idx = $scope.allPersons.findIndex(function(el, idx, array) {
return person._id == el._id;
});
if (all_person_idx != -1) {
$scope.allPersons.splice(all_person_idx, 1);
}
}, true);
$scope.setTicketAttribute(person, 'attended', true, null, true);
};
$scope.deleteTicket = function(person) {
@ -356,8 +366,9 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
$scope.addTicket = function(person) {
person.event_id = $state.params.id;
EventTicket.add(person, function(ticket) {
$log.debug('addTicket');
$log.debug(ticket);
$scope._localAddTicket(ticket);
$scope._localAddTicket(ticket, person);
if (!$state.is('event.tickets')) {
$state.go('event.ticket.edit', {id: $scope.event._id, ticket_id: ticket._id});
} else {
@ -385,7 +396,7 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
return;
}
$scope.ticket.cancelled = !$scope.ticket.cancelled;
$scope.setPersonAttribute($scope.ticket, 'cancelled', $scope.ticket.cancelled, function() {
$scope.setTicketAttribute($scope.ticket, 'cancelled', $scope.ticket.cancelled, function() {
$scope.guiOptions.dangerousActionsEnabled = false;
});
};
@ -570,7 +581,7 @@ eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$state', 'Person
$scope.personForm.$setPristine(false);
};
$scope.setPersonAttributeAtEvent = function(evnt, key, value) {
$scope.setTicketAttributeAtEvent = function(evnt, key, value) {
var attrs = {_id: evnt._id, person_id: $state.params.id};
attrs[key] = value;
Event.updatePerson(attrs,

View file

@ -18,7 +18,7 @@ function convert_dates(obj) {
eventManServices.factory('Event', ['$resource', '$rootScope',
function($resource, $rootScope) {
return $resource('events/:id', {id: '@_id', ticket_id: '@_id'}, {
return $resource('events/:id', {id: '@_id'}, {
all: {
method: 'GET',
@ -58,6 +58,16 @@ eventManServices.factory('Event', ['$resource', '$rootScope',
update: {
method: 'PUT',
interceptor : {responseError: $rootScope.errorHandler}
},
group_persons: {
method: 'GET',
url: 'events/:id/group_persons',
isArray: true,
transformResponse: function(data, headers) {
data = angular.fromJson(data);
return data.persons || [];
}
}
});
}]

View file

@ -576,6 +576,15 @@ class EventsHandler(CollectionHandler):
event['persons'] = []
return output
def filter_input_post(self, data):
# Auto-generate the group_id, if missing.
if 'group_id' not in data:
data['group_id'] = self.gen_id()
return data
filter_input_post_all = filter_input_post
filter_input_put = filter_input_post
def filter_input_post_tickets(self, data):
if not self.has_permission('event|update'):
if 'attended' in data:
@ -584,6 +593,23 @@ class EventsHandler(CollectionHandler):
filter_input_put_tickets = filter_input_post_tickets
def handle_get_group_persons(self, id_, resource_id=None):
persons = []
this_query = {'_id': id_}
this_event = self.db.query('events', this_query)[0]
group_id = this_event.get('group_id')
if group_id is None:
return {'persons': persons}
this_persons = [p for p in (this_event.get('persons') or []) if not p.get('cancelled')]
this_emails = filter(None, [p.get('email') for p in this_persons])
all_query = {'group_id': group_id}
events = self.db.query('events', all_query)
for event in events:
if str(event.get('_id')) == id_:
continue
persons += [p for p in (event.get('persons') or []) if p.get('email') and p.get('email') not in this_emails]
return {'persons': persons}
def _get_person_data(self, person_id_or_query, persons):
"""Filter a list of persons returning the first item with a given person_id
or which set of keys specified in a dictionary match their respective values."""