class IUTPerson(model.Schema):

    personTitle = schema.Choice(
        title=_('Salutation'),
        source=getPersonTitleVocabulary(),
        required=False
    )

    email = schema.TextLine(
        title=_(u'E-Mail'),
        required=True
    )

    prename = schema.TextLine(
        title=_(u'Prename'),
        required=True
    )

    surname = schema.TextLine(
        title=_(u'Surname'),
        required=True
    )

    note = schema.TextLine(
        title=_(u'Note'),
        required=False
    )
def sendSignOffNotification(person):
    isEmail = validation.validatorFor('isEmail')
    timeSlot = person.aq_parent
    day = timeSlot.aq_parent
    signupSheet = day.aq_parent

    lang = ILanguage(signupSheet).get_language()
    if len(lang) == 0:
        lang = 'de'

    contactInfo = signupSheet.contactInfo
    extraInfoStr = person.getExtraInfoAsString()
    fromEmail = signupSheet.contactInfo

    # mail to person who signed up
    if isEmail(person.email) != 1:
        return

    url = signupSheet.absolute_url()
    toEmail = person.email

    subject = signupSheet.emailCancelSubject
    if subject is None or len(subject) == 0:
        subject = signupSheet.Title() + ' - ' \
                  + translate(_(u'Cancellation Notification'),
                              target_language=lang)
    else:
        subject = replaceCustomMailPlaceholders(
            subject, person.Title(), signupSheet.Title(), url,
            timeSlot.getLabel(), extraInfoStr)

    content = signupSheet.emailCancelContent
    if content is not None and len(content) > 0:
        message = replaceCustomMailPlaceholders(
            content, person.Title(), signupSheet.Title(), url,
            timeSlot.getLabel(), extraInfoStr)
    else:
        # default message if no content has been specified
        message = translate(_(u'Hello'), target_language=lang) + ' ' + person.Title() + ',\n\n'
        message += translate(_(u'Following slot has been cancelled:'),
                             target_language=lang) + '\n'
        message += timeSlot.getLabel() + '\n\n'

        if len(extraInfoStr) > 0:
            message += translate(_(u'Additional information'),
                                 target_language=lang) + '\n'
            message += extraInfoStr + '\n\n'

        if len(contactInfo) > 0:
            message += translate(_('If you have any questions please contact:'),
                                 target_language=lang) + ' ' + contactInfo + '\n\n'

        message += url + '\n\n'

    api.portal.send_email(recipient=toEmail, sender=fromEmail,
                          subject=subject, body=message)
Exemple #3
0
 def getCurrentState(self):
     state = api.content.get_state(self.context)
     if state == 'signedup':
         return (_(u'Signed Up'), 'bg-success')
     elif state == 'unconfirmed':
         return (_(u'Waiting for confirmation'), 'bg-warning')
     elif state == 'signedoff':
         return (_(u'Signed off'), 'bg-danger')
     elif state == 'waiting':
         return (_(u'Waiting List'), 'bg-info')
Exemple #4
0
def translateReviewState(state):
    mappings = {
        'signedup': _(u'Signed Up'),
        'signedoff': _(u'Signed Off'),
        'unconfirmed': _(u'Waiting for confirmation'),
        'waiting': _(u'Waiting List'),
    }
    if state not in mappings:
        return state
    return mappings[state]
Exemple #5
0
    def getSlotAndSignUserUpForIt(self, slotIDLabel):
        status = 'error'
        error = ''

        allowSignupForMultipleSlots = self.context.allowSignupForMultipleSlots

        (date, time) = slotIDLabel.split(' @ ')
        day = self.context.getDay(date)
        timeSlot = day.getTimeSlot(time, True)
        slotTitleLabel = timeSlot.getLabel()
        allowWaitingList = timeSlot.allowWaitingList
        numberOfAvailableSlots = timeSlot.getNumberOfAvailableSlots()

        if (not allowSignupForMultipleSlots
            ) and self.context.countSlotsByEmail(self.email) > 0:
            error = _(
                'You are already signed up for a slot in this signup sheet.')

        elif timeSlot.isUserSignedUpForThisSlot(self.email):
            error = _('You are already signed up for this slot.')

        elif allowWaitingList or numberOfAvailableSlots > 0:
            person = self.createPersonObject(timeSlot)

            if numberOfAvailableSlots > 0:
                if self.context.signupsRequireConfirmation:
                    if self.isEmailValid():
                        self.sendWaitForConfirmationEmail(
                            self.context, slotTitleLabel, person)
                        status = 'unconfirmed'
                else:
                    # sign up user directly if there are available slots and
                    # no confirmation by the manager is required
                    self.signupPerson(person)
                    status = 'signedup'
            else:
                self.putPersonOnWaitingList(person)
                status = 'waiting'

            # purge signup view to make sure everybody sees updated info
            notify(Purge(self.context))
        else:
            error = _(
                'The slot you selected is already full. Please select a different one.'
            )

        result = dict()
        result['slotLabel'] = slotTitleLabel
        result['status'] = status
        result['error'] = error
        self.results.append(result)
