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)
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')
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]
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)
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)
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
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)
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')
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)
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()
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')