class IVacationBooking(Interface): title = TextLine( title=_('label_title', u'Title'), description=_('description_title', u'This text will appear in the calendar cells'), default=u'', ) gate = Choice( title=_('label_gate', u'Gate'), description=_('description_gate', u'The gate that will be unavailable'), default=u'', vocabulary='rg.prenotazioni.gates', ) start_date = Date( title=_('label_start', u'Start date '), description=_(" format (YYYY-MM-DD)"), default=None, ) start_time = TextLine( title=_('label_start_time', u'Start time'), description=_('invalid_time'), constraint=check_time, default=u'00:00', ) end_time = TextLine(title=_('label_end_time', u'End time'), description=_('invalid_time'), constraint=check_time, default=u'23:59')
def action_book(self, action): ''' Book this resource ''' data, errors = self.extractData() parsed_data = self.get_parsed_data(data) start_date = data['start_date'] if self.has_slot_conflicts(parsed_data): msg = _('slot_conflict_error', u'This gate has some booking schedule in this time ' u'period.') raise ActionExecutionError( Invalid(msg) ) elif not self.prenotazioni.is_valid_day(start_date): msg = _('day_error', u'This day is not valid.') raise ActionExecutionError( Invalid(msg) ) self.do_book(parsed_data) qs = {'data': data['start_date'].strftime('%d/%m/%Y')} target = urlify(self.context.absolute_url(), params=qs) return self.request.response.redirect(target)
class ISettimanaTipoRow(model.Schema): giorno = schema.TextLine(title=_(u"Giorno"), required=False) inizio_m = schema.Choice( title=_(u"Ora inizio mattina"), vocabulary="rg.prenotazioni.VocOreInizio", required=False, ) end_m = schema.Choice( title=_(u"Ora fine mattina"), vocabulary="rg.prenotazioni.VocOreInizio", required=False, ) inizio_p = schema.Choice( title=_(u"Ora inizio pomeriggio"), vocabulary="rg.prenotazioni.VocOreInizio", required=False, ) end_p = schema.Choice( title=_(u"Ora fine pomeriggio"), vocabulary="rg.prenotazioni.VocOreInizio", required=False, )
def action_move(self, action): ''' Book this resource ''' data, errors = self.extractData() data['tipology'] = self.context.getTipologia_prenotazione() conflict_manager = self.prenotazioni_view.conflict_manager current_data = self.context.getData_prenotazione() current = {'booking_date': current_data, 'tipology': data['tipology']} current_slot = conflict_manager.get_choosen_slot(current) current_gate = self.context.getGate() exclude = {current_gate: [current_slot]} if conflict_manager.conflicts(data, exclude=exclude): msg = _(u'Sorry, this slot is not available or does not fit your ' u'booking.') api.portal.show_message(msg, self.request, type="error") raise ActionExecutionError(Invalid(msg)) if self.exceedes_date_limit(data): msg = _(u'Sorry, you can not book this slot for now.') api.portal.show_message(msg, self.request, type="error") raise ActionExecutionError(Invalid(msg)) obj = self.do_move(data) obj # pyflakes msg = _('booking_moved') IStatusMessage(self.request).add(msg, 'info') booking_date = data['booking_date'].strftime('%d/%m/%Y') target = urlify(self.prenotazioni_folder.absolute_url(), paths=['prenotazioni_week_view'], params={'data': booking_date}) return self.request.response.redirect(target)
def validate(self, action, data): ''' Checks if we can book those data ''' # We inject the tipology of this context data['tipology'] = self.context.getTipologia_prenotazione() errors = super(MoveForm, self).validate(action, data) conflict_manager = self.prenotazioni_view.conflict_manager current_data = self.context.getData_prenotazione() current = { 'booking_date': current_data.asdatetime(), 'tipology': data['tipology'] } current_slot = conflict_manager.get_choosen_slot(current) current_gate = self.context.getGate() exclude = {current_gate: [current_slot]} if conflict_manager.conflicts(data, exclude=exclude): msg = _(u'Sorry, this slot is not available or does not fit your ' u'booking.') self.set_invariant_error(errors, ['booking_date'], msg) if self.exceedes_date_limit(data): msg = _(u'Sorry, you can not book this slot for now.') self.set_invariant_error(errors, ['booking_date'], msg) for error in errors: api.portal.show_message(error.errors, self.request, type="error") return errors
class MovedPrenotazioneEditForm(EditForm): """ An edit form for the mail action """ form_fields = form.FormFields(IMovedPrenotazioneAction) label = _(u"Edit moved booking Mail Action") description = _(u"A mail action that sends email notify when a booking is moved in an other slot.") form_name = _(u"Configure element")
class ITipologiaRow(Interface): name = schema.TextLine( title=_(u"Typology name"), required=True, ) duration = schema.Choice(title=_(u"Duration value"), required=True, vocabulary="rg.prenotazioni.VocDurataIncontro")
class MovedPrenotazioneAddForm(ActionAddForm): """ An add form for the mail action """ schema = IMovedPrenotazioneAction label = _(u"Add moved booking Mail Action") description = _( u"A mail action that sends email notify when a booking is moved in an other slot." ) form_name = _(u"Configure element") Type = MovedPrenotazioneAction
class IAddForm(Interface): """ Interface for creating a prenotazione """ booking_date = Datetime( title=_('label_booking_time', u'Booking time'), default=None, constraint=check_is_future_date, ) tipology = Choice( title=_('label_tipology', u'Tipology'), required=True, default=u'', vocabulary='rg.prenotazioni.tipologies', ) fullname = TextLine( title=_('label_fullname', u'Fullname'), default=u'', ) email = TextLine( title=_('label_email', u'Email'), required=True, default=u'', constraint=check_valid_email, ) phone = TextLine( title=_('label_phone', u'Phone number'), required=False, default=u'', constraint=check_phone_number, ) mobile = TextLine( title=_('label_mobile', u'Mobile number'), required=False, default=u'', constraint=check_phone_number, ) subject = Text( title=_('label_subject', u'Subject'), default=u'', required=False, ) agency = TextLine( title=_('label_agency', u'Agency'), description=_('description_agency', u'If you work for an agency please specify its name'), default=u'', required=False, ) captcha = Captcha( title=_('label_captcha', u'Type the code from the picture shown below.'), default='', )
class IMoveForm(Interface): """ Interface for moving a prenotazione """ booking_date = Datetime( title=_('label_booking_time', u'Booking time'), default=None, ) gate = TextLine(title=_('label_gate', u'Gate'), default=u'', required=False)
def __call__(self): ''' Redirects to the context if no data is found in the request ''' # we should always have a booking date if not self.booking_DateTime: msg = _('please_pick_a_date', "Please select a time slot") return self.redirect(self.back_to_booking_url, msg) # and if we have it, we should have enough time to do something if not self.has_enough_time(): msg = _('time_slot_to_short', "You cannot book any typology at this time") return self.redirect(self.back_to_booking_url, msg) return super(AddForm, self).__call__()
class MovedPrenotazioneAddForm(AddForm): """ An add form for the mail action """ form_fields = form.FormFields(IMovedPrenotazioneAction) label = _(u"Add moved booking Mail Action") description = _(u"A mail action that sends email notify when a booking is moved in an other slot.") form_name = _(u"Configure element") def create(self, data): a = MovedPrenotazioneAction() form.applyChanges(a, self.form_fields, data) return a
def validate(self, action, data): ''' Checks if we can book those data ''' errors = super(AddForm, self).validate(action, data) if not data.get('booking_date'): return errors conflict_manager = self.prenotazioni.conflict_manager if conflict_manager.conflicts(data): msg = _(u'Sorry, this slot is not available anymore.') self.set_invariant_error(errors, ['booking_date'], msg) if self.exceedes_date_limit(data): msg = _(u'Sorry, you can not book this slot for now.') self.set_invariant_error(errors, ['booking_date'], msg) return errors
def __call__(self, *args): uid = self.request.get('UID', '') self.request.SESSION.set('UID', uid) pu = getToolByName(self.context, 'plone_utils') pu.addPortalMessage( _(u"Seleziona la data nella quale spostare l'appuntamento")) self.request.RESPONSE.redirect(self.context.absolute_url())
def do_book(self, data): ''' Execute the multiple booking ''' booker = IBooker(self.context.aq_inner) slots = self.get_slots(data) start_date = DateTime(data['start_date'].strftime('%Y/%m/%d')) for slot in slots: booking_date = start_date + (float(slot.lower_value) / 86400) slot.__class__ = BaseSlot duration = float(len(slot)) / 86400 # duration = float(len(slot)) / 60 slot_data = {'fullname': data['title'], 'subject': u'', 'agency': u'', 'booking_date': booking_date, 'telefono': u'', 'mobile': u'', 'email': u'', 'tipologia_prenotazione': u'', } booker.create(slot_data, duration=duration, force_gate=data.get('gate')) msg = _('booking_created') IStatusMessage(self.request).add(msg, 'info')
def do_book(self, data): ''' Execute the multiple booking ''' booker = IBooker(self.context.aq_inner) slots = self.get_slots(data) start_date = DateTime(data['start_date'].strftime('%Y/%m/%d')) for slot in slots: booking_date = start_date + (float(slot.lower_value) / 86400) slot.__class__ = BaseSlot duration = float(len(slot)) / 86400 # duration = float(len(slot)) / 60 slot_data = { 'fullname': data['title'], 'subject': u'', 'agency': u'', 'booking_date': booking_date, 'telefono': u'', 'mobile': u'', 'email': u'', 'tipologia_prenotazione': u'', } booker.create(slot_data, duration=duration, force_gate=data.get('gate')) msg = _('booking_created') IStatusMessage(self.request).add(msg, 'info')
def label(self): ''' The lable of this view ''' title = self.prenotazione.getPrenotazioniFolder().Title().decode( 'utf8') # noqa return _('reservation_request', u'Booking request for: ${name}', mapping={'name': title})
def label(self): ''' The lable of this view ''' title = self.prenotazione.getPrenotazioniFolder().Title().decode('utf8') # noqa return _( 'reservation_request', u'Booking request for: ${name}', mapping={'name': title} )
def post_validate(self, REQUEST, errors): ''' Add validation for already booked objects ''' if not REQUEST.get('data_prenotazione'): errors['data_prenotazione'] = _(u"Formato della data non corretto") else: self.validateOverbooking(REQUEST, errors) return super(Prenotazione, self).post_validate(REQUEST, errors)
def validate_invariants(self, data, errors): ''' Validate invariants errors ''' parsed_data = self.get_parsed_data(data) start_date = data['start_date'] if self.has_slot_conflicts(parsed_data): msg = _( 'slot_conflict_error', u'This gate has some booking schedule in this time ' u'period.') elif not self.prenotazioni.is_valid_day(start_date): msg = _('day_error', u'This day is not valid.') else: msg = '' if not msg: return fields_to_notify = ['start_date', 'start_time', 'end_time'] self.set_invariant_error(errors, fields_to_notify, msg)
def __call__(self, *args, **kwargs): # trick for redirecting if self.request.get('HTTP_REFERER') and \ '/portal_factory/Prenotazione/' in self.request.get('HTTP_REFERER'): putils = getToolByName(self.context, 'plone_utils') putils.addPortalMessage(_(u"Booking done")) #notify(ActionSucceededEvent(self.context, 'foo', 'submit', 'pending')) self.request.response.redirect(self.context.aq_inner.aq_parent.absolute_url()) return return self.index()
def get_foreseen_booking_time(self, day, slot): """ Return the foreseen booking time message """ booking_url = self.prenotazioni.get_anonymous_booking_url(day, slot) message = _( 'foreseen_booking_time', default=u"Foreseen booking time: ${booking_time}", mapping={'booking_time': booking_url['title']} ) return message
def action_book(self, action, data): ''' Book this resource ''' self.do_book(data) msg = _('booking_created', 'Booking created') IStatusMessage(self.request).add(msg, 'info') booking_date = data['booking_date'].strftime('%d/%m/%Y') target = ('%s?data=%s') % (self.context.absolute_url(), booking_date) self.request.response.redirect(target)
def __call__(self, *args, **kwargs): # trick for redirecting if self.request.get('HTTP_REFERER') and \ '/portal_factory/Prenotazione/' in self.request.get('HTTP_REFERER'): putils = getToolByName(self.context, 'plone_utils') putils.addPortalMessage(_(u"Booking done")) #notify(ActionSucceededEvent(self.context, 'foo', 'submit', 'pending')) self.request.response.redirect( self.context.aq_inner.aq_parent.absolute_url()) return return self.index()
def test_vocab_voc_ore_inizio(self): vocab_name = 'rg.prenotazioni.VocOreInizio' factory = getUtility(IVocabularyFactory, vocab_name) self.assertTrue(IVocabularyFactory.providedBy(factory)) vocabulary = factory(self.portal) self.assertTrue(IVocabularyTokenized.providedBy(vocabulary)) self.assertEqual( vocabulary.getTerm('sony-a7r-iii').title, _(u'Sony Aplha 7R III'), )
def label(self): ''' Check if user is anonymous ''' booking_date = self.booking_DateTime if not booking_date: return '' localized_date = self.localized_time(booking_date) return _('label_selected_date', u"Selected date: ${date} — Time slot: ${slot}", mapping={'date': localized_date, 'slot': booking_date.hour()})
class ISearchForm(Interface): """ Interface for creating a prenotazione """ text = TextLine( title=_('label_text', u'Text to search'), default=u'', required=False, ) review_state = Choice( title=__("State"), default='', required=False, source='rg.prenotazioni.booking_review_states' ) gate = Choice( title=_("label_gate", u"Gate"), default='', required=False, source='rg.prenotazioni.gates' ) start = Datetime( title=_('label_start', u'Start date '), description=_(" format (YYYY-MM-DD)"), default=None, constraint=check_date, required=False, ) end = Datetime( title=_('label_end', u'End date'), description=_(" format (YYYY-MM-DD)"), default=None, constraint=check_date, required=False, )
class IMovedPrenotazioneAction(Interface): """Definition of the configuration available for a mail action """ subject = schema.TextLine( title=_(u"Subject"), description=_(u"Subject of the message"), required=True ) source = schema.TextLine( title=_(u"Sender email"), description=_('source_help', default=u"The email address that sends the email. If no email is " u"provided here, it will use the address from portal."), required=False ) message = schema.Text( title=_(u"Message"), description=_('message_help', default=u"Type in here the message that you want to mail. Some " u"defined content can be replaced: ${title} will be replaced with booking title (user fullname). ${date} will be replaced with booking new date. ${url} will be replaced by the booking url. ${portal} will be replaced by the title " u"of the portal."), required=True )
class PrenotazionePrint(BrowserView): ''' This is a view to proxy autorizzazione ''' print_action = "javascript:this.print();" description = _('confirm_booking_waiting_message', u'Your booking has to be confirmed by the administrators') @property @memoize def label(self): ''' The lable of this view ''' title = self.prenotazione.getPrenotazioniFolder().Title().decode( 'utf8') # noqa return _('reservation_request', u'Booking request for: ${name}', mapping={'name': title}) @property @memoize def prenotazione(self): ''' Get's the prenotazione by uid ''' uid = self.request.get("uid") if not uid: return pc = getToolByName(self.context, 'portal_catalog') query = {'portal_type': 'Prenotazione', 'UID': uid} brains = pc.unrestrictedSearchResults(query) if len(brains) != 1: return None return brains[0]._unrestrictedGetObject() def __call__(self): ''' Se non c'e' la prenotazione vai all'oggetto padre ''' if not self.prenotazione: qs = {} data = self.request.get('data') if data: qs['data'] = data msg = "Not found" IStatusMessage(self.request).add(msg, 'warning') target = urlify(self.context.absolute_url(), params=qs) return self.request.response.redirect(target) else: return super(PrenotazionePrint, self).__call__()
def action_move(self, action, data): ''' Book this resource ''' obj = self.do_move(data) obj # pyflakes msg = _('booking_moved') IStatusMessage(self.request).add(msg, 'info') booking_date = data['booking_date'].strftime('%d/%m/%Y') target = urlify(self.prenotazioni_folder.absolute_url(), paths=['prenotazioni_week_view'], params={'data': booking_date}) return self.request.response.redirect(target)
def action_book(self, action, data): ''' Book this resource ''' obj = self.do_book(data) msg = _('booking_created') IStatusMessage(self.request).add(msg, 'info') booking_date = data['booking_date'].strftime('%d/%m/%Y') params = {'data': booking_date, 'uid': obj.UID()} target = urlify(self.context.absolute_url(), paths=["@@prenotazione_print"], params=params) return self.request.response.redirect(target)
def action_move(self, action): ''' Book this resource ''' data, errors = self.extractData() data['tipology'] = self.context.getTipologia_prenotazione() conflict_manager = self.prenotazioni_view.conflict_manager current_data = self.context.getData_prenotazione() current = {'booking_date': current_data, 'tipology': data['tipology']} current_slot = conflict_manager.get_choosen_slot(current) current_gate = self.context.getGate() exclude = {current_gate: [current_slot]} if conflict_manager.conflicts(data, exclude=exclude): msg = _(u'Sorry, this slot is not available or does not fit your ' u'booking.') api.portal.show_message(msg, self.request, type="error") raise ActionExecutionError( Invalid(msg) ) if self.exceedes_date_limit(data): msg = _(u'Sorry, you can not book this slot for now.') api.portal.show_message(msg, self.request, type="error") raise ActionExecutionError( Invalid(msg) ) obj = self.do_move(data) obj # pyflakes msg = _('booking_moved') IStatusMessage(self.request).add(msg, 'info') booking_date = data['booking_date'].strftime('%d/%m/%Y') target = urlify(self.prenotazioni_folder.absolute_url(), paths=['prenotazioni_week_view'], params={'data': booking_date}) return self.request.response.redirect(target)
def action_book(self, action): ''' Book this resource ''' data, errors = self.extractData() parsed_data = self.get_parsed_data(data) start_date = data['start_date'] if self.has_slot_conflicts(parsed_data): msg = _( 'slot_conflict_error', u'This gate has some booking schedule in this time ' u'period.') raise ActionExecutionError(Invalid(msg)) elif not self.prenotazioni.is_valid_day(start_date): msg = _('day_error', u'This day is not valid.') raise ActionExecutionError(Invalid(msg)) self.do_book(parsed_data) qs = {'data': data['start_date'].strftime('%d/%m/%Y')} target = urlify(self.context.absolute_url(), params=qs) return self.request.response.redirect(target)
def action_book(self, action): ''' Book this resource ''' data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return if not data.get('booking_date'): raise WidgetActionExecutionError( 'booking_date', Invalid(_(u"Please provide a booking date")) ) conflict_manager = self.prenotazioni.conflict_manager if conflict_manager.conflicts(data): msg = _(u'Sorry, this slot is not available anymore.') raise WidgetActionExecutionError( 'booking_date', Invalid(msg) ) if self.exceedes_date_limit(data): msg = _(u'Sorry, you can not book this slot for now.') raise WidgetActionExecutionError( 'booking_date', Invalid(msg) ) captcha = getMultiAdapter( (aq_inner(self.context), self.request), name='recaptcha' ) if 'captcha' in data and not captcha.verify(): msg=_(u"Please check the captcha") raise ActionExecutionError(Invalid(msg)) obj = self.do_book(data) if not obj: msg = _(u'Sorry, this slot is not available anymore.') api.portal.show_message( message=msg, type='warning', request=self.request) target = self.back_to_booking_url return self.request.response.redirect(target) msg = _('booking_created') api.portal.show_message(message=msg, type='info', request=self.request) booking_date = data['booking_date'].strftime('%d/%m/%Y') params = {'data': booking_date, 'uid': obj.UID()} target = urlify(self.context.absolute_url(), paths=["@@prenotazione_print"], params=params) return self.request.response.redirect(target)
class IAddForm(Interface): """ Interface for creating a prenotazione """ fullname = TextLine( title=_('label_fullname', u'Fullname'), default=u'', ) subject = Text( title=_('label_subject', u'Subject'), default=u'', required=False, ) booking_date = Datetime( title=_('label_booking_time', u'Booking time'), default=None, ) agency = TextLine( title=_('label_agency', u'Agency'), description=_('description_agency', u'If you work for an agency please specify its name'), default=u'', required=False, ) phone = TextLine( title=_('label_phone', u'Phone number'), required=False, default=u'', ) email = TextLine( title=_('label_email', u'Email'), default=u'', ) captcha = Captcha( title=_('label_captcha', u'Type the code from the picture shown below.'), default='', )
def __call__(self, *args): uid = self.request.get('UID', '') self.request.SESSION.set('UID', uid) pu = getToolByName(self.context, 'plone_utils') pu.addPortalMessage(_(u"Seleziona la data nella quale spostare l'appuntamento")) self.request.RESPONSE.redirect(self.context.absolute_url())
PrenotazioniFolderSchema = BaseFolderSchema.copy() + atapi.Schema(( # -*- Your Archetypes field definitions here ... -*- atapi.TextField( 'descriptionAgenda', required=False, searchable=True, storage=atapi.AnnotationStorage(migrate=True), validators=('isTidyHtmlWithCleanup',), default_output_type='text/x-html-safe', widget=atapi.RichWidget( description=("Inserire il testo di presentazione " "dell'agenda corrente"), label=_(u'Descrizione Agenda', default=u''), rows=10, allow_file_upload=zconf.ATDocument.allow_document_upload), ), atapi.DateTimeField( 'daData', storage=atapi.AnnotationStorage(), widget=atapi.CalendarWidget( label=_(u'Data inizio validità'), description=_(u""), show_hm=False, ), required=True, default=DateTime(), ),
def summary(self): return _(u"Email report to prenotazione owner")
from Products.CMFCore.utils import getToolByName from Products.CMFCore import permissions from Products.Archetypes import atapi from Products.Archetypes.utils import DisplayList from Products.Archetypes.ExtensibleMetadata import _zone from Products.ATContentTypes.content import base, schemata from rg.prenotazioni import prenotazioniMessageFactory as _ from rg.prenotazioni.config import PROJECTNAME from rg.prenotazioni.interfaces import IPrenotazione, IPrenotazioniFolder from zope.interface import implements OVERBOOKED_MESSAGE = _('overbook_message', default=u"Siamo spiacenti, è già stato preso un appuntamento " u"nella stessa fascia oraria, premere il pulsante " u"ANNULLA per effettuare una nuova richiesta di " u"prenotazione") PrenotazioneSchema = schemata.ATContentTypeSchema.copy() + atapi.Schema(( atapi.StringField( 'tipologia_prenotazione', storage=atapi.AnnotationStorage(), vocabulary='getElencoTipologie', widget=atapi.SelectionWidget( label=_(u"Tipologia della prenotazione"), condition='object/getElencoTipologie', ),