Exemple #6
0
class IUTTimeslot(model.Schema):

    directives.widget(
        'startTime', DatetimeWidget, pattern_options={'date': 'false'})
    startTime = schema.Timedelta(
        title=_('Start Time'),
        required=True
    )

    directives.widget(
        'endTime', DatetimeWidget, pattern_options={'date': 'false'})
    endTime = schema.Timedelta(
        title=_(u'End Time'),
        required=True
    )

    name = schema.TextLine(
        title=_(u'Name'),
        description=_(u'Optional name'),
        required=False
    )

    maxCapacity = schema.Int(
        title=_(u'Max capacity'),
        description=_(u'The max number of people'),
        required=True,
        default=1
    )

    allowWaitingList = schema.Bool(
        title=_(u'Allow Waiting List'),
        description=_(u'Check if you want to allow signups to waiting list once max capacity is reached')  # noqa: E501
    )
 def getExtraInfo(self):
     extraInfo = []
     fields = getAllExtraFields(self)
     for field in fields:
         value = getattr(self, field['name'], '')
         extraInfo.append((_(field['label']), value))
     return extraInfo
    def getDaysGroupedByMonth(self):
        days = self.getDays()
        result = dict()
        mTrans = dict()

        for day in days:
            # use integer coded month as key since it is easier to sort automatically
            # february 2019: 201902
            # december 2018: 201812
            monthStr = str(day.date.month)
            if len(monthStr) < 2:
                monthStr = '0' + monthStr
            key = str(day.date.year) + monthStr

            if key in result:
                result[key].append(day)
            else:
                result[key] = [day]
                # but for translation use month code (like 'Mar')
                mTrans[key] = _(day.date.strftime('%b'))

        keys = result.keys()
        keys.sort()

        return (result, keys, mTrans)
Exemple #9
0
    def getTimeSlot(self, timeslotId, checkExpirationDate=False):
        brains = api.content.find(context=self,
                                  portal_type='UTTimeslot',
                                  depth=1,
                                  id=timeslotId)
        if len(brains) == 0:
            raise ValueError(
                _(u'The TimeSlot {0} was not found.'.format(timeslotId)))

        if checkExpirationDate:
            now = DateTime()
            if (not brains[0].expires > now):
                raise ValueError(
                    _(u'The TimeSlot {0} was not found.'.format(timeslotId)))

        timeSlot = brains[0].getObject()
        return timeSlot
Exemple #10
0
 def getExtraInfoAsString(self):
     extraInfo = []
     fields = getAllExtraFields(self)
     for field in fields:
         value = getattr(self, field['name'], False)
         if value:
             extraInfo.append(_(field['label']) + ': ' + value)
     return '\n'.join(extraInfo)
Exemple #11
0
 def removeAllPersons(self):
     count = self.context.removeAllPersons()
     api.portal.show_message(message=_(
         u'Successfully removed {0} persons.'.format(str(count))),
                             request=self.request,
                             type='info')
     return self.request.response.redirect(self.context.absolute_url() +
                                           '/manager-summary')
