def errors(self): errors = [] if not self.class_teacher_fullname or not self.class_teacher_natel: errors.append(u("Enseignant")) if not self.n_participants: errors.append(u("Nombre de participants")) if not self.leader or self.helpers.count() != MAX_MONO1_PER_QUALI: errors.append(u("Moniteurs")) if not self.actor: errors.append(u("Intervenant")) if not self.activity_A or not self.activity_B or not self.activity_C: errors.append(u('Postes')) if errors: return mark_safe( '<br />'.join([ '<span class="btn-warning btn-xs disabled">' ' <span class="glyphicon glyphicon-warning-sign"></span>' ' %s' '</span>' % e for e in errors]) )
def get_dataset(self): dataset = Dataset() # Prépare le fichier dataset.append_col([ u('Date'), u('Canton'), u('Établissement'), u('Emplacement'), u('Heures'), u('Nombre de qualifs'), # Logistique u('Moniteur +'), u('Mauvais temps'), u('Pommes'), u('Total vélos'), u('Total casques'), u('Remarques'), # Qualif u('Classe'), u('Enseignant'), u('Moniteur 2'), u('Moniteur 1'), u('Moniteur 1'), u('Nombre d\'élèves'), u('Nombre de vélos'), u('Nombre de casques'), CATEGORY_CHOICE_A, CATEGORY_CHOICE_B, CATEGORY_CHOICE_C, u('Intervenant'), u('Remarques'), ]) session = self.object session_place = session.place if not session_place: session_place = ( session.address_city if session.address_city else session.organization.address_city ) col = [ date(session.day), session.organization.address_canton, session.organization.name, session_place, '%s - %s' % (time(session.begin), time(session.end)), session.n_qualifications, EXPORT_NAMETEL.format( name=session.superleader.get_full_name(), tel=session.superleader.profile.natel ) if session.superleader else '', str(session.fallback), session.apples, session.n_bikes, session.n_helmets, session.comments, ] if session.n_qualifications: for quali in session.qualifications.all(): if not len(col): col = [''] * 12 col.append(quali.name) col.append( EXPORT_NAMETEL.format( name=quali.class_teacher_fullname, tel=quali.class_teacher_natel ) if quali.class_teacher_fullname else '' ) col.append( EXPORT_NAMETEL.format( name=quali.leader.get_full_name(), tel=quali.leader.profile.natel ) if quali.leader else '' ) for i in range(2): try: helper = quali.helpers.all()[i] col.append( EXPORT_NAMETEL.format( name=helper.get_full_name(), tel=helper.profile.natel ) if helper else '' ) except IndexError: col.append('') col.append(quali.n_participants) col.append(quali.n_bikes) col.append(quali.n_helmets) col.append( str(quali.activity_A) if quali.activity_A else '') col.append( str(quali.activity_B) if quali.activity_B else '') col.append( str(quali.activity_C) if quali.activity_C else '') col.append( EXPORT_NAMETEL.format( name=quali.actor.get_full_name(), tel=quali.actor.profile.natel ) if quali.actor else '' ) col.append(quali.comments) dataset.append_col(col) col = [] else: col += [''] * 13 dataset.append_col(col) return dataset
from django.views.generic.detail import DetailView from django.views.generic.edit import CreateView, DeleteView, UpdateView from rolepermissions.mixins import HasPermissionsMixin from tablib import Dataset from apps.common.views import ExportMixin from defivelo.views import MenuView from ..forms import SessionForm from ..models import Session from ..models.qualification import ( CATEGORY_CHOICE_A, CATEGORY_CHOICE_B, CATEGORY_CHOICE_C, ) from .mixins import CantonSeasonFormMixin EXPORT_NAMETEL = u('{name} - {tel}') class SessionMixin(CantonSeasonFormMixin, HasPermissionsMixin, MenuView): required_permission = 'challenge_session_crud' model = Session context_object_name = 'session' form_class = SessionForm def get_queryset(self): qs = super(SessionMixin, self).get_queryset() try: return qs.filter( organization__address_canton__in=self.season.cantons ) except FieldError:
def get_dataset(self): dataset = Dataset() firstcol = [ u('Date'), u('Canton'), u('Établissement'), u('Emplacement'), u('Heures'), u('Nombre de qualifs'), ] # Trouve toutes les personnes qui sont présentes dans cette saison qs = get_user_model().objects user_filter = [ # Moniteurs + Q(sess_monplus__in=self.season.sessions_with_qualifs), # Moniteurs 2 Q(qualifs_mon2__session__in=self.season.sessions_with_qualifs), # Moniteurs 1 Q(qualifs_mon1__session__in=self.season.sessions_with_qualifs), # Intervenants Q(qualifs_actor__session__in=self.season.sessions_with_qualifs), ] qs = ( qs.filter(reduce(operator.or_, user_filter)) .distinct() .order_by('first_name', 'last_name') ) firstcol += [user.get_full_name() for user in qs] dataset.append_col(firstcol) for session in self.season.sessions_with_qualifs: session_place = session.place if not session_place: session_place = ( session.address_city if session.address_city else session.organization.address_city ) col = [ date(session.day), session.organization.address_canton, session.organization.name, session_place, '%s - %s' % (time(session.begin), time(session.end)), session.n_qualifications, ] for user in qs: label = '' if user == session.superleader: # Translators: Nom court pour 'Moniteur +' label = u('M+') else: for quali in session.qualifications.all(): if user == quali.leader: # Translators: Nom court pour 'Moniteur 2' label = u('M2') break elif user in quali.helpers.all(): # Translators: Nom court pour 'Moniteur 1' label = u('M1') break elif user == quali.actor: # Translators: Nom court pour 'Intervenant' label = u('I') break col += [label] dataset.append_col(col) return dataset
class FileUploadHistory(models.Model): ENQUEUED = u'Enqueued' PROCESSING = u'Processing' PROCESSED = u'Processed' FAILED = u'Failed' STATE_CHOICES = ( (ENQUEUED, ENQUEUED), (PROCESSING, PROCESSING), (PROCESSED, PROCESSED), (FAILED, FAILED), ) type = models.CharField(max_length=50) # uploaded_file max_length=100. Filename must have maximum of 73 chars (100 - 27 = 73) uploaded_file = models.FileField(upload_to=content_file_name) # if zina_compatible: # from django.contrib.auth.models import User # user_model = User # # else: # pass # user_model = get_user_model() TODO: Fix import # When user is None, the instance was created by scripts etc. user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='file_upload_history', on_delete=models.SET_NULL) # Execution attributes results = models.TextField(blank=True) state = models.CharField(max_length=16, null=True, blank=True, choices=STATE_CHOICES) upload_timestamp = models.DateTimeField(auto_now_add=True) # upload_time start_execution_timestamp = models.DateTimeField(null=True, blank=True, default=None) finish_execution_timestamp = models.DateTimeField(null=True, blank=True, default=None) notification_sent = models.NullBooleanField(default=False) original_filename = models.CharField(max_length=100, null=True, blank=True, default=None) form_params = models.TextField(blank=True, null=True) validate_end = models.NullBooleanField() celery_tasks = models.CharField(max_length=250, null=True, blank=True) objects = FileUploadHistoryManager() sheet_importers = models.ManyToManyField('neo_importer.FileUploadHistory', null=True, blank=True, verbose_name=u('sheet importers')) # class Meta: # db_table = 'data_importer_fileuploadhistory' def __unicode__(self): return '[%s] %s' % (str(self.upload_timestamp), self.type) def __str__(self): return '[%s] %s' % (str(self.upload_timestamp), self.type) def duration(self): "Duration includes the time the task is waiting in celery to be processed." if not self.finish_execution_timestamp or not self.start_execution_timestamp: return timedelta(0) return self.finish_execution_timestamp - self.start_execution_timestamp def is_processed(self): return self.state == self.PROCESSED def results_as_html(self): return mark_safe('<p>%s</p>' % self.results.replace('\n', '<br/>')) def file_link(self): if self.uploaded_file and os.path.exists(self.uploaded_file.path): _url = reverse('data_importer:download_file', args=[ self.id, ]) return "<a href='%s'>Download</a>" % _url else: return 'No attachment' file_link.allow_tags = True def save(self, *args, **kwargs): if self.original_filename is None and self.uploaded_file: self.original_filename = self.uploaded_file.name super(FileUploadHistory, self).save() def decode_results(self): if not self.sheet_importers.exists(): return self.decode_data(self.results) return [ self.decode_data(i.results) for i in self.sheet_importers.all() ] def encode_data(self, data): import zlib, base64 if not isinstance(data, str): data = json.dumps(data, default=lambda o: o.__dict__) try: data = zlib.compress(bytearray(data, encoding='UTF-8'), 9) except: data = zlib.compress(data, 9) return base64.b64encode(data) @classmethod def decode_data(cls, data): if not data: return {} import zlib, base64 try: data = zlib.decompress(base64.b64decode(data)).decode('utf-8') data = json.loads(data) except ValueError: data = {} return data def get_form_params(self): return self.decode_data(self.form_params) def set_form_params(self, data): form_params = self.encode_data(data) if (type(form_params).__name__ == 'bytes'): form_params = form_params.decode() self.form_params = form_params
from __future__ import unicode_literals from django.conf import settings from django.db import models from django.db.models import Q from django.utils.encoding import python_2_unicode_compatible from django.utils.safestring import mark_safe from django.utils.translation import ugettext as u, ugettext_lazy as _ from parler.models import TranslatableModel, TranslatedFields from apps.user import FORMATION_KEYS, FORMATION_M2 from .. import MAX_MONO1_PER_QUALI from .session import Session CATEGORY_CHOICE_A = u('Vélo urbain') CATEGORY_CHOICE_B = u('Mécanique') CATEGORY_CHOICE_C = u('Rencontre') CATEGORY_CHOICES = ( ('A', CATEGORY_CHOICE_A), ('B', CATEGORY_CHOICE_B), ('C', CATEGORY_CHOICE_C), ) @python_2_unicode_compatible class QualificationActivity(TranslatableModel): translations = TranslatedFields( name=models.CharField(_('Nom'), max_length=255)