Beispiel #1
0
class EditPersonalCampaign(dexterity.EditForm):
    grok.name('edit-personal-campaign')
    grok.require('collective.salesforce.fundraising.EditPersonalCampaign')
    grok.context(IPersonalCampaignPage)

    label = _(u"Edit My Fundraising Page")
    description = _(u"Use the form below to edit your fundraising page to "
                    "create the most effective appeal to your friends and "
                    "family.")
    schema = IEditPersonalCampaignPage
Beispiel #2
0
class CreateDonationDonorQuote(form.Form):
    grok.name('create-donor-quote')
    grok.require('zope2.View')
    grok.context(IDonation)

    @property
    def action(self):
        """See interfaces.IInputForm"""
        return '%s/create-donor-quote' % self.context.absolute_url()

    @property
    def fields(self):
        return field.Fields(IDonorQuote).select('quote', 'name', 'image',
                                                'key', 'amount')

    ignoreContext = True

    label = _(u"Testimonial")
    description = _(u"Provide a quote to inspire others to give.")

    def updateWidgets(self):
        super(CreateDonationDonorQuote, self).updateWidgets()
        self.widgets['key'].mode = 'hidden'
        self.widgets['amount'].mode = 'hidden'

    @button.buttonAndHandler(_(u'Submit'))
    def handleOk(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        donation = self.context

        if data['key'] != donation.secret_key:
            raise Unauthorized

        # Add a donor quote in the current context,
        # using the data from the form
        parent_campaign = donation.get_fundraising_campaign()
        quote = createContentInContainer(
            donation,
            'collective.salesforce.fundraising.donorquote',
            checkConstraints=False,
            **data)

        quote.parent_sf_id = parent_campaign.sf_object_id

        # FIXME: This is not saving to Salesforce yet

        # Send the user back to the thank you page with a note about their
        # quote. Hide the donor quote section of the thank you page
        IStatusMessage(self.request).add(u'Your story has been successfully '
                                         'submitted.')
        self.request.response.redirect('%s?hide=donorquote&key=%s' %
                                       (donation.absolute_url(), data['key']))
Beispiel #3
0
class CreateOfflineDonation(form.Form):
    grok.name('create-offline-donation')
    grok.require('collective.salesforce.fundraising.EditPersonalCampaign')
    grok.context(IPersonalCampaignPage)
    schema = ICreateOfflineDonation

    fields = field.Fields(ICreateOfflineDonation)
    fields['payment_method'].widgetFactory = radio.RadioFieldWidget

    ignoreContext = True

    label = _(u"Add Offline Donation")
    description = _(u"If you have raised money offline via cash or check, "
                    "enter them here so you get credit towards your goal")

    @button.buttonAndHandler(_(u'Submit'))
    def handleOk(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        data['title'] = '%s %s - One-time Offline Donation' % (
            data['first_name'], data['last_name'])
        data['secret_key'] = build_secret_key()
        data['stage'] = 'Pledged'
        data['products'] = []
        data['campaign_sf_id'] = self.context.sf_object_id
        data['payment_date'] = datetime.date.today()
        data['transaction_id'] = 'offline:' + data['secret_key']
        data['offline'] = True

        # Add a donation in the current context,
        # using the data from the form
        parent_campaign = self.context
        createContentInContainer(parent_campaign,
                                 'collective.salesforce.fundraising.donation',
                                 checkConstraints=False,
                                 **data)

        # Add the donation to the campaign totals
        # self.context.add_donation(data['amount'])

        IStatusMessage(self.request).add(u'Your offline gift was entered and '
                                         'will be counted in your total '
                                         'raised. The gift and donor contact '
                                         'information will appear in '
                                         '"My Donors" shortly.')
        self.request.response.redirect(parent_campaign.absolute_url())
def validateEmail(value):
    site = getSite()

    res = get_brains_for_email(site, value)
    if not res:
        raise Invalid(_(u"No existing user account found to set password.  Please use the registration form to create an account."))

    # Auto log in the user
    # NOTE: This is to allow the current anon user access to the user profile.  If there is an error, you MUST log the user out before raising an exception
    mtool = getToolByName(site, 'portal_membership')
    acl = getToolByName(site, 'acl_users')
    newSecurityManager(None, acl.getUser(value))
    mtool.loginUser()

    person = res[0].getObject()

    if person.registered == True:
        mtool.logoutUser()
        raise Invalid(_(u"This account already has a password set.  If you have forgotten the password, please use the forgot password link to reset your password."))    
def validateEmail(value):
    site = getSite()

    res = get_brains_for_email(site, value)
    if res:
        membership = getToolByName(site, 'portal_membership')
        member = membership.getMemberById(value)
    else:
        member = None

    if member is None:
        raise Invalid(_(u"No existing user account found to set password. "
                        " Please use the registration form to create an"
                        "account."))

    person = res[0].getObject()

    if person.registered:
        raise Invalid(_(u"This account already has a password set.  If you "
                        "have forgotten the password, please use the forgot "
                        "password link to reset your password."))
Beispiel #6
0
def validateEmail(value):
    site = getSite()

    res = get_brains_for_email(site, value)
    if res:
        membership = getToolByName(site, 'portal_membership')
        member = membership.getMemberById(value)
    else:
        member = None

    if member is None:
        raise Invalid(
            _(u"No existing user account found to set password. "
              " Please use the registration form to create an"
              "account."))

    person = res[0].getObject()

    if person.registered:
        raise Invalid(
            _(u"This account already has a password set.  If you "
              "have forgotten the password, please use the forgot "
              "password link to reset your password."))
Beispiel #7
0
class IPersonalCampaignPage(model.Schema, IImageScaleTraversable):
    """
    A personal fundraising page
    """

    personal_appeal = RichText(
        title=u"Personal Appeal",
        description=
        u"Your donors will want to know why to donate to your campaign.  You can use the default text or personalize your appeal.  Remember, your page will mostly be visited by people who know you so a personalized message is often more effective",
    )

    thank_you_message = RichText(
        title=u"Thank You Message",
        description=
        u"This message will be shown to your donors after they donate.  You can use the default text or personalize your thank you message",
    )

    image = namedfile.field.NamedBlobImage(
        title=_(u"Image"),
        description=
        _(u"Provide an image to use in promoting your campaign.  The image will show up on your page and also when someone shares your page on social networks."
          ),
    )
    model.load("models/personal_campaign_page.xml")
Beispiel #8
0
class IEditPersonalCampaignPage(form.Schema, IImageScaleTraversable):
    """
    Limited editing interface for a Personal Campaign Page
    """

    title = schema.TextLine(
        title=_(u"Title"),
        description=_(u"Provide a brief title for your campaign"),
        max_length=80,
    )
    description = schema.Text(
        title=_(u"Description"),
        description=
        _(u"Provide a 1-3 sentence pitch for your campaign.  This will be shown above the donation form on your page and as the description of your page when it is shared on social networks such as Facebook."
          ),
    )
    image = namedfile.field.NamedBlobImage(
        title=_(u"Image"),
        description=
        _(u"Provide an image to use in promoting your campaign.  The image will show up on your page and also when someone shares your page on social networks.  Accepted format are jpg, gif, and png"
          ),
    )
    goal = schema.Int(
        title=_(u"Goal"),
        description=_(
            u"Set the dollar amount goal you aim to raise in your campaign"),
    )
    personal_appeal = RichText(
        title=u"Personal Appeal",
        description=
        u"Your donors will want to know why to donate to your campaign.  You can use the default text or personalize your appeal.  Remember, your page will mostly be visited by people who know you so a personalized message is often more effective",
    )

    thank_you_message = RichText(
        title=u"Thank You Message",
        description=
        u"This message will be shown to your donors after they donate.  You can use the default text or personalize your thank you message",
    )
Beispiel #9
0
class IAddPerson(form.Schema, IEmail):
    """
    Add Interface for a Person with limited fields
    NOTE: This seems to be the only way to get a custom edit form with limited
    fields since we're using the model xml for most fields
    """
    first_name = schema.TextLine(
        title=_(u"First Name"),
    )
    last_name = schema.TextLine(
        title=_(u"Last Name"),
    )
    email_opt_in = schema.Bool(
        title=_(u"Join our Email List?"),
        description=_(u"Check this box to receive "
                      "occassional updates via email"),
        required=False,
        default=True,
    )
    password = schema.Password(
        title=_(u"Password"),
    )
    password_confirm = schema.Password(
        title=_(u"Confirm Password"),
    )

    came_from = schema.TextLine(
        title=_(u"Redirect after create"),
        required=False,
    )

    form.mode(came_from='hidden')

    @invariant
    def passwordsInvariant(data):
        if data.password != data.password_confirm:
            raise Invalid(_(u"Your passwords do not match, please enter the "
                            "same password in both fields"))
 def passwordsInvariant(data):
     if data.password != data.password_confirm:
         raise Invalid(_(u"Your passwords do not match, please enter the same password in both fields"))
Beispiel #11
0
class CreatePersonalCampaignPageForm(form.Form):
    grok.name('create-personal-campaign-page')
    grok.require('collective.salesforce.fundraising.AddPersonalCampaign')
    grok.context(IFundraisingCampaign)
    schema = IEditPersonalCampaignPage

    @property
    def fields(self):
        fields = field.Fields(IPersonalCampaignPage).select(
            'title', 'description', 'image', 'goal', 'personal_appeal',
            'thank_you_message')

        # Make the image field required
        image_field = copy.copy(fields['image'].field)
        image_field.required = True
        fields['image'].field = image_field

        return fields

    ignoreContext = True

    label = _(u"Create My Fundraising Page")
    description = _(u"Set a goal and encourage your friends,"
                    " family, and colleagues to donate towards your goal.")

    @button.buttonAndHandler(_(u'Create'))
    def handleOk(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # Don't allow creation of a personal page if one already exists
        existing_personal_campaign = \
            self.context.get_personal_fundraising_campaign_url()
        if existing_personal_campaign:
            messages = IStatusMessage(self.request)
            messages.add("You can't create more than one "
                         "personal page per campaign.")
            self.request.response.redirect(self.context.absolute_url())
            return

        # Add a personal campaign within the current context,
        # using the data from the form.
        parent_campaign = self.context
        campaign = createContentInContainer(
            parent_campaign,
            'collective.salesforce.fundraising.personalcampaignpage',
            checkConstraints=False,
            **data)

        mtool = getToolByName(self.context, 'portal_membership')
        member = mtool.getAuthenticatedMember()
        person_res = get_brains_for_email(self.context,
                                          member.getProperty('email'))
        person = None
        contact_id = None
        if person_res:
            person = person_res[0].getObject()
            contact_id = person.sf_object_id

        settings = get_settings()

        # Add the campaign in Salesforce
        sfconn = getUtility(ISalesforceUtility).get_connection()
        data = {
            'Type': 'Personal Fundraising',
            'ParentId': parent_campaign.sf_object_id,
            'Name': data['title'],
            'Description': data['description'],
            'Public_Name__c': data['title'],
            'ExpectedRevenue': data['goal'],
            'Personal_Campaign_Contact__c': contact_id,
            'IsActive': True,
            'Status': 'In Progress',
        }
        if settings.sf_campaign_record_type_personal:
            data['RecordTypeID'] = settings.sf_campaign_record_type_personal

        res = sfconn.Campaign.create(data)
        if not res['success']:
            raise Exception(res['errors'][0])

        # Save the Id of the new campaign so it can be updated later.
        campaign.parent_sf_id = parent_campaign.sf_object_id
        campaign.sf_object_id = res['id']
        campaign.contact_sf_id = contact_id
        campaign.reindexObject()

        # Send email confirmation and links.
        try:
            campaign.send_email_personal_page_created()
        except HTTPRequestException as e:
            failure = {
                'func_name': 'MemorialEmailView',
                'func': '',
                'args': '',
                'kwargs': '',
                'portal_path': '',
                'context_path': repr(self.context),
                'userfolder_path': '',
                'user_id': '',
                'tb': e,
            }
            email_failure_from_portal(self.context, failure)

        # Send the user to their new campaign.
        IStatusMessage(self.request).add(u'Welcome to your fundraising page!')
        self.request.response.redirect(campaign.absolute_url())

    @button.buttonAndHandler(_(u"Cancel"))
    def handleCancel(self, action):
        return
Beispiel #12
0
class AddPersonForm(form.SchemaForm):
    grok.name('create-user-account')
    grok.context(ISiteRoot)

    schema = IAddPerson
    ignoreContext = True

    label = _(u"Register a User Account")
    description = _(u"Use the form below to create your user account.")

    def updateWidgets(self):
        super(AddPersonForm, self).updateWidgets()
        email = self.request.form.get('email')
        if not email:
            email = self.request.form.get('form.widgets.email')
        self.widgets['email'].value = email
        came_from = self.request.form.get('came_from')
        if not came_from:
            came_from = self.request.form.get('form.widgets.came_from')
        self.widgets['came_from'].value = came_from

    @button.buttonAndHandler(_(u"Submit"))
    def handleOk(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        data = {
            'first_name': data['first_name'],
            'last_name': data['last_name'],
            'fullname': '%s %s' % (data['first_name'], data['last_name']),
            'username': data['email'],
            'email': data['email'].lower(),
            'email_opt_in': data['email_opt_in'],
            'password': pw_encrypt(data['password']),
            'registered': True,
        }

        data_enc = {}
        for key, value in data.items():
            if key == 'email':
                data_enc[key] = value.encode('ascii')
                continue
            if isinstance(value, unicode):
                data_enc[key] = value.encode('utf8')
            else:
                data_enc[key] = value

        # Create the login user
        reg = getToolByName(self.context, 'portal_registration')
        reg.addMember(
            data_enc['email'],
            data_enc['password'],
            properties=data,
        )

        # Create the user object portal reg and PAS should do this for us
        people_container = getattr(getSite(), 'people')
        createContentInContainer(people_container,
                                 'collective.salesforce.fundraising.person',
                                 checkConstraints=False,
                                 **data)

        # Authenticate the user
        mtool = getToolByName(self.context, 'portal_membership')
        acl = getToolByName(self.context, 'acl_users')
        newSecurityManager(None, acl.getUser(data_enc['email']))
        mtool.loginUser()

        # See if came_from was passed
        # fix odd bug where came_from is a list of two values
        came_from = self.request.form.get('form.widgets.came_from', None)
        if came_from and isinstance(came_from, (list, tuple)):
            came_from = came_from[0]

        if came_from:
            self.request.form['came_from'] = came_from

        # merge in with standard plone login process.
        login_next = self.context.restrictedTraverse('login_next')
        html = login_next()

        # Send the response from login_next() to the browser.
        if self.request.response.getStatus() == 200:
            self.render = lambda: html
Beispiel #13
0
class SetPasswordForm(form.SchemaForm):
    grok.name('set-password-form')
    grok.context(ISiteRoot)

    schema = ISetPassword
    ignoreContext = True

    label = _(u"Set Your Password")
    description = _(u"Use this form to set a password for your account "
                    u"which you can use in the future to log in.")

    def updateWidgets(self):
        super(SetPasswordForm, self).updateWidgets()
        self.widgets['email'].value = self.request.form.get('email', None)

    @button.buttonAndHandler(_(u"Submit"))
    def handleOk(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        email = data['email']

        site = getSite()
        membership = getToolByName(site, 'portal_membership')
        member = membership.getMemberById(email)

        # Like mailPassword() in CMFPlone.RegistrationTool, render
        # and send the message ourselves to avoid tripping over security.
        reset_tool = getToolByName(site, 'portal_password_reset')
        reset = reset_tool.requestReset(member.getId())
        encoding = site.getProperty('email_charset', 'utf-8')
        mail_text = site.mail_password_template(site,
                                                self.request,
                                                member=member,
                                                reset=reset,
                                                password=member.getPassword(),
                                                charset=encoding)
        # The mail headers are not properly encoded, so we need to extract
        # them and let MailHost manage the encoding.
        if isinstance(mail_text, unicode):
            mail_text = mail_text.encode(encoding)
        message_obj = message_from_string(mail_text.strip())
        subject = message_obj['Subject']
        m_to = message_obj['To']
        m_from = message_obj['From']
        host = getToolByName(site, 'MailHost')
        host.send(mail_text,
                  m_to,
                  m_from,
                  subject=subject,
                  charset=encoding,
                  immediate=False)

        brains = get_brains_for_email(site, email)
        if brains is not None:
            person = brains[0].getObject()
            # person.registered must be set in order for the user
            # to log in with a password.
            person.registered = True

        self.request.response.redirect(self.context.absolute_url() +
                                       '/mail_password_response')
Beispiel #14
0
class ISetPassword(form.Schema):
    email = schema.TextLine(
        title=_(u"Email Address"),
        description=_(u""),
    )
Beispiel #15
0
class CreateDonorQuote(form.Form):
    grok.name('create-donor-quote')
    grok.require('collective.salesforce.fundraising.AddDonorQuote')
    grok.context(IFundraisingCampaign)

    @property
    def fields(self):
        return field.Fields(IDonorQuote).select('quote', 'name', 'image',
                                                'contact_sf_id', 'donation_id',
                                                'amount')

    ignoreContext = True

    label = _(u"Testimonial")
    description = _(u"Provide a quote to inspire others to give.")

    def updateWidgets(self):
        super(CreateDonorQuote, self).updateWidgets()
        self.widgets['contact_sf_id'].mode = 'hidden'
        self.widgets['donation_id'].mode = 'hidden'
        self.widgets['amount'].mode = 'hidden'

    @button.buttonAndHandler(_(u'Submit'))
    def handleOk(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # Add a donor quote in the current context,
        # using the data from the form
        parent_campaign = self.context
        quote = createContentInContainer(
            parent_campaign,
            'collective.salesforce.fundraising.donorquote',
            checkConstraints=False,
            **data)

        # Add the Constituent Quote to Salesforce
        sfconn = getUtility(ISalesforceUtility).get_connection()
        res = sfconn.Constituent_Quote__c.create({
            'Quote__c':
            data['quote'],
            'Name__c':
            data['name'],
            'Campaign__c':
            parent_campaign.sf_object_id,
            'Contact__c':
            data['contact_sf_id'],
            'Opportunity__c':
            data['donation_id'],
            'Amount__c':
            data['amount'],
        })

        if not res['success']:
            raise Exception(res['errors'][0])

        # Save the Id of the constituent quote so it can be updated
        quote.sf_object_id = res[0]['id']
        quote.parent_sf_id = parent_campaign.sf_object_id
        quote.reindexObject(idxs=['sf_object_id'])

        # Send the user back to the thank you page with a note about their
        # quote. Hide the donor quote section of the thank you page
        IStatusMessage(self.request).add(u'Your story has been '
                                         'successfully submitted.')
        if data['donation_id'] and data['amount']:
            self.request.response.redirect(
                parent_campaign.absolute_url() +
                '/thank-you?hide=donorquote&donation_id=%s&amount=%s' %
                (data['donation_id'], data['amount']))
        else:
            self.request.response.redirect(parent_campaign.absolute_url() +
                                           '/thank-you?hide=donorquote')
Beispiel #16
0
 def passwordsInvariant(data):
     if data.password != data.password_confirm:
         raise Invalid(_(u"Your passwords do not match, please enter the "
                         "same password in both fields"))