Exemple #12
0
    def getListOfEmptyRequiredFields(self):
        fields = self.context.getExtraFields()

        requiredExtraFields = []
        emptyRequiredFields = []

        for field in fields:
            if field['required']:
                requiredExtraFields.append(field)

        for field in requiredExtraFields:
            if (len(getattr(self, field['name'], '')) < 1):
                emptyRequiredFields.append(
                    translate(_(field['label']),
                              target_language=self.currentLanguage))

        if getattr(self.context, 'dataUsageDeclaration', False) \
           and getattr(self.context, 'dataUsageDeclarationConsentRequired', True):
            if self.agreeDataUsage is False:
                emptyRequiredFields.append(
                    translate(_('fieldName_agreeDataUsageDeclaration'),
                              target_language=self.currentLanguage))

        fields = [('prename', 'Prename'), ('surname', 'Surname'),
                  ('email', 'Your email address')]
        for (name, label) in fields:
            if len(getattr(self, name)) < 1:
                emptyRequiredFields.append(
                    translate(_(label), target_language=self.currentLanguage))

        if self.context.askForPersonTitle and len(self.personTitle) < 1:
            emptyRequiredFields.append(
                translate(_('Title of the person'),
                          target_language=self.currentLanguage))

        return emptyRequiredFields
    def sendCancellationNotification(self, timeSlot, email, fullname,
                                     extraInfoStr, isOnWaitingList):
        day = timeSlot.aq_parent
        signupSheet = day.aq_parent

        contactInfo = signupSheet.contactInfo
        isEmail = validation.validatorFor('isEmail')
        if not signupSheet.notifyContactInfo or \
           not isEmail(contactInfo) or len(contactInfo) < 1:
            return

        lang = ILanguage(signupSheet).get_language()
        if len(lang) == 0:
            lang = 'de'

        toEmail = contactInfo
        fromEmail = signupSheet.contactInfo
        subject = signupSheet.Title() + ' - ' \
            + translate(_(u'Cancellation Notification'), target_language=lang)

        message = translate(_(u'Hello'), target_language=lang) + ',\n\n'

        if isOnWaitingList:
            message += translate(_(
                u'A signup has been cancelled from the waiting list of following slot:'
            ),
                                 target_language=lang) + '\n'  # noqa: E501
        else:
            message += translate(_(u'Following slot has been cancelled:'),
                                 target_language=lang) + '\n'
        message += timeSlot.getLabel() + '\n\n'

        message += translate(_(u'Name'),
                             target_language=lang) + ': ' + fullname + '\n'
        message += translate(_(u'E-Mail'),
                             target_language=lang) + ': ' + email + '\n\n'

        if len(extraInfoStr) > 0:
            message += translate(_(u'Additional information'),
                                 target_language=lang) + '\n'
            message += extraInfoStr + '\n\n'

        api.portal.send_email(recipient=toEmail,
                              sender=fromEmail,
                              subject=subject,
                              body=message)
Exemple #14
0
class IUTDay(model.Schema):

    date = schema.Date(title=_(u'Date'), required=True)
def sendWaitingListConfirmationEmail(person):
    isEmail = validation.validatorFor('isEmail')

    timeSlot = person.aq_parent
    day = timeSlot.aq_parent
    signupSheet = day.aq_parent

    lang = ILanguage(signupSheet).get_language()
    if len(lang) == 0:
        lang = 'de'

    extraInfoStr = person.getExtraInfoAsString()
    contactInfo = signupSheet.contactInfo
    fromEmail = signupSheet.contactInfo

    if isEmail(person.email) != 1:
        return

    url = signupSheet.absolute_url()
    toEmail = person.email

    subject = signupSheet.emailWaitinglistSubject
    if subject is None or len(subject) == 0:
        subject = signupSheet.Title() + ' - ' \
            + translate(_('Waiting List Confirmation'), target_language=lang)
    else:
        subject = replaceCustomMailPlaceholders(
            subject, person.Title(), signupSheet.Title(), url,
            timeSlot.getLabel(), extraInfoStr)

    content = signupSheet.emailWaitinglistContent
    if content is not None and len(content) > 0:
        message = replaceCustomMailPlaceholders(
            content, person.Title(), signupSheet.Title(), url,
            timeSlot.getLabel(), extraInfoStr)
    else:
        # default message if no content has been specified
        message = translate(_('Hello'), target_language=lang) + ' ' + person.Title() + ',\n\n'
        message += translate(_('This message is to confirm that you have been added to the waiting list for:'), target_language=lang) + '\n'  # noqa: E501
        message += timeSlot.getLabel() + '\n\n'

        if len(extraInfoStr) > 0:
            message += translate(_(u'Additional information'),
                                 target_language=lang) + '\n'
            message += extraInfoStr + '\n\n'

        if len(contactInfo) > 0:
            message += translate(_('If you have any questions please contact:'),
                                 target_language=lang) + ' ' + contactInfo + '\n\n'

        message += url + '\n\n'

    api.portal.send_email(recipient=toEmail, sender=fromEmail,
                          subject=subject, body=message)

    # mail to contact person of the signup sheet
    if signupSheet.notifyContactInfo and len(contactInfo) > 0 and isEmail(contactInfo):
        toEmail = contactInfo
        subject = signupSheet.Title() + ' - ' \
            + translate(_('Waiting List Notification'), target_language=lang)

        message = translate(_('Hello'), target_language=lang) + ',\n\n'
        message += translate(_('A new signup has been added to the waiting list for:'),
                             target_language=lang) + '\n'
        message += timeSlot.getLabel() + '\n\n'

        message += translate(_(u'Name'), target_language=lang) + ': ' + person.Title() + '\n'
        message += translate(_(u'E-Mail'), target_language=lang) + ': ' + person.email + '\n\n'

        if len(extraInfoStr) > 0:
            message += translate(_(u'Additional information'), target_language=lang) + '\n'
            message += extraInfoStr + '\n\n'

        message += '\nURL: ' + person.absolute_url() + '\n\n'

        api.portal.send_email(recipient=toEmail, sender=fromEmail,
                              subject=subject, body=message)
class IUTSignupSheet(model.Schema):

    text = RichText(
        title=_(u'Text'),
        description=_(
            u'This (formatted) text will be displayed above the form'),
        required=False)

    contactInfo = schema.TextLine(
        title=_(u'Contact Information'),
        description=_(
            u'Contact information for the manager of the signup sheet.'),
        required=True)

    notifyContactInfo = schema.Bool(
        title=_(u'Send notification mails to contact info'),
        description=
        _(u'Send notifications to the mail address provided in the contact info field on new signups or cancellations'
          ),  # noqa: E501
        default=True)

    signupsRequireConfirmation = schema.Bool(
        title=_(u'Manager has to confirm signups'),
        description=
        _(u'Signups have to be confirmed by the manager (can also be rejected).'
          ),
        default=False)

    allowSignupForExternals = schema.Bool(
        title=_(u'Allow Signup For External User'),
        description=_(
            u'Allow signup for users which do not have an university account'))

    allowSignupForMultipleSlots = schema.Bool(
        title=_(u'Allow Signup For Multiple Slots'),
        description=_(u'Allow the user to signup for more than one slot.'))

    enableAutoMovingUpFromWaitingList = schema.Bool(
        title=_(u'Automatic move up from waiting list'),
        description=
        _(u'If a signup is cancelled, the first person on the waiting list (sorted by date) is automatically signed up.'
          ),  # noqa: E501
        default=True)

    showSlotNames = schema.Bool(
        title=_(u'Show Individual Time Slot Names'),
        description=_(u'Whether or not to show individual slot names.'),
        default=True)

    hideAvailability = schema.Bool(
        title=_(u'Hide availability'),
        description=_(u'Hide how many persons can sign up for a slot'))

    hideDateTime = schema.Bool(
        title=_(u'Hide date and time'),
        description=_(
            u'For signups that are not bound to a certain time slot'))

    askForPersonTitle = schema.Bool(
        title=_(u'Ask for person title'),
        description=_(
            u'Additionally to name and mail address a field for the persons title will be displayed.'
        )  # noqa: E501
    )

    extraFieldsForm = RelationChoice(
        title=_(u'Additional form'),
        description=_(u'Additional form to be filled in for registration.'),
        source=CatalogSource(portal_type=['EasyForm']),
        required=False)

    model.fieldset(
        'mailsettings',
        label=_(u'Mail settings'),
        description=
        _(u"Following placeholders can be used:<br/>$$name$$ -> Full name of user<br/>$$title$$ -> Title of the signup sheet<br/>$$url$$ -> URL of the signup sheet<br/>$$slot$$ -> Date and time of slot (name of slot if date and time hid)<br/>$$data$$ -> Additional data (see 'additional form')"
          ),  # noqa: E501
        fields=[
            'emailConfirmationSubject', 'emailConfirmationContent',
            'emailWaitForConfirmationSubject',
            'emailWaitForConfirmationContent', 'emailWaitinglistSubject',
            'emailWaitinglistContent', 'emailCancelSubject',
            'emailCancelContent'
        ])

    # confirmation email
    emailConfirmationSubject = schema.TextLine(
        title=_(u'Confirmation Email Subject'),
        description=_(u'This email will be send on successful registration.'),
        required=False)

    emailConfirmationContent = schema.Text(
        title=_(u'Confirmation Email Content'), required=False)

    # wait for confirmation email
    emailWaitForConfirmationSubject = schema.TextLine(
        title=_(u'Wait For Confirmation Email Subject'),
        description=
        _(u'This email will be send when user registered for a timeslot and a confirmation is required (if field "Manager has to confirm signups" is set).'
          ),  # noqa: E501
        required=False)

    emailWaitForConfirmationContent = schema.Text(
        title=_(u'Wait For Confirmation Email Content'), required=False)

    # waiting list email
    emailWaitinglistSubject = schema.TextLine(
        title=_(u'Waitinglist Email Subject'),
        description=_(
            u'This email will be send on registration for the waitinglist.'),
        required=False)

    emailWaitinglistContent = schema.Text(
        title=_(u'Waitinglist Email Content'), required=False)

    # cancellation email
    emailCancelSubject = schema.TextLine(
        title=_(u'Cancellation Email Subject'),
        description=_(
            u'This email will be send on a registration cancellation.'),
        required=False)

    emailCancelContent = schema.Text(title=_(u'Cancellation Email Content'),
                                     required=False)
 def getDay(self, dayId):
     brains = api.content.find(context=self, portal_type='UTDay', id=dayId)
     if len(brains) == 0:
         raise ValueError(_(u'The date {0} was not found.'.format(dayId)))
     return brains[0].getObject()
Exemple #18
0
    def sendWaitForConfirmationEmail(self, signupSheet, slotTitleLabel,
                                     person):
        url = signupSheet.absolute_url()

        lang = ILanguage(signupSheet).get_language()
        if len(lang) == 0:
            lang = 'de'

        extraInfoStr = ''
        for (fieldStr, fieldTrans) in self.extra_fields():
            value = getattr(self, fieldStr, '')
            if len(value) > 0:
                extraInfoStr += u'{0}: {1}\n'.format(
                    translate(fieldTrans, target_language=lang), value)

        # mail to person who signed up to waiting list
        contactInfo = signupSheet.getContactInfo()
        toEmail = self.email
        fromEmail = signupSheet.getContactInfo()

        subject = signupSheet.getEmailWaitForConfirmationSubject()
        if len(subject) == 0:
            subject = u'{0} - {1}'.format(
                signupSheet.Title(),
                translate(_('Wait For Confirmation'), target_language=lang))
        else:
            subject = replaceCustomMailPlaceholders(subject, person.Title(),
                                                    signupSheet.Title(), url,
                                                    slotTitleLabel,
                                                    extraInfoStr)

        content = signupSheet.getEmailWaitForConfirmationContent()
        if len(content) > 0:
            message = replaceCustomMailPlaceholders(content, person.Title(),
                                                    signupSheet.Title(), url,
                                                    slotTitleLabel,
                                                    extraInfoStr)
        else:
            # default message if no content has been specified
            message = translate(
                _('Hello'),
                target_language=lang) + ' ' + person.Title() + ',\n\n'
            message += translate(_('You signed up for following slot:'),
                                 target_language=lang) + '\n'  # noqa: E501
            message += slotTitleLabel + '\n'
            message += translate(_(
                'You will receive another email as soon as your registration has been confirmed (or rejected).'
            ),
                                 target_language=lang) + '\n\n'  # noqa: E501

            if len(extraInfoStr) > 0:
                message += translate(_(u'Additional information'),
                                     target_language=lang) + '\n'  # noqa: E501
                message += extraInfoStr + '\n\n'

            if len(contactInfo) > 0:
                message += translate(
                    _('If you have any questions please contact:'),
                    target_language=lang
                ) + ' ' + contactInfo + '\n\n'  # noqa: E501

            message += url + '\n\n'

        mailHost = self.context.MailHost
        mailHost.secureSend(message,
                            toEmail,
                            fromEmail,
                            subject,
                            charset='utf-8')

        # mail to contact person of the signup sheet
        isEmail = validation.validatorFor('isEmail')
        if signupSheet.getNotifyContactInfo(
        ) and len(contactInfo) > 0 and isEmail(contactInfo):
            toEmail = contactInfo
            fromEmail = signupSheet.getContactInfo()

            subject = u'{0} - {1}'.format(
                signupSheet.Title(),
                translate(_('Wait For Confirmation'), target_language=lang))

            message = translate(_('Hello'), target_language=lang) + ',\n\n'
            message += translate(
                _('A new signup is waiting for confirmation'),
                target_language=lang) + ' (' + person.absolute_url(
                ) + '):\n'  # noqa: E501
            message += slotTitleLabel + '\n'
            message += translate(
                _(u'Name'),
                target_language=lang) + ': ' + person.Title() + '\n'
            message += translate(
                _(u'E-Mail'),
                target_language=lang) + ': ' + self.email + '\n\n'

            if len(extraInfoStr) > 0:
                message += translate(_(u'Additional information'),
                                     target_language=lang) + '\n'  # noqa: E501
                message += extraInfoStr + '\n\n'

            message += '\nURL: ' + person.absolute_url() + '\n\n'

            mailHost = self.context.MailHost
            mailHost.secureSend(message,
                                toEmail,
                                fromEmail,
                                subject,
                                charset='utf-